/*
 * Copyright 2010 Maarten Lankhorst for CodeWeavers
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#define NONAMELESSUNION
#define CINTERFACE
#define COBJMACROS
#include "config.h"

#include <stdarg.h>
#ifdef HAVE_AL_AL_H
#include <AL/al.h>
#include <AL/alc.h>
#elif defined(HAVE_OPENAL_AL_H)
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
#endif

#include "windef.h"
#include "winbase.h"
#include "winnls.h"
#include "winreg.h"
#include "wine/debug.h"
#include "wine/unicode.h"

#include "ole2.h"
#include "mmdeviceapi.h"
#include "dshow.h"
#include "dsound.h"
#include "audioclient.h"
#include "endpointvolume.h"
#include "audiopolicy.h"

#include "mmdevapi.h"

WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi);

#ifdef HAVE_OPENAL

typedef struct ACRender ACRender;
typedef struct ACCapture ACCapture;
typedef struct ACSession ACSession;
typedef struct ASVolume ASVolume;
typedef struct AClock AClock;

typedef struct ACImpl {
    const IAudioClientVtbl *lpVtbl;
    LONG ref;

    MMDevice *parent;
    BOOL init, running;
    CRITICAL_SECTION *crst;
    HANDLE handle;
    DWORD locked, flags, bufsize, pad, padpartial, ofs, psize, candisconnect;
    BYTE *buffer;
    WAVEFORMATEX *pwfx;
    ALuint source;
    INT64 frameswritten;
    REFERENCE_TIME laststamp;
    HANDLE timer_id;
    ALCdevice *dev;
    ALint format;

    ACRender *render;
    ACCapture *capture;
    ACSession *session;
    ASVolume *svolume;
    AClock *clock;
} ACImpl;

struct ACRender {
    const IAudioRenderClientVtbl *lpVtbl;
    LONG ref;
    ACImpl *parent;
};

struct ACCapture {
    const IAudioCaptureClientVtbl *lpVtbl;
    LONG ref;
    ACImpl *parent;
};

struct ACSession {
    const IAudioSessionControl2Vtbl *lpVtbl;
    LONG ref;
    ACImpl *parent;
};

struct ASVolume {
    const ISimpleAudioVolumeVtbl *lpVtbl;
    LONG ref;
    ACImpl *parent;
};

struct AClock {
    const IAudioClockVtbl *lpVtbl;
    const IAudioClock2Vtbl *lp2Vtbl;
    LONG ref;
    ACImpl *parent;
};

static const IAudioClientVtbl ACImpl_Vtbl;
static const IAudioRenderClientVtbl ACRender_Vtbl;
static const IAudioCaptureClientVtbl ACCapture_Vtbl;
static const IAudioSessionControl2Vtbl ACSession_Vtbl;
static const ISimpleAudioVolumeVtbl ASVolume_Vtbl;
static const IAudioClockVtbl AClock_Vtbl;
static const IAudioClock2Vtbl AClock2_Vtbl;

static HRESULT AudioRenderClient_Create(ACImpl *parent, ACRender **ppv);
static void AudioRenderClient_Destroy(ACRender *This);
static HRESULT AudioCaptureClient_Create(ACImpl *parent, ACCapture **ppv);
static void AudioCaptureClient_Destroy(ACCapture *This);
static HRESULT AudioSessionControl_Create(ACImpl *parent, ACSession **ppv);
static void AudioSessionControl_Destroy(ACSession *This);
static HRESULT AudioSimpleVolume_Create(ACImpl *parent, ASVolume **ppv);
static void AudioSimpleVolume_Destroy(ASVolume *This);
static HRESULT AudioClock_Create(ACImpl *parent, AClock **ppv);
static void AudioClock_Destroy(AClock *This);

static int valid_dev(ACImpl *This)
{
    if (!This->dev)
        return 0;
    if (This->parent->flow == eRender && This->dev != This->parent->device)
        return 0;
    return 1;
}

static int get_format_PCM(WAVEFORMATEX *format)
{
    if (format->nChannels > 2) {
        FIXME("nChannels > 2 not documented for WAVE_FORMAT_PCM!\n");
        return 0;
    }

    format->cbSize = 0;

    if (format->nBlockAlign != format->wBitsPerSample/8*format->nChannels) {
        WARN("Invalid nBlockAlign %u, from %u %u\n",
             format->nBlockAlign, format->wBitsPerSample, format->nChannels);
        return 0;
    }

    switch (format->wBitsPerSample) {
        case 8: {
            switch (format->nChannels) {
            case 1: return AL_FORMAT_MONO8;
            case 2: return AL_FORMAT_STEREO8;
            }
        }
        case 16: {
            switch (format->nChannels) {
            case 1: return AL_FORMAT_MONO16;
            case 2: return AL_FORMAT_STEREO16;
            }
        }
    }

    if (!(format->wBitsPerSample % 8))
        WARN("Could not get OpenAL format (%d-bit, %d channels)\n",
             format->wBitsPerSample, format->nChannels);
    return 0;
}

/* Speaker configs */
#define MONO SPEAKER_FRONT_CENTER
#define STEREO (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT)
#define REAR (SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT)
#define QUAD (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT)
#define X5DOT1 (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT)
#define X6DOT1 (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_CENTER|SPEAKER_SIDE_LEFT|SPEAKER_SIDE_RIGHT)
#define X7DOT1 (SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT|SPEAKER_SIDE_LEFT|SPEAKER_SIDE_RIGHT)

static int get_format_EXT(WAVEFORMATEX *format)
{
    WAVEFORMATEXTENSIBLE *wfe;

    if(format->cbSize < sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX)) {
        WARN("Invalid cbSize specified for WAVE_FORMAT_EXTENSIBLE (%d)\n", format->cbSize);
        return 0;
    }

    wfe = (WAVEFORMATEXTENSIBLE*)format;
    wfe->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX);
    if (wfe->Samples.wValidBitsPerSample &&
        wfe->Samples.wValidBitsPerSample != format->wBitsPerSample) {
        FIXME("wValidBitsPerSample(%u) != wBitsPerSample(%u) unsupported\n",
              wfe->Samples.wValidBitsPerSample, format->wBitsPerSample);
        return 0;
    }

    TRACE("Extensible values:\n"
          "    Samples     = %d\n"
          "    ChannelMask = 0x%08x\n"
          "    SubFormat   = %s\n",
          wfe->Samples.wReserved, wfe->dwChannelMask,
          debugstr_guid(&wfe->SubFormat));

    if (wfe->dwChannelMask != MONO
        && wfe->dwChannelMask != STEREO
        && !palIsExtensionPresent("AL_EXT_MCFORMATS")) {
        /* QUAD PCM might still work, special case */
        if (palIsExtensionPresent("AL_LOKI_quadriphonic")
            && IsEqualGUID(&wfe->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)
            && wfe->dwChannelMask == QUAD) {
            if (format->wBitsPerSample == 16)
                return AL_FORMAT_QUAD16_LOKI;
            else if (format->wBitsPerSample == 8)
                return AL_FORMAT_QUAD8_LOKI;
        }
        WARN("Not all formats available\n");
        return 0;
    }

    if(IsEqualGUID(&wfe->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM)) {
        if (format->wBitsPerSample == 8) {
            switch (wfe->dwChannelMask) {
            case   MONO: return AL_FORMAT_MONO8;
            case STEREO: return AL_FORMAT_STEREO8;
            case   REAR: return AL_FORMAT_REAR8;
            case   QUAD: return AL_FORMAT_QUAD8;
            case X5DOT1: return AL_FORMAT_51CHN8;
            case X6DOT1: return AL_FORMAT_61CHN8;
            case X7DOT1: return AL_FORMAT_71CHN8;
            default: break;
            }
        } else if (format->wBitsPerSample  == 16) {
            switch (wfe->dwChannelMask) {
            case   MONO: return AL_FORMAT_MONO16;
            case STEREO: return AL_FORMAT_STEREO16;
            case   REAR: return AL_FORMAT_REAR16;
            case   QUAD: return AL_FORMAT_QUAD16;
            case X5DOT1: return AL_FORMAT_51CHN16;
            case X6DOT1: return AL_FORMAT_61CHN16;
            case X7DOT1: return AL_FORMAT_71CHN16;
            default: break;
            }
        }
        else if (!(format->wBitsPerSample  % 8))
            ERR("Could not get OpenAL PCM format (%d-bit, mask 0x%08x)\n",
                format->wBitsPerSample, wfe->dwChannelMask);
        return 0;
    }
    else if(IsEqualGUID(&wfe->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)) {
        if (format->wBitsPerSample != 32) {
            WARN("Invalid valid bits %u/32\n", format->wBitsPerSample);
            return 0;
        }
        switch (wfe->dwChannelMask) {
        case   MONO: return AL_FORMAT_MONO_FLOAT32;
        case STEREO: return AL_FORMAT_STEREO_FLOAT32;
        case   REAR: return AL_FORMAT_REAR32;
        case   QUAD: return AL_FORMAT_QUAD32;
        case X5DOT1: return AL_FORMAT_51CHN32;
        case X6DOT1: return AL_FORMAT_61CHN32;
        case X7DOT1: return AL_FORMAT_71CHN32;
        default:
            ERR("Could not get OpenAL float format (%d-bit, mask 0x%08x)\n",
                format->wBitsPerSample, wfe->dwChannelMask);
            return 0;
        }
    }
    else if (!IsEqualGUID(&wfe->SubFormat, &GUID_NULL))
        ERR("Unhandled extensible format: %s\n", debugstr_guid(&wfe->SubFormat));
    return 0;
}

