ReactOS 0.4.15-dev-7842-g558ab78
streaming.c File Reference
#include "precomp.h"
Include dependency graph for streaming.c:

Go to the source code of this file.

Functions

VOID DoWaveStreaming (IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance)
 
VOID CALLBACK CompleteIO (IN DWORD dwErrorCode, IN DWORD dwNumberOfBytesTransferred, IN LPOVERLAPPED lpOverlapped)
 
MMRESULT WriteFileEx_Committer (IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, IN PVOID OffsetPtr, IN DWORD Length, IN PSOUND_OVERLAPPED Overlap, IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine)
 
MMRESULT StopStreamingInSoundThread (IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, IN PVOID Parameter)
 
MMRESULT StopStreaming (IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance)
 
MMRESULT PerformWaveStreaming (IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, IN PVOID Parameter)
 
DWORD WINAPI WaveActivateSoundStreaming (IN PVOID lpParameter)
 
VOID InitiateSoundStreaming (IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance)
 

Function Documentation

◆ CompleteIO()

VOID CALLBACK CompleteIO ( IN DWORD  dwErrorCode,
IN DWORD  dwNumberOfBytesTransferred,
IN LPOVERLAPPED  lpOverlapped 
)

Definition at line 157 of file streaming.c.

161{
163 PSOUND_DEVICE SoundDevice;
164 PSOUND_DEVICE_INSTANCE SoundDeviceInstance;
166 PWAVEHDR WaveHdr;
167 PWAVEHDR_EXTENSION HdrExtension;
169 DWORD Bytes;
170
171 WaveHdr = (PWAVEHDR) SoundOverlapped->Header;
172 SND_ASSERT( WaveHdr );
173
174 HdrExtension = (PWAVEHDR_EXTENSION) WaveHdr->reserved;
175 SND_ASSERT( HdrExtension );
176
177 SoundDeviceInstance = SoundOverlapped->SoundDeviceInstance;
178
179 Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
181
182 Result = GetSoundDeviceType(SoundDevice, &DeviceType);
184
185 do
186 {
187
188 /* We have an available buffer now */
189 -- SoundDeviceInstance->OutstandingBuffers;
190
191 /* Did we finish a WAVEHDR and aren't looping? */
192 if ( HdrExtension->BytesCompleted + dwNumberOfBytesTransferred >= WaveHdr->dwBufferLength &&
193 SoundOverlapped->PerformCompletion )
194 {
195 /* Wave buffer fully completed */
196 Bytes = WaveHdr->dwBufferLength - HdrExtension->BytesCompleted;
197
198 HdrExtension->BytesCompleted += Bytes;
199 dwNumberOfBytesTransferred -= Bytes;
200
201 CompleteWaveHeader(SoundDeviceInstance, WaveHdr);
202 SND_TRACE(L"%d/%d bytes of wavehdr completed\n", HdrExtension->BytesCompleted, WaveHdr->dwBufferLength);
203 }
204 else
205 {
206 /* Partially completed */
207 HdrExtension->BytesCompleted += dwNumberOfBytesTransferred;
208 SND_TRACE(L"%d/%d bytes of wavehdr completed\n", HdrExtension->BytesCompleted, WaveHdr->dwBufferLength);
209 break;
210 }
211
212 /* Move to next wave header */
213 WaveHdr = WaveHdr->lpNext;
214
215 if (!WaveHdr)
216 {
217 /* No following WaveHdr */
218 SND_ASSERT(dwNumberOfBytesTransferred == 0);
219 break;
220 }
221
222 HdrExtension = (PWAVEHDR_EXTENSION) WaveHdr->reserved;
223 SND_ASSERT( HdrExtension );
224
225
226 }while(dwNumberOfBytesTransferred);
227
228 // AUDIO-BRANCH DIFF
229 // completion callback is performed in a thread
230 DoWaveStreaming(SoundDeviceInstance);
231
232 //CompleteWavePortion(SoundDeviceInstance, dwNumberOfBytesTransferred);
233
235}
static VOID FreeMemory(PCREATE_DATA Data)
Definition: create.c:134
unsigned long DWORD
Definition: ntddk_ex.h:95
_In_ UINT Bytes
Definition: mmcopy.h:9
DeviceType
Definition: mmdrv.h:42
struct _WAVEHDR_EXTENSION * PWAVEHDR_EXTENSION
struct _SOUND_OVERLAPPED * PSOUND_OVERLAPPED
UCHAR MMDEVICE_TYPE
Definition: mmebuddy.h:88
MMRESULT GetSoundDeviceFromInstance(IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, OUT PSOUND_DEVICE *SoundDevice)
MMRESULT GetSoundDeviceType(IN PSOUND_DEVICE SoundDevice, OUT PMMDEVICE_TYPE DeviceType)
Definition: devicelist.c:346
VOID CompleteWaveHeader(IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, IN PWAVEHDR Header)
Definition: header.c:274
#define MMSUCCESS(result)
Definition: mmebuddy.h:80
#define SND_TRACE(...)
#define SND_ASSERT(condition)
UINT MMRESULT
Definition: mmsystem.h:962
struct wavehdr_tag * PWAVEHDR
_In_ HANDLE _In_ DWORD _In_ DWORD _Inout_opt_ LPOVERLAPPED lpOverlapped
Definition: mswsock.h:93
#define L(x)
Definition: ntvdm.h:50
VOID DoWaveStreaming(IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance)
Definition: streaming.c:20
BOOL PerformCompletion
Definition: mmebuddy.h:123
PWAVEHDR Header
Definition: mmebuddy.h:122
struct _SOUND_DEVICE_INSTANCE * SoundDeviceInstance
Definition: mmebuddy.h:121
DWORD BytesCompleted
Definition: mmebuddy.h:313
DWORD dwBufferLength
Definition: mmsystem.h:1015
DWORD_PTR reserved
Definition: mmsystem.h:1021
struct wavehdr_tag * lpNext
Definition: mmsystem.h:1020
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409

