[PATCH 15/27] dsound: Implement capture buffer based on mmdevapi, try 2

Maarten Lankhorst m.b.lankhorst at gmail.com
Thu Apr 7 21:43:51 CDT 2011


---
 dlls/dsound/capture.c       |  507 ++++++++++++++++++++++++++++++++++++++++++-
 dlls/dsound/tests/capture.c |    2 +-
 2 files changed, 504 insertions(+), 5 deletions(-)

diff --git a/dlls/dsound/capture.c b/dlls/dsound/capture.c
index 42e42b9..df34910 100644
--- a/dlls/dsound/capture.c
+++ b/dlls/dsound/capture.c
@@ -43,16 +43,45 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(dsound);
 
+typedef struct IDirectSoundCaptureBufferImpl IDirectSoundCaptureBufferImpl;
+
 typedef struct IDirectSoundCaptureImpl
 {
     IDirectSoundCapture IDirectSoundCapture_iface;
     LONG ref;
 
     GUID device;
+    IDirectSoundCaptureBufferImpl *buf;
     CRITICAL_SECTION crst;
     BOOL is_8, voice;
+    UINT timer_id;
+    DWORD timer_res;
 } IDirectSoundCaptureImpl;
 
+struct IDirectSoundCaptureBufferImpl
+{
+    IDirectSoundCaptureBuffer8 IDirectSoundCaptureBuffer8_iface;
+    LONG ref;
+    IDirectSoundCaptureImpl *parent;
+    IAudioClient *dev;
+    IAudioCaptureClient *cap_dev;
+    DWORD buf_size;
+    BYTE *buf;
+    WAVEFORMATEX *format;
+    DSBPOSITIONNOTIFY *notify;
+    DWORD nnotify;
+
+    DWORD pos;
+    BOOL playing, looping;
+};
+
+static void IDirectSoundCaptureBufferImpl_Destroy(IDirectSoundCaptureBufferImpl *This);
+
+static IDirectSoundCaptureBufferImpl *impl_from_IDirectSoundCaptureBuffer8(IDirectSoundCaptureBuffer8 *iface)
+{
+    return CONTAINING_RECORD(iface, IDirectSoundCaptureBufferImpl, IDirectSoundCaptureBuffer8_iface);
+}
+
 static void IDirectSoundCaptureImpl_Destroy(IDirectSoundCaptureImpl *This);
 
 static IDirectSoundCaptureImpl *impl_from_IDirectSoundCapture(IDirectSoundCapture *iface)
@@ -60,6 +89,462 @@ static IDirectSoundCaptureImpl *impl_from_IDirectSoundCapture(IDirectSoundCaptur
     return CONTAINING_RECORD(iface, IDirectSoundCaptureImpl, IDirectSoundCapture_iface);
 }
 
