ReactOS  0.4.14-dev-854-gb9426a3
wave.c File Reference
#include "mmdrv.h"
#include <debug.h>
Include dependency graph for wave.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define MAX_WAVE_BUFFER_SIZE   65536
 

Functions

MMRESULT QueueWaveBuffer (SessionInfo *session_info, LPWAVEHDR wave_header)
 
VOID ReturnCompletedBuffers (SessionInfo *session_info)
 
DWORD ProcessSessionThreadRequest (SessionInfo *session_info)
 
DWORD WaveThread (LPVOID parameter)
 
DWORD GetWaveFormatExSize (PWAVEFORMATEX format)
 
DWORD QueryWaveFormat (DeviceType device_type, PVOID lpFormat)
 
BOOL SetWaveFormat (HANDLE device_handle, PWAVEFORMATEX format)
 
DWORD WriteWaveBuffer (DWORD_PTR private_handle, PWAVEHDR wave_header, DWORD wave_header_size)
 

Macro Definition Documentation

◆ MAX_WAVE_BUFFER_SIZE

#define MAX_WAVE_BUFFER_SIZE   65536

Definition at line 18 of file wave.c.

◆ NDEBUG

#define NDEBUG

Definition at line 15 of file wave.c.

Function Documentation

◆ GetWaveFormatExSize()

DWORD GetWaveFormatExSize ( PWAVEFORMATEX  format)

Definition at line 320 of file wave.c.

321 {
322  if ( format->wFormatTag == WAVE_FORMAT_PCM )
323  return sizeof(PCMWAVEFORMAT);
324  else
325  return sizeof(WAVEFORMATEX) + format->cbSize;
326 }
struct tWAVEFORMATEX WAVEFORMATEX
Definition: austream.idl:23
struct pcmwaveformat_tag PCMWAVEFORMAT
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
#define WAVE_FORMAT_PCM
Definition: constants.h:425

Referenced by SetWaveFormat().

◆ ProcessSessionThreadRequest()

DWORD ProcessSessionThreadRequest ( SessionInfo session_info)

Definition at line 136 of file wave.c.

