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/capt... ============================================================================== --- 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/capt... ============================================================================== --- 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/dsou... ============================================================================== --- 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/noti... ============================================================================== --- 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@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/prec... ============================================================================== --- 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