Referenced by DoWaveStreaming().

◆ DoWaveStreaming()

VOID DoWaveStreaming ( IN PSOUND_DEVICE_INSTANCE  SoundDeviceInstance)

Definition at line 20 of file streaming.c.

22{
25 PSOUND_DEVICE SoundDevice;
28 PWAVEHDR_EXTENSION HeaderExtension;
29
30 Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
32
33 Result = GetSoundDeviceType(SoundDevice, &DeviceType);
35
39 SND_ASSERT( FunctionTable->CommitWaveBuffer );
40
41 /* No point in doing anything if no resources available to use */
42 if ( SoundDeviceInstance->OutstandingBuffers >= SoundDeviceInstance->BufferCount )
43 {
44 SND_TRACE(L"DoWaveStreaming: No available buffers to stream with - doing nothing\n");
45 return;
46 }
47
48 /* Is there any work to do? */
49 Header = SoundDeviceInstance->HeadWaveHeader;
50
51 if ( ! Header )
52 {
53 SND_TRACE(L"DoWaveStreaming: No work to do - doing nothing\n");
54 return;
55 }
56
57 while ( ( SoundDeviceInstance->OutstandingBuffers < SoundDeviceInstance->BufferCount ) &&
58 ( Header ) && SoundDeviceInstance->ResetInProgress == FALSE)
59 {
60 HeaderExtension = (PWAVEHDR_EXTENSION) Header->reserved;
61 SND_ASSERT( HeaderExtension );
62
63 /* Saniy checks */
65 SND_ASSERT(Header->dwFlags & WHDR_INQUEUE);
66
67 /* Can never be *above* the length */
68 SND_ASSERT( HeaderExtension->BytesCommitted <= Header->dwBufferLength );
69
70 /* Is this header entirely committed? */
71 if ( HeaderExtension->BytesCommitted == Header->dwBufferLength )
72 {
73 {
74 /* Move on to the next header */
75 SND_ASSERT(Header != Header->lpNext);
76 Header = Header->lpNext;
77 }
78 }
79 else
80 {
81 PSOUND_OVERLAPPED Overlap;
82 LPVOID OffsetPtr;
83 DWORD BytesRemaining, BytesToCommit;
84 BOOL OK;
85
86 /* Where within the header buffer to stream from */
87 OffsetPtr = Header->lpData + HeaderExtension->BytesCommitted;
88
89 /* How much of this header has not been committed */
90 BytesRemaining = Header->dwBufferLength - HeaderExtension->BytesCommitted;
91
92 /* We can commit anything up to the buffer size limit */
93 BytesToCommit = BytesRemaining > SoundDeviceInstance->FrameSize ?
94 SoundDeviceInstance->FrameSize :
95 BytesRemaining;
96
97 /* Should always have something to commit by this point */
98 SND_ASSERT( BytesToCommit > 0 );
99
100 /* We need a new overlapped info structure for each buffer */
102
103 if ( Overlap )
104 {
105 ZeroMemory(Overlap, sizeof(SOUND_OVERLAPPED));
106 Overlap->SoundDeviceInstance = SoundDeviceInstance;
107 Overlap->Header = Header;
108
109 /* Don't complete this header if it's part of a loop */
110 Overlap->PerformCompletion = TRUE;
111// ( SoundDeviceInstance->LoopsRemaining > 0 );
112
113 /* Adjust the commit-related counters */
114 HeaderExtension->BytesCommitted += BytesToCommit;
115 ++ SoundDeviceInstance->OutstandingBuffers;
116
117 OK = MMSUCCESS(FunctionTable->CommitWaveBuffer(SoundDeviceInstance,
118 OffsetPtr,
119 BytesToCommit,
120 Overlap,
121 CompleteIO));
122
123 if ( ! OK )
124 {
125 /* Clean-up and try again on the next iteration (is this OK?) */
126 SND_WARN(L"FAILED\n");
127
128 FreeMemory(Overlap);
129 HeaderExtension->BytesCommitted -= BytesToCommit;
130 -- SoundDeviceInstance->OutstandingBuffers;
131 }
132 }
133 }
134 }
135}
Definition: Header.h:9
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
#define AllocateStruct(thing)
Definition: mmebuddy.h:27
MMRESULT GetSoundDeviceFunctionTable(IN PSOUND_DEVICE SoundDevice, OUT PMMFUNCTION_TABLE *FunctionTable)
Definition: functiontable.c:47
#define SND_WARN(...)
#define WHDR_INQUEUE
Definition: mmsystem.h:197
#define WHDR_PREPARED
Definition: mmsystem.h:194
VOID CALLBACK CompleteIO(IN DWORD dwErrorCode, IN DWORD dwNumberOfBytesTransferred, IN LPOVERLAPPED lpOverlapped)
Definition: streaming.c:157
DWORD BytesCommitted
Definition: mmebuddy.h:312
#define OK(condition, fail_message,...)
#define ZeroMemory
Definition: winbase.h:1712
static WLX_DISPATCH_VERSION_1_4 FunctionTable
Definition: wlx.c:722