137 {
139 
140  switch ( session_info->thread.function )
141  {
142  case WODM_WRITE :
143  {
144  result = QueueWaveBuffer(session_info,
145  (LPWAVEHDR) session_info->thread.parameter);
146  break;
147  }
148 
149  case WODM_RESET :
150  {
151  /* TODO */
152  break;
153  }
154 
155  case WODM_PAUSE :
156  {
157  /* TODO */
158  break;
159  }
160 
161  case WODM_RESTART :
162  {
163  /* TODO */
164  break;
165  }
166 
167  case WODM_GETPOS :
168  {
169  /* TODO */
170  break;
171  }
172 
173  case WODM_SETPITCH :
174  {
175  result = SetDeviceData(session_info->kernel_device_handle,
177  (PBYTE) session_info->thread.parameter,
178  sizeof(DWORD));
179  break;
180  }
181 
182  case WODM_GETPITCH :
183  {
184  result = GetDeviceData(session_info->kernel_device_handle,
186  (PBYTE) session_info->thread.parameter,
187  sizeof(DWORD));
188  break;
189  }
190 
191  case WODM_SETVOLUME :
192  {
193  break;
194  }
195 
196  case WODM_GETVOLUME :
197  {
198 #if 0
199  result = GetDeviceData(session_info->kernel_device_handle,
201  (PBYTE) session_info->thread.parameter,);
202 #endif
203  break;
204  }
205 
206  case WODM_SETPLAYBACKRATE :
207  {
208  result = SetDeviceData(session_info->kernel_device_handle,
210  (PBYTE) session_info->thread.parameter,
211  sizeof(DWORD));
212  break;
213  }
214 
215  case WODM_GETPLAYBACKRATE :
216  {
217  result = GetDeviceData(session_info->kernel_device_handle,
219  (PBYTE) session_info->thread.parameter,
220  sizeof(DWORD));
221  break;
222  }
223 
224  case WODM_CLOSE :
225  {
226  DPRINT("Thread was asked if OK to close device\n");
227 
228  if ( session_info->wave_queue != NULL )
230  else
232 
233  break;
234  }
235 
236  case DRVM_TERMINATE :
237  {
238  DPRINT("Terminating thread...\n");
240  break;
241  }
242 
243  default :
244  {
245  DPRINT("INVALID FUNCTION\n");
247  break;
248  }
249  }
250 
251  /* We're done with the function now */
252 
253  return result;
254 }
DWORD function
Definition: mmdrv.h:117
PWAVEHDR wave_queue
Definition: mmdrv.h:158
#define WODM_PAUSE
Definition: mmddk.h:115
MMRESULT QueueWaveBuffer(SessionInfo *session_info, LPWAVEHDR wave_header)
Definition: wave.c:21
BOOL GetDeviceData(LPD3D9_DEVICEDATA pDeviceData)
Definition: d3d9_caps.c:126
#define WODM_GETPLAYBACKRATE
Definition: mmddk.h:123
#define WODM_RESTART
Definition: mmddk.h:116
UINT MMRESULT
Definition: mmsystem.h:962
#define IOCTL_WAVE_SET_PITCH
Definition: mmdef.h:58
#define WODM_GETPITCH
Definition: mmddk.h:119
#define WAVERR_STILLPLAYING
Definition: mmsystem.h:177
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#define WODM_GETVOLUME
Definition: mmddk.h:121
#define DRVM_TERMINATE
Definition: mmdrv.h:86
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define MMSYSERR_ERROR
Definition: mmsystem.h:97
#define WODM_WRITE
Definition: mmddk.h:114
unsigned long DWORD
Definition: ntddk_ex.h:95
#define WODM_SETPITCH
Definition: mmddk.h:120
#define IOCTL_WAVE_GET_VOLUME
Definition: mmdef.h:57
#define WODM_SETVOLUME
Definition: mmddk.h:122
HANDLE kernel_device_handle
Definition: mmdrv.h:136
#define WODM_CLOSE
Definition: mmddk.h:111
ThreadInfo thread
Definition: mmdrv.h:172
#define IOCTL_WAVE_SET_PLAYBACK_RATE
Definition: mmdef.h:60
#define IOCTL_WAVE_GET_PLAYBACK_RATE
Definition: mmdef.h:61
#define IOCTL_WAVE_GET_PITCH
Definition: mmdef.h:59
MMRESULT SetDeviceData(HANDLE device_handle, DWORD ioctl, PBYTE input_buffer, DWORD buffer_size)
Definition: kernel.c:139
#define WODM_SETPLAYBACKRATE
Definition: mmddk.h:124
#define WODM_GETPOS
Definition: mmddk.h:118
GLuint64EXT * result
Definition: glext.h:11304
BYTE * PBYTE
Definition: pedump.c:66
PVOID parameter
Definition: mmdrv.h:118
#define WODM_RESET
Definition: mmddk.h:117

Referenced by WaveThread().

◆ QueryWaveFormat()

DWORD QueryWaveFormat ( DeviceType  device_type,
PVOID  lpFormat 
)

Definition at line 335 of file wave.c.

338 {
339  /* TODO */
340  return WAVERR_BADFORMAT;
341 }
#define WAVERR_BADFORMAT
Definition: mmsystem.h:176

Referenced by wodMessage().

◆ QueueWaveBuffer()

MMRESULT QueueWaveBuffer ( SessionInfo session_info,
LPWAVEHDR  wave_header 
)

Definition at line 21 of file wave.c.