static ALint get_format(WAVEFORMATEX *in)
{
    int ret = 0;
    if (in->wFormatTag == WAVE_FORMAT_PCM)
        ret = get_format_PCM(in);
    else if (in->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
        ret = get_format_EXT(in);
    return ret;
}

static REFERENCE_TIME gettime(void) {
    LARGE_INTEGER stamp, freq;
    QueryPerformanceCounter(&stamp);
    QueryPerformanceFrequency(&freq);
    return (stamp.QuadPart * (INT64)10000000) / freq.QuadPart;
}

HRESULT AudioClient_Create(MMDevice *parent, IAudioClient **ppv)
{
    ACImpl *This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This));
    *ppv = (IAudioClient*)This;
    if (!*ppv)
        return E_OUTOFMEMORY;
    This->crst = &parent->crst;
    This->lpVtbl = &ACImpl_Vtbl;
    This->ref = 1;
    This->parent = parent;
    return S_OK;
}

static void AudioClient_Destroy(ACImpl *This)
{
    if (This->timer_id)
        DeleteTimerQueueTimer(NULL, This->timer_id, INVALID_HANDLE_VALUE);
    if (This->render)
        AudioRenderClient_Destroy(This->render);
    if (This->capture)
        AudioCaptureClient_Destroy(This->capture);
    if (This->session)
        AudioSessionControl_Destroy(This->session);
    if (This->svolume)
        AudioSimpleVolume_Destroy(This->svolume);
    if (This->clock)
        AudioClock_Destroy(This->clock);
    if (!valid_dev(This))
        TRACE("Not destroying device since none exists\n");
    else if (This->parent->flow == eRender) {
        setALContext(This->parent->ctx);
        IAudioClient_Stop((IAudioClient*)This);
        IAudioClient_Reset((IAudioClient*)This);
        palDeleteSources(1, &This->source);
        getALError();
        popALContext();
    }
    else if (This->parent->flow == eCapture)
        palcCaptureCloseDevice(This->dev);
    HeapFree(GetProcessHeap(), 0, This->pwfx);
    HeapFree(GetProcessHeap(), 0, This->buffer);
    HeapFree(GetProcessHeap(), 0, This);
}

static void CALLBACK AC_tick(void *data, BOOLEAN fired)
{
    ACImpl *This = data;
    DWORD pad;

    EnterCriticalSection(This->crst);
    if (This->running)
        IAudioClient_GetCurrentPadding((IAudioClient*)This, &pad);
    LeaveCriticalSection(This->crst);
}

/* Open device and set/update internal mixing format based on information
 * openal provides us. if the device cannot be opened, assume 48khz
 * Guessing the frequency is harmless, since if GetMixFormat fails to open
 * the device, then Initialize will likely fail as well
 */
static HRESULT AC_OpenRenderAL(ACImpl *This)
{
    char alname[MAX_PATH];
    MMDevice *cur = This->parent;

    alname[sizeof(alname)-1] = 0;
    if (cur->device)
        return cur->ctx ? S_OK : AUDCLNT_E_SERVICE_NOT_RUNNING;

    WideCharToMultiByte(CP_UNIXCP, 0, cur->alname, -1,
                        alname, sizeof(alname)/sizeof(*alname)-1, NULL, NULL);
    cur->device = palcOpenDevice(alname);
    if (!cur->device) {
        ALCenum err = palcGetError(NULL);
        WARN("Could not open device %s: 0x%04x\n", alname, err);
        return AUDCLNT_E_DEVICE_IN_USE;
    }
    cur->ctx = palcCreateContext(cur->device, NULL);
    if (!cur->ctx) {
        ALCenum err = palcGetError(cur->device);
        ERR("Could not create context: 0x%04x\n", err);
        return AUDCLNT_E_SERVICE_NOT_RUNNING;
    }
    if (!cur->device)
        return AUDCLNT_E_DEVICE_IN_USE;
    return S_OK;
}

static HRESULT AC_OpenCaptureAL(ACImpl *This)
{
    char alname[MAX_PATH];
    ALint freq, size;

    freq = This->pwfx->nSamplesPerSec;
    size = This->bufsize;

    alname[sizeof(alname)-1] = 0;
    if (This->dev) {
        FIXME("Attempting to open device while already open\n");
        return S_OK;
    }
    WideCharToMultiByte(CP_UNIXCP, 0, This->parent->alname, -1,
                        alname, sizeof(alname)/sizeof(*alname)-1, NULL, NULL);
    This->dev = palcCaptureOpenDevice(alname, freq, This->format, size);
    if (!This->dev) {
        ALCenum err = palcGetError(NULL);
        FIXME("Could not open device %s with buf size %u: 0x%04x\n",
              alname, This->bufsize, err);
        return AUDCLNT_E_DEVICE_IN_USE;
    }
    return S_OK;
}

static HRESULT WINAPI AC_QueryInterface(IAudioClient *iface, REFIID riid, void **ppv)
{
    TRACE("(%p)->(%s,%p)\n", iface, debugstr_guid(riid), ppv);

    if (!ppv)
        return E_POINTER;
    *ppv = NULL;
    if (IsEqualIID(riid, &IID_IUnknown)
        || IsEqualIID(riid, &IID_IAudioClient))
        *ppv = iface;
    if (*ppv) {
        IUnknown_AddRef((IUnknown*)*ppv);
        return S_OK;
    }
    WARN("Unknown interface %s\n", debugstr_guid(riid));
    return E_NOINTERFACE;
}

static ULONG WINAPI AC_AddRef(IAudioClient *iface)
{
    ACImpl *This = (ACImpl*)iface;
    ULONG ref;
    ref = InterlockedIncrement(&This->ref);
    TRACE("Refcount now %i\n", ref);
    return ref;
}

static ULONG WINAPI AC_Release(IAudioClient *iface)
{
    ACImpl *This = (ACImpl*)iface;
    ULONG ref;
    ref = InterlockedDecrement(&This->ref);
    TRACE("Refcount now %i\n", ref);
    if (!ref)
        AudioClient_Destroy(This);
    return ref;
}

