[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