Referenced by CompleteIO(), EnqueueWaveHeader(), and PerformWaveStreaming().

◆ InitiateSoundStreaming()

VOID InitiateSoundStreaming ( IN PSOUND_DEVICE_INSTANCE  SoundDeviceInstance)

Definition at line 383 of file streaming.c.

385{
387
388 hThread = CreateThread(NULL, 0, WaveActivateSoundStreaming, (PVOID)SoundDeviceInstance, 0, NULL);
389
390 if (hThread != NULL)
392}
#define NULL
Definition: types.h:112
#define CloseHandle
Definition: compat.h:739
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
HANDLE hThread
Definition: wizard.c:28
DWORD WINAPI WaveActivateSoundStreaming(IN PVOID lpParameter)
Definition: streaming.c:372

Referenced by MmeSetState().

◆ PerformWaveStreaming()

MMRESULT PerformWaveStreaming ( IN PSOUND_DEVICE_INSTANCE  SoundDeviceInstance,
IN PVOID  Parameter 
)

Definition at line 361 of file streaming.c.

364{
365 DoWaveStreaming(SoundDeviceInstance);
366
367 return MMSYSERR_NOERROR;
368}
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96

Referenced by WaveActivateSoundStreaming().

◆ StopStreaming()

MMRESULT StopStreaming ( IN PSOUND_DEVICE_INSTANCE  SoundDeviceInstance)

Definition at line 334 of file streaming.c.

336{
338 PSOUND_DEVICE SoundDevice;
340
341 if ( ! IsValidSoundDeviceInstance(SoundDeviceInstance) )
343
344 Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
345 if ( ! MMSUCCESS(Result) )
347
348 Result = GetSoundDeviceType(SoundDevice, &DeviceType);
349 if ( ! MMSUCCESS(Result) )
351
354
355 return CallSoundThread(SoundDeviceInstance,
357 NULL);
358}
MMRESULT CallSoundThread(IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, IN SOUND_THREAD_REQUEST_HANDLER RequestHandler, IN PVOID Parameter OPTIONAL)
Definition: thread.c:71
MMRESULT TranslateInternalMmResult(IN MMRESULT Result)
Definition: utility.c:132
BOOLEAN IsValidSoundDeviceInstance(IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance)
#define MMSYSERR_NOTSUPPORTED
Definition: mmsystem.h:104
#define MMSYSERR_INVALHANDLE
Definition: mmsystem.h:101
@ WAVE_IN_DEVICE_TYPE
Definition: sndtypes.h:28
@ WAVE_OUT_DEVICE_TYPE
Definition: sndtypes.h:29
MMRESULT StopStreamingInSoundThread(IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, IN PVOID Parameter)
Definition: streaming.c:271

Referenced by MmeResetWavePlayback().

◆ StopStreamingInSoundThread()

MMRESULT StopStreamingInSoundThread ( IN PSOUND_DEVICE_INSTANCE  SoundDeviceInstance,
IN PVOID  Parameter 
)

Definition at line 271 of file streaming.c.

274{
278 PSOUND_DEVICE SoundDevice;
279
280 /* set state reset in progress */
281 SoundDeviceInstance->ResetInProgress = TRUE;
282
283 /* Get sound device */
284 Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
286
287 /* Obtain the function table */
290
291 /* Obtain device instance type */
292 Result = GetSoundDeviceType(SoundDevice, &DeviceType);
294
295 /* Check if reset function is supported */
296 if (FunctionTable->ResetStream)
297 {
298 /* cancel all current audio buffers */
299 FunctionTable->ResetStream(SoundDeviceInstance, DeviceType, TRUE);
300 }
301 while(SoundDeviceInstance->OutstandingBuffers)
302 {
303 SND_TRACE(L"StopStreamingInSoundThread OutStandingBufferCount %lu\n", SoundDeviceInstance->OutstandingBuffers);
304 /* wait until pending i/o has completed */
305 SleepEx(10, TRUE);
306 }
307
308 /* complete all current headers */
309 while( SoundDeviceInstance->HeadWaveHeader )
310 {
311 SND_TRACE(L"StopStreamingInSoundThread: Completing Header %p\n", SoundDeviceInstance->HeadWaveHeader);
312 CompleteWaveHeader( SoundDeviceInstance, SoundDeviceInstance->HeadWaveHeader );
313 }
314
315 /* there should be no oustanding buffers now */
316 SND_ASSERT(SoundDeviceInstance->OutstandingBuffers == 0);
317
318
319 /* Check if reset function is supported */
320 if (FunctionTable->ResetStream)
321 {
322 /* finish the reset */
323 FunctionTable->ResetStream(SoundDeviceInstance, DeviceType, FALSE);
324 }
325
326 /* clear state reset in progress */
327 SoundDeviceInstance->ResetInProgress = FALSE;
328
329
330 return MMSYSERR_NOERROR;
331}
DWORD WINAPI SleepEx(IN DWORD dwMilliseconds, IN BOOL bAlertable)
Definition: synch.c:802

Referenced by StopStreaming().

◆ WaveActivateSoundStreaming()

DWORD WINAPI WaveActivateSoundStreaming ( IN PVOID  lpParameter)

Definition at line 372 of file streaming.c.

374{
377 NULL);
378
379 ExitThread(0);
380}
VOID WINAPI ExitThread(IN DWORD uExitCode)
Definition: thread.c:365
MMRESULT PerformWaveStreaming(IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, IN PVOID Parameter)
Definition: streaming.c:361

Referenced by InitiateSoundStreaming().

◆ WriteFileEx_Committer()

MMRESULT WriteFileEx_Committer ( IN PSOUND_DEVICE_INSTANCE  SoundDeviceInstance,
IN PVOID  OffsetPtr,
IN DWORD  Length,
IN PSOUND_OVERLAPPED  Overlap,
IN LPOVERLAPPED_COMPLETION_ROUTINE  CompletionRoutine 
)

Definition at line 238 of file streaming.c.

244{
246
247 VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance );
248 VALIDATE_MMSYS_PARAMETER( OffsetPtr );
249 VALIDATE_MMSYS_PARAMETER( Overlap );
251
252 GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
253
254 if ( ! WriteFileEx(Handle, OffsetPtr, Length, (LPOVERLAPPED)Overlap, CompletionRoutine) )
255 {
256 // TODO
257 }
258
259 return MMSYSERR_NOERROR;
260}
BOOL WINAPI WriteFileEx(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, IN LPOVERLAPPED lpOverlapped, IN LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
Definition: rw.c:262
ULONG Handle
Definition: gdb_input.c:15
#define VALIDATE_MMSYS_PARAMETER(parameter_condition)
Definition: mmebuddy.h:71
MMRESULT GetSoundDeviceInstanceHandle(IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, OUT PVOID *Handle)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
_In_ WDFREQUEST _In_opt_ PFN_WDF_REQUEST_COMPLETION_ROUTINE CompletionRoutine
Definition: wdfrequest.h:895

Referenced by FoundDevice().