24 {
25  PWAVEHDR queue_node, previous_node;
26  DPRINT("Queueing wave buffer\n");
27 
28  if ( ! wave_header )
29  {
30  return MMSYSERR_INVALPARAM;
31  }
32 
33  if ( ! wave_header->lpData )
34  {
35  return MMSYSERR_INVALPARAM;
36  }
37 
38  /* Headers must be prepared first */
39  if ( ! ( wave_header->dwFlags & WHDR_PREPARED ) )
40  {
41  DPRINT("I was given a header which hasn't been prepared yet!\n");
42  return WAVERR_UNPREPARED;
43  }
44 
45  /* ...and they must not already be in the playing queue! */
46  if ( wave_header->dwFlags & WHDR_INQUEUE )
47  {
48  DPRINT("I was given a header for a buffer which is already playing\n");
49  return WAVERR_STILLPLAYING;
50  }
51 
52  /* Initialize */
53  wave_header->dwBytesRecorded = 0;
54 
55  /* Clear the DONE bit, and mark the buffer as queued */
56  wave_header->dwFlags &= ~WHDR_DONE;
57  wave_header->dwFlags |= WHDR_INQUEUE;
58 
59  /* Save our handle in the header */
60  wave_header->reserved = (DWORD_PTR) session_info;
61 
62  /* Locate the end of the queue */
63  previous_node = NULL;
64  queue_node = session_info->wave_queue;
65 
66  while ( queue_node )
67  {
68  previous_node = queue_node;
69  queue_node = queue_node->lpNext;
70  }
71 
72  /* Go back a step to obtain the previous node (non-NULL) */
73  queue_node = previous_node;
74 
75  /* Append our buffer here, and terminate the queue */
76  queue_node->lpNext = wave_header;
77  wave_header->lpNext = NULL;
78 
79  /* When no buffers are playing there's no play queue so we start one */
80 #if 0
81  if ( ! session_info->next_buffer )
82  {
83  session_info->buffer_position = 0;
84  session_info->next_buffer = wave_header;
85  }
86 #endif
87 
88  /* Pass to the driver - happens automatically during playback */
89 // return PerformWaveIO(session_info);
90  return MMSYSERR_NOERROR;
91 }
PWAVEHDR wave_queue
Definition: mmdrv.h:158
#define DWORD_PTR
Definition: treelist.c:76
LPSTR lpData
Definition: mmsystem.h:1014
#define WAVERR_STILLPLAYING
Definition: mmsystem.h:177
DWORD dwFlags
Definition: mmsystem.h:1018
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
struct wavehdr_tag * lpNext
Definition: mmsystem.h:1020
#define MMSYSERR_INVALPARAM
Definition: mmsystem.h:107
#define WHDR_INQUEUE
Definition: mmsystem.h:197
#define WHDR_PREPARED
Definition: mmsystem.h:194
#define WAVERR_UNPREPARED
Definition: mmsystem.h:178
#define WHDR_DONE
Definition: mmsystem.h:193
DWORD_PTR reserved
Definition: mmsystem.h:1021
DWORD buffer_position
Definition: mmdrv.h:166
DWORD dwBytesRecorded
Definition: mmsystem.h:1016

Referenced by ProcessSessionThreadRequest().

◆ ReturnCompletedBuffers()

VOID ReturnCompletedBuffers ( SessionInfo session_info)

Definition at line 94 of file wave.c.

95 {
97 
98  /* Set the current header and test to ensure it's not NULL */
99  while ( ( header = session_info->wave_queue ) )
100  {
101  if ( header->dwFlags & WHDR_DONE )
102  {
103  DWORD message;
104 
105  /* Mark as done, and unqueued */
106  header->dwFlags &= ~WHDR_INQUEUE;
107  header->dwFlags |= WHDR_DONE;
108 
109  /* Trim it from the start of the queue */
110  session_info->wave_queue = header->lpNext;
111 
112  /* Choose appropriate notification */
113  message = (session_info->device_type == WaveOutDevice) ? WOM_DONE :
114  WIM_DATA;
115 
116  DPRINT("Notifying client that buffer 0x%p is done\n", header);
117 
118  /* Notify the client */
119  NotifyClient(session_info, message, (DWORD_PTR) header, 0);
120  }
121  }
122 
123  /* TODO: Perform I/O as a new buffer may have arrived */
124 }
PWAVEHDR wave_queue
Definition: mmdrv.h:158
#define WOM_DONE
Definition: mmsystem.h:183
Definition: tftpd.h:59
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: glext.h:5579
BOOL NotifyClient(SessionInfo *session_info, DWORD message, DWORD_PTR parameter1, DWORD_PTR parameter2)
Definition: mme.c:25
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
DeviceType device_type
Definition: mmdrv.h:133
unsigned long DWORD
Definition: ntddk_ex.h:95
uint32_t DWORD_PTR
Definition: typedefs.h:63
#define WHDR_INQUEUE
Definition: mmsystem.h:197
#define WHDR_DONE
Definition: mmsystem.h:193
#define WIM_DATA
Definition: mmsystem.h:186

Referenced by WaveThread().

◆ SetWaveFormat()

BOOL SetWaveFormat ( HANDLE  device_handle,
PWAVEFORMATEX  format 
)

Definition at line 349 of file wave.c.

