[PATCH 16/27] dsound: Add notification position support for capture, try 2
Maarten Lankhorst
m.b.lankhorst at gmail.com
Thu Apr 7 21:52:20 CDT 2011
---
dlls/dsound/capture.c | 129 ++++++++++++++++++++++++++++++++++++++++++-
dlls/dsound/tests/capture.c | 2 +-
2 files changed, 128 insertions(+), 3 deletions(-)
diff --git a/dlls/dsound/capture.c b/dlls/dsound/capture.c
index df34910..a9906c2 100644
--- a/dlls/dsound/capture.c
+++ b/dlls/dsound/capture.c
@@ -61,7 +61,8 @@ typedef struct IDirectSoundCaptureImpl
struct IDirectSoundCaptureBufferImpl
{
IDirectSoundCaptureBuffer8 IDirectSoundCaptureBuffer8_iface;
- LONG ref;
+ IDirectSoundNotify IDirectSoundNotify_iface;
+ LONG ref, notify_ref;
IDirectSoundCaptureImpl *parent;
IAudioClient *dev;
IAudioCaptureClient *cap_dev;
@@ -82,6 +83,11 @@ static IDirectSoundCaptureBufferImpl *impl_from_IDirectSoundCaptureBuffer8(IDire
return CONTAINING_RECORD(iface, IDirectSoundCaptureBufferImpl, IDirectSoundCaptureBuffer8_iface);
}
+static IDirectSoundCaptureBufferImpl *impl_from_IDirectSoundNotify(IDirectSoundNotify *iface)
+{
+ return CONTAINING_RECORD(iface, IDirectSoundCaptureBufferImpl, IDirectSoundNotify_iface);
+}
+
static void IDirectSoundCaptureImpl_Destroy(IDirectSoundCaptureImpl *This);
static IDirectSoundCaptureImpl *impl_from_IDirectSoundCapture(IDirectSoundCapture *iface)
@@ -91,7 +97,32 @@ static IDirectSoundCaptureImpl *impl_from_IDirectSoundCapture(IDirectSoundCaptur
static void trigger_notifies(IDirectSoundCaptureBufferImpl *buf, DWORD lastpos, DWORD curpos)
{
- TRACE("stub\n");
+ DWORD i;
+ if (lastpos == curpos)
+ return;
+ for (i = 0; i < buf->nnotify; ++i)
+ {
+ DSBPOSITIONNOTIFY *not = &buf->notify[i];
+ HANDLE event = not->hEventNotify;
+ DWORD ofs = not->dwOffset;
+
+ if (ofs == DSCBPN_OFFSET_STOP)
+ continue;
+
+ /* Wraparound case */
+ if (curpos < lastpos)
+ {
+ if (ofs < curpos
+ || ofs >= lastpos)
+ SetEvent(event);
+ continue;
+ }
+
+ /* Normal case */
+ if (ofs >= lastpos
+ && ofs < curpos)
+ SetEvent(event);
+ }
}
static void CALLBACK IDirectSoundCaptureBufferImpl_timer(UINT timerID, UINT msg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
@@ -158,6 +189,8 @@ static HRESULT WINAPI IDirectSoundCaptureBufferImpl_QueryInterface(IDirectSoundC
IsEqualIID(riid, &IID_IDirectSoundCaptureBuffer) ||
(This->parent->is_8 && IsEqualIID(riid, &IID_IDirectSoundCaptureBuffer8)))
*ppv = &This->IDirectSoundCaptureBuffer8_iface;
+ else if (IsEqualIID(riid, &IID_IDirectSoundNotify))
+ *ppv = &This->IDirectSoundNotify_iface;
if (!*ppv)
return E_NOINTERFACE;
IUnknown_AddRef((IUnknown*)*ppv);
@@ -516,12 +549,104 @@ static const IDirectSoundCaptureBuffer8Vtbl IDirectSoundCaptureBufferImpl_Vtbl =
IDirectSoundCaptureBufferImpl_GetFXStatus
};
+static HRESULT WINAPI IDirectSoundNotifyImpl_QueryInterface(IDirectSoundNotify *iface, REFIID riid, void **ppv)
+{
+ IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundNotify(iface);
+ return IDirectSoundCaptureBuffer_QueryInterface((IDirectSoundCaptureBuffer*)This, riid, ppv);
+}
+
+static ULONG WINAPI IDirectSoundNotifyImpl_AddRef(IDirectSoundNotify *iface)
+{
+ IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundNotify(iface);
+ LONG ret;
+
+ ret = InterlockedIncrement(&This->notify_ref);
+ if (ret == 1)
+ IUnknown_AddRef(&This->IDirectSoundCaptureBuffer8_iface);
+ TRACE("new refcount %d\n", ret);
+ return ret;
+}
+
+static ULONG WINAPI IDirectSoundNotifyImpl_Release(IDirectSoundNotify *iface)
+{
+ IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundNotify(iface);
+ LONG ret;
+
+ ret = InterlockedDecrement(&This->notify_ref);
+ TRACE("new refcount %d\n", ret);
+ if (!ret)
+ IUnknown_Release(&This->IDirectSoundCaptureBuffer8_iface);
+ return ret;
+}
+
+static HRESULT WINAPI IDirectSoundNotifyImpl_SetNotificationPositions(IDirectSoundNotify *iface, DWORD count, const DSBPOSITIONNOTIFY *notifications)
+{
+ IDirectSoundCaptureBufferImpl *This = impl_from_IDirectSoundNotify(iface);
+ DSBPOSITIONNOTIFY *nots;
+ HRESULT hr;
+ DWORD state;
+
+ EnterCriticalSection(&This->parent->crst);
+ hr = DSERR_INVALIDPARAM;
+ if (count && !notifications)
+ goto out;
+
+ hr = IDirectSoundCaptureBuffer_GetStatus(&This->IDirectSoundCaptureBuffer8_iface, &state);
+ if (FAILED(hr))
+ goto out;
+
+ hr = DSERR_INVALIDCALL;
+ if (state & DSCBSTATUS_CAPTURING)
+ goto out;
+
+ if (!count)
+ {
+ HeapFree(GetProcessHeap(), 0, This->notify);
+ This->notify = 0;
+ This->nnotify = 0;
+ }
+ else
+ {
+ DWORD i;
+ hr = DSERR_INVALIDPARAM;
+ for (i = 0; i < count; ++i)
+ {
+ if (notifications[i].dwOffset >= This->buf_size
+ && notifications[i].dwOffset != DSCBPN_OFFSET_STOP)
+ goto out;
+ TRACE("ofs: %u/%x with event %p\n", notifications[i].dwOffset, notifications[i].dwOffset, notifications[i].hEventNotify);
+ }
+ hr = E_OUTOFMEMORY;
+ nots = HeapAlloc(GetProcessHeap(), 0, count*sizeof(*nots));
+ if (!nots)
+ goto out;
+ memcpy(nots, notifications, count*sizeof(*nots));
+ HeapFree(GetProcessHeap(), 0, This->notify);
+ This->notify = nots;
+ This->nnotify = count;
+ hr = S_OK;
+ }
+
+out:
+ LeaveCriticalSection(&This->parent->crst);
+ return hr;
+}
+
+static const IDirectSoundNotifyVtbl DSCNot_Vtbl =
+{
+ IDirectSoundNotifyImpl_QueryInterface,
+ IDirectSoundNotifyImpl_AddRef,
+ IDirectSoundNotifyImpl_Release,
+ IDirectSoundNotifyImpl_SetNotificationPositions
+};
+
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->IDirectSoundNotify_iface.lpVtbl = &DSCNot_Vtbl;
This->ref = 1;
*buf = This;
return S_OK;
diff --git a/dlls/dsound/tests/capture.c b/dlls/dsound/tests/capture.c
index 2146eb7..87a5a59 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));
- todo_wine ok((rc==DS_OK)&&(state.notify!=NULL),
+ ok((rc==DS_OK)&&(state.notify!=NULL),
"IDirectSoundCaptureBuffer_QueryInterface() failed: %08x\n", rc);
if (rc!=DS_OK)
return;
--
1.7.4.1
--------------010601070101020007090403--
More information about the wine-patches
mailing list