/*
 * QEMU DirectSound audio driver header
 *
 * Copyright (c) 2005 Vassili Karpov (malc)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#ifdef DSBTYPE_IN
#define NAME "capture buffer"
#define NAME2 "DirectSoundCapture"
#define TYPE in
#define IFACE IDirectSoundCaptureBuffer
#define BUFPTR LPDIRECTSOUNDCAPTUREBUFFER
#define FIELD dsound_capture_buffer
#define FIELD2 dsound_capture
#define HWVOICE HWVoiceIn
#define DSOUNDVOICE DSoundVoiceIn
#else
#define NAME "playback buffer"
#define NAME2 "DirectSound"
#define TYPE out
#define IFACE IDirectSoundBuffer
#define BUFPTR LPDIRECTSOUNDBUFFER
#define FIELD dsound_buffer
#define FIELD2 dsound
#define HWVOICE HWVoiceOut
#define DSOUNDVOICE DSoundVoiceOut
#endif

static int glue (dsound_unlock_, TYPE) (
    BUFPTR buf,
    LPVOID p1,
    LPVOID p2,
    DWORD blen1,
    DWORD blen2
    )
{
    HRESULT hr;

    hr = glue (IFACE, _Unlock) (buf, p1, blen1, p2, blen2);
    if (FAILED (hr)) {
        dsound_logerr (hr, "Could not unlock " NAME "\n");
        return -1;
    }

    return 0;
}

static int glue (dsound_lock_, TYPE) (
    BUFPTR buf,
    struct audio_pcm_info *info,
    DWORD pos,
    DWORD len,
    LPVOID *p1p,
    LPVOID *p2p,
    DWORD *blen1p,
    DWORD *blen2p,
    int entire,
    dsound *s
    )
{
    HRESULT hr;
    DWORD flag;

#ifdef DSBTYPE_IN
    flag = entire ? DSCBLOCK_ENTIREBUFFER : 0;
#else
    flag = entire ? DSBLOCK_ENTIREBUFFER : 0;
#endif
    hr = glue(IFACE, _Lock)(buf, pos, len, p1p, blen1p, p2p, blen2p, flag);

    if (FAILED (hr)) {
#ifndef DSBTYPE_IN
        if (hr == DSERR_BUFFERLOST) {
            if (glue (dsound_restore_, TYPE) (buf, s)) {
                dsound_logerr (hr, "Could not lock " NAME "\n");
            }
            goto fail;
        }
#endif
        dsound_logerr (hr, "Could not lock " NAME "\n");
        goto fail;
    }

    if ((p1p && *p1p && (*blen1p & info->align)) ||
        (p2p && *p2p && (*blen2p & info->align))) {
        dolog("DirectSound returned misaligned buffer %ld %ld\n",
              *blen1p, *blen2p);
        glue(dsound_unlock_, TYPE)(buf, *p1p, p2p ? *p2p : NULL, *blen1p,
                                   blen2p ? *blen2p : 0);
        goto fail;
    }

    if (p1p && !*p1p && *blen1p) {
        dolog("warning: !p1 && blen1=%ld\n", *blen1p);
        *blen1p = 0;
    }

    if (p2p && !*p2p && *blen2p) {
        dolog("warning: !p2 && blen2=%ld\n", *blen2p);
        *blen2p = 0;
    }

    return 0;

 fail:
    *p1p = NULL - 1;
    *blen1p = -1;
    if (p2p) {
        *p2p = NULL - 1;
        *blen2p = -1;
    }
    return -1;
}

#ifdef DSBTYPE_IN
static void dsound_fini_in (HWVoiceIn *hw)
#else
static void dsound_fini_out (HWVoiceOut *hw)
#endif
{
    HRESULT hr;
#ifdef DSBTYPE_IN
    DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
#else
    DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
#endif

    if (ds->FIELD) {
        hr = glue (IFACE, _Stop) (ds->FIELD);
        if (FAILED (hr)) {
            dsound_logerr (hr, "Could not stop " NAME "\n");
        }

        hr = glue (IFACE, _Release) (ds->FIELD);
        if (FAILED (hr)) {
            dsound_logerr (hr, "Could not release " NAME "\n");
        }
        ds->FIELD = NULL;
    }
}

#ifdef DSBTYPE_IN
static int dsound_init_in(HWVoiceIn *hw, struct audsettings *as,
                          void *drv_opaque)
#else
static int dsound_init_out(HWVoiceOut *hw, struct audsettings *as,
                           void *drv_opaque)
#endif
{
    int err;
    HRESULT hr;
    dsound *s = drv_opaque;
    WAVEFORMATEX wfx;
    struct audsettings obt_as;
#ifdef DSBTYPE_IN
    const char *typ = "ADC";
    DSoundVoiceIn *ds = (DSoundVoiceIn *) hw;
    DSCBUFFERDESC bd;
    DSCBCAPS bc;
    AudiodevPerDirectionOptions *pdo = s->dev->u.dsound.in;
#else
    const char *typ = "DAC";
    DSoundVoiceOut *ds = (DSoundVoiceOut *) hw;
    DSBUFFERDESC bd;
    DSBCAPS bc;
    AudiodevPerDirectionOptions *pdo = s->dev->u.dsound.out;
#endif

    if (!s->FIELD2) {
        dolog ("Attempt to initialize voice without " NAME2 " object\n");
        return -1;
    }

    err = waveformat_from_audio_settings (&wfx, as);
    if (err) {
        return -1;
    }

    memset (&bd, 0, sizeof (bd));
    bd.dwSize = sizeof (bd);
    bd.lpwfxFormat = &wfx;
    bd.dwBufferBytes = audio_buffer_bytes(pdo, as, 92880);
#ifdef DSBTYPE_IN
    hr = IDirectSoundCapture_CreateCaptureBuffer (
        s->dsound_capture,
        &bd,
        &ds->dsound_capture_buffer,
        NULL
        );
#else
    bd.dwFlags = DSBCAPS_STICKYFOCUS | DSBCAPS_GETCURRENTPOSITION2;
    hr = IDirectSound_CreateSoundBuffer (
        s->dsound,
        &bd,
        &ds->dsound_buffer,
        NULL
        );
#endif

    if (FAILED (hr)) {
        dsound_logerr2 (hr, typ, "Could not create " NAME "\n");
        return -1;
    }

    hr = glue (IFACE, _GetFormat) (ds->FIELD, &wfx, sizeof (wfx), NULL);
    if (FAILED (hr)) {
        dsound_logerr2 (hr, typ, "Could not get " NAME " format\n");
        goto fail0;
    }

#ifdef DEBUG_DSOUND
    dolog (NAME "\n");
    print_wave_format (&wfx);
#endif

    memset (&bc, 0, sizeof (bc));
    bc.dwSize = sizeof (bc);

    hr = glue (IFACE, _GetCaps) (ds->FIELD, &bc);
    if (FAILED (hr)) {
        dsound_logerr2 (hr, typ, "Could not get " NAME " format\n");
        goto fail0;
    }

    err = waveformat_to_audio_settings (&wfx, &obt_as);
    if (err) {
        goto fail0;
    }

    obt_as.endianness = 0;
    audio_pcm_init_info (&hw->info, &obt_as);

    if (bc.dwBufferBytes & hw->info.align) {
        dolog (
            "GetCaps returned misaligned buffer size %ld, alignment %d\n",
            bc.dwBufferBytes, hw->info.align + 1
            );
    }
    hw->size_emul = bc.dwBufferBytes;
    hw->samples = bc.dwBufferBytes >> hw->info.shift;
    ds->s = s;

#ifdef DEBUG_DSOUND
    dolog ("caps %ld, desc %ld\n",
           bc.dwBufferBytes, bd.dwBufferBytes);
#endif
    return 0;

 fail0:
    glue (dsound_fini_, TYPE) (hw);
    return -1;
}

#undef NAME
#undef NAME2
#undef TYPE
#undef IFACE
#undef BUFPTR
#undef FIELD
#undef FIELD2
#undef HWVOICE
#undef DSOUNDVOICE