static HRESULT WINAPI AC_Initialize(IAudioClient *iface, AUDCLNT_SHAREMODE mode, DWORD flags, REFERENCE_TIME duration, REFERENCE_TIME period, const WAVEFORMATEX *pwfx, const GUID *sessionguid)
{
    ACImpl *This = (ACImpl*)iface;
    HRESULT hr = S_OK;
    WAVEFORMATEX *pwfx2;
    REFERENCE_TIME time, bufsize;

    TRACE("(%p)->(%x,%x,%u,%u,%p,%s)\n", This, mode, flags, (int)duration, (int)period, pwfx, debugstr_guid(sessionguid));
    if (This->init)
        return AUDCLNT_E_ALREADY_INITIALIZED;
    if (mode != AUDCLNT_SHAREMODE_SHARED
        && mode != AUDCLNT_SHAREMODE_EXCLUSIVE) {
        WARN("Unknown mode %x\n", mode);
        return AUDCLNT_E_NOT_INITIALIZED;
    }

    if (flags & ~(AUDCLNT_STREAMFLAGS_CROSSPROCESS
                  |AUDCLNT_STREAMFLAGS_LOOPBACK
                  |AUDCLNT_STREAMFLAGS_EVENTCALLBACK
                  |AUDCLNT_STREAMFLAGS_NOPERSIST
                  |AUDCLNT_STREAMFLAGS_RATEADJUST
                  |AUDCLNT_SESSIONFLAGS_EXPIREWHENUNOWNED
                  |AUDCLNT_SESSIONFLAGS_DISPLAY_HIDE
                  |AUDCLNT_SESSIONFLAGS_DISPLAY_HIDEWHENEXPIRED)) {
        WARN("Unknown flags 0x%08x\n", flags);
        return E_INVALIDARG;
    }
    if (flags)
        WARN("Flags 0x%08x ignored\n", flags);
    if (!pwfx)
        return E_POINTER;
    if (sessionguid)
        WARN("Session guid %s ignored\n", debugstr_guid(sessionguid));

    hr = IAudioClient_IsFormatSupported(iface, mode, pwfx, &pwfx2);
    CoTaskMemFree(pwfx2);
    if (FAILED(hr) || pwfx2) {
        WARN("Format not supported, or had to be modified!\n");
        return AUDCLNT_E_UNSUPPORTED_FORMAT;
    }
    EnterCriticalSection(This->crst);
    HeapFree(GetProcessHeap(), 0, This->pwfx);
    This->pwfx = HeapAlloc(GetProcessHeap(), 0, sizeof(*pwfx) + pwfx->cbSize);
    if (!This->pwfx) {
        hr = E_OUTOFMEMORY;
        goto out;
    }
    memcpy(This->pwfx, pwfx, sizeof(*pwfx) + pwfx->cbSize);
    if (pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) {
        WAVEFORMATEXTENSIBLE *wfe = (WAVEFORMATEXTENSIBLE *)This->pwfx;
        switch (pwfx->nChannels) {
            case 1: wfe->dwChannelMask = MONO; break;
            case 2: wfe->dwChannelMask = STEREO; break;
            case 4: wfe->dwChannelMask = QUAD; break;
            case 6: wfe->dwChannelMask = X5DOT1; break;
            case 7: wfe->dwChannelMask = X6DOT1; break;
            case 8: wfe->dwChannelMask = X7DOT1; break;
        default:
            ERR("How did we end up with %i channels?\n", pwfx->nChannels);
            hr = AUDCLNT_E_UNSUPPORTED_FORMAT;
            goto out;
        }
    }

    hr = IAudioClient_GetDevicePeriod(iface, &time, NULL);
    if (FAILED(hr))
        goto out;

    This->psize = (DWORD64)This->pwfx->nSamplesPerSec * time / (DWORD64)10000000;
    if (duration > 20000000)
        duration = 20000000;

    bufsize = duration / time * This->psize;
    if (duration % time)
        bufsize += This->psize;
    This->bufsize = bufsize;
    This->psize *= This->pwfx->nBlockAlign;
    bufsize *= pwfx->nBlockAlign;

    This->format = get_format(This->pwfx);
    if (This->parent->flow == eRender) {
        char silence[32];
        ALuint buf = 0, towrite;

        hr = AC_OpenRenderAL(This);
        This->dev = This->parent->device;
        if (FAILED(hr))
            goto out;

        /* Test the returned format */
        towrite = sizeof(silence);
        towrite -= towrite % This->pwfx->nBlockAlign;
        if (This->pwfx->wBitsPerSample != 8)
            memset(silence, 0, sizeof(silence));
        else
            memset(silence, 128, sizeof(silence));
        setALContext(This->parent->ctx);
        getALError();
        palGenBuffers(1, &buf);
        palBufferData(buf, This->format, silence, towrite, This->pwfx->nSamplesPerSec);
        palDeleteBuffers(1, &buf);
        if (palGetError())
            hr = AUDCLNT_E_UNSUPPORTED_FORMAT;
        else if (!This->source) {
            palGenSources(1, &This->source);
            palSourcei(This->source, AL_LOOPING, AL_FALSE);
            getALError();
        }
        popALContext();
    }
    else
        hr = AC_OpenCaptureAL(This);

    if (FAILED(hr))
        goto out;

    This->candisconnect = palcIsExtensionPresent(This->dev, "ALC_EXT_disconnect");
    This->buffer = HeapAlloc(GetProcessHeap(), 0, bufsize);
    if (!This->buffer) {
        hr = E_OUTOFMEMORY;
        goto out;
    }
    This->flags = flags;
    This->handle = NULL;
    This->running = FALSE;
    This->init = TRUE;
out:
    LeaveCriticalSection(This->crst);
    return hr;
}

static HRESULT WINAPI AC_GetBufferSize(IAudioClient *iface, UINT32 *frames)
{
    ACImpl *This = (ACImpl*)iface;
    TRACE("(%p)->(%p)\n", This, frames);
    if (!This->init)
        return AUDCLNT_E_NOT_INITIALIZED;
    if (!frames)
        return E_POINTER;
    *frames = This->bufsize;
    return S_OK;
}

static HRESULT WINAPI AC_GetStreamLatency(IAudioClient *iface, REFERENCE_TIME *latency)
{
    ACImpl *This = (ACImpl*)iface;
    TRACE("(%p)->(%p)\n", This, latency);

    if (!This->init)
        return AUDCLNT_E_NOT_INITIALIZED;

    if (!latency)
        return E_POINTER;

    *latency = 50000;

    return S_OK;
}

static int disconnected(ACImpl *This)
{
    if (!This->candisconnect)
        return 0;
    if (This->parent->flow == eRender) {
        if (This->parent->device) {
            ALCint con = 1;
            palcGetIntegerv(This->parent->device, ALC_CONNECTED, 1, &con);
            palcGetError(This->parent->device);
            if (!con) {
                palcCloseDevice(This->parent->device);
                This->parent->device = NULL;
                This->parent->ctx = NULL;
                This->dev = NULL;
            }
        }

        if (!This->parent->device && FAILED(AC_OpenRenderAL(This))) {
            This->pad -= This->padpartial;
            This->padpartial = 0;
            return 1;
        }
        if (This->parent->device != This->dev) {
            WARN("Emptying buffer after newly reconnected!\n");
            This->pad -= This->padpartial;
            This->padpartial = 0;

            This->dev = This->parent->device;
            setALContext(This->parent->ctx);
            palGenSources(1, &This->source);
            palSourcei(This->source, AL_LOOPING, AL_FALSE);
            getALError();

            if (This->render && !This->locked && This->pad) {
                UINT pad = This->pad;
                BYTE *data;
                This->pad = 0;

                /* Probably will cause sound glitches, who cares? */
                IAudioRenderClient_GetBuffer((IAudioRenderClient *)This->render, pad, &data);
                IAudioRenderClient_ReleaseBuffer((IAudioRenderClient *)This->render, pad, 0);
            }
            popALContext();
        }
    } else {
        if (This->dev) {
            ALCint con = 1;
            palcGetIntegerv(This->dev, ALC_CONNECTED, 1, &con);
            palcGetError(This->dev);
            if (!con) {
                palcCaptureCloseDevice(This->dev);
                This->dev = NULL;
            }
        }

        if (!This->dev) {
            if (FAILED(AC_OpenCaptureAL(This)))
                return 1;

            WARN("Emptying buffer after newly reconnected!\n");
            This->pad = This->ofs = 0;
            if (This->running)
                palcCaptureStart(This->dev);
        }
    }
    return 0;
}

