/*
 * Sample Wine Driver for Advanced Linux Sound System (ALSA)
 *      Based on version <final> of the ALSA API
 *
 * Copyright 2007 - Maarten Lankhorst
 *
 * 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
 */

/*======================================================================*
 *              Low level dsound input implementation			*
 *======================================================================*/

#include "config.h"
#include "wine/port.h"

#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <errno.h>
#include <limits.h>
#include <fcntl.h>
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif
#ifdef HAVE_SYS_MMAN_H
# include <sys/mman.h>
#endif
#include "windef.h"
#include "winbase.h"
#include "wingdi.h"
#include "winerror.h"
#include "winuser.h"
#include "mmddk.h"

#include "alsa.h"
#include "wine/library.h"
#include "wine/unicode.h"
#include "wine/debug.h"

/* Notify timer checks every 10 ms with a resolution of 2 ms */
#define DS_TIME_DEL 10
#define DS_TIME_RES 2

WINE_DEFAULT_DEBUG_CHANNEL(dsalsa);

typedef struct IDsCaptureDriverBufferImpl IDsCaptureDriverBufferImpl;

typedef struct IDsCaptureDriverImpl
{
    const IDsCaptureDriverVtbl *lpVtbl;
    LONG ref;
    IDsCaptureDriverBufferImpl* capture_buffer;
    UINT wDevID;
} IDsCaptureDriverImpl;

typedef struct IDsCaptureDriverNotifyImpl
{
    const IDsDriverNotifyVtbl *lpVtbl;
    LONG ref;
    IDsCaptureDriverBufferImpl *buffer;
    DSBPOSITIONNOTIFY *notifies;
    DWORD nrofnotifies, playpos;
    UINT timerID;
} IDsCaptureDriverNotifyImpl;

struct IDsCaptureDriverBufferImpl
{
    const IDsCaptureDriverBufferVtbl *lpVtbl;
    LONG ref;
    IDsCaptureDriverImpl *drv;
    IDsCaptureDriverNotifyImpl *notify;

    CRITICAL_SECTION pcm_crst;
    LPBYTE mmap_buffer, presented_buffer;
    DWORD mmap_buflen_bytes, play_looping, mmap_ofs_bytes;
    BOOL mmap;

    /* Note: snd_pcm_frames_to_bytes(This->pcm, mmap_buflen_frames) != mmap_buflen_bytes */
    /* The actual buffer may differ in size from the wanted buffer size */

    snd_pcm_t *pcm;
    snd_pcm_hw_params_t *hw_params;
    snd_pcm_sw_params_t *sw_params;
    snd_pcm_uframes_t mmap_buflen_frames, mmap_pos;
};

static void Capture_CheckNotify(IDsCaptureDriverNotifyImpl *This, DWORD from, DWORD len)
{
    unsigned i;
    for (i = 0; i < This->nrofnotifies; ++i) {
        LPDSBPOSITIONNOTIFY event = This->notifies + i;
        DWORD offset = event->dwOffset;
        TRACE("checking %d, position %d, event = %p\n", i, offset, event->hEventNotify);

        if (offset == DSBPN_OFFSETSTOP) {
            if (!from && !len) {
                SetEvent(event->hEventNotify);
                TRACE("signalled event %p (%d)\n", event->hEventNotify, i);
                return;
            }
            else return;
        }

        if (offset >= from && offset < (from + len))
        {
            TRACE("signalled event %p (%d)\n", event->hEventNotify, i);
            SetEvent(event->hEventNotify);
        }
    }
}

static void CALLBACK Capture_Notify(UINT timerID, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
{
    IDsCaptureDriverBufferImpl *This = (IDsCaptureDriverBufferImpl *)dwUser;
    DWORD last_playpos, playpos;
    PIDSCDRIVERBUFFER iface = (PIDSCDRIVERBUFFER)This;

    /* **** */
    /* Don't deadlock since there is a critical section can be held by the timer api itself while running this code */
    if (!TryEnterCriticalSection(&This->pcm_crst)) return;

    IDsDriverBuffer_GetPosition(iface, &playpos, NULL);
    last_playpos = This->notify->playpos;
    This->notify->playpos = playpos;

    if (snd_pcm_state(This->pcm) != SND_PCM_STATE_RUNNING || last_playpos == playpos || !This->notify->nrofnotifies || !This->notify->notifies)
        goto done;

    if (playpos < last_playpos)
    {
        Capture_CheckNotify(This->notify, last_playpos, This->mmap_buflen_bytes);
        if (playpos)
            Capture_CheckNotify(This->notify, 0, playpos);
    }
    else Capture_CheckNotify(This->notify, last_playpos, playpos - last_playpos);

done:
    LeaveCriticalSection(&This->pcm_crst);
    /* **** */
}

static HRESULT WINAPI IDsCaptureDriverNotifyImpl_QueryInterface(PIDSDRIVERNOTIFY iface, REFIID riid, LPVOID *ppobj)
{
    IDsCaptureDriverNotifyImpl *This = (IDsCaptureDriverNotifyImpl *)iface;
    TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);

    if ( IsEqualGUID(riid, &IID_IUnknown) ||
         IsEqualGUID(riid, &IID_IDsDriverNotify) ) {
        IDsDriverNotify_AddRef(iface);
        *ppobj = This;
        return DS_OK;
    }

    FIXME( "Unknown IID %s\n", debugstr_guid(riid));

    *ppobj = 0;
    return E_NOINTERFACE;
}

static ULONG WINAPI IDsCaptureDriverNotifyImpl_AddRef(PIDSDRIVERNOTIFY iface)
{
    IDsCaptureDriverNotifyImpl *This = (IDsCaptureDriverNotifyImpl *)iface;
    ULONG refCount = InterlockedIncrement(&This->ref);

    TRACE("(%p) ref was %d\n", This, refCount - 1);

    return refCount;
}

static ULONG WINAPI IDsCaptureDriverNotifyImpl_Release(PIDSDRIVERNOTIFY iface)
{
    IDsCaptureDriverNotifyImpl *This = (IDsCaptureDriverNotifyImpl *)iface;
    ULONG refCount = InterlockedDecrement(&This->ref);

    TRACE("(%p) ref was %d\n", This, refCount + 1);

    if (!refCount) {
        This->buffer->notify = NULL;
        if (This->timerID)
        {
            timeKillEvent(This->timerID);
            timeEndPeriod(DS_TIME_RES);
        }
        HeapFree(GetProcessHeap(), 0, This->notifies);
        HeapFree(GetProcessHeap(), 0, This);
        TRACE("(%p) released\n", This);
    }
    return refCount;
}

static HRESULT WINAPI IDsCaptureDriverNotifyImpl_SetNotificationPositions(PIDSDRIVERNOTIFY iface, DWORD howmuch, LPCDSBPOSITIONNOTIFY notify)
{
    DWORD len = howmuch * sizeof(DSBPOSITIONNOTIFY);
    unsigned i;
    LPVOID notifies;
    IDsCaptureDriverNotifyImpl *This = (IDsCaptureDriverNotifyImpl *)iface;
    TRACE("(%p,0x%08x,%p)\n",This,howmuch,notify);

    if (!notify) {
        WARN("invalid parameter\n");
        return DSERR_INVALIDPARAM;
    }

    if (TRACE_ON(dsalsa))
        for (i=0;i<howmuch; ++i)
            TRACE("notify at %d to %p\n", notify[i].dwOffset, notify[i].hEventNotify);

    /* **** */
    EnterCriticalSection(&This->buffer->pcm_crst);

    /* Make an internal copy of the caller-supplied array.
     * Replace the existing copy if one is already present. */
    if (This->notifies)
        notifies = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->notifies, len);
    else
        notifies = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);

    if (!notifies)
    {
        LeaveCriticalSection(&This->buffer->pcm_crst);
        /* **** */
        return DSERR_OUTOFMEMORY;
    }
    This->notifies = notifies;
    memcpy(This->notifies, notify, len);
    This->nrofnotifies = howmuch;
    IDsDriverBuffer_GetPosition((PIDSCDRIVERBUFFER)This->buffer, &This->playpos, NULL);

    if (!This->timerID)
    {
        timeBeginPeriod(DS_TIME_RES);
        This->timerID = timeSetEvent(DS_TIME_DEL, DS_TIME_RES, Capture_Notify, (DWORD_PTR)This->buffer, TIME_PERIODIC | TIME_KILL_SYNCHRONOUS);
    }

    LeaveCriticalSection(&This->buffer->pcm_crst);
    /* **** */

    return S_OK;
}

static const IDsDriverNotifyVtbl dscdnvt =
{
    IDsCaptureDriverNotifyImpl_QueryInterface,
    IDsCaptureDriverNotifyImpl_AddRef,
    IDsCaptureDriverNotifyImpl_Release,
    IDsCaptureDriverNotifyImpl_SetNotificationPositions,
};

#if 0
/** Convert the position an application sees into a position ALSA sees */
static snd_pcm_uframes_t fakepos_to_realpos(const IDsCaptureDriverBufferImpl* This, DWORD fakepos)
{
    snd_pcm_uframes_t realpos;
    if (fakepos < This->mmap_ofs_bytes)
        realpos = This->mmap_buflen_bytes + fakepos - This->mmap_ofs_bytes;
    else realpos = fakepos - This->mmap_ofs_bytes;
    return snd_pcm_bytes_to_frames(This->pcm, realpos) % This->mmap_buflen_frames;
}
#endif

/** Convert the position ALSA sees into a position an application sees */
static DWORD realpos_to_fakepos(const IDsCaptureDriverBufferImpl* This, snd_pcm_uframes_t realpos)
{
    DWORD realposb = snd_pcm_frames_to_bytes(This->pcm, realpos);
    return (realposb + This->mmap_ofs_bytes) % This->mmap_buflen_bytes;
}

/** Raw copy data, with buffer wrap around */
static void CopyDataWrap(const IDsCaptureDriverBufferImpl* This, LPBYTE dest, DWORD fromwhere, DWORD copylen, DWORD buflen)
{
    DWORD remainder = buflen - fromwhere;
    if (remainder >= copylen)
    {
        CopyMemory(dest, This->mmap_buffer + fromwhere, copylen);
    }
    else
    {
        CopyMemory(dest, This->mmap_buffer + fromwhere, remainder);
        copylen -= remainder;
        CopyMemory(dest, This->mmap_buffer, copylen);
    }
}

/** Copy data from the mmap buffer to backbuffer, taking into account all wraparounds that may occur */
static void CopyData(const IDsCaptureDriverBufferImpl* This, snd_pcm_uframes_t fromwhere, snd_pcm_uframes_t len)
{
    DWORD dlen = snd_pcm_frames_to_bytes(This->pcm, len) % This->mmap_buflen_bytes;

    /* Backbuffer */
    DWORD ofs = realpos_to_fakepos(This, fromwhere);
    DWORD remainder = This->mmap_buflen_bytes - ofs;

    /* MMAP buffer */
    DWORD realbuflen = snd_pcm_frames_to_bytes(This->pcm, This->mmap_buflen_frames);
    DWORD realofs = snd_pcm_frames_to_bytes(This->pcm, fromwhere);

    if (remainder >= dlen)
    {
       CopyDataWrap(This, This->presented_buffer + ofs, realofs, dlen, realbuflen);
    }
    else
    {
       CopyDataWrap(This, This->presented_buffer + ofs, realofs, remainder, realbuflen);
       dlen -= remainder;
       CopyDataWrap(This, This->presented_buffer, (realofs+remainder)%realbuflen, dlen, realbuflen);
    }
}

/** Fill buffers, for starting and stopping
 * Alsa won't start playing until everything is filled up
 * This also updates mmap_pos
 *
 * Returns: Amount of periods in use so snd_pcm_avail_update
 * doesn't have to be called up to 4x in GetPosition()
 */
static snd_pcm_uframes_t CommitAll(IDsCaptureDriverBufferImpl *This, DWORD forced)
{
    const snd_pcm_channel_area_t *areas;
    snd_pcm_uframes_t used;
    const snd_pcm_uframes_t commitahead = This->mmap_buflen_frames;

    used = This->mmap_buflen_frames - snd_pcm_avail_update(This->pcm);
    TRACE("%p needs to commit to %lu, used: %lu\n", This, commitahead, used);
    if (used < commitahead && (forced || This->play_looping))
    {
        snd_pcm_uframes_t done, putin = commitahead - used;
        if (This->mmap)
        {
            snd_pcm_mmap_begin(This->pcm, &areas, &This->mmap_pos, &putin);
            CopyData(This, This->mmap_pos, putin);
            done = snd_pcm_mmap_commit(This->pcm, This->mmap_pos, putin);

            This->mmap_pos += done;
            used += done;
            putin = commitahead - used;

            if (This->mmap_pos == This->mmap_buflen_frames && (snd_pcm_sframes_t)putin > 0 && This->play_looping)
            {
                This->mmap_ofs_bytes += snd_pcm_frames_to_bytes(This->pcm, This->mmap_buflen_frames);
                This->mmap_ofs_bytes %= This->mmap_buflen_bytes;

                snd_pcm_mmap_begin(This->pcm, &areas, &This->mmap_pos, &putin);
                CopyData(This, This->mmap_pos, putin);
                done = snd_pcm_mmap_commit(This->pcm, This->mmap_pos, putin);

                This->mmap_pos += done;
                used += done;
            }
        }
        else
        {
            DWORD pos;
            snd_pcm_sframes_t ret;

            snd_pcm_uframes_t cap = snd_pcm_bytes_to_frames(This->pcm, This->mmap_buflen_bytes);
            pos = realpos_to_fakepos(This, This->mmap_pos);
            if (This->mmap_pos + putin > cap)
                putin = cap - This->mmap_pos;
            ret = snd_pcm_readi(This->pcm, This->presented_buffer + pos, putin);
            if (ret == -EPIPE)
            {
                WARN("Underrun occurred\n");
                snd_pcm_prepare(This->pcm);
                ret = snd_pcm_readi(This->pcm, This->presented_buffer + pos, putin);
                snd_pcm_start(This->pcm);
            }
            if (ret < 0)
            {
                WARN("Committing data: %ld / %s (%ld)\n", ret, snd_strerror(ret), putin);
                ret = 0;
            }
            This->mmap_pos += ret;
            used += ret;
            /* At this point mmap_pos may be >= This->mmap_pos this is harmless
             * realpos_to_fakepos handles it well, and below it is truncated
             */

            putin = commitahead - used;
            if (putin > 0)
            {
                pos = realpos_to_fakepos(This, This->mmap_pos);
                ret = snd_pcm_readi(This->pcm, This->presented_buffer + pos, putin);
                if (ret > 0)
                {
                    This->mmap_pos += ret;
                    used += ret;
                }
            }
        }

    }

    if (This->mmap_pos >= This->mmap_buflen_frames)
    {
        This->mmap_ofs_bytes += snd_pcm_frames_to_bytes(This->pcm, This->mmap_buflen_frames);
        This->mmap_ofs_bytes %= This->mmap_buflen_bytes;
        This->mmap_pos -= This->mmap_buflen_frames;
    }

    return used;
}

static void CheckXRUN(IDsCaptureDriverBufferImpl* This)
{
    snd_pcm_state_t state = snd_pcm_state(This->pcm);
    int err;

    if ( state == SND_PCM_STATE_XRUN )
    {
        err = snd_pcm_prepare(This->pcm);
        CommitAll(This, FALSE);
        snd_pcm_start(This->pcm);
        WARN("xrun occurred\n");
        if ( err < 0 )
            ERR("recovery from xrun failed, prepare failed: %s\n", snd_strerror(err));
    }
    else if ( state == SND_PCM_STATE_SUSPENDED )
    {
        int err = snd_pcm_resume(This->pcm);
        TRACE("recovery from suspension occurred\n");
        if (err < 0 && err != -EAGAIN){
            err = snd_pcm_prepare(This->pcm);
            if (err < 0)
                ERR("recovery from suspend failed, prepare failed: %s\n", snd_strerror(err));
        }
    }
    else if ( state != SND_PCM_STATE_RUNNING)
    {
        WARN("Unhandled state: %d\n", state);
    }
}

/**
 * Allocate the memory-mapped buffer for direct sound, and set up the
 * callback.
 */
static int CreateMMAP(IDsCaptureDriverBufferImpl* pdbi)
{
    snd_pcm_t *pcm = pdbi->pcm;
    snd_pcm_format_t format;
    snd_pcm_uframes_t frames, ofs, avail, psize, boundary;
    unsigned int channels, bits_per_sample, bits_per_frame;
    int err, mmap_mode;
    const snd_pcm_channel_area_t *areas;
    snd_pcm_hw_params_t *hw_params = pdbi->hw_params;
    snd_pcm_sw_params_t *sw_params = pdbi->sw_params;

    mmap_mode = snd_pcm_type(pcm);

    if (mmap_mode == SND_PCM_TYPE_HW)
        TRACE("mmap'd buffer is a direct hardware buffer.\n");
    else if (mmap_mode == SND_PCM_TYPE_DMIX)
        TRACE("mmap'd buffer is an ALSA dmix buffer\n");
    else
        TRACE("mmap'd buffer is an ALSA type %d buffer\n", mmap_mode);

    err = snd_pcm_hw_params_get_period_size(hw_params, &psize, NULL);
    err = snd_pcm_hw_params_get_format(hw_params, &format);
    err = snd_pcm_hw_params_get_buffer_size(hw_params, &frames);
    err = snd_pcm_hw_params_get_channels(hw_params, &channels);
    bits_per_sample = snd_pcm_format_physical_width(format);
    bits_per_frame = bits_per_sample * channels;

    if (TRACE_ON(dsalsa))
        ALSA_TraceParameters(hw_params, NULL, FALSE);

    TRACE("format=%s  frames=%ld  channels=%d  bits_per_sample=%d  bits_per_frame=%d\n",
          snd_pcm_format_name(format), frames, channels, bits_per_sample, bits_per_frame);

    pdbi->mmap_buflen_frames = frames;
    snd_pcm_sw_params_current(pcm, sw_params);
    snd_pcm_sw_params_set_start_threshold(pcm, sw_params, 0);
    snd_pcm_sw_params_get_boundary(sw_params, &boundary);
    snd_pcm_sw_params_set_stop_threshold(pcm, sw_params, boundary);
    snd_pcm_sw_params_set_silence_threshold(pcm, sw_params, INT_MAX);
    snd_pcm_sw_params_set_silence_size(pcm, sw_params, 0);
    snd_pcm_sw_params_set_avail_min(pcm, sw_params, 0);
    err = snd_pcm_sw_params(pcm, sw_params);

    pdbi->mmap_ofs_bytes = 0;
    if (!pdbi->mmap)
    {
        pdbi->mmap_buffer = NULL;

        frames = snd_pcm_bytes_to_frames(pdbi->pcm, pdbi->mmap_buflen_bytes);
        snd_pcm_format_set_silence(format, pdbi->presented_buffer, frames);
        pdbi->mmap_pos = 0;
    }
    else
    {
        err = snd_pcm_mmap_begin(pcm, &areas, &ofs, &avail);
        if ( err < 0 )
        {
            ERR("Can't map sound device for direct access: %s/%d\n", snd_strerror(err), err);
            return DSERR_GENERIC;
        }
        snd_pcm_format_set_silence(format, areas->addr, pdbi->mmap_buflen_frames);
        pdbi->mmap_pos = ofs + snd_pcm_mmap_commit(pcm, ofs, 0);
        pdbi->mmap_buffer = areas->addr;
    }

    TRACE("created mmap buffer of %ld frames (%d bytes) at %p\n",
        pdbi->mmap_buflen_frames, pdbi->mmap_buflen_bytes, pdbi->mmap_buffer);

    return DS_OK;
}

static HRESULT WINAPI IDsCaptureDriverBufferImpl_QueryInterface(PIDSCDRIVERBUFFER iface, REFIID riid, LPVOID *ppobj)
{
    IDsCaptureDriverBufferImpl *This = (IDsCaptureDriverBufferImpl *)iface;
    if ( IsEqualGUID(riid, &IID_IUnknown) ||
         IsEqualGUID(riid, &IID_IDsCaptureDriverBuffer) ) {
        IDsCaptureDriverBuffer_AddRef(iface);
        *ppobj = iface;
        return DS_OK;
    }

    if ( IsEqualGUID( &IID_IDsDriverNotify, riid ) ) {
        if (!This->notify)
        {
            This->notify = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDsCaptureDriverNotifyImpl));
            if (!This->notify)
                return DSERR_OUTOFMEMORY;
            This->notify->lpVtbl = &dscdnvt;
            This->notify->buffer = This;

            /* Keep a lock on IDsDriverNotify for ourself, so it is destroyed when the buffer is */
            IDsDriverNotify_AddRef((PIDSDRIVERNOTIFY)This->notify);
        }
        IDsDriverNotify_AddRef((PIDSDRIVERNOTIFY)This->notify);
        *ppobj = This->notify;
        return DS_OK;
    }

    if ( IsEqualGUID( &IID_IDsDriverPropertySet, riid ) ) {
        FIXME("Unsupported interface IID_IDsDriverPropertySet\n");
        return E_FAIL;
    }

    FIXME("(): Unknown interface %s\n", debugstr_guid(riid));
    return DSERR_UNSUPPORTED;
}

static ULONG WINAPI IDsCaptureDriverBufferImpl_AddRef(PIDSCDRIVERBUFFER iface)
{
    IDsCaptureDriverBufferImpl *This = (IDsCaptureDriverBufferImpl *)iface;
    ULONG refCount = InterlockedIncrement(&This->ref);

    TRACE("(%p)->(ref before=%u)\n",This, refCount - 1);

    return refCount;
}

static ULONG WINAPI IDsCaptureDriverBufferImpl_Release(PIDSCDRIVERBUFFER iface)
{
    IDsCaptureDriverBufferImpl *This = (IDsCaptureDriverBufferImpl *)iface;
    ULONG refCount = InterlockedDecrement(&This->ref);

    TRACE("(%p)->(ref before=%u)\n",This, refCount + 1);

    if (refCount)
        return refCount;

    EnterCriticalSection(&This->pcm_crst);
    if (This->notify)
        IDsDriverNotify_Release((PIDSDRIVERNOTIFY)This->notify);
    TRACE("mmap buffer %p destroyed\n", This->mmap_buffer);

    This->drv->capture_buffer = NULL;
    LeaveCriticalSection(&This->pcm_crst);
    This->pcm_crst.DebugInfo->Spare[0] = 0;
    DeleteCriticalSection(&This->pcm_crst);

    snd_pcm_drop(This->pcm);
    snd_pcm_close(This->pcm);
    This->pcm = NULL;
    HeapFree(GetProcessHeap(), 0, This->presented_buffer);
    HeapFree(GetProcessHeap(), 0, This->sw_params);
    HeapFree(GetProcessHeap(), 0, This->hw_params);
    HeapFree(GetProcessHeap(), 0, This);
    return 0;
}

static HRESULT WINAPI IDsCaptureDriverBufferImpl_Lock(PIDSCDRIVERBUFFER iface, LPVOID*ppvAudio1,LPDWORD pdwLen1,LPVOID*ppvAudio2,LPDWORD pdwLen2, DWORD dwWritePosition,DWORD dwWriteLen, DWORD dwFlags)
{
    IDsCaptureDriverBufferImpl *This = (IDsCaptureDriverBufferImpl *)iface;
    TRACE("(%p,%p,%p,%p,%p,%d,%d,0x%08x)\n", This, ppvAudio1, pdwLen1, ppvAudio2, pdwLen2, dwWritePosition, dwWriteLen, dwFlags);

    if (ppvAudio1)
        *ppvAudio1 = (LPBYTE)This->presented_buffer + dwWritePosition;

    if (dwWritePosition + dwWriteLen <= This->mmap_buflen_bytes) {
        if (pdwLen1)
            *pdwLen1 = dwWriteLen;
        if (ppvAudio2)
            *ppvAudio2 = 0;
        if (pdwLen2)
            *pdwLen2 = 0;
    } else {
        if (pdwLen1)
            *pdwLen1 = This->mmap_buflen_bytes - dwWritePosition;
        if (ppvAudio2)
            *ppvAudio2 = This->presented_buffer;
        if (pdwLen2)
            *pdwLen2 = dwWriteLen - (This->mmap_buflen_bytes - dwWritePosition);
    }
    return DS_OK;
}

static HRESULT WINAPI IDsCaptureDriverBufferImpl_Unlock(PIDSCDRIVERBUFFER iface, LPVOID pvAudio1,DWORD dwLen1, LPVOID pvAudio2,DWORD dwLen2)
{
    IDsCaptureDriverBufferImpl *This = (IDsCaptureDriverBufferImpl *)iface;
    TRACE("(%p,%p,%d,%p,%d)\n",This,pvAudio1,dwLen1,pvAudio2,dwLen2);
    return DS_OK;
}

static HRESULT WINAPI IDsCaptureDriverBufferImpl_SetFormat(PIDSCDRIVERBUFFER iface, LPWAVEFORMATEX pwfx)
{
    IDsCaptureDriverBufferImpl *This = (IDsCaptureDriverBufferImpl *)iface;
    WINE_WAVEDEV *wwi = &WInDev[This->drv->wDevID];
    snd_pcm_t *pcm = NULL;
    snd_pcm_hw_params_t *hw_params = This->hw_params;
    snd_pcm_format_t format = -1;
    snd_pcm_uframes_t buffer_size;
    DWORD rate = pwfx->nSamplesPerSec;
    int err=0;
    BOOL mmap;

    TRACE("(%p, %p)\n", iface, pwfx);

    switch (pwfx->wBitsPerSample)
    {
        case  8: format = SND_PCM_FORMAT_U8; break;
        case 16: format = SND_PCM_FORMAT_S16_LE; break;
        case 24: format = SND_PCM_FORMAT_S24_3LE; break;
        case 32: format = SND_PCM_FORMAT_S32_LE; break;
        default: FIXME("Unsupported bpp: %d\n", pwfx->wBitsPerSample); return DSERR_GENERIC;
    }

    /* **** */
    EnterCriticalSection(&This->pcm_crst);

    err = snd_pcm_open(&pcm, wwi->pcmname, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);

    if (err < 0)
    {
        if (errno != EBUSY || !This->pcm)
        {
            /* **** */
            LeaveCriticalSection(&This->pcm_crst);
            WARN("Cannot open sound device: %s\n", snd_strerror(err));
            return DSERR_GENERIC;
        }
        snd_pcm_drop(This->pcm);
        snd_pcm_close(This->pcm);
        This->pcm = NULL;
        err = snd_pcm_open(&pcm, wwi->pcmname, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
        if (err < 0)
        {
            /* **** */
            LeaveCriticalSection(&This->pcm_crst);
            WARN("Cannot open sound device: %s\n", snd_strerror(err));
            return DSERR_BUFFERLOST;
        }
    }

    /* Set some defaults */
    snd_pcm_hw_params_any(pcm, hw_params);

    err = snd_pcm_hw_params_set_channels(pcm, hw_params, pwfx->nChannels);
    if (err < 0) { WARN("Could not set channels to %d\n", pwfx->nChannels); goto err; }

    err = snd_pcm_hw_params_set_format(pcm, hw_params, format);
    if (err < 0) { WARN("Could not set format to %d bpp\n", pwfx->wBitsPerSample); goto err; }

    err = snd_pcm_hw_params_set_rate_near(pcm, hw_params, &rate, NULL);
    if (err < 0) { rate = pwfx->nSamplesPerSec; WARN("Could not set rate\n"); goto err; }

    if (!ALSA_NearMatch(rate, pwfx->nSamplesPerSec))
    {
        WARN("Could not set sound rate to %d, but instead to %d\n", pwfx->nSamplesPerSec, rate);
        pwfx->nSamplesPerSec = rate;
        pwfx->nAvgBytesPerSec = rate * pwfx->nBlockAlign;
        /* Let DirectSound detect this */
    }

    snd_pcm_hw_params_set_periods_integer(pcm, hw_params);
    buffer_size = This->mmap_buflen_bytes / pwfx->nBlockAlign;
    snd_pcm_hw_params_set_buffer_size_near(pcm, hw_params, &buffer_size);
    buffer_size = 5000;
    snd_pcm_hw_params_set_period_time_near(pcm, hw_params, (unsigned int*)&buffer_size, NULL);

    err = snd_pcm_hw_params_set_access (pcm, hw_params, SND_PCM_ACCESS_MMAP_INTERLEAVED);
    if (err < 0)
    {
        err = snd_pcm_hw_params_set_access (pcm, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
        if (err < 0) { WARN("Could not set access\n"); goto err; }
        mmap = 0;
    }
    else
        mmap = 1;

    err = snd_pcm_hw_params(pcm, hw_params);
    if (err < 0) { WARN("Could not set hw parameters\n"); goto err; }

    if (This->pcm)
    {
        snd_pcm_drop(This->pcm);
        snd_pcm_close(This->pcm);
    }
    This->pcm = pcm;
    This->mmap = mmap;

    snd_pcm_prepare(This->pcm);
    CreateMMAP(This);

    /* **** */
    LeaveCriticalSection(&This->pcm_crst);
    return S_OK;

    err:
    if (err < 0)
        WARN("Failed to apply changes: %s\n", snd_strerror(err));

    if (!This->pcm)
        This->pcm = pcm;
    else
        snd_pcm_close(pcm);

    if (This->pcm)
        snd_pcm_hw_params_current(This->pcm, This->hw_params);

    /* **** */
    LeaveCriticalSection(&This->pcm_crst);
    return DSERR_BADFORMAT;
}

static HRESULT WINAPI IDsCaptureDriverBufferImpl_GetPosition(PIDSCDRIVERBUFFER iface, LPDWORD lpdwCappos, LPDWORD lpdwReadpos)
{
    IDsCaptureDriverBufferImpl *This = (IDsCaptureDriverBufferImpl *)iface;
    snd_pcm_uframes_t hw_pptr, hw_wptr;

    EnterCriticalSection(&This->pcm_crst);

    if (!This->pcm)
    {
        FIXME("Bad pointer for pcm: %p\n", This->pcm);
        LeaveCriticalSection(&This->pcm_crst);
        return DSERR_GENERIC;
    }

    if (snd_pcm_state(This->pcm) != SND_PCM_STATE_RUNNING)
    {
        CheckXRUN(This);
        hw_pptr = This->mmap_pos;
    }
    else
    {
        /* FIXME: Unused at the moment */
        snd_pcm_uframes_t used = CommitAll(This, FALSE);

        if (This->mmap_pos > used)
            hw_pptr = This->mmap_pos - used;
        else
            hw_pptr = This->mmap_buflen_frames - used + This->mmap_pos;
    }
    hw_wptr = This->mmap_pos;

    if (lpdwCappos)
        *lpdwCappos = realpos_to_fakepos(This, hw_pptr);
    if (lpdwReadpos)
        *lpdwReadpos = realpos_to_fakepos(This, hw_wptr);

    LeaveCriticalSection(&This->pcm_crst);

    TRACE("hw_pptr=%u, hw_wptr=%u playpos=%u(%p), writepos=%u(%p)\n", (unsigned int)hw_pptr, (unsigned int)hw_wptr, realpos_to_fakepos(This, hw_pptr), lpdwCappos, realpos_to_fakepos(This, hw_wptr), lpdwReadpos);
    return DS_OK;
}

static HRESULT WINAPI IDsCaptureDriverBufferImpl_GetStatus(PIDSCDRIVERBUFFER iface, LPDWORD lpdwStatus)
{
    IDsCaptureDriverBufferImpl *This = (IDsCaptureDriverBufferImpl *)iface;
    snd_pcm_state_t state;
    TRACE("(%p,%p)\n",iface,lpdwStatus);

    state = snd_pcm_state(This->pcm);
    switch (state)
    {
    case SND_PCM_STATE_XRUN:
    case SND_PCM_STATE_SUSPENDED:
    case SND_PCM_STATE_RUNNING:
        *lpdwStatus = DSCBSTATUS_CAPTURING | (This->play_looping ? DSCBSTATUS_LOOPING : 0);
        break;
    default:
        *lpdwStatus = 0;
        break;
    }

    TRACE("State: %d, flags: 0x%08x\n", state, *lpdwStatus);
    return DS_OK;
}

static HRESULT WINAPI IDsCaptureDriverBufferImpl_Start(PIDSCDRIVERBUFFER iface, DWORD dwFlags)
{
    IDsCaptureDriverBufferImpl *This = (IDsCaptureDriverBufferImpl *)iface;
    TRACE("(%p,%x)\n",iface,dwFlags);

    /* **** */
    EnterCriticalSection(&This->pcm_crst);
    snd_pcm_start(This->pcm);
    This->play_looping = !!(dwFlags & DSCBSTART_LOOPING);
    if (!This->play_looping)
        /* Not well supported because of the difference in ALSA size and DSOUND's notion of size
         * what it does right now is fill the buffer once.. ALSA size */
        FIXME("Non-looping buffers are not properly supported!\n");
    CommitAll(This, TRUE);

    if (This->notify && This->notify->nrofnotifies && This->notify->notifies)
    {
        DWORD playpos = realpos_to_fakepos(This, This->mmap_pos);
        if (playpos)
            Capture_CheckNotify(This->notify, 0, playpos);
        This->notify->playpos = playpos;
    }

    /* **** */
    LeaveCriticalSection(&This->pcm_crst);
    return DS_OK;
}

static HRESULT WINAPI IDsCaptureDriverBufferImpl_Stop(PIDSCDRIVERBUFFER iface)
{
    IDsCaptureDriverBufferImpl *This = (IDsCaptureDriverBufferImpl *)iface;
    TRACE("(%p)\n",iface);

    /* **** */
    EnterCriticalSection(&This->pcm_crst);
    This->play_looping = FALSE;
    snd_pcm_drop(This->pcm);
    snd_pcm_prepare(This->pcm);

    if (This->notify && This->notify->notifies && This->notify->nrofnotifies)
        Capture_CheckNotify(This->notify, 0, 0);

    /* **** */
    LeaveCriticalSection(&This->pcm_crst);
    return DS_OK;
}

static const IDsCaptureDriverBufferVtbl dsdbvt =
{
    IDsCaptureDriverBufferImpl_QueryInterface,
    IDsCaptureDriverBufferImpl_AddRef,
    IDsCaptureDriverBufferImpl_Release,
    IDsCaptureDriverBufferImpl_Lock,
    IDsCaptureDriverBufferImpl_Unlock,
    IDsCaptureDriverBufferImpl_SetFormat,
    IDsCaptureDriverBufferImpl_GetPosition,
    IDsCaptureDriverBufferImpl_GetStatus,
    IDsCaptureDriverBufferImpl_Start,
    IDsCaptureDriverBufferImpl_Stop
};

static HRESULT WINAPI IDsCaptureDriverImpl_QueryInterface(PIDSCDRIVER iface, REFIID riid, LPVOID *ppobj)
{
    /* IDsCaptureDriverImpl *This = (IDsCaptureDriverImpl *)iface; */
    FIXME("(%p): stub!\n",iface);
    return DSERR_UNSUPPORTED;
}

static ULONG WINAPI IDsCaptureDriverImpl_AddRef(PIDSCDRIVER iface)
{
    IDsCaptureDriverImpl *This = (IDsCaptureDriverImpl *)iface;
    ULONG refCount = InterlockedIncrement(&This->ref);

    TRACE("(%p)->(ref before=%u)\n",This, refCount - 1);

    return refCount;
}

static ULONG WINAPI IDsCaptureDriverImpl_Release(PIDSCDRIVER iface)
{
    IDsCaptureDriverImpl *This = (IDsCaptureDriverImpl *)iface;
    ULONG refCount = InterlockedDecrement(&This->ref);

    TRACE("(%p)->(ref before=%u)\n",This, refCount + 1);

    if (refCount)
        return refCount;

    HeapFree(GetProcessHeap(), 0, This);
    return 0;
}

static HRESULT WINAPI IDsCaptureDriverImpl_GetDriverDesc(PIDSCDRIVER iface, PDSDRIVERDESC pDesc)
{
    IDsCaptureDriverImpl *This = (IDsCaptureDriverImpl *)iface;
    TRACE("(%p,%p)\n",iface,pDesc);
    *pDesc			= WInDev[This->wDevID].ds_desc;
    pDesc->dwFlags		= 0;
    pDesc->dnDevNode		= WInDev[This->wDevID].waveDesc.dnDevNode;
    pDesc->wVxdId		= 0;
    pDesc->wReserved		= 0;
    pDesc->ulDeviceNum		= This->wDevID;
    pDesc->dwHeapType		= DSDHEAP_NOHEAP;
    pDesc->pvDirectDrawHeap	= NULL;
    pDesc->dwMemStartAddress	= 0xDEAD0000;
    pDesc->dwMemEndAddress	= 0xDEAF0000;
    pDesc->dwMemAllocExtra	= 0;
    pDesc->pvReserved1		= NULL;
    pDesc->pvReserved2		= NULL;
    return DS_OK;
}

static HRESULT WINAPI IDsCaptureDriverImpl_Open(PIDSCDRIVER iface)
{
    HRESULT hr = S_OK;
    IDsCaptureDriverImpl *This = (IDsCaptureDriverImpl *)iface;
    int err=0;
    snd_pcm_t *pcm = NULL;
    snd_pcm_hw_params_t *hw_params;

    /* While this is not really needed, it is a good idea to do this,
     * to see if sound can be initialized */

    hw_params = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, snd_pcm_hw_params_sizeof());
    if (!hw_params)
    {
        hr = DSERR_OUTOFMEMORY;
        WARN("--> %08x\n", hr);
        return hr;
    }

    err = snd_pcm_open(&pcm, WInDev[This->wDevID].pcmname, SND_PCM_STREAM_CAPTURE, SND_PCM_NONBLOCK);
    if (err < 0) goto err;
    err = snd_pcm_hw_params_any(pcm, hw_params);
    if (err < 0) goto err;
    err = snd_pcm_hw_params_set_access (pcm, hw_params, SND_PCM_ACCESS_MMAP_INTERLEAVED);
    if (err < 0)
    {
        err = snd_pcm_hw_params_set_access (pcm, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED);
        if (err < 0) goto err;
    }

    TRACE("Success\n");
    snd_pcm_close(pcm);
    HeapFree(GetProcessHeap(), 0, hw_params);
    return hr;

    err:
    hr = DSERR_GENERIC;
    WARN("Failed to open device: %s\n", snd_strerror(err));
    if (pcm)
        snd_pcm_close(pcm);
    HeapFree(GetProcessHeap(), 0, hw_params);
    WARN("--> %08x\n", hr);
    return hr;
}

static HRESULT WINAPI IDsCaptureDriverImpl_Close(PIDSCDRIVER iface)
{
    IDsCaptureDriverImpl *This = (IDsCaptureDriverImpl *)iface;
    TRACE("(%p) stub, harmless\n",This);
    return DS_OK;
}

static HRESULT WINAPI IDsCaptureDriverImpl_GetCaps(PIDSCDRIVER iface, PDSCDRIVERCAPS pCaps)
{
    IDsCaptureDriverImpl *This = (IDsCaptureDriverImpl *)iface;
    WINE_WAVEDEV *wwi = &WInDev[This->wDevID];
    TRACE("(%p,%p)\n",iface,pCaps);
    pCaps->dwSize = sizeof(DSCDRIVERCAPS);
    pCaps->dwFlags = wwi->ds_caps.dwFlags;
    pCaps->dwFormats = wwi->incaps.dwFormats;
    pCaps->dwChannels = wwi->incaps.wChannels;
    return DS_OK;
}

static HRESULT WINAPI IDsCaptureDriverImpl_CreateCaptureBuffer(PIDSCDRIVER iface,
						      LPWAVEFORMATEX pwfx,
						      DWORD dwFlags, DWORD dwCardAddress,
						      LPDWORD pdwcbBufferSize,
						      LPBYTE *ppbBuffer,
						      LPVOID *ppvObj)
{
    IDsCaptureDriverImpl *This = (IDsCaptureDriverImpl *)iface;
    IDsCaptureDriverBufferImpl** ippdsdb = (IDsCaptureDriverBufferImpl**)ppvObj;
    HRESULT err;

    TRACE("(%p,%p,%x,%x)\n",iface,pwfx,dwFlags,dwCardAddress);

    if (This->capture_buffer)
        return DSERR_ALLOCATED;

    This->capture_buffer = *ippdsdb = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDsCaptureDriverBufferImpl));
    if (*ippdsdb == NULL)
        return DSERR_OUTOFMEMORY;

    (*ippdsdb)->hw_params = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, snd_pcm_hw_params_sizeof());
    (*ippdsdb)->sw_params = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, snd_pcm_sw_params_sizeof());
    (*ippdsdb)->presented_buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, *pdwcbBufferSize);
    if (!(*ippdsdb)->hw_params || !(*ippdsdb)->sw_params || !(*ippdsdb)->presented_buffer)
    {
        HeapFree(GetProcessHeap(), 0, (*ippdsdb)->sw_params);
        HeapFree(GetProcessHeap(), 0, (*ippdsdb)->hw_params);
        HeapFree(GetProcessHeap(), 0, (*ippdsdb)->presented_buffer);
        return DSERR_OUTOFMEMORY;
    }
    (*ippdsdb)->lpVtbl = &dsdbvt;
    (*ippdsdb)->ref = 1;
    (*ippdsdb)->drv = This;
    (*ippdsdb)->mmap_buflen_bytes = *pdwcbBufferSize;
    InitializeCriticalSection(&(*ippdsdb)->pcm_crst);
    (*ippdsdb)->pcm_crst.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": ALSA_DSCAPTURE.pcm_crst");

    /* SetFormat initialises pcm */
    err = IDsDriverBuffer_SetFormat((IDsDriverBuffer*)*ppvObj, pwfx);
    if (FAILED(err))
    {
        WARN("Error occurred: %08x\n", err);
        goto err;
    }
    *ppbBuffer = (*ippdsdb)->presented_buffer;

    /* buffer is ready to go */
    TRACE("buffer created at %p\n", *ippdsdb);
    return err;

    err:
    HeapFree(GetProcessHeap(), 0, (*ippdsdb)->presented_buffer);
    HeapFree(GetProcessHeap(), 0, (*ippdsdb)->sw_params);
    HeapFree(GetProcessHeap(), 0, (*ippdsdb)->hw_params);
    HeapFree(GetProcessHeap(), 0, *ippdsdb);
    *ippdsdb = NULL;
    return err;
}

static const IDsCaptureDriverVtbl dscdvt =
{
    IDsCaptureDriverImpl_QueryInterface,
    IDsCaptureDriverImpl_AddRef,
    IDsCaptureDriverImpl_Release,
    IDsCaptureDriverImpl_GetDriverDesc,
    IDsCaptureDriverImpl_Open,
    IDsCaptureDriverImpl_Close,
    IDsCaptureDriverImpl_GetCaps,
    IDsCaptureDriverImpl_CreateCaptureBuffer
};

/**************************************************************************
 *                              widDsCreate                     [internal]
 */
DWORD widDsCreate(UINT wDevID, PIDSCDRIVER* drv)
{
    IDsCaptureDriverImpl** idrv = (IDsCaptureDriverImpl**)drv;
    TRACE("(%d,%p)\n",wDevID,drv);

    *idrv = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(IDsCaptureDriverImpl));
    if (!*idrv)
        return MMSYSERR_NOMEM;
    (*idrv)->lpVtbl	= &dscdvt;
    (*idrv)->ref	= 1;

    (*idrv)->wDevID	= wDevID;
    return MMSYSERR_NOERROR;
}

/**************************************************************************
 *                              widDsDesc                       [internal]
 */
DWORD widDsDesc(UINT wDevID, PDSDRIVERDESC desc)
{
    *desc = WInDev[wDevID].ds_desc;
    return MMSYSERR_NOERROR;
}