+static void trigger_notifies(IDirectSoundCaptureBufferImpl *buf, DWORD lastpos, DWORD curpos)
+{
+    TRACE("stub\n");
+}
+
+static void CALLBACK IDirectSoundCaptureBufferImpl_timer(UINT timerID, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
+{
+    IDirectSoundCaptureImpl *This = (IDirectSoundCaptureImpl*)dwUser;
+    IDirectSoundCaptureBufferImpl *buf;
+    UINT32 avail = 0;
+
+    EnterCriticalSection(&This->crst);
+    buf = This->buf;
+    if (!buf || !buf->dev || !buf->playing)
+        goto out;
+
+    IAudioCaptureClient_GetNextPacketSize(buf->cap_dev, &avail);
+    if (avail)
+    {
+        BYTE *data = 0;
+        UINT32 read = 0;
+        DWORD flags = 0;
+        UINT64 pos = 0;
+        DWORD block = buf->format->nBlockAlign;
+
+        IAudioCaptureClient_GetBuffer(buf->cap_dev, &data, &read, &flags, &pos, 0);
+        if (read * block + buf->pos >= buf->buf_size)
+        {
+            if (!buf->looping)
+            {
+                trigger_notifies(buf, buf->pos, 0);
+                memcpy(buf->buf + buf->pos, data, buf->buf_size - buf->pos);
+                buf->pos = 0;
+                IAudioCaptureClient_ReleaseBuffer(buf->cap_dev, read);
+                IDirectSoundCaptureBuffer8_Stop(&buf->IDirectSoundCaptureBuffer8_iface);
+            }
+            else
+            {
+                DWORD firstpart = buf->buf_size - buf->pos, oldpos = buf->pos;
+                memcpy(buf->buf + buf->pos, data, firstpart);
+                buf->pos = read * block - firstpart;
+                memcpy(buf->buf, data + firstpart, buf->pos);
+                trigger_notifies(buf, oldpos, buf->pos);
+                IAudioCaptureClient_ReleaseBuffer(buf->cap_dev, read);
+            }
+        } else {
+            memcpy(buf->buf + buf->pos, data, read * block);
+            trigger_notifies(buf, buf->pos, buf->pos + read * block);
+            buf->pos += read * block;
+            IAudioCaptureClient_ReleaseBuffer(buf->cap_dev, read);
+        }
+    }
+
+out:
+    LeaveCriticalSection(&This->crst);
+    return;
+}
+
+static HRESULT WINAPI IDirectSoundCaptureBufferImpl_QueryInterface(IDirectSoundCaptureBuffer8 *iface, REFIID riid, void **ppv)
+{
+    IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface);
+    if (!ppv)
+        return E_POINTER;
+    TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppv);
+    *ppv = NULL;
+    if (IsEqualIID(riid, &IID_IUnknown) ||
+        IsEqualIID(riid, &IID_IDirectSoundCaptureBuffer) ||
+        (This->parent->is_8 && IsEqualIID(riid, &IID_IDirectSoundCaptureBuffer8)))
+        *ppv = &This->IDirectSoundCaptureBuffer8_iface;
+    if (!*ppv)
+        return E_NOINTERFACE;
+    IUnknown_AddRef((IUnknown*)*ppv);
+    return S_OK;
+}
+
+static ULONG WINAPI IDirectSoundCaptureBufferImpl_AddRef(IDirectSoundCaptureBuffer8 *iface)
+{
+    IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface);
+    LONG ref;
+    ref = InterlockedIncrement(&This->ref);
+    TRACE("Reference count incremented to %i\n", ref);
+    return ref;
+}
+
+static ULONG WINAPI IDirectSoundCaptureBufferImpl_Release(IDirectSoundCaptureBuffer8 *iface)
+{
+    IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface);
+    LONG ref;
+    ref = InterlockedDecrement(&This->ref);
+    TRACE("Reference count decremented to %i\n", ref);
+    if (!ref)
+        IDirectSoundCaptureBufferImpl_Destroy(This);
+    return ref;
+}
+
+static HRESULT WINAPI IDirectSoundCaptureBufferImpl_GetCaps(IDirectSoundCaptureBuffer8 *iface, DSCBCAPS *caps)
+{
+    IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface);
+
+    if (!caps || caps->dwSize < sizeof(*caps))
+        return DSERR_INVALIDPARAM;
+    caps->dwSize = sizeof(*caps);
+    caps->dwFlags = 0;
+    caps->dwBufferBytes = This->buf_size;
+    return S_OK;
+}
+
+static HRESULT WINAPI IDirectSoundCaptureBufferImpl_GetCurrentPosition(IDirectSoundCaptureBuffer8 *iface, DWORD *cappos, DWORD *readpos)
+{
+    IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface);
+    DWORD pos1, pos2;
+    TRACE("(%p)->(%p, %p)\n", This, cappos, readpos);
+    EnterCriticalSection(&This->parent->crst);
+    pos1 = This->pos;
+    if (This->playing)
+    {
+        pos2 = This->format->nSamplesPerSec / 100;
+        pos2 *= This->format->nBlockAlign;
+        pos2 += pos1;
+        if (!This->looping && pos2 > This->buf_size)
+            pos2 = 0;
+        else
+            pos2 %= This->buf_size;
+    }
+    else
+        pos2 = pos1;
+    pos2 %= This->buf_size;
+    LeaveCriticalSection(&This->parent->crst);
+    TRACE("Reporting %u %u\n", pos1, pos2);
+    if (readpos)
+        *readpos = pos1;
+    if (cappos)
+        *cappos = pos2;
+    return S_OK;
+}
+
+static HRESULT WINAPI IDirectSoundCaptureBufferImpl_GetFormat(IDirectSoundCaptureBuffer8 *iface, WAVEFORMATEX *wfx, DWORD size, DWORD *written)
+{
+    IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface);
+    TRACE("(%p,%p,%u,%p)\n", This, wfx, size, written);
+
+    if (size > sizeof(WAVEFORMATEX) + This->format->cbSize)
+        size = sizeof(WAVEFORMATEX) + This->format->cbSize;
+
+    if (wfx)
+    {
+        CopyMemory(wfx, This->format, size);
+        if (written)
+            *written = size;
+    } else if (written)
+        *written = sizeof(WAVEFORMATEX) + This->format->cbSize;
+    else
+        return DSERR_INVALIDPARAM;
+
+    return S_OK;
+}
+
+static HRESULT WINAPI IDirectSoundCaptureBufferImpl_GetStatus(IDirectSoundCaptureBuffer8 *iface, DWORD *status)
+{
+    IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface);
+    TRACE("(%p)->(%p)\n", This, status);
+
+    if (!status)
+        return DSERR_INVALIDPARAM;
+    EnterCriticalSection(&This->parent->crst);
+    *status = 0;
+    if (This->playing)
+    {
+        *status |= DSCBSTATUS_CAPTURING;
+        if (This->looping)
+            *status |= DSCBSTATUS_LOOPING;
+    }
+    LeaveCriticalSection(&This->parent->crst);
+
+    return S_OK;
+}
+
+static HRESULT WINAPI IDirectSoundCaptureBufferImpl_Initialize(IDirectSoundCaptureBuffer8 *iface, IDirectSoundCapture *parent, const DSCBUFFERDESC *desc)
+{
+    IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface);
+    WAVEFORMATEX *format;
+    HRESULT hr;
+    IMMDevice *dev = NULL;
+
+    if (This->parent)
+        return DSERR_ALREADYINITIALIZED;
+    This->parent = impl_from_IDirectSoundCapture(parent);
+    if (!desc->lpwfxFormat || !desc->dwBufferBytes)
+        return DSERR_INVALIDPARAM;
+
+    format = desc->lpwfxFormat;
+    if (format->nChannels > 2)
+    {
+        WARN("nChannels > 2 not supported for recording\n");
+        return DSERR_INVALIDPARAM;
+    }
+
+    if (!This->format)
+        This->format = HeapAlloc(GetProcessHeap(), 0, sizeof(WAVEFORMATEXTENSIBLE));
+    if (!This->format)
+        return DSERR_OUTOFMEMORY;
+
+    if (format->wFormatTag == WAVE_FORMAT_PCM
+        || format->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
+    {
+        if (format->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
+        {
+            if (format->cbSize < sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX))
+                return DSERR_INVALIDPARAM;
+            else if (format->cbSize > sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX)
+                && format->cbSize != sizeof(WAVEFORMATEXTENSIBLE))
+                return DSERR_CONTROLUNAVAIL;
+
+            memcpy(This->format, format, sizeof(WAVEFORMATEXTENSIBLE));
+            This->format->cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
+        }
+        else
+        {
+            memcpy(This->format, format, sizeof(WAVEFORMATEX));
+            This->format->cbSize = 0;
+        }
+
+        This->format->nBlockAlign = This->format->wBitsPerSample * This->format->nChannels / 8;
+        This->format->nAvgBytesPerSec = This->format->nSamplesPerSec * This->format->nBlockAlign;
+    }
+    else if (format->wFormatTag)
+        WARN("Unhandled formattag %x\n", format->wFormatTag);
+
+    This->buf_size = desc->dwBufferBytes;
+    hr = DSOUND_obtain_immdevice(eCapture, &This->parent->device, This->parent->voice ? eCommunications : eMultimedia, &dev);
+    if (SUCCEEDED(hr))
+        hr = IMMDevice_Activate(dev, &IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&This->dev);
+    if (SUCCEEDED(hr))
+        hr = IAudioClient_Initialize(This->dev, AUDCLNT_SHAREMODE_SHARED, 0, 5000000, 0, This->format, NULL);
+    if (SUCCEEDED(hr))
+        hr = IAudioClient_GetService(This->dev, &IID_IAudioCaptureClient, (void**)&This->cap_dev);
+    if (FAILED(hr))
+    {
+        if (This->dev)
+            IUnknown_Release(This->dev);
+        This->dev = NULL;
+        if (dev)
+            IUnknown_Release(dev);
+        if (hr == AUDCLNT_E_UNSUPPORTED_FORMAT)
+        {
+            WARN("Couldn't open device: bad format\n");
+            return DSERR_BADFORMAT;
+        }
+        ERR("couldn't open device %s %i: %08x\n", debugstr_guid(&This->parent->device), This->format->nSamplesPerSec, hr);
+        return hr == DSERR_INVALIDPARAM;
+    }
+    This->buf = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, This->buf_size);
+    if (!This->buf)
+    {
+        IAudioCaptureClient_Release(This->cap_dev);
+        IAudioClient_Release(This->dev);
+        WARN("Out of memory\n");
+        return DSERR_INVALIDPARAM;
+    }
+
+    return S_OK;
+}
+
+static HRESULT WINAPI IDirectSoundCaptureBufferImpl_Lock(IDirectSoundCaptureBuffer8 *iface, DWORD ofs, DWORD bytes, void **ptr1, DWORD *len1, void **ptr2, DWORD *len2, DWORD flags)
+{
+    IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface);
+    HRESULT hr;
+    DWORD remain;
+    TRACE("(%p)->(%u, %u, %p, %p, %p, %p, %#x)\n", This, ofs, bytes, ptr1, len1, ptr2, len2, flags);
+
+    EnterCriticalSection(&This->parent->crst);
+    hr = DSERR_INVALIDPARAM;
+    if (ptr1)
+        *ptr1 = NULL;
+    if (len1)
+        *len1 = 0;
+    if (ptr2)
+        *ptr2 = NULL;
+    if (len2)
+        *len2 = 0;
+    if (ofs >= This->buf_size)
+    {
+        WARN("Invalid ofs %u\n", ofs);
+        goto out;
+    }
+    if (!ptr1 || !len1)
+    {
+        WARN("Invalid pointer/len %p %p\n", ptr1, len1);
+        goto out;
+    }
+    if (flags & DSCBLOCK_ENTIREBUFFER)
+        bytes = This->buf_size;
+    if (bytes > This->buf_size)
+    {
+        WARN("Invalid size %u\n", bytes);
+        goto out;
+    }
+
+    if (ofs + bytes >= This->buf_size)
+    {
+        *len1 = This->buf_size - ofs;
+        remain = bytes - *len1;
+    }
+    else
+    {
+        *len1 = bytes;
+        remain = 0;
+    }
+    *ptr1 = This->buf + ofs;
+
+    if (ptr2 && len2 && remain)
+    {
+        *ptr2 = This->buf;
+        *len2 = remain;
+    }
+    hr = S_OK;
+
+out:
+    LeaveCriticalSection(&This->parent->crst);
+    return hr;
+}
+
+static void IDirectSoundCaptureBufferImpl_starttimer(IDirectSoundCaptureBufferImpl *This)
+{
+    TIMECAPS time;
+    REFERENCE_TIME min_period, default_period;
+    DWORD triggertime, res = DS_TIME_RES;
+
+    if (This->parent->timer_id)
+        return;
+
+    timeGetDevCaps(&time, sizeof(TIMECAPS));
+    IAudioClient_GetDevicePeriod(This->dev, &default_period, &min_period);
+    triggertime = default_period / 10000;
+    if (triggertime < time.wPeriodMin)
+        triggertime = time.wPeriodMin;
+    TRACE("Calling timer every %u ms\n", triggertime);
+    if (res < time.wPeriodMin)
+        res = time.wPeriodMin;
+    if (timeBeginPeriod(res) == TIMERR_NOCANDO)
+        WARN("Could not set minimum resolution, don't expect sound\n");
+    This->parent->timer_res = res;
+    This->parent->timer_id = timeSetEvent(triggertime, res, IDirectSoundCaptureBufferImpl_timer, (DWORD_PTR)This->parent, TIME_PERIODIC | TIME_KILL_SYNCHRONOUS);
+}
+
+static HRESULT WINAPI IDirectSoundCaptureBufferImpl_Start(IDirectSoundCaptureBuffer8 *iface, DWORD flags)
+{
+    IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface);
+    TRACE("(%p)->(%08x)\n", This, flags);
+
+    EnterCriticalSection(&This->parent->crst);
+    if (!This->playing)
+    {
+        IDirectSoundCaptureBufferImpl_starttimer(This);
+        This->playing = 1;
+        IAudioClient_Start(This->dev);
+    }
+    This->looping = !!(flags & DSCBSTART_LOOPING);
+    LeaveCriticalSection(&This->parent->crst);
+    return S_OK;
+}
+
+static HRESULT WINAPI IDirectSoundCaptureBufferImpl_Stop(IDirectSoundCaptureBuffer8 *iface)
+{
+    IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface);
+    TRACE("(%p)\n", This);
+
+    EnterCriticalSection(&This->parent->crst);
+    if (This->playing)
+    {
+        DWORD i;
+
+        for (i = 0; i < This->nnotify; ++i)
+            if (This->notify[i].dwOffset == DSCBPN_OFFSET_STOP)
+            {
+                SetEvent(This->notify[i].hEventNotify);
+                break;
+            }
+        This->playing = This->looping = 0;
+        IAudioClient_Stop(This->dev);
+        IAudioClient_Reset(This->dev);
+    }
+    LeaveCriticalSection(&This->parent->crst);
+    return S_OK;
+}
+
+static HRESULT WINAPI IDirectSoundCaptureBufferImpl_Unlock(IDirectSoundCaptureBuffer8 *iface, void *ptr1, DWORD len1, void *ptr2, DWORD len2)
+{
+    IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface);
+    TRACE("(%p)->(%p,%u,%p,%u)\n", This, ptr1, len2, ptr2, len2);
+
+    if (!ptr1)
+        return DSERR_INVALIDPARAM;
+    return S_OK;
+}
+
+static HRESULT WINAPI IDirectSoundCaptureBufferImpl_GetObjectInPath(IDirectSoundCaptureBuffer8 *iface, REFGUID guid, DWORD num, REFGUID riid, void **ppv)
+{
+    IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface);
+    FIXME("(%p)->(%s %u %s %p) stub\n", This, debugstr_guid(guid), num, debugstr_guid(riid), ppv);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI IDirectSoundCaptureBufferImpl_GetFXStatus(IDirectSoundCaptureBuffer8 *iface, DWORD count, DWORD *status)
+{
+    IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundCaptureBuffer8(iface);
+    FIXME("(%p)->(%u %p) stub\n", This, count, status);
+    return E_NOTIMPL;
+}
+
+static const IDirectSoundCaptureBuffer8Vtbl IDirectSoundCaptureBufferImpl_Vtbl = {
+    IDirectSoundCaptureBufferImpl_QueryInterface,
+    IDirectSoundCaptureBufferImpl_AddRef,
+    IDirectSoundCaptureBufferImpl_Release,
+    IDirectSoundCaptureBufferImpl_GetCaps,
+    IDirectSoundCaptureBufferImpl_GetCurrentPosition,
+    IDirectSoundCaptureBufferImpl_GetFormat,
+    IDirectSoundCaptureBufferImpl_GetStatus,
+    IDirectSoundCaptureBufferImpl_Initialize,
+    IDirectSoundCaptureBufferImpl_Lock,
+    IDirectSoundCaptureBufferImpl_Start,
+    IDirectSoundCaptureBufferImpl_Stop,
+    IDirectSoundCaptureBufferImpl_Unlock,
+    IDirectSoundCaptureBufferImpl_GetObjectInPath,
+    IDirectSoundCaptureBufferImpl_GetFXStatus
+};
+
+static HRESULT IDirectSoundCaptureBufferImpl_Create(IDirectSoundCaptureBufferImpl **buf)
+{
+    IDirectSoundCaptureBufferImpl *This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*This));
+    if (!This)
+        return E_OUTOFMEMORY;
+    This->IDirectSoundCaptureBuffer8_iface.lpVtbl = &IDirectSoundCaptureBufferImpl_Vtbl;
+    This->ref = 1;
+    *buf = This;
+    return S_OK;
+}
+
+static void IDirectSoundCaptureBufferImpl_Destroy(IDirectSoundCaptureBufferImpl *This)
+{
+    if (This->dev)
+    {
+        if (This->playing)
+            IAudioClient_Stop(This->dev);
+        IAudioCaptureClient_Release(This->cap_dev);
+        IAudioClient_Release(This->dev);
+    }
+    if (This->parent)
+        This->parent->buf = NULL;
+    HeapFree(GetProcessHeap(), 0, This->notify);
+    HeapFree(GetProcessHeap(), 0, This->format);
+    HeapFree(GetProcessHeap(), 0, This->buf);
+    HeapFree(GetProcessHeap(), 0, This);
+}
+
+
 static HRESULT WINAPI IDirectSoundCaptureImpl_QueryInterface(IDirectSoundCapture *iface, REFIID riid, void **ppobj)
 {
     IDirectSoundCaptureImpl *This = impl_from_IDirectSoundCapture(iface);
@@ -139,10 +624,17 @@ static HRESULT WINAPI IDirectSoundCaptureImpl_CreateCaptureBuffer(IDirectSoundCa
         goto out;
     }
 
-    hr = DSERR_NODRIVER;
-    FIXME("Stub\n");
-    if (!desc->dwBufferBytes)
-        hr = DSERR_INVALIDPARAM;
+    hr = IDirectSoundCaptureBufferImpl_Create(&This->buf);
+    if (SUCCEEDED(hr))
+    {
+        hr = IDirectSoundCaptureBuffer_Initialize((IDirectSoundCaptureBuffer*)This->buf, iface, desc);
+        if (FAILED(hr))
+        {
+            IDirectSoundCaptureBufferImpl_Destroy(This->buf);
+            This->buf = NULL;
+        }
+    }
+    *ppv = (IDirectSoundCaptureBuffer*)&This->buf->IDirectSoundCaptureBuffer8_iface;
 out:
     LeaveCriticalSection(&This->crst);
     return hr;
@@ -252,7 +744,14 @@ HRESULT DSOUND_CaptureCreate8(REFIID riid, LPDIRECTSOUNDCAPTURE8 *cap)
 
 static void IDirectSoundCaptureImpl_Destroy(IDirectSoundCaptureImpl *This)
 {
+    if (This->timer_id)
+    {
+        timeKillEvent(This->timer_id);
+        timeEndPeriod(This->timer_res);
+    }
     EnterCriticalSection(&This->crst);
+    if (This->buf)
+        IDirectSoundCaptureBufferImpl_Destroy(This->buf);
     LeaveCriticalSection(&This->crst);
     This->crst.DebugInfo->Spare[0] = 0;
     DeleteCriticalSection(&This->crst);
diff --git a/dlls/dsound/tests/capture.c b/dlls/dsound/tests/capture.c
index 87a5a59..2146eb7 100644
--- a/dlls/dsound/tests/capture.c
+++ b/dlls/dsound/tests/capture.c
@@ -377,7 +377,7 @@ static void test_capture_buffer(LPDIRECTSOUNDCAPTURE dsco,
 
     rc=IDirectSoundCaptureBuffer_QueryInterface(dscbo,&IID_IDirectSoundNotify,
                                                 (void **)&(state.notify));
-    ok((rc==DS_OK)&&(state.notify!=NULL),
+    todo_wine ok((rc==DS_OK)&&(state.notify!=NULL),
        "IDirectSoundCaptureBuffer_QueryInterface() failed: %08x\n", rc);
     if (rc!=DS_OK)
 	return;
-- 
1.7.4.1


--------------000304010706090502090205--



More information about the wine-patches mailing list