// File: /workspace/github_c_makefile_star2_O3/jonof[P]jfaudiolib/src/driver_sdl.c
// Function: SDLDrv_PCM_Init
int SDLDrv_PCM_Init(int * mixrate, int * numchannels, int * samplebits, void * initdata)
{
    Uint32 inited;
    int err = 0;
    SDL_AudioSpec spec, actual;

    (void)initdata;

    if (Initialised) {
        SDLDrv_PCM_Shutdown();
    }

    inited = SDL_WasInit(SDL_INIT_EVERYTHING);

    if (inited == 0) {
        // nothing was initialised
        err = SDL_Init(SDL_INIT_AUDIO);
        StartedSDLInit |= 0x80000000 + SDL_INIT_AUDIO;
    } else if (!(inited & SDL_INIT_AUDIO)) {
        err = SDL_InitSubSystem(SDL_INIT_AUDIO);
        StartedSDLInit |= SDL_INIT_AUDIO;
    }

    if (err < 0) {
        ErrorCode = SDLErr_InitSubSystem;
        return SDLErr_Error;
    }

    StartedSDL |= SDL_INIT_AUDIO;

    #if (SDL_MAJOR_VERSION == 1)
    {
        char drivername[256] = "(error)";
        SDL_AudioDriverName(drivername, sizeof(drivername));
        ASS_Message("SDLDrv: audio driver: %s\n", drivername);
    }
    #else
    {
        const char * drivername = SDL_GetCurrentAudioDriver();
        ASS_Message("SDLDrv: audio driver: %s\n", drivername ? drivername : "(error)");
    }
    #endif

    memset(&spec, 0, sizeof(spec));
    spec.freq = *mixrate;
    spec.format = (*samplebits == 8) ? AUDIO_U8 : AUDIO_S16SYS;
    spec.channels = *numchannels;
    spec.callback = fillData;
    spec.userdata = 0;

    // Mix buffer to be a power of 2, min 512 samples, and 4096 samples at 48kHz.
    spec.samples = 512;
    while (spec.samples < (4096 * *mixrate / 48000))
        spec.samples += spec.samples;

    memset(&actual, 0, sizeof(actual));

    err = SDL_OpenAudio(&spec, &actual);
    if (err < 0) {
        ErrorCode = SDLErr_OpenAudio;
        return SDLErr_Error;
    }

    if (actual.freq == 0 || actual.channels == 0) {
        // hack for when SDL said it opened the audio, but clearly didn't
        SDL_CloseAudio();
        ErrorCode = SDLErr_OpenAudio;
        return SDLErr_Error;
    }

    err = 0;

    *mixrate = actual.freq;
    if (actual.format == AUDIO_U8 || actual.format == AUDIO_S16SYS) {
        *samplebits = actual.format & 0xff;
    } else {
        const char *format;
        switch (actual.format) {
            case AUDIO_U8: format = "AUDIO_U8"; break;
            case AUDIO_S8: format = "AUDIO_S8"; break;
            case AUDIO_U16LSB: format = "AUDIO_U16LSB"; break;
            case AUDIO_S16LSB: format = "AUDIO_S16LSB"; break;
            case AUDIO_U16MSB: format = "AUDIO_U16MSB"; break;
            case AUDIO_S16MSB: format = "AUDIO_S16MSB"; break;
            default: format = "?!"; break;
        }
        ASS_Message("SDLDrv: audio format: %s\n", format);
        ErrorCode = SDLErr_OpenAudio;
        err = 1;
    }
    if (actual.channels == 1 || actual.channels == 2) {
        *numchannels = actual.channels;
    } else {
        ASS_Message("SDLDrv: audio channels: %d\n", actual.channels);
        ErrorCode = SDLErr_OpenAudio;
        err = 1;
    }
    // ASS_Message("SDLDrv: actual samples = %d vs spec samples = %d\n", actual.samples, spec.samples);

    if (err) {
        SDL_CloseAudio();
        return SDLErr_Error;
    } else {
        Initialised = 1;
        return SDLErr_Ok;
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x48, %rsp
movq %rdx, %r14
movq %rsi, %rbx
movq %rdi, %r15
cmpb $0x1, 0x10afe(%rip)     # 0x19754
jne 0x8c5d
callq 0x8e63
movl $0xf231, %edi           # imm = 0xF231
callq 0x2120
testl %eax, %eax
je 0x8c80
testb $0x10, %al
jne 0x8c9d
movl $0x10, %ebp
movl $0x10, %edi
callq 0x21b0
jmp 0x8c8f
movl $0x10, %edi
callq 0x21a0
movl $0x80000010, %ebp       # imm = 0x80000010
orl %ebp, 0x10ac3(%rip)     # 0x19758
testl %eax, %eax
js 0x8d78
orb $0x10, 0x10ab8(%rip)    # 0x1975c
callq 0x2080
testq %rax, %rax
leaq 0x2373(%rip), %rsi      # 0xb026
cmovneq %rax, %rsi
leaq 0x234e(%rip), %rdi      # 0xb00c
xorl %eax, %eax
callq 0x8b10
xorps %xmm0, %xmm0
movaps %xmm0, (%rsp)
movl (%r15), %eax
movl %eax, (%rsp)
movl (%r14), %ecx
cmpl $0x8, %ecx
movl $0x8010, %edx           # imm = 0x8010
cmovel %ecx, %edx
movw %dx, 0x4(%rsp)
movb (%rbx), %cl
movb %cl, 0x6(%rsp)
leaq 0x1bd(%rip), %rcx       # 0x8eaf
movq %rcx, 0x10(%rsp)
movq $0x0, 0x18(%rsp)
shll $0xc, %eax
cltq
imulq $0x57619f1, %rax, %rax  # imm = 0x57619F1
movq %rax, %rcx
shrq $0x3f, %rcx
sarq $0x2a, %rax
addl %ecx, %eax
movw $0x200, %dx             # imm = 0x200
movl %edx, %ecx
movzwl %dx, %esi
leal (%rcx,%rcx), %edx
cmpl %esi, %eax
jg 0x8d1d
movq %rsp, %rdi
movw %cx, 0x8(%rdi)
xorps %xmm0, %xmm0
leaq 0x20(%rsp), %rsi
movaps %xmm0, (%rsi)
movaps %xmm0, 0x10(%rsi)
callq 0x2360
testl %eax, %eax
js 0x8d69
movl 0x20(%rsp), %ecx
testl %ecx, %ecx
sete %dl
movb 0x26(%rsp), %al
testb %al, %al
sete %sil
orb %dl, %sil
cmpb $0x1, %sil
jne 0x8d87
callq 0x2110
movl $0x3, 0x109dd(%rip)     # 0x19750
jmp 0x8e53
movl $0x2, 0x109ce(%rip)     # 0x19750
jmp 0x8e53
movl %ecx, (%r15)
movzwl 0x24(%rsp), %ebp
cmpl $0x8007, %ebp           # imm = 0x8007
jg 0x8db2
cmpl $0x8, %ebp
je 0x8dca
cmpl $0x10, %ebp
je 0x8de6
cmpl $0x1010, %ebp           # imm = 0x1010
jne 0x8ddd
leaq 0x2294(%rip), %rsi      # 0xb044
jmp 0x8df6
cmpl $0x8008, %ebp           # imm = 0x8008
je 0x8dd4
cmpl $0x9010, %ebp           # imm = 0x9010
je 0x8def
cmpl $0x8010, %ebp           # imm = 0x8010
jne 0x8ddd
movl %ebp, %ecx
andl $0x18, %ecx
movl %ecx, (%r14)
jmp 0x8e12
leaq 0x2253(%rip), %rsi      # 0xb02e
jmp 0x8df6
leaq 0x227a(%rip), %rsi      # 0xb05e
jmp 0x8df6
leaq 0x224a(%rip), %rsi      # 0xb037
jmp 0x8df6
leaq 0x225b(%rip), %rsi      # 0xb051
leaq 0x2264(%rip), %rdi      # 0xb061
xorl %eax, %eax
callq 0x8b10
movl $0x3, 0x10942(%rip)     # 0x19750
movb 0x26(%rsp), %al
movzbl %al, %esi
leal -0x1(%rsi), %eax
cmpb $0x1, %al
ja 0x8e36
movl %esi, (%rbx)
cmpl $0x8, %ebp
je 0x8e2b
cmpl $0x8010, %ebp           # imm = 0x8010
jne 0x8e4e
movb $0x1, 0x10922(%rip)     # 0x19754
xorl %eax, %eax
jmp 0x8e58
leaq 0x223e(%rip), %rdi      # 0xb07b
xorl %eax, %eax
callq 0x8b10
movl $0x3, 0x10902(%rip)     # 0x19750
callq 0x2110
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
addq $0x48, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq