// File: /workspace/github_c_makefile_star2_O2/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, 0x104eb(%rip)     # 0x18764
jne 0x8280
callq 0x8464
movl $0xf231, %edi           # imm = 0xF231
callq 0x2120
testl %eax, %eax
je 0x829e
testb $0x10, %al
jne 0x82b9
pushq $0x10
popq %rbp
movl %ebp, %edi
callq 0x21b0
jmp 0x82ab
pushq $0x10
popq %rdi
callq 0x21a0
movl $0x80000010, %ebp       # imm = 0x80000010
orl %ebp, 0x104b7(%rip)     # 0x18768
testl %eax, %eax
js 0x8383
orb $0x10, 0x104ac(%rip)    # 0x1876c
callq 0x2080
testq %rax, %rax
leaq 0x1cbf(%rip), %rsi      # 0x9f8e
cmovneq %rax, %rsi
leaq 0x1c9a(%rip), %rdi      # 0x9f74
xorl %eax, %eax
callq 0x813d
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 0x19d(%rip), %rcx       # 0x84ab
movq %rcx, 0x10(%rsp)
andq $0x0, 0x18(%rsp)
shll $0xc, %eax
movl $0xbb80, %ecx           # imm = 0xBB80
cltd
idivl %ecx
movw $0x200, %dx             # imm = 0x200
movl %edx, %ecx
movzwl %dx, %esi
leal (%rcx,%rcx), %edx
cmpl %esi, %eax
jg 0x8328
movq %rsp, %rdi
movw %cx, 0x8(%rdi)
xorps %xmm0, %xmm0
leaq 0x20(%rsp), %rsi
movaps %xmm0, (%rsi)
movaps %xmm0, 0x10(%rsi)
callq 0x2370
testl %eax, %eax
js 0x8374
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 0x8392
callq 0x2110
movl $0x3, 0x103e2(%rip)     # 0x18760
jmp 0x8456
movl $0x2, 0x103d3(%rip)     # 0x18760
jmp 0x8456
movl %ecx, (%r15)
movzwl 0x24(%rsp), %ebp
cmpl $0x8, %ebp
je 0x83c4
cmpl $0x10, %ebp
je 0x83f2
cmpl $0x1010, %ebp           # imm = 0x1010
je 0x83ce
cmpl $0x8008, %ebp           # imm = 0x8008
je 0x83e0
cmpl $0x9010, %ebp           # imm = 0x9010
je 0x83d7
cmpl $0x8010, %ebp           # imm = 0x8010
jne 0x83e9
movl %ebp, %ecx
andl $0x18, %ecx
movl %ecx, (%r14)
jmp 0x8415
leaq 0x1bd7(%rip), %rsi      # 0x9fac
jmp 0x83f9
leaq 0x1bdb(%rip), %rsi      # 0x9fb9
jmp 0x83f9
leaq 0x1baf(%rip), %rsi      # 0x9f96
jmp 0x83f9
leaq 0x1bd6(%rip), %rsi      # 0x9fc6
jmp 0x83f9
leaq 0x1ba6(%rip), %rsi      # 0x9f9f
leaq 0x1bc9(%rip), %rdi      # 0x9fc9
xorl %eax, %eax
callq 0x813d
movl $0x3, 0x1034f(%rip)     # 0x18760
movb 0x26(%rsp), %al
movzbl %al, %esi
leal -0x1(%rsi), %eax
cmpb $0x1, %al
ja 0x8439
movl %esi, (%rbx)
cmpl $0x8, %ebp
je 0x842e
cmpl $0x8010, %ebp           # imm = 0x8010
jne 0x8451
movb $0x1, 0x1032f(%rip)     # 0x18764
xorl %eax, %eax
jmp 0x8459
leaq 0x1ba3(%rip), %rdi      # 0x9fe3
xorl %eax, %eax
callq 0x813d
movl $0x3, 0x1030f(%rip)     # 0x18760
callq 0x2110
pushq $-0x1
popq %rax
addq $0x48, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq