ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

notify.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.