Author: janderwald
Date: Sat Nov 7 14:49:01 2009
New Revision: 43997
URL:
http://svn.reactos.org/svn/reactos?rev=43997&view=rev
Log:
[DSOUND]
- Add more checks IDirectSoundCapture::CreateCaptureBuffer
- Implement IDirectSoundNotify interface
- Needs work from ks / portcls to work on formats supported natively by the driver
Added:
trunk/reactos/dll/directx/dsound_new/notify.c (with props)
Modified:
trunk/reactos/dll/directx/dsound_new/capture.c
trunk/reactos/dll/directx/dsound_new/capturebuffer.c
trunk/reactos/dll/directx/dsound_new/dsound_new.rbuild
trunk/reactos/dll/directx/dsound_new/precomp.h
Modified: trunk/reactos/dll/directx/dsound_new/capture.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/dsound_new/cap…
==============================================================================
--- trunk/reactos/dll/directx/dsound_new/capture.c [iso-8859-1] (original)
+++ trunk/reactos/dll/directx/dsound_new/capture.c [iso-8859-1] Sat Nov 7 14:49:01 2009
@@ -18,7 +18,6 @@
LPFILTERINFO Filter;
}CDirectSoundCaptureImpl, *LPCDirectSoundCaptureImpl;
-
HRESULT
WINAPI
CDirectSoundCapture_fnQueryInterface(
@@ -100,25 +99,20 @@
if (!lpcDSBufferDesc || !ppDSCBuffer || pUnkOuter != NULL)
{
- DPRINT("Invalid parameter %p %p %p\n", lpcDSBufferDesc, ppDSCBuffer,
pUnkOuter);
+ /* invalid param */
return DSERR_INVALIDPARAM;
}
/* check buffer description */
- if ((lpcDSBufferDesc->dwSize != sizeof(DSCBUFFERDESC) &&
lpcDSBufferDesc->dwSize != sizeof(DSCBUFFERDESC1)) || lpcDSBufferDesc->dwReserved !=
0)
- {
- DPRINT("Invalid buffer description size %u expected %u or %u dwReserved
%u\n", lpcDSBufferDesc->dwSize, sizeof(DSBUFFERDESC1), sizeof(DSBUFFERDESC),
lpcDSBufferDesc->dwReserved);
- return DSERR_INVALIDPARAM;
- }
-
- /* sanity check */
- ASSERT(lpcDSBufferDesc->lpwfxFormat);
-
- if (lpcDSBufferDesc->lpwfxFormat)
- {
- DPRINT("This %p wFormatTag %x nChannels %u nSamplesPerSec %u nAvgBytesPerSec
%u NBlockAlign %u wBitsPerSample %u cbSize %u\n",
- This, lpcDSBufferDesc->lpwfxFormat->wFormatTag,
lpcDSBufferDesc->lpwfxFormat->nChannels,
lpcDSBufferDesc->lpwfxFormat->nSamplesPerSec,
lpcDSBufferDesc->lpwfxFormat->nAvgBytesPerSec,
lpcDSBufferDesc->lpwfxFormat->nBlockAlign,
lpcDSBufferDesc->lpwfxFormat->wBitsPerSample,
lpcDSBufferDesc->lpwfxFormat->cbSize);
- }
+ if ((lpcDSBufferDesc->dwSize != sizeof(DSCBUFFERDESC) &&
lpcDSBufferDesc->dwSize != sizeof(DSCBUFFERDESC1)) ||
+ lpcDSBufferDesc->dwReserved != 0 || lpcDSBufferDesc->dwBufferBytes == 0 ||
lpcDSBufferDesc->lpwfxFormat == NULL)
+ {
+ /* invalid buffer description */
+ return DSERR_INVALIDPARAM;
+ }
+
+ DPRINT("This %p wFormatTag %x nChannels %u nSamplesPerSec %u nAvgBytesPerSec %u
NBlockAlign %u wBitsPerSample %u cbSize %u\n",
+ This, lpcDSBufferDesc->lpwfxFormat->wFormatTag,
lpcDSBufferDesc->lpwfxFormat->nChannels,
lpcDSBufferDesc->lpwfxFormat->nSamplesPerSec,
lpcDSBufferDesc->lpwfxFormat->nAvgBytesPerSec,
lpcDSBufferDesc->lpwfxFormat->nBlockAlign,
lpcDSBufferDesc->lpwfxFormat->wBitsPerSample,
lpcDSBufferDesc->lpwfxFormat->cbSize);
hResult = NewDirectSoundCaptureBuffer((LPDIRECTSOUNDCAPTUREBUFFER8*)ppDSCBuffer,
This->Filter, lpcDSBufferDesc);
return hResult;
Modified: trunk/reactos/dll/directx/dsound_new/capturebuffer.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/dsound_new/cap…
==============================================================================
--- trunk/reactos/dll/directx/dsound_new/capturebuffer.c [iso-8859-1] (original)
+++ trunk/reactos/dll/directx/dsound_new/capturebuffer.c [iso-8859-1] Sat Nov 7 14:49:01
2009
@@ -15,11 +15,14 @@
const GUID KSDATAFORMAT_TYPE_AUDIO = {0x73647561L, 0x0000, 0x0010, {0x80,
0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
const GUID KSDATAFORMAT_SPECIFIER_WAVEFORMATEX = {0x05589f81L, 0xc356, 0x11ce, {0xbf,
0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}};
const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5,
0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
+const GUID KSEVENTSETID_LoopedStreaming = {0x4682B940L, 0xC6EF, 0x11D0, {0x96,
0xD8, 0x00, 0xAA, 0x00, 0x51, 0xE5, 0x1D}};
+
typedef struct
{
IDirectSoundCaptureBuffer8Vtbl *lpVtbl;
+
LONG ref;
LPFILTERINFO Filter;
HANDLE hPin;
@@ -36,6 +39,8 @@
volatile LONG StopMixerThread;
volatile LONG CurrentMixPosition;
+ LPDIRECTSOUNDNOTIFY Notify;
+
}CDirectSoundCaptureBufferImpl, *LPCDirectSoundCaptureBufferImpl;
DWORD
@@ -108,6 +113,13 @@
BufferPosition += BytesWritten;
DPRINT("MixPosition %u BufferPosition %u BytesRead %u BytesWritten %u
MixLength %u BufferLength %u\n", MixPosition, BufferPosition, BytesRead,
BytesWritten, MixLength, BufferLength);
}
+
+ /* Notify Events */
+ if (This->Notify)
+ {
+ DoNotifyPositionEvents(This->Notify, This->CurrentMixPosition,
BufferPosition);
+ }
+
/* update offset */
InterlockedExchange(&This->CurrentMixPosition, (LONG)BufferPosition);
@@ -143,6 +155,25 @@
{
*ppobj = (LPVOID)&This->lpVtbl;
InterlockedIncrement(&This->ref);
+ return S_OK;
+ }
+
+ /* check if the interface is supported */
+ if (IsEqualIID(riid, &IID_IDirectSoundNotify))
+ {
+ if (!This->Notify)
+ {
+ HRESULT hr = NewDirectSoundNotify(&This->Notify, This->bLoop,
This->bMix, This->hPin, This->BufferSize);
+ if (FAILED(hr))
+ return hr;
+
+ *ppobj = (LPVOID)This->Notify;
+ return S_OK;
+ }
+
+ /* increment reference count on existing notify object */
+ IDirectSoundNotify_AddRef(This->Notify);
+ *ppobj = (LPVOID)This->Notify;
return S_OK;
}
@@ -650,6 +681,8 @@
};
+
+
HRESULT
NewDirectSoundCaptureBuffer(
LPDIRECTSOUNDCAPTUREBUFFER8 *OutBuffer,
Modified: trunk/reactos/dll/directx/dsound_new/dsound_new.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/dsound_new/dso…
==============================================================================
--- trunk/reactos/dll/directx/dsound_new/dsound_new.rbuild [iso-8859-1] (original)
+++ trunk/reactos/dll/directx/dsound_new/dsound_new.rbuild [iso-8859-1] Sat Nov 7
14:49:01 2009
@@ -22,6 +22,7 @@
<file>dsound.c</file>
<file>enum.c</file>
<file>misc.c</file>
+ <file>notify.c</file>
<file>primary.c</file>
<file>property.c</file>
<file>regsvr.c</file>
Added: trunk/reactos/dll/directx/dsound_new/notify.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/dsound_new/not…
==============================================================================
--- trunk/reactos/dll/directx/dsound_new/notify.c (added)
+++ trunk/reactos/dll/directx/dsound_new/notify.c [iso-8859-1] Sat Nov 7 14:49:01 2009
@@ -1,0 +1,256 @@
+/*
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS Configuration of network devices
+ * FILE: dll/directx/dsound_new/notify.c
+ * PURPOSE: IDirectSoundNotify implementation
+ *
+ * PROGRAMMERS: Johannes Anderwald (janderwald(a)reactos.org)
+ */
+
+
+#include "precomp.h"
+
+typedef struct tagNOTIFYEVENT
+{
+ DWORD NotifyCount;
+ PLOOPEDSTREAMING_POSITION_EVENT_DATA Notify;
+ struct tagNOTIFYEVENT *lpNext;
+}NOTIFYEVENT, *LPNOTIFYEVENT;
+
+typedef struct
+{
+ IDirectSoundNotifyVtbl * lpVtbl;
+ LONG ref;
+
+ LPNOTIFYEVENT EventListHead;
+ BOOL bLoop;
+ BOOL bMix;
+ HANDLE hPin;
+ DWORD BufferSize;
+
+}CDirectSoundNotifyImpl, *LPCDirectSoundNotifyImpl;
+
+static
+ULONG
+WINAPI
+IDirectSoundNotify_fnAddRef(
+ LPDIRECTSOUNDNOTIFY iface)
+{
+ ULONG ref;
+ LPCDirectSoundNotifyImpl This = (LPCDirectSoundNotifyImpl)CONTAINING_RECORD(iface,
CDirectSoundNotifyImpl, lpVtbl);
+
+ /* increment reference count */
+ ref = InterlockedIncrement(&This->ref);
+
+ return ref;
+}
+
+static
+ULONG
+WINAPI
+IDirectSoundNotify_fnRelease(
+ LPDIRECTSOUNDNOTIFY iface)
+{
+ ULONG ref;
+ LPCDirectSoundNotifyImpl This = (LPCDirectSoundNotifyImpl)CONTAINING_RECORD(iface,
CDirectSoundNotifyImpl, lpVtbl);
+
+ ref = InterlockedDecrement(&(This->ref));
+
+ if (!ref)
+ {
+ HeapFree(GetProcessHeap(), 0, This);
+ }
+
+ return ref;
+}
+
+HRESULT
+WINAPI
+IDirectSoundNotify_fnQueryInterface(
+ LPDIRECTSOUNDNOTIFY iface,
+ IN REFIID riid,
+ LPVOID* ppobj)
+{
+ LPCDirectSoundNotifyImpl This = (LPCDirectSoundNotifyImpl)CONTAINING_RECORD(iface,
CDirectSoundNotifyImpl, lpVtbl);
+
+ /* check if the interface is supported */
+ if (IsEqualIID(riid, &IID_IDirectSoundNotify) || IsEqualIID(riid,
&IID_IUnknown))
+ {
+ *ppobj = (LPVOID)&This->lpVtbl;
+ InterlockedIncrement(&This->ref);
+ return S_OK;
+ }
+
+ return E_NOINTERFACE;
+}
+
+HRESULT
+WINAPI
+IDirectSoundNotify_fnSetNotificationPositions(
+ LPDIRECTSOUNDNOTIFY iface,
+ DWORD dwPositionNotifies,
+ LPCDSBPOSITIONNOTIFY pcPositionNotifies)
+{
+ DWORD Index;
+ LPNOTIFYEVENT Notify;
+ DWORD Result;
+ KSEVENT Request;
+
+ LPCDirectSoundNotifyImpl This = (LPCDirectSoundNotifyImpl)CONTAINING_RECORD(iface,
CDirectSoundNotifyImpl, lpVtbl);
+
+ if (dwPositionNotifies > DSBNOTIFICATIONS_MAX)
+ {
+ /* invalid param */
+ return DSERR_INVALIDPARAM;
+ }
+
+ /* verify notification event handles */
+ for(Index = 0; Index < dwPositionNotifies; Index++)
+ {
+ ASSERT(pcPositionNotifies[Index].hEventNotify);
+ ASSERT(pcPositionNotifies[Index].dwOffset < This->BufferSize ||
pcPositionNotifies[Index].dwOffset != DSBPN_OFFSETSTOP);
+
+ if (pcPositionNotifies[Index].hEventNotify == NULL)
+ return DSERR_INVALIDPARAM;
+
+ if (pcPositionNotifies[Index].dwOffset > This->BufferSize &&
pcPositionNotifies[Index].dwOffset != DSBPN_OFFSETSTOP)
+ return DSERR_INVALIDPARAM;
+ }
+
+ /* allocate new array */
+ Notify = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NOTIFYEVENT));
+ if (!Notify)
+ {
+ /* not enough memory */
+ return DSERR_OUTOFMEMORY;
+ }
+
+ /* allocate new array */
+ Notify->Notify = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwPositionNotifies
* sizeof(LOOPEDSTREAMING_POSITION_EVENT_DATA));
+ if (!Notify->Notify)
+ {
+ /* not enough memory */
+ HeapFree(GetProcessHeap(), 0, Notify);
+ return DSERR_OUTOFMEMORY;
+ }
+
+ /* FIXME support non-looped streaming */
+ ASSERT(This->bLoop);
+
+ /* prepare request */
+ Request.Set = KSEVENTSETID_LoopedStreaming;
+ Request.Id = KSEVENT_LOOPEDSTREAMING_POSITION;
+ Request.Flags = KSEVENT_TYPE_ENABLE;
+
+ for(Index = 0; Index < dwPositionNotifies; Index++)
+ {
+ /* initialize event entries */
+ Notify->Notify[Index].Position = pcPositionNotifies[Index].dwOffset;
+ Notify->Notify[Index].KsEventData.EventHandle.Event =
pcPositionNotifies[Index].hEventNotify;
+ Notify->Notify[Index].KsEventData.NotificationType = KSEVENTF_EVENT_HANDLE;
+
+ if (This->bMix == FALSE)
+ {
+ /* format is supported natively */
+ Result = SyncOverlappedDeviceIoControl(This->hPin, IOCTL_KS_ENABLE_EVENT,
(PVOID)&Request, sizeof(KSEVENT), (PVOID)&Notify->Notify[Index],
sizeof(LOOPEDSTREAMING_POSITION_EVENT_DATA), NULL);
+
+ if (Result != ERROR_SUCCESS)
+ {
+ DPRINT1("Failed to enable event %p Position %u\n",
pcPositionNotifies[Index].hEventNotify, pcPositionNotifies[Index].dwOffset);
+ return DSERR_GENERIC;
+ }
+ }
+ }
+
+ /* enlarge notify count */
+ Notify->NotifyCount = dwPositionNotifies;
+
+ if (This->EventListHead)
+ {
+ Notify->lpNext = This->EventListHead;
+ }
+
+ /* insert at front */
+ (void)InterlockedExchangePointer((LPVOID*)&This->EventListHead, Notify);
+
+ return DS_OK;
+}
+
+static IDirectSoundNotifyVtbl vt_DirectSoundNotify =
+{
+ /* IUnknown methods */
+ IDirectSoundNotify_fnQueryInterface,
+ IDirectSoundNotify_fnAddRef,
+ IDirectSoundNotify_fnRelease,
+ /* IDirectSoundNotify */
+ IDirectSoundNotify_fnSetNotificationPositions
+};
+
+
+VOID
+DoNotifyPositionEvents(
+ LPDIRECTSOUNDNOTIFY iface,
+ DWORD OldPosition,
+ DWORD NewPosition)
+{
+ DWORD Index;
+ LPNOTIFYEVENT CurEventList;
+
+ LPCDirectSoundNotifyImpl This = (LPCDirectSoundNotifyImpl)CONTAINING_RECORD(iface,
CDirectSoundNotifyImpl, lpVtbl);
+
+ CurEventList = This->EventListHead;
+
+ while(CurEventList)
+ {
+ for(Index = 0; Index < CurEventList->NotifyCount; Index++)
+ {
+ if (NewPosition > OldPosition)
+ {
+ /* buffer progress no overlap */
+ if (OldPosition < CurEventList->Notify[Index].Position &&
CurEventList->Notify[Index].Position <= NewPosition)
+ {
+ /* process event */
+
SetEvent(CurEventList->Notify[Index].KsEventData.EventHandle.Event);
+ }
+ }
+ else
+ {
+ /* buffer wrap-arround */
+ if (OldPosition < CurEventList->Notify[Index].Position ||
NewPosition > CurEventList->Notify[Index].Position)
+ {
+ /* process event */
+
SetEvent(CurEventList->Notify[Index].KsEventData.EventHandle.Event);
+ }
+ }
+ }
+
+ /* iterate to next event list */
+ CurEventList = CurEventList->lpNext;
+ }
+}
+
+HRESULT
+NewDirectSoundNotify(
+ LPDIRECTSOUNDNOTIFY * Notify,
+ BOOL bLoop,
+ BOOL bMix,
+ HANDLE hPin,
+ DWORD BufferSize)
+{
+ LPCDirectSoundNotifyImpl This = HeapAlloc(GetProcessHeap(), 0,
sizeof(CDirectSoundNotifyImpl));
+
+ if (!This)
+ return DSERR_OUTOFMEMORY;
+
+ This->lpVtbl = &vt_DirectSoundNotify;
+ This->bLoop = bLoop;
+ This->bMix = bMix;
+ This->hPin = hPin;
+ This->ref = 1;
+ This->EventListHead = NULL;
+ This->BufferSize = BufferSize;
+
+ *Notify = (LPDIRECTSOUNDNOTIFY)&This->lpVtbl;
+ return DS_OK;
+
+}
Propchange: trunk/reactos/dll/directx/dsound_new/notify.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/dll/directx/dsound_new/precomp.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/directx/dsound_new/pre…
==============================================================================
--- trunk/reactos/dll/directx/dsound_new/precomp.h [iso-8859-1] (original)
+++ trunk/reactos/dll/directx/dsound_new/precomp.h [iso-8859-1] Sat Nov 7 14:49:01 2009
@@ -252,4 +252,19 @@
LPFILTERINFO Filter,
LPCDSCBUFFERDESC lpcDSBufferDesc);
+/* notify.c */
+VOID
+DoNotifyPositionEvents(
+ LPDIRECTSOUNDNOTIFY iface,
+ DWORD OldPosition,
+ DWORD NewPosition);
+
+HRESULT
+NewDirectSoundNotify(
+ LPDIRECTSOUNDNOTIFY * Notify,
+ BOOL bLoop,
+ BOOL bMix,
+ HANDLE hPin,
+ DWORD BufferSize);
+
#endif