static HRESULT WINAPI AC_GetCurrentPadding(IAudioClient *iface, UINT32 *numpad)
{
    ACImpl *This = (ACImpl*)iface;
    ALint avail = 0;

    TRACE("(%p)->(%p)\n", This, numpad);
    if (!This->init)
        return AUDCLNT_E_NOT_INITIALIZED;
    if (!numpad)
        return E_POINTER;
    EnterCriticalSection(This->crst);
    if (disconnected(This)) {
        REFERENCE_TIME time = gettime(), period;

        WARN("No device found, faking increment\n");
        IAudioClient_GetDevicePeriod(iface, &period, NULL);
        while (This->running && time - This->laststamp >= period) {
            This->laststamp += period;

            if (This->parent->flow == eCapture) {
                This->pad += This->psize;
                if (This->pad > This->bufsize)
                    This->pad = This->bufsize;
            } else {
                if (This->pad <= This->psize) {
                    This->pad = 0;
                    break;
                } else
                    This->pad -= This->psize;
            }
        }

        if (This->parent->flow == eCapture)
            *numpad = This->pad >= This->psize ? This->psize : 0;
        else
            *numpad = This->pad;
    } else if (This->parent->flow == eRender) {
        UINT64 played = 0;
        ALint state, padpart;
        setALContext(This->parent->ctx);

        palGetSourcei(This->source, AL_BYTE_OFFSET, &padpart);
        palGetSourcei(This->source, AL_SOURCE_STATE, &state);
        padpart /= This->pwfx->nBlockAlign;
        if (state == AL_STOPPED && This->running)
            padpart = This->pad;
        if (This->running && This->padpartial != padpart) {
            This->padpartial = padpart;
            This->laststamp = gettime();
#if 0 /* Manipulative lie */
        } else if (This->running) {
            ALint size = This->pad - padpart;
            if (size > This->psize)
                size = This->psize;
            played = (gettime() - This->laststamp)*8;
            played = played * This->pwfx->nSamplesPerSec / 10000000;
            if (played > size)
                played = size;
#endif
        }
        *numpad = This->pad - This->padpartial - played;
        if (This->handle && *numpad + This->psize <= This->bufsize)
            SetEvent(This->handle);
        getALError();
        popALContext();
    } else {
        DWORD block = This->pwfx->nBlockAlign;
        DWORD psize = This->psize / block;
        palcGetIntegerv(This->dev, ALC_CAPTURE_SAMPLES, 1, &avail);
        if (avail) {
            DWORD ofs = This->ofs + This->pad;
            BYTE *buf1;
            ofs %= This->bufsize;
            buf1 = This->buffer + (ofs * block);
            This->laststamp = gettime();
            if (This->handle)
                SetEvent(This->handle);

            if (ofs + avail <= This->bufsize)
                palcCaptureSamples(This->dev, buf1, avail);
            else {
                DWORD part1 = This->bufsize - ofs;
                palcCaptureSamples(This->dev, buf1, part1);
                palcCaptureSamples(This->dev, This->buffer, avail - part1);
            }
            This->pad += avail;
            This->frameswritten += avail;
            /* Increase ofs if the app forgets to read */
            if (This->pad > This->bufsize) {
                DWORD rest;
                WARN("Overflowed! %u bytes\n", This->pad - This->bufsize);
                This->ofs += This->pad - This->bufsize;
                rest = This->ofs % psize;
                if (rest)
                    This->ofs += psize - rest;
                This->ofs %= This->bufsize;
                This->pad = This->bufsize;
            }
        }
        if (This->pad >= psize)
            *numpad = psize;
        else
            *numpad = 0;
    }
    LeaveCriticalSection(This->crst);

    TRACE("%u queued\n", *numpad);
    return S_OK;
}

