ReactOS 0.4.16-dev-251-ga17b6e9
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}
#define WAVE_FORMAT_PCM
Definition: constants.h:425
struct pcmwaveformat_tag PCMWAVEFORMAT
Definition: format.c:58

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 {
177 (PBYTE) session_info->thread.parameter,
178 sizeof(DWORD));
179 break;
180 }
181
182 case WODM_GETPITCH :
183 {
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
201 (PBYTE) session_info->thread.parameter,);
202#endif
203 break;
204 }
205
207 {
210 (PBYTE) session_info->thread.parameter,
211 sizeof(DWORD));
212 break;
213 }
214
216 {
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}
BOOL GetDeviceData(LPD3D9_DEVICEDATA pDeviceData)
Definition: d3d9_caps.c:126
#define NULL
Definition: types.h:112
MMRESULT SetDeviceData(HANDLE device_handle, DWORD ioctl, PBYTE input_buffer, DWORD buffer_size)
Definition: kernel.c:139
#define WODM_SETVOLUME
Definition: mmddk.h:122
#define WODM_RESET
Definition: mmddk.h:117
#define WODM_GETVOLUME
Definition: mmddk.h:121
#define WODM_WRITE
Definition: mmddk.h:114
#define WODM_RESTART
Definition: mmddk.h:116
#define WODM_GETPITCH
Definition: mmddk.h:119
#define WODM_SETPLAYBACKRATE
Definition: mmddk.h:124
#define WODM_GETPOS
Definition: mmddk.h:118
#define WODM_SETPITCH
Definition: mmddk.h:120
#define WODM_GETPLAYBACKRATE
Definition: mmddk.h:123
#define WODM_CLOSE
Definition: mmddk.h:111
#define WODM_PAUSE
Definition: mmddk.h:115
MMRESULT QueueWaveBuffer(SessionInfo *session_info, LPWAVEHDR wave_header)
Definition: wave.c:21
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint64EXT * result
Definition: glext.h:11304
#define IOCTL_WAVE_SET_PLAYBACK_RATE
Definition: mmdef.h:60
#define IOCTL_WAVE_GET_PITCH
Definition: mmdef.h:59
#define IOCTL_WAVE_GET_VOLUME
Definition: mmdef.h:57
#define IOCTL_WAVE_SET_PITCH
Definition: mmdef.h:58
#define IOCTL_WAVE_GET_PLAYBACK_RATE
Definition: mmdef.h:61
#define DRVM_TERMINATE
Definition: mmdrv.h:86
#define WAVERR_STILLPLAYING
Definition: mmsystem.h:177
UINT MMRESULT
Definition: mmsystem.h:962
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
#define MMSYSERR_ERROR
Definition: mmsystem.h:97
BYTE * PBYTE
Definition: pedump.c:66
#define DPRINT
Definition: sndvol32.h:73
ThreadInfo thread
Definition: mmdrv.h:172
HANDLE kernel_device_handle
Definition: mmdrv.h:136
PWAVEHDR wave_queue
Definition: mmdrv.h:158
PVOID parameter
Definition: mmdrv.h:118
DWORD function
Definition: mmdrv.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 {
31 }
32
33 if ( ! wave_header->lpData )
34 {
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");
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}
#define WHDR_INQUEUE
Definition: mmsystem.h:197
#define MMSYSERR_INVALPARAM
Definition: mmsystem.h:107
#define WHDR_PREPARED
Definition: mmsystem.h:194
#define WAVERR_UNPREPARED
Definition: mmsystem.h:178
DWORD buffer_position
Definition: mmdrv.h:166
DWORD dwFlags
Definition: mmsystem.h:1018
DWORD dwBytesRecorded
Definition: mmsystem.h:1016
LPSTR lpData
Definition: mmsystem.h:1014
DWORD_PTR reserved
Definition: mmsystem.h:1021
struct wavehdr_tag * lpNext
Definition: mmsystem.h:1020
#define DWORD_PTR
Definition: treelist.c:76

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 {
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}
@ WaveOutDevice
Definition: mmdrv.h:43
BOOL NotifyClient(SessionInfo *session_info, DWORD message, DWORD_PTR parameter1, DWORD_PTR parameter2)
Definition: mme.c:25
#define WOM_DONE
Definition: mmsystem.h:183
#define WIM_DATA
Definition: mmsystem.h:186
#define WHDR_DONE
Definition: mmsystem.h:193
DeviceType device_type
Definition: mmdrv.h:133
Definition: tftpd.h:60
uint32_t DWORD_PTR
Definition: typedefs.h:65

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}
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
GLsizeiptr size
Definition: glext.h:5919
#define IOCTL_WAVE_SET_FORMAT
Definition: mmdef.h:51

◆ WaveThread()

DWORD WaveThread ( LPVOID  parameter)

Definition at line 266 of file wave.c.

267{
269 SessionInfo* session_info = (SessionInfo*) parameter;
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}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
BOOL WINAPI SetThreadPriority(IN HANDLE hThread, IN int nPriority)
Definition: thread.c:700
DWORD ProcessSessionThreadRequest(SessionInfo *session_info)
Definition: wave.c:136
VOID ReturnCompletedBuffers(SessionInfo *session_info)
Definition: wave.c:94
#define INFINITE
Definition: serial.h:102
unsigned int BOOL
Definition: ntddk_ex.h:94
void MSVCRT() terminate()
VOID PerformWaveIO(SessionInfo *session_info)
Definition: wave_io.c:39
MMRESULT result
Definition: mmdrv.h:120
HANDLE ready_event
Definition: mmdrv.h:113
HANDLE go_event
Definition: mmdrv.h:114
DWORD WINAPI WaitForSingleObjectEx(IN HANDLE hHandle, IN DWORD dwMilliseconds, IN BOOL bAlertable)
Definition: synch.c:94
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
HANDLE WINAPI GetCurrentThread(void)
Definition: proc.c:1148
#define WAIT_IO_COMPLETION
Definition: winbase.h:437
#define THREAD_PRIORITY_TIME_CRITICAL
Definition: winbase.h:307

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}
MMRESULT CallSessionThread(SessionInfo *session_info, ThreadFunction function, PVOID thread_parameter)
Definition: session.c:219
#define ASSERT(a)
Definition: mode.c:44

Referenced by wodMessage().