/*
 * 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;
    BYTE *buffer;
    WAVEFORMATEX *pwfx;
    ALuint source;
    INT64 frameswritten;
    REFERENCE_TIME laststamp;
    HANDLE timer_id;
    ALCdevice *capdev;
    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 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 (This->parent->flow == eRender && This->init) {
        setALContext(This->parent->ctx);
        IAudioClient_Stop((IAudioClient*)This);
        IAudioClient_Reset((IAudioClient*)This);
        palDeleteSources(1, &This->source);
        getALError();
        popALContext();
    }
    if (This->capdev)
        palcCaptureCloseDevice(This->capdev);
    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);
        FIXME("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);
        FIXME("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->capdev) {
        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->capdev = palcCaptureOpenDevice(alname, freq, This->format, size);
    if (!This->capdev) {
        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);
        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->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 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 (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->capdev, 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->capdev, buf1, avail);
            else {
                DWORD part1 = This->bufsize - ofs;
                palcCaptureSamples(This->capdev, buf1, part1);
                palcCaptureSamples(This->capdev, 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 (This->parent->flow == eRender) {
        setALContext(This->parent->ctx);
        palSourcePlay(This->source);
        getALError();
        popALContext();
    }
    else
        palcCaptureStart(This->capdev);

    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 (This->parent->flow == eRender) {
        ALint state;
        setALContext(This->parent->ctx);
        This->running = FALSE;
        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->capdev);
    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 (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->capdev, ALC_CAPTURE_SAMPLES, 1, &avail);
        if (avail)
            palcCaptureSamples(This->capdev, 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 locked = This->parent->locked;
    DWORD freq = This->parent->pwfx->nSamplesPerSec;
    DWORD bpp = This->parent->pwfx->wBitsPerSample;
    ALuint albuf;

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

    if (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);
    setALContext(This->parent->parent->ctx);

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

    ofs *= framesize;
    written *= framesize;
    bufsize *= framesize;
    locked *= 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);

    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();
    }
    This->parent->locked = 0;

    getALError();
    popALContext();
    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