static HRESULT WINAPI AC_IsFormatSupported(IAudioClient *iface, AUDCLNT_SHAREMODE mode, const WAVEFORMATEX *pwfx, WAVEFORMATEX **outpwfx)
{
    ACImpl *This = (ACImpl*)iface;
    WAVEFORMATEX *tmp;
    DWORD mask;
    DWORD size;
    TRACE("(%p)->(%x,%p,%p)\n", This, mode, pwfx, outpwfx);
    if (!pwfx)
        return E_POINTER;

    if (mode == AUDCLNT_SHAREMODE_SHARED && !outpwfx)
        return E_POINTER;
    if (mode != AUDCLNT_SHAREMODE_SHARED
        && mode != AUDCLNT_SHAREMODE_EXCLUSIVE) {
        WARN("Unknown mode %x\n", mode);
        return E_INVALIDARG;
    }

    if (pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
        size = sizeof(WAVEFORMATEXTENSIBLE);
    else if (pwfx->wFormatTag == WAVE_FORMAT_PCM)
        size = sizeof(WAVEFORMATEX);
    else
        return AUDCLNT_E_UNSUPPORTED_FORMAT;

    if (pwfx->nSamplesPerSec < 8000
        || pwfx->nSamplesPerSec > 192000)
        return AUDCLNT_E_UNSUPPORTED_FORMAT;
    if (pwfx->wFormatTag != WAVE_FORMAT_EXTENSIBLE
        || !IsEqualIID(&((WAVEFORMATEXTENSIBLE*)pwfx)->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)) {
        if (pwfx->wBitsPerSample > 16)
            return AUDCLNT_E_UNSUPPORTED_FORMAT;
    }

    switch (pwfx->nChannels) {
        case 1: mask = MONO; break;
        case 2: mask = STEREO; break;
        case 4: mask = QUAD; break;
        case 6: mask = X5DOT1; break;
        case 7: mask = X6DOT1; break;
        case 8: mask = X7DOT1; break;
        default:
            TRACE("Unsupported channel count %i\n", pwfx->nChannels);
            return AUDCLNT_E_UNSUPPORTED_FORMAT;
    }
    tmp = CoTaskMemAlloc(size);
    if (outpwfx)
        *outpwfx = tmp;
    if (!tmp)
        return E_OUTOFMEMORY;

    memcpy(tmp, pwfx, size);
    tmp->nBlockAlign = tmp->nChannels * tmp->wBitsPerSample / 8;
    tmp->nAvgBytesPerSec = tmp->nBlockAlign * tmp->nSamplesPerSec;
    tmp->cbSize = size - sizeof(WAVEFORMATEX);
    if (tmp->wFormatTag == WAVE_FORMAT_EXTENSIBLE) {
        WAVEFORMATEXTENSIBLE *ex = (WAVEFORMATEXTENSIBLE*)tmp;

        if (ex->Samples.wValidBitsPerSample)
            ex->Samples.wValidBitsPerSample = ex->Format.wBitsPerSample;

        /* Rear is a special allowed case */
        if (ex->dwChannelMask
            && !(ex->Format.nChannels == 2 && ex->dwChannelMask == REAR))
            ex->dwChannelMask = mask;
    }

    if (memcmp(pwfx, tmp, size)) {
        if (outpwfx)
            return S_FALSE;
        CoTaskMemFree(tmp);
        return AUDCLNT_E_UNSUPPORTED_FORMAT;
    }
    if (outpwfx)
        *outpwfx = NULL;
    CoTaskMemFree(tmp);
    return S_OK;
}

static HRESULT WINAPI AC_GetMixFormat(IAudioClient *iface, WAVEFORMATEX **pwfx)
{
    ACImpl *This = (ACImpl*)iface;
    PROPVARIANT pv = { VT_EMPTY };
    HRESULT hr = S_OK;

    TRACE("(%p)->(%p)\n", This, pwfx);
    if (!pwfx)
        return E_POINTER;

    hr = MMDevice_GetPropValue(&This->parent->devguid, This->parent->flow,
                               &PKEY_AudioEngine_DeviceFormat, &pv);
    *pwfx = (WAVEFORMATEX*)pv.u.blob.pBlobData;
    if (SUCCEEDED(hr) && pv.vt == VT_EMPTY)
        return E_FAIL;

    TRACE("Returning 0x%08x\n", hr);
    return hr;
}

static HRESULT WINAPI AC_GetDevicePeriod(IAudioClient *iface, REFERENCE_TIME *defperiod, REFERENCE_TIME *minperiod)
{
    ACImpl *This = (ACImpl*)iface;

    TRACE("(%p)->(%p)\n", This, minperiod);
    if (!defperiod && !minperiod)
        return E_POINTER;

    if (minperiod)
        *minperiod = 30000;
    if (defperiod)
        *defperiod = 200000;
    return S_OK;
}

static HRESULT WINAPI AC_Start(IAudioClient *iface)
{
    ACImpl *This = (ACImpl*)iface;
    HRESULT hr;
    REFERENCE_TIME refresh;

    TRACE("(%p)\n", This);
    if (!This->init)
        return AUDCLNT_E_NOT_INITIALIZED;
    if (This->flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK) {
        if (!This->handle)
            return AUDCLNT_E_EVENTHANDLE_NOT_SET;
        FIXME("Event handles not fully tested\n");
    }
    EnterCriticalSection(This->crst);
    if (This->running) {
        hr = AUDCLNT_E_NOT_STOPPED;
        goto out;
    }
    if (!valid_dev(This))
        WARN("No valid device\n");
    else if (This->parent->flow == eRender) {
        setALContext(This->parent->ctx);
        palSourcePlay(This->source);
        getALError();
        popALContext();
    }
    else
        palcCaptureStart(This->dev);

    AC_GetDevicePeriod(iface, &refresh, NULL);
    if (!This->timer_id && This->handle)
        CreateTimerQueueTimer(&This->timer_id, NULL, AC_tick, This,
                              refresh / 20000, refresh / 20000,
                              WT_EXECUTEINTIMERTHREAD);
    /* Set to 0, otherwise risk running the clock backwards
     * This will cause AudioClock::GetPosition to return the maximum
     * possible value for the current buffer
     */
    This->laststamp = 0;
    This->running = TRUE;
    hr = S_OK;
out:
    LeaveCriticalSection(This->crst);
    return hr;
}

static HRESULT WINAPI AC_Stop(IAudioClient *iface)
{
    ACImpl *This = (ACImpl*)iface;
    HANDLE timer_id;
    TRACE("(%p)\n", This);
    if (!This->init)
        return AUDCLNT_E_NOT_INITIALIZED;
    if (!This->running)
        return S_FALSE;
    EnterCriticalSection(This->crst);
    if (!valid_dev(This))
        WARN("No valid device\n");
    else if (This->parent->flow == eRender) {
        ALint state;
        setALContext(This->parent->ctx);
        palSourcePause(This->source);
        while (1) {
            state = AL_STOPPED;
            palGetSourcei(This->source, AL_SOURCE_STATE, &state);
            if (state != AL_PLAYING)
                break;
            Sleep(1);
        }
        getALError();
        popALContext();
    }
    else
        palcCaptureStop(This->dev);
    This->running = FALSE;
    timer_id = This->timer_id;
    This->timer_id = 0;
    LeaveCriticalSection(This->crst);
    if (timer_id)
        DeleteTimerQueueTimer(NULL, timer_id, INVALID_HANDLE_VALUE);
    return S_OK;
}

static HRESULT WINAPI AC_Reset(IAudioClient *iface)
{
    ACImpl *This = (ACImpl*)iface;
    HRESULT hr = S_OK;
    TRACE("(%p)\n", This);
    if (!This->init)
        return AUDCLNT_E_NOT_INITIALIZED;
    if (This->running)
        return AUDCLNT_E_NOT_STOPPED;
    EnterCriticalSection(This->crst);
    if (This->locked) {
        hr = AUDCLNT_E_BUFFER_OPERATION_PENDING;
        goto out;
    }
    if (!valid_dev(This))
        WARN("No valid device\n");
    else if (This->parent->flow == eRender) {
        ALuint buf;
        ALint n = 0;
        setALContext(This->parent->ctx);
        palSourceStop(This->source);
        palGetSourcei(This->source, AL_BUFFERS_PROCESSED, &n);
        while (n--) {
            palSourceUnqueueBuffers(This->source, 1, &buf);
            palDeleteBuffers(1, &buf);
        }
        getALError();
        popALContext();
    } else {
        ALint avail = 0;
        palcGetIntegerv(This->dev, ALC_CAPTURE_SAMPLES, 1, &avail);
        if (avail)
            palcCaptureSamples(This->dev, This->buffer, avail);
    }
    This->pad = This->padpartial = 0;
    This->ofs = 0;
    This->frameswritten = 0;
out:
    LeaveCriticalSection(This->crst);
    return hr;
}

static HRESULT WINAPI AC_SetEventHandle(IAudioClient *iface, HANDLE handle)
{
    ACImpl *This = (ACImpl*)iface;
    TRACE("(%p)\n", This);
    if (!This->init)
        return AUDCLNT_E_NOT_INITIALIZED;
    if (!handle)
        return E_INVALIDARG;
    if (!(This->flags & AUDCLNT_STREAMFLAGS_EVENTCALLBACK))
        return AUDCLNT_E_EVENTHANDLE_NOT_EXPECTED;
    This->handle = handle;
    return S_OK;
}

static HRESULT WINAPI AC_GetService(IAudioClient *iface, REFIID riid, void **ppv)
{
    ACImpl *This = (ACImpl*)iface;
    HRESULT hr = S_OK;
    TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppv);
    if (!This->init)
        return AUDCLNT_E_NOT_INITIALIZED;
    if (!ppv)
        return E_POINTER;
    *ppv = NULL;

    if (IsEqualIID(riid, &IID_IAudioRenderClient)) {
        if (This->parent->flow != eRender)
            return AUDCLNT_E_WRONG_ENDPOINT_TYPE;
        if (!This->render)
            hr = AudioRenderClient_Create(This, &This->render);
        *ppv = This->render;
    } else if (IsEqualIID(riid, &IID_IAudioCaptureClient)) {
        if (This->parent->flow != eCapture)
            return AUDCLNT_E_WRONG_ENDPOINT_TYPE;
        if (!This->capture)
            hr = AudioCaptureClient_Create(This, &This->capture);
        *ppv = This->capture;
    } else if (IsEqualIID(riid, &IID_IAudioSessionControl)) {
        if (!This->session)
            hr = AudioSessionControl_Create(This, &This->session);
        *ppv = This->session;
    } else if (IsEqualIID(riid, &IID_ISimpleAudioVolume)) {
        if (!This->svolume)
            hr = AudioSimpleVolume_Create(This, &This->svolume);
        *ppv = This->svolume;
    } else if (IsEqualIID(riid, &IID_IAudioClock)) {
        if (!This->clock)
            hr = AudioClock_Create(This, &This->clock);
        *ppv = This->clock;
    }

    if (FAILED(hr))
        return hr;

    if (*ppv) {
        IUnknown_AddRef((IUnknown*)*ppv);
        return S_OK;
    }

    FIXME("stub %s\n", debugstr_guid(riid));
    return E_NOINTERFACE;
}

static const IAudioClientVtbl ACImpl_Vtbl =
{
    AC_QueryInterface,
    AC_AddRef,
    AC_Release,
    AC_Initialize,
    AC_GetBufferSize,
    AC_GetStreamLatency,
    AC_GetCurrentPadding,
    AC_IsFormatSupported,
    AC_GetMixFormat,
    AC_GetDevicePeriod,
    AC_Start,
    AC_Stop,
    AC_Reset,
    AC_SetEventHandle,
    AC_GetService
};

static HRESULT AudioRenderClient_Create(ACImpl *parent, ACRender **ppv)
{
    ACRender *This;

    This = *ppv = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
    if (!This)
        return E_OUTOFMEMORY;
    This->lpVtbl = &ACRender_Vtbl;
    This->ref = 0;
    This->parent = parent;
    return S_OK;
}

static void AudioRenderClient_Destroy(ACRender *This)
{
    This->parent->render = NULL;
    HeapFree(GetProcessHeap(), 0, This);
}

static HRESULT WINAPI ACR_QueryInterface(IAudioRenderClient *iface, REFIID riid, void **ppv)
{
    TRACE("(%p)->(%s,%p)\n", iface, debugstr_guid(riid), ppv);

    if (!ppv)
        return E_POINTER;
    *ppv = NULL;
    if (IsEqualIID(riid, &IID_IUnknown)
        || IsEqualIID(riid, &IID_IAudioRenderClient))
        *ppv = iface;
    if (*ppv) {
        IUnknown_AddRef((IUnknown*)*ppv);
        return S_OK;
    }
    WARN("Unknown interface %s\n", debugstr_guid(riid));
    return E_NOINTERFACE;
}

static ULONG WINAPI ACR_AddRef(IAudioRenderClient *iface)
{
    ACRender *This = (ACRender*)iface;
    ULONG ref;
    ref = InterlockedIncrement(&This->ref);
    TRACE("Refcount now %i\n", ref);
    return ref;
}

static ULONG WINAPI ACR_Release(IAudioRenderClient *iface)
{
    ACRender *This = (ACRender*)iface;
    ULONG ref;
    ref = InterlockedDecrement(&This->ref);
    TRACE("Refcount now %i\n", ref);
    if (!ref)
        AudioRenderClient_Destroy(This);
    return ref;
}

