Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygennotify.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS Configuration of network devices 00004 * FILE: dll/directx/dsound_new/notify.c 00005 * PURPOSE: IDirectSoundNotify implementation 00006 * 00007 * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org) 00008 */ 00009 00010 00011 #include "precomp.h" 00012 00013 typedef struct tagNOTIFYEVENT 00014 { 00015 DWORD NotifyCount; 00016 PLOOPEDSTREAMING_POSITION_EVENT_DATA Notify; 00017 struct tagNOTIFYEVENT *lpNext; 00018 }NOTIFYEVENT, *LPNOTIFYEVENT; 00019 00020 typedef struct 00021 { 00022 IDirectSoundNotifyVtbl * lpVtbl; 00023 LONG ref; 00024 00025 LPNOTIFYEVENT EventListHead; 00026 BOOL bLoop; 00027 BOOL bMix; 00028 HANDLE hPin; 00029 DWORD BufferSize; 00030 00031 }CDirectSoundNotifyImpl, *LPCDirectSoundNotifyImpl; 00032 00033 static 00034 ULONG 00035 WINAPI 00036 IDirectSoundNotify_fnAddRef( 00037 LPDIRECTSOUNDNOTIFY iface) 00038 { 00039 ULONG ref; 00040 LPCDirectSoundNotifyImpl This = (LPCDirectSoundNotifyImpl)CONTAINING_RECORD(iface, CDirectSoundNotifyImpl, lpVtbl); 00041 00042 /* increment reference count */ 00043 ref = InterlockedIncrement(&This->ref); 00044 00045 return ref; 00046 } 00047 00048 static 00049 ULONG 00050 WINAPI 00051 IDirectSoundNotify_fnRelease( 00052 LPDIRECTSOUNDNOTIFY iface) 00053 { 00054 ULONG ref; 00055 LPCDirectSoundNotifyImpl This = (LPCDirectSoundNotifyImpl)CONTAINING_RECORD(iface, CDirectSoundNotifyImpl, lpVtbl); 00056 00057 ref = InterlockedDecrement(&(This->ref)); 00058 00059 if (!ref) 00060 { 00061 HeapFree(GetProcessHeap(), 0, This); 00062 } 00063 00064 return ref; 00065 } 00066 00067 HRESULT 00068 WINAPI 00069 IDirectSoundNotify_fnQueryInterface( 00070 LPDIRECTSOUNDNOTIFY iface, 00071 IN REFIID riid, 00072 LPVOID* ppobj) 00073 { 00074 LPCDirectSoundNotifyImpl This = (LPCDirectSoundNotifyImpl)CONTAINING_RECORD(iface, CDirectSoundNotifyImpl, lpVtbl); 00075 00076 /* check if the interface is supported */ 00077 if (IsEqualIID(riid, &IID_IDirectSoundNotify) || IsEqualIID(riid, &IID_IUnknown)) 00078 { 00079 *ppobj = (LPVOID)&This->lpVtbl; 00080 InterlockedIncrement(&This->ref); 00081 return S_OK; 00082 } 00083 00084 return E_NOINTERFACE; 00085 } 00086 00087 HRESULT 00088 WINAPI 00089 IDirectSoundNotify_fnSetNotificationPositions( 00090 LPDIRECTSOUNDNOTIFY iface, 00091 DWORD dwPositionNotifies, 00092 LPCDSBPOSITIONNOTIFY pcPositionNotifies) 00093 { 00094 DWORD Index; 00095 LPNOTIFYEVENT Notify; 00096 DWORD Result; 00097 KSEVENT Request; 00098 00099 LPCDirectSoundNotifyImpl This = (LPCDirectSoundNotifyImpl)CONTAINING_RECORD(iface, CDirectSoundNotifyImpl, lpVtbl); 00100 00101 if (dwPositionNotifies > DSBNOTIFICATIONS_MAX) 00102 { 00103 /* invalid param */ 00104 return DSERR_INVALIDPARAM; 00105 } 00106 00107 /* verify notification event handles */ 00108 for(Index = 0; Index < dwPositionNotifies; Index++) 00109 { 00110 ASSERT(pcPositionNotifies[Index].hEventNotify); 00111 ASSERT(pcPositionNotifies[Index].dwOffset < This->BufferSize || pcPositionNotifies[Index].dwOffset != DSBPN_OFFSETSTOP); 00112 00113 if (pcPositionNotifies[Index].hEventNotify == NULL) 00114 return DSERR_INVALIDPARAM; 00115 00116 if (pcPositionNotifies[Index].dwOffset > This->BufferSize && pcPositionNotifies[Index].dwOffset != DSBPN_OFFSETSTOP) 00117 return DSERR_INVALIDPARAM; 00118 } 00119 00120 /* allocate new array */ 00121 Notify = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(NOTIFYEVENT)); 00122 if (!Notify) 00123 { 00124 /* not enough memory */ 00125 return DSERR_OUTOFMEMORY; 00126 } 00127 00128 /* allocate new array */ 00129 Notify->Notify = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwPositionNotifies * sizeof(LOOPEDSTREAMING_POSITION_EVENT_DATA)); 00130 if (!Notify->Notify) 00131 { 00132 /* not enough memory */ 00133 HeapFree(GetProcessHeap(), 0, Notify); 00134 return DSERR_OUTOFMEMORY; 00135 } 00136 00137 /* FIXME support non-looped streaming */ 00138 ASSERT(This->bLoop); 00139 00140 /* prepare request */ 00141 Request.Set = KSEVENTSETID_LoopedStreaming; 00142 Request.Id = KSEVENT_LOOPEDSTREAMING_POSITION; 00143 Request.Flags = KSEVENT_TYPE_ENABLE; 00144 00145 for(Index = 0; Index < dwPositionNotifies; Index++) 00146 { 00147 /* initialize event entries */ 00148 Notify->Notify[Index].Position = pcPositionNotifies[Index].dwOffset; 00149 Notify->Notify[Index].KsEventData.EventHandle.Event = pcPositionNotifies[Index].hEventNotify; 00150 Notify->Notify[Index].KsEventData.NotificationType = KSEVENTF_EVENT_HANDLE; 00151 00152 if (This->bMix == FALSE) 00153 { 00154 /* format is supported natively */ 00155 Result = SyncOverlappedDeviceIoControl(This->hPin, IOCTL_KS_ENABLE_EVENT, (PVOID)&Request, sizeof(KSEVENT), (PVOID)&Notify->Notify[Index], sizeof(LOOPEDSTREAMING_POSITION_EVENT_DATA), NULL); 00156 00157 if (Result != ERROR_SUCCESS) 00158 { 00159 DPRINT1("Failed to enable event %p Position %u\n", pcPositionNotifies[Index].hEventNotify, pcPositionNotifies[Index].dwOffset); 00160 } 00161 } 00162 } 00163 00164 /* enlarge notify count */ 00165 Notify->NotifyCount = dwPositionNotifies; 00166 00167 if (This->EventListHead) 00168 { 00169 Notify->lpNext = This->EventListHead; 00170 } 00171 00172 /* insert at front */ 00173 (void)InterlockedExchangePointer((LPVOID*)&This->EventListHead, Notify); 00174 00175 return DS_OK; 00176 } 00177 00178 static IDirectSoundNotifyVtbl vt_DirectSoundNotify = 00179 { 00180 /* IUnknown methods */ 00181 IDirectSoundNotify_fnQueryInterface, 00182 IDirectSoundNotify_fnAddRef, 00183 IDirectSoundNotify_fnRelease, 00184 /* IDirectSoundNotify */ 00185 IDirectSoundNotify_fnSetNotificationPositions 00186 }; 00187 00188 00189 VOID 00190 DoNotifyPositionEvents( 00191 LPDIRECTSOUNDNOTIFY iface, 00192 DWORD OldPosition, 00193 DWORD NewPosition) 00194 { 00195 DWORD Index; 00196 LPNOTIFYEVENT CurEventList; 00197 00198 LPCDirectSoundNotifyImpl This = (LPCDirectSoundNotifyImpl)CONTAINING_RECORD(iface, CDirectSoundNotifyImpl, lpVtbl); 00199 00200 CurEventList = This->EventListHead; 00201 00202 while(CurEventList) 00203 { 00204 for(Index = 0; Index < CurEventList->NotifyCount; Index++) 00205 { 00206 if (NewPosition > OldPosition) 00207 { 00208 /* buffer progress no overlap */ 00209 if (OldPosition < CurEventList->Notify[Index].Position && CurEventList->Notify[Index].Position <= NewPosition) 00210 { 00211 /* process event */ 00212 SetEvent(CurEventList->Notify[Index].KsEventData.EventHandle.Event); 00213 } 00214 } 00215 else 00216 { 00217 /* buffer wrap-arround */ 00218 if (OldPosition < CurEventList->Notify[Index].Position || NewPosition > CurEventList->Notify[Index].Position) 00219 { 00220 /* process event */ 00221 SetEvent(CurEventList->Notify[Index].KsEventData.EventHandle.Event); 00222 } 00223 } 00224 } 00225 00226 /* iterate to next event list */ 00227 CurEventList = CurEventList->lpNext; 00228 } 00229 } 00230 00231 HRESULT 00232 NewDirectSoundNotify( 00233 LPDIRECTSOUNDNOTIFY * Notify, 00234 BOOL bLoop, 00235 BOOL bMix, 00236 HANDLE hPin, 00237 DWORD BufferSize) 00238 { 00239 LPCDirectSoundNotifyImpl This = HeapAlloc(GetProcessHeap(), 0, sizeof(CDirectSoundNotifyImpl)); 00240 00241 if (!This) 00242 return DSERR_OUTOFMEMORY; 00243 00244 This->lpVtbl = &vt_DirectSoundNotify; 00245 This->bLoop = bLoop; 00246 This->bMix = bMix; 00247 This->hPin = hPin; 00248 This->ref = 1; 00249 This->EventListHead = NULL; 00250 This->BufferSize = BufferSize; 00251 00252 *Notify = (LPDIRECTSOUNDNOTIFY)&This->lpVtbl; 00253 return DS_OK; 00254 00255 } Generated on Thu May 24 2012 04:21:53 for ReactOS by
1.7.6.1
|