[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