static HRESULT WINAPI ACR_GetBuffer(IAudioRenderClient *iface, UINT32 frames, BYTE **data)
{
    ACRender *This = (ACRender*)iface;
    DWORD free, framesize;
    TRACE("(%p)->(%u,%p)\n", This, frames, data);

    if (!data)
        return E_POINTER;
    if (!frames)
        return S_OK;
    *data = NULL;
    if (This->parent->locked) {
        ERR("Locked\n");
        return AUDCLNT_E_OUT_OF_ORDER;
    }
    AC_GetCurrentPadding((IAudioClient*)This->parent, &free);
    if (This->parent->bufsize-free < frames) {
        ERR("Too large: %u %u %u\n", This->parent->bufsize, free, frames);
        return AUDCLNT_E_BUFFER_TOO_LARGE;
    }
    EnterCriticalSection(This->parent->crst);
    This->parent->locked = frames;
    framesize = This->parent->pwfx->nBlockAlign;

    /* Exact offset doesn't matter, offset could be 0 forever
     * but increasing it is easier to debug */
    if (This->parent->ofs + frames > This->parent->bufsize)
        This->parent->ofs = 0;
    *data = This->parent->buffer + This->parent->ofs * framesize;

    LeaveCriticalSection(This->parent->crst);
    return S_OK;
}

static HRESULT WINAPI ACR_ReleaseBuffer(IAudioRenderClient *iface, UINT32 written, DWORD flags)
{
    ACRender *This = (ACRender*)iface;
    BYTE *buf = This->parent->buffer;
    DWORD framesize = This->parent->pwfx->nBlockAlign;
    DWORD ofs = This->parent->ofs;
    DWORD bufsize = This->parent->bufsize;
    DWORD freq = This->parent->pwfx->nSamplesPerSec;
    DWORD bpp = This->parent->pwfx->wBitsPerSample;
    ALuint albuf;

    TRACE("(%p)->(%u,%x)\n", This, written, flags);

    if (This->parent->locked < written)
        return AUDCLNT_E_INVALID_SIZE;

    if (flags & ~AUDCLNT_BUFFERFLAGS_SILENT)
        return E_INVALIDARG;

    if (!written) {
        if (This->parent->locked)
            FIXME("Handled right?\n");
        This->parent->locked = 0;
        return S_OK;
    }

    if (!This->parent->locked)
        return AUDCLNT_E_OUT_OF_ORDER;

    EnterCriticalSection(This->parent->crst);

    This->parent->ofs += written;
    This->parent->ofs %= bufsize;
    This->parent->pad += written;
    This->parent->frameswritten += written;
    This->parent->locked = 0;

    ofs *= framesize;
    written *= framesize;
    bufsize *= framesize;

    if (flags & AUDCLNT_BUFFERFLAGS_SILENT)
        memset(buf+ofs, bpp != 8 ? 0 : 128, written);
    TRACE("buf: %p, ofs: %x, written %u, freq %u\n", buf, ofs, written, freq);
    if (!valid_dev(This->parent))
        goto out;

    setALContext(This->parent->parent->ctx);
    palGenBuffers(1, &albuf);
    palBufferData(albuf, This->parent->format, buf+ofs, written, freq);
    palSourceQueueBuffers(This->parent->source, 1, &albuf);
    TRACE("Queued %u\n", albuf);

    if (This->parent->running) {
        ALint state = AL_PLAYING, done = 0, padpart = 0;

        palGetSourcei(This->parent->source, AL_BUFFERS_PROCESSED, &done);
        palGetSourcei(This->parent->source, AL_BYTE_OFFSET, &padpart);
        palGetSourcei(This->parent->source, AL_SOURCE_STATE, &state);
        padpart /= framesize;

        if (state == AL_STOPPED) {
            padpart = This->parent->pad;
            /* Buffer might have been processed in the small window
             * between first and third call */
            palGetSourcei(This->parent->source, AL_BUFFERS_PROCESSED, &done);
        }
        if (done || This->parent->padpartial != padpart)
            This->parent->laststamp = gettime();
        This->parent->padpartial = padpart;

        while (done--) {
            ALint size, bits, chan;
            ALuint which;

            palSourceUnqueueBuffers(This->parent->source, 1, &which);
            palGetBufferi(which, AL_SIZE, &size);
            palGetBufferi(which, AL_BITS, &bits);
            palGetBufferi(which, AL_CHANNELS, &chan);
            size /= bits * chan / 8;
            if (size > This->parent->pad) {
                ERR("Overflow!\n");
                size = This->parent->pad;
            }
            This->parent->pad -= size;
            This->parent->padpartial -= size;
            TRACE("Unqueued %u\n", which);
            palDeleteBuffers(1, &which);
        }

        if (state != AL_PLAYING) {
            ERR("Starting from %x\n", state);
            palSourcePlay(This->parent->source);
        }
        getALError();
    }
    getALError();
    popALContext();
out:
    LeaveCriticalSection(This->parent->crst);

    return S_OK;
}

static const IAudioRenderClientVtbl ACRender_Vtbl = {
    ACR_QueryInterface,
    ACR_AddRef,
    ACR_Release,
    ACR_GetBuffer,
    ACR_ReleaseBuffer
};

static HRESULT AudioCaptureClient_Create(ACImpl *parent, ACCapture **ppv)
{
    ACCapture *This;
    This = *ppv = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
    if (!This)
        return E_OUTOFMEMORY;
    This->lpVtbl = &ACCapture_Vtbl;
    This->ref = 0;
    This->parent = parent;
    return S_OK;
}

static void AudioCaptureClient_Destroy(ACCapture *This)
{
    This->parent->capture = NULL;
    HeapFree(GetProcessHeap(), 0, This);
}

static HRESULT WINAPI ACC_QueryInterface(IAudioCaptureClient *iface, REFIID riid, void **ppv)
{
    TRACE("(%p)->(%s,%p)\n", iface, debugstr_guid(riid), ppv);

    if (!ppv)
        return E_POINTER;
    *ppv = NULL;
    if (IsEqualIID(riid, &IID_IUnknown)
        || IsEqualIID(riid, &IID_IAudioCaptureClient))
        *ppv = iface;
    if (*ppv) {
        IUnknown_AddRef((IUnknown*)*ppv);
        return S_OK;
    }
    WARN("Unknown interface %s\n", debugstr_guid(riid));
    return E_NOINTERFACE;
}

static ULONG WINAPI ACC_AddRef(IAudioCaptureClient *iface)
{
    ACCapture *This = (ACCapture*)iface;
    ULONG ref;
    ref = InterlockedIncrement(&This->ref);
    TRACE("Refcount now %i\n", ref);
    return ref;
}

static ULONG WINAPI ACC_Release(IAudioCaptureClient *iface)
{
    ACCapture *This = (ACCapture*)iface;
    ULONG ref;
    ref = InterlockedDecrement(&This->ref);
    TRACE("Refcount now %i\n", ref);
    if (!ref)
        AudioCaptureClient_Destroy(This);
    return ref;
}

static HRESULT WINAPI ACC_GetBuffer(IAudioCaptureClient *iface, BYTE **data, UINT32 *frames, DWORD *flags, UINT64 *devpos, UINT64 *qpcpos)
{
    ACCapture *This = (ACCapture*)iface;
    HRESULT hr;
    DWORD block = This->parent->pwfx->nBlockAlign;
    DWORD ofs, bufsize;
    TRACE("(%p)->(%p,%p,%p,%p,%p)\n", This, data, frames, flags, devpos, qpcpos);

    if (!data)
        return E_POINTER;
    if (!frames)
        return E_POINTER;
    if (!flags) {
        FIXME("Flags can be null?\n");
        return E_POINTER;
    }
    EnterCriticalSection(This->parent->crst);
    hr = AUDCLNT_E_OUT_OF_ORDER;
    if (This->parent->locked)
        goto out;
    IAudioCaptureClient_GetNextPacketSize(iface, frames);
    ofs = This->parent->ofs;
    bufsize = This->parent->bufsize;
    if ( (ofs*block) % This->parent->psize)
        ERR("Unaligned offset %u with %u\n", ofs*block, This->parent->psize);
    *data = This->parent->buffer + ofs * block;
    This->parent->locked = *frames;
    if (devpos)
        *devpos = This->parent->frameswritten - This->parent->pad;
    if (qpcpos)
        *qpcpos = This->parent->laststamp;
    if (*frames)
        hr = S_OK;
    else
        hr = AUDCLNT_S_BUFFER_EMPTY;
out:
    LeaveCriticalSection(This->parent->crst);
    TRACE("Returning %08x %i\n", hr, *frames);
    return hr;
}

static HRESULT WINAPI ACC_ReleaseBuffer(IAudioCaptureClient *iface, UINT32 written)
{
    ACCapture *This = (ACCapture*)iface;
    HRESULT hr = S_OK;
    EnterCriticalSection(This->parent->crst);
    if (!written || written == This->parent->locked) {
        This->parent->locked = 0;
        This->parent->ofs += written;
        This->parent->ofs %= This->parent->bufsize;
        This->parent->pad -= written;
    } else if (!This->parent->locked)
        hr = AUDCLNT_E_OUT_OF_ORDER;
    else
        hr = AUDCLNT_E_INVALID_SIZE;
    LeaveCriticalSection(This->parent->crst);
    return hr;
}

static HRESULT WINAPI ACC_GetNextPacketSize(IAudioCaptureClient *iface, UINT32 *frames)
{
    ACCapture *This = (ACCapture*)iface;

    return AC_GetCurrentPadding((IAudioClient*)This->parent, frames);
}

static const IAudioCaptureClientVtbl ACCapture_Vtbl =
{
    ACC_QueryInterface,
    ACC_AddRef,
    ACC_Release,
    ACC_GetBuffer,
    ACC_ReleaseBuffer,
    ACC_GetNextPacketSize
};

static HRESULT AudioSessionControl_Create(ACImpl *parent, ACSession **ppv)
{
    ACSession *This;
    This = *ppv = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
    if (!This)
        return E_OUTOFMEMORY;
    This->lpVtbl = &ACSession_Vtbl;
    This->ref = 0;
    This->parent = parent;
    return S_OK;
}

static void AudioSessionControl_Destroy(ACSession *This)
{
    This->parent->session = NULL;
    HeapFree(GetProcessHeap(), 0, This);
}

static HRESULT WINAPI ACS_QueryInterface(IAudioSessionControl2 *iface, REFIID riid, void **ppv)
{
    TRACE("(%p)->(%s,%p)\n", iface, debugstr_guid(riid), ppv);

    if (!ppv)
        return E_POINTER;
    *ppv = NULL;
    if (IsEqualIID(riid, &IID_IUnknown)
        || IsEqualIID(riid, &IID_IAudioSessionControl)
        || IsEqualIID(riid, &IID_IAudioSessionControl2))
        *ppv = iface;
    if (*ppv) {
        IUnknown_AddRef((IUnknown*)*ppv);
        return S_OK;
    }
    WARN("Unknown interface %s\n", debugstr_guid(riid));
    return E_NOINTERFACE;
}

static ULONG WINAPI ACS_AddRef(IAudioSessionControl2 *iface)
{
    ACSession *This = (ACSession*)iface;
    ULONG ref;
    ref = InterlockedIncrement(&This->ref);
    TRACE("Refcount now %i\n", ref);
    return ref;
}

static ULONG WINAPI ACS_Release(IAudioSessionControl2 *iface)
{
    ACSession *This = (ACSession*)iface;
    ULONG ref;
    ref = InterlockedDecrement(&This->ref);
    TRACE("Refcount now %i\n", ref);
    if (!ref)
        AudioSessionControl_Destroy(This);
    return ref;
}

static HRESULT WINAPI ACS_GetState(IAudioSessionControl2 *iface, AudioSessionState *state)
{
    ACSession *This = (ACSession*)iface;
    TRACE("(%p)->(%p)\n", This, state);

    if (!state)
        return E_POINTER;
    *state = This->parent->parent->state;
    return E_NOTIMPL;
}

static HRESULT WINAPI ACS_GetDisplayName(IAudioSessionControl2 *iface, WCHAR **name)
{
    ACSession *This = (ACSession*)iface;
    TRACE("(%p)->(%p)\n", This, name);
    FIXME("stub\n");
    if (name)
        *name = NULL;
    return E_NOTIMPL;
}