352 {
353  DWORD bytes_returned;
354  DWORD size;
355 
357 
358  DPRINT("SetWaveFormat\n");
359 
360  return DeviceIoControl(device_handle,
362  (PVOID) format,
363  size,
364  NULL,
365  0,
366  &bytes_returned,
367  NULL);
368 }
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
GLsizeiptr size
Definition: glext.h:5919
#define IOCTL_WAVE_SET_FORMAT
Definition: mmdef.h:51
unsigned long DWORD
Definition: ntddk_ex.h:95
BOOL WINAPI DeviceIoControl(IN HANDLE hDevice, IN DWORD dwIoControlCode, IN LPVOID lpInBuffer OPTIONAL, IN DWORD nInBufferSize OPTIONAL, OUT LPVOID lpOutBuffer OPTIONAL, IN DWORD nOutBufferSize OPTIONAL, OUT LPDWORD lpBytesReturned OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: deviceio.c:136
DWORD GetWaveFormatExSize(PWAVEFORMATEX format)
Definition: wave.c:320

◆ WaveThread()

DWORD WaveThread ( LPVOID  parameter)

Definition at line 266 of file wave.c.

267 {
269  SessionInfo* session_info = (SessionInfo*) parameter;
270  BOOL terminate = FALSE;
271 
272  /* All your CPU time are belong to us */
274 
275  DPRINT("Wave processing thread setting ready state\n");
276 
277  SetEvent(session_info->thread.ready_event);
278 
279  while ( ! terminate )
280  {
281  /* Wait for GO event, or IO completion notification */
282  while ( WaitForSingleObjectEx(session_info->thread.go_event,
283  INFINITE,
285  {
286  /* A buffer has been finished with - pass back to the client */
287  ReturnCompletedBuffers(session_info);
288  }
289 
290  DPRINT("Wave processing thread woken up\n");
291 
292  /* Set the terminate flag if that's what the caller wants */
293  terminate = (session_info->thread.function == DRVM_TERMINATE);
294 
295  /* Process the request */
296  DPRINT("Processing thread request\n");
297  result = ProcessSessionThreadRequest(session_info);
298 
299  /* Store the result code */
300  session_info->thread.result = result;
301 
302  /* Submit new buffers and continue existing ones */
303  DPRINT("Performing wave I/O\n");
304  PerformWaveIO(session_info);
305 
306  /* Now we're ready for more action */
307  DPRINT("Wave processing thread sleeping\n");
308  SetEvent(session_info->thread.ready_event);
309  }
310 
311  return 0;
312 }
DWORD function
Definition: mmdrv.h:117
DWORD WINAPI WaitForSingleObjectEx(IN HANDLE hHandle, IN DWORD dwMilliseconds, IN BOOL bAlertable)
Definition: synch.c:94
#define TRUE
Definition: types.h:120
HANDLE ready_event
Definition: mmdrv.h:113
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
UINT MMRESULT
Definition: mmsystem.h:962
HANDLE WINAPI GetCurrentThread(VOID)
Definition: proc.c:1148
unsigned int BOOL
Definition: ntddk_ex.h:94
VOID PerformWaveIO(SessionInfo *session_info)
Definition: wave_io.c:39
MMRESULT result
Definition: mmdrv.h:120
void DPRINT(...)
Definition: polytest.cpp:61
#define WAIT_IO_COMPLETION
Definition: winbase.h:392
BOOL WINAPI SetThreadPriority(IN HANDLE hThread, IN int nPriority)
Definition: thread.c:699
VOID ReturnCompletedBuffers(SessionInfo *session_info)
Definition: wave.c:94
#define DRVM_TERMINATE
Definition: mmdrv.h:86
void MSVCRT() terminate()
#define MMSYSERR_ERROR
Definition: mmsystem.h:97
#define THREAD_PRIORITY_TIME_CRITICAL
Definition: winbase.h:278
DWORD ProcessSessionThreadRequest(SessionInfo *session_info)
Definition: wave.c:136
ThreadInfo thread
Definition: mmdrv.h:172
HANDLE go_event
Definition: mmdrv.h:114
#define INFINITE
Definition: serial.h:102
GLuint64EXT * result
Definition: glext.h:11304

Referenced by StartSessionThread().

◆ WriteWaveBuffer()

DWORD WriteWaveBuffer ( DWORD_PTR  private_handle,
PWAVEHDR  wave_header,
DWORD  wave_header_size 
)

Definition at line 372 of file wave.c.

376 {
377  SessionInfo* session_info = (SessionInfo*) private_handle;
378  ASSERT(session_info);
379 
380  /* Let the processing thread know that it has work to do */
381  return CallSessionThread(session_info, WODM_WRITE, wave_header);
382 }
#define WODM_WRITE
Definition: mmddk.h:114
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
MMRESULT CallSessionThread(SessionInfo *session_info, ThreadFunction function, PVOID thread_parameter)
Definition: session.c:219

Referenced by wodMessage().