/*
 * 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)
        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);

    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;
    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
        && pwfx->wFormatTag != WAVE_FORMAT_PCM)
        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;
    }
    if (outpwfx)
        *outpwfx = NULL;
    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) {
        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