static HRESULT WINAPI ACS_SetDisplayName(IAudioSessionControl2 *iface, const WCHAR *name, const GUID *session)
{
    ACSession *This = (ACSession*)iface;
    TRACE("(%p)->(%p,%s)\n", This, name, debugstr_guid(session));
    FIXME("stub\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ACS_GetIconPath(IAudioSessionControl2 *iface, WCHAR **path)
{
    ACSession *This = (ACSession*)iface;
    TRACE("(%p)->(%p)\n", This, path);
    FIXME("stub\n");
    if (path)
        *path = NULL;
    return E_NOTIMPL;
}

static HRESULT WINAPI ACS_SetIconPath(IAudioSessionControl2 *iface, const WCHAR *path, const GUID *session)
{
    ACSession *This = (ACSession*)iface;
    TRACE("(%p)->(%p,%s)\n", This, path, debugstr_guid(session));
    FIXME("stub\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ACS_GetGroupingParam(IAudioSessionControl2 *iface, GUID *group)
{
    ACSession *This = (ACSession*)iface;
    TRACE("(%p)->(%p)\n", This, group);
    FIXME("stub\n");
    if (group)
        *group = GUID_NULL;
    return E_NOTIMPL;
}

static HRESULT WINAPI ACS_SetGroupingParam(IAudioSessionControl2 *iface, GUID *group, const GUID *session)
{
    ACSession *This = (ACSession*)iface;
    TRACE("(%p)->(%s,%s)\n", This, debugstr_guid(group), debugstr_guid(session));
    FIXME("stub\n");
    return E_NOTIMPL;
}

static HRESULT WINAPI ACS_RegisterAudioSessionNotification(IAudioSessionControl2 *iface, IAudioSessionEvents *events)
{
    ACSession *This = (ACSession*)iface;
    TRACE("(%p)->(%p)\n", This, events);
    FIXME("stub\n");
    return S_OK;
}

static HRESULT WINAPI ACS_UnregisterAudioSessionNotification(IAudioSessionControl2 *iface, IAudioSessionEvents *events)
{
    ACSession *This = (ACSession*)iface;
    TRACE("(%p)->(%p)\n", This, events);
    FIXME("stub\n");
    return S_OK;
}

static HRESULT WINAPI ACS_GetSessionIdentifier(IAudioSessionControl2 *iface, WCHAR **id)
{
    ACSession *This = (ACSession*)iface;
    TRACE("(%p)->(%p)\n", This, id);
    FIXME("stub\n");
    if (id)
        *id = NULL;
    return E_NOTIMPL;
}

static HRESULT WINAPI ACS_GetSessionInstanceIdentifier(IAudioSessionControl2 *iface, WCHAR **id)
{
    ACSession *This = (ACSession*)iface;
    TRACE("(%p)->(%p)\n", This, id);
    FIXME("stub\n");
    if (id)
        *id = NULL;
    return E_NOTIMPL;
}

static HRESULT WINAPI ACS_GetProcessId(IAudioSessionControl2 *iface, DWORD *pid)
{
    ACSession *This = (ACSession*)iface;
    TRACE("(%p)->(%p)\n", This, pid);

    if (!pid)
        return E_POINTER;
    *pid = GetCurrentProcessId();
    return S_OK;
}

static HRESULT WINAPI ACS_IsSystemSoundsSession(IAudioSessionControl2 *iface)
{
    ACSession *This = (ACSession*)iface;
    TRACE("(%p)\n", This);

    return S_FALSE;
}

static HRESULT WINAPI ACS_SetDuckingPreference(IAudioSessionControl2 *iface, BOOL optout)
{
    ACSession *This = (ACSession*)iface;
    TRACE("(%p)\n", This);

    return S_OK;
}

static const IAudioSessionControl2Vtbl ACSession_Vtbl =
{
    ACS_QueryInterface,
    ACS_AddRef,
    ACS_Release,
    ACS_GetState,
    ACS_GetDisplayName,
    ACS_SetDisplayName,
    ACS_GetIconPath,
    ACS_SetIconPath,
    ACS_GetGroupingParam,
    ACS_SetGroupingParam,
    ACS_RegisterAudioSessionNotification,
    ACS_UnregisterAudioSessionNotification,
    ACS_GetSessionIdentifier,
    ACS_GetSessionInstanceIdentifier,
    ACS_GetProcessId,
    ACS_IsSystemSoundsSession,
    ACS_SetDuckingPreference
};

static HRESULT AudioSimpleVolume_Create(ACImpl *parent, ASVolume **ppv)
{
    ASVolume *This;
    This = *ppv = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
    if (!This)
        return E_OUTOFMEMORY;
    This->lpVtbl = &ASVolume_Vtbl;
    This->ref = 0;
    This->parent = parent;
    return S_OK;
}

static void AudioSimpleVolume_Destroy(ASVolume *This)
{
    This->parent->svolume = NULL;
    HeapFree(GetProcessHeap(), 0, This);
}

static HRESULT WINAPI ASV_QueryInterface(ISimpleAudioVolume *iface, REFIID riid, void **ppv)
{
    TRACE("(%p)->(%s,%p)\n", iface, debugstr_guid(riid), ppv);

    if (!ppv)
        return E_POINTER;
    *ppv = NULL;
    if (IsEqualIID(riid, &IID_IUnknown)
        || IsEqualIID(riid, &IID_ISimpleAudioVolume))
        *ppv = iface;
    if (*ppv) {
        IUnknown_AddRef((IUnknown*)*ppv);
        return S_OK;
    }
    WARN("Unknown interface %s\n", debugstr_guid(riid));
    return E_NOINTERFACE;
}

static ULONG WINAPI ASV_AddRef(ISimpleAudioVolume *iface)
{
    ASVolume *This = (ASVolume*)iface;
    ULONG ref;
    ref = InterlockedIncrement(&This->ref);
    TRACE("Refcount now %i\n", ref);
    return ref;
}

static ULONG WINAPI ASV_Release(ISimpleAudioVolume *iface)
{
    ASVolume *This = (ASVolume*)iface;
    ULONG ref;
    ref = InterlockedDecrement(&This->ref);
    TRACE("Refcount now %i\n", ref);
    if (!ref)
        AudioSimpleVolume_Destroy(This);
    return ref;
}

static HRESULT WINAPI ASV_SetMasterVolume(ISimpleAudioVolume *iface, float level, const GUID *context)
{
    ASVolume *This = (ASVolume*)iface;
    TRACE("(%p)->(%f,%p)\n", This, level, context);

    FIXME("stub\n");
    return S_OK;
}

static HRESULT WINAPI ASV_GetMasterVolume(ISimpleAudioVolume *iface, float *level)
{
    ASVolume *This = (ASVolume*)iface;
    TRACE("(%p)->(%p)\n", This, level);

    *level = 1.f;
    FIXME("stub\n");
    return S_OK;
}

static HRESULT WINAPI ASV_SetMute(ISimpleAudioVolume *iface, BOOL mute, const GUID *context)
{
    ASVolume *This = (ASVolume*)iface;
    TRACE("(%p)->(%u,%p)\n", This, mute, context);

    FIXME("stub\n");
    return S_OK;
}

static HRESULT WINAPI ASV_GetMute(ISimpleAudioVolume *iface, BOOL *mute)
{
    ASVolume *This = (ASVolume*)iface;
    TRACE("(%p)->(%p)\n", This, mute);

    *mute = 0;
    FIXME("stub\n");
    return S_OK;
}

static const ISimpleAudioVolumeVtbl ASVolume_Vtbl  =
{
    ASV_QueryInterface,
    ASV_AddRef,
    ASV_Release,
    ASV_SetMasterVolume,
    ASV_GetMasterVolume,
    ASV_SetMute,
    ASV_GetMute
};

static HRESULT AudioClock_Create(ACImpl *parent, AClock **ppv)
{
    AClock *This;
    This = *ppv = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
    if (!This)
        return E_OUTOFMEMORY;
    This->lpVtbl = &AClock_Vtbl;
    This->lp2Vtbl = &AClock2_Vtbl;
    This->ref = 0;
    This->parent = parent;
    return S_OK;
}

static void AudioClock_Destroy(AClock *This)
{
    This->parent->clock = NULL;
    HeapFree(GetProcessHeap(), 0, This);
}

static HRESULT WINAPI AClock_QueryInterface(IAudioClock *iface, REFIID riid, void **ppv)
{
    AClock *This = (AClock*)iface;
    TRACE("(%p)->(%s,%p)\n", iface, debugstr_guid(riid), ppv);

    if (!ppv)
        return E_POINTER;
    *ppv = NULL;
    if (IsEqualIID(riid, &IID_IUnknown)
        || IsEqualIID(riid, &IID_IAudioClock))
        *ppv = iface;
    else if (IsEqualIID(riid, &IID_IAudioClock2))
        *ppv = &This->lp2Vtbl;
    if (*ppv) {
        IUnknown_AddRef((IUnknown*)*ppv);
        return S_OK;
    }
    WARN("Unknown interface %s\n", debugstr_guid(riid));
    return E_NOINTERFACE;
}

static ULONG WINAPI AClock_AddRef(IAudioClock *iface)
{
    AClock *This = (AClock*)iface;
    ULONG ref;
    ref = InterlockedIncrement(&This->ref);
    TRACE("Refcount now %i\n", ref);
    return ref;
}

static ULONG WINAPI AClock_Release(IAudioClock *iface)
{
    AClock *This = (AClock*)iface;
    ULONG ref;
    ref = InterlockedDecrement(&This->ref);
    TRACE("Refcount now %i\n", ref);
    if (!ref)
        AudioClock_Destroy(This);
    return ref;
}

static HRESULT WINAPI AClock_GetFrequency(IAudioClock *iface, UINT64 *freq)
{
    AClock *This = (AClock*)iface;
    TRACE("(%p)->(%p)\n", This, freq);

    *freq = (UINT64)This->parent->pwfx->nSamplesPerSec;
    return S_OK;
}

static HRESULT WINAPI AClock_GetPosition(IAudioClock *iface, UINT64 *pos, UINT64 *qpctime)
{
    AClock *This = (AClock*)iface;
    DWORD pad;

    TRACE("(%p)->(%p,%p)\n", This, pos, qpctime);

    if (!pos)
        return E_POINTER;

    EnterCriticalSection(This->parent->crst);
    AC_GetCurrentPadding((IAudioClient*)This->parent, &pad);
    *pos = This->parent->frameswritten - pad;
    if (qpctime)
        *qpctime = gettime();
    LeaveCriticalSection(This->parent->crst);

    return S_OK;
}

static HRESULT WINAPI AClock_GetCharacteristics(IAudioClock *iface, DWORD *chars)
{
    AClock *This = (AClock*)iface;
    TRACE("(%p)->(%p)\n", This, chars);

    if (!chars)
        return E_POINTER;
    *chars = AUDIOCLOCK_CHARACTERISTIC_FIXED_FREQ;
    return S_OK;
}

static const IAudioClockVtbl AClock_Vtbl =
{
    AClock_QueryInterface,
    AClock_AddRef,
    AClock_Release,
    AClock_GetFrequency,
    AClock_GetPosition,
    AClock_GetCharacteristics
};

static AClock *get_clock_from_clock2(IAudioClock2 *iface)
{
    return (AClock*)((char*)iface - offsetof(AClock,lp2Vtbl));
}

static HRESULT WINAPI AClock2_QueryInterface(IAudioClock2 *iface, REFIID riid, void **ppv)
{
    AClock *This = get_clock_from_clock2(iface);
    return IUnknown_QueryInterface((IUnknown*)This, riid, ppv);
}

static ULONG WINAPI AClock2_AddRef(IAudioClock2 *iface)
{
    AClock *This = get_clock_from_clock2(iface);
    return IUnknown_AddRef((IUnknown*)This);
}

static ULONG WINAPI AClock2_Release(IAudioClock2 *iface)
{
    AClock *This = get_clock_from_clock2(iface);
    return IUnknown_Release((IUnknown*)This);
}

static HRESULT WINAPI AClock2_GetPosition(IAudioClock2 *iface, UINT64 *pos, UINT64 *qpctime)
{
    AClock *This = get_clock_from_clock2(iface);
    return AClock_GetPosition((IAudioClock*)This, pos, qpctime);
}

static const IAudioClock2Vtbl AClock2_Vtbl =
{
    AClock2_QueryInterface,
    AClock2_AddRef,
    AClock2_Release,
    AClock2_GetPosition
};

#endif
