cf75c197b77616e0d478ef68fe0469a7cc41d3d4
[reactos.git] / reactos / include / reactos / libs / sound / mmebuddy.h
1 /*
2 * PROJECT: ReactOS Sound System "MME Buddy" Library
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: include/reactos/libs/sound/mmebuddy.h
5 *
6 * PURPOSE: Header for the "MME Buddy" helper library (located in
7 * lib/drivers/sound/mmebuddy)
8 *
9 * PROGRAMMERS: Andrew Greenwood (silverblade@reactos.org)
10 *
11 * HISTORY: 4 July 2008 - Created
12 * 31 Dec 2008 - Split off NT4-specific code into a separate library
13 *
14 * NOTES: MME Buddy was the best name I could come up with...
15 * The structures etc. here should be treated as internal to the
16 * library so should not be directly accessed elsewhere. Perhaps they
17 * can be moved to an internal header?
18 */
19
20 #ifndef ROS_AUDIO_MMEBUDDY_H
21 #define ROS_AUDIO_MMEBUDDY_H
22
23 /*
24 Hacky debug macro
25 */
26
27 #define POPUP(...) \
28 { \
29 WCHAR dbg_popup_msg[1024], dbg_popup_title[256]; \
30 wsprintf(dbg_popup_title, L"%hS(%d)", __FILE__, __LINE__); \
31 wsprintf(dbg_popup_msg, __VA_ARGS__); \
32 MessageBox(0, dbg_popup_msg, dbg_popup_title, MB_OK | MB_TASKMODAL); \
33 }
34
35 #ifndef NDEBUG
36 #define SND_ERR(...) \
37 { \
38 WCHAR dbg_popup_msg[1024]; \
39 wsprintf(dbg_popup_msg, __VA_ARGS__); \
40 OutputDebugString(dbg_popup_msg); \
41 }
42 #define SND_WARN(...) \
43 { \
44 WCHAR dbg_popup_msg[1024]; \
45 wsprintf(dbg_popup_msg, __VA_ARGS__); \
46 OutputDebugString(dbg_popup_msg); \
47 }
48 #define SND_TRACE(...) \
49 { \
50 WCHAR dbg_popup_msg[1024]; \
51 wsprintf(dbg_popup_msg, __VA_ARGS__); \
52 OutputDebugString(dbg_popup_msg); \
53 }
54
55 #define SND_ASSERT(condition) \
56 { \
57 if ( ! ( condition ) ) \
58 { \
59 SND_ERR(L"ASSERT FAILED: %hS\n", #condition); \
60 POPUP(L"ASSERT FAILED: %hS\n", #condition); \
61 ExitProcess(1); \
62 } \
63 }
64
65 #define DUMP_WAVEHDR_QUEUE(sound_device_instance) \
66 { \
67 PWAVEHDR CurrDumpHdr = sound_device_instance->HeadWaveHeader; \
68 SND_TRACE(L"-- Current wave header list --\n"); \
69 while ( CurrDumpHdr ) \
70 { \
71 SND_TRACE(L"%x | %d bytes | flags: %x\n", CurrDumpHdr->lpData, \
72 CurrDumpHdr->dwBufferLength, \
73 CurrDumpHdr->dwFlags); \
74 CurrDumpHdr = CurrDumpHdr->lpNext; \
75 } \
76 }
77
78 #else
79 #define SND_ERR(...) do {} while ( 0 )
80 #define SND_WARN(...) do {} while ( 0 )
81 #define SND_TRACE(...) do {} while ( 0 )
82 #define SND_ASSERT(condition) do {} while ( 0 )
83 #endif
84
85 /*
86 Some memory allocation helper macros
87 */
88
89 #define AllocateStruct(thing) \
90 (thing*) AllocateMemory(sizeof(thing))
91
92 #define StringLengthToBytes(chartype, string_length) \
93 ( ( string_length + 1 ) * sizeof(chartype) )
94
95 #define AllocateWideString(string_length) \
96 (PWSTR) AllocateMemory(StringLengthToBytes(WCHAR, string_length))
97
98 #define ZeroWideString(string) \
99 ZeroMemory(string, StringLengthToBytes(WCHAR, wcslen(string)))
100
101 #define CopyWideString(dest, source) \
102 CopyMemory(dest, source, StringLengthToBytes(WCHAR, wcslen(source)))
103
104
105 /*
106 Helps find the minimum/maximum of two values
107 */
108
109 #define MinimumOf(value_a, value_b) \
110 ( value_a < value_b ? value_a : value_b )
111
112 #define MaximumOf(value_a, value_b) \
113 ( value_a > value_b ? value_a : value_b )
114
115
116 /*
117 Convert a device type into a zero-based array index
118 */
119
120 #define SOUND_DEVICE_TYPE_TO_INDEX(x) \
121 ( x - MIN_SOUND_DEVICE_TYPE )
122
123 #define INDEX_TO_SOUND_DEVICE_TYPE(x) \
124 ( x + MIN_SOUND_DEVICE_TYPE )
125
126
127 /*
128 Validation
129 */
130
131 #define IsValidSoundDeviceType IS_VALID_SOUND_DEVICE_TYPE
132
133 #define VALIDATE_MMSYS_PARAMETER(parameter_condition) \
134 { \
135 if ( ! (parameter_condition) ) \
136 { \
137 SND_ERR(L"FAILED parameter check: %hS\n", #parameter_condition); \
138 return MMSYSERR_INVALPARAM; \
139 } \
140 }
141
142 #define MMSUCCESS(result) \
143 ( result == MMSYSERR_NOERROR )
144
145
146 /*
147 Types and Structures
148 */
149
150 typedef UCHAR MMDEVICE_TYPE, *PMMDEVICE_TYPE;
151 struct _SOUND_DEVICE;
152 struct _SOUND_DEVICE_INSTANCE;
153
154
155 #define DEFINE_GETCAPS_FUNCTYPE(func_typename, caps_type) \
156 typedef MMRESULT (*func_typename)( \
157 IN struct _SOUND_DEVICE* SoundDevice, \
158 OUT caps_type Capabilities, \
159 IN DWORD CapabilitiesSize);
160
161 /* This one is for those of us who don't care */
162 DEFINE_GETCAPS_FUNCTYPE(MMGETCAPS_FUNC, PVOID);
163
164 /* These are for those of us that do */
165 DEFINE_GETCAPS_FUNCTYPE(MMGETWAVEOUTCAPS_FUNC, LPWAVEOUTCAPS);
166 DEFINE_GETCAPS_FUNCTYPE(MMGETWAVEINCAPS_FUNC, LPWAVEINCAPS );
167 DEFINE_GETCAPS_FUNCTYPE(MMGETMIDIOUTCAPS_FUNC, LPMIDIOUTCAPS);
168 DEFINE_GETCAPS_FUNCTYPE(MMGETMIDIINCAPS_FUNC, LPMIDIINCAPS );
169
170 struct _SOUND_DEVICE;
171 struct _SOUND_DEVICE_INSTANCE;
172
173
174 /*
175 By extending the OVERLAPPED structure, it becomes possible to provide the
176 I/O completion routines with additional information.
177 */
178
179 typedef struct _SOUND_OVERLAPPED
180 {
181 OVERLAPPED Standard;
182 struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance;
183 PWAVEHDR Header;
184 } SOUND_OVERLAPPED, *PSOUND_OVERLAPPED;
185
186 typedef MMRESULT (*WAVE_COMMIT_FUNC)(
187 IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
188 IN PVOID OffsetPtr,
189 IN DWORD Bytes,
190 IN PSOUND_OVERLAPPED Overlap,
191 IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine);
192
193
194
195 typedef MMRESULT (*MMWAVEQUERYFORMATSUPPORT_FUNC)(
196 IN struct _SOUND_DEVICE* Device,
197 IN PWAVEFORMATEX WaveFormat,
198 IN DWORD WaveFormatSize);
199
200 typedef MMRESULT (*MMWAVESETFORMAT_FUNC)(
201 IN struct _SOUND_DEVICE_INSTANCE* Instance,
202 IN PWAVEFORMATEX WaveFormat,
203 IN DWORD WaveFormatSize);
204
205 typedef MMRESULT (*MMOPEN_FUNC)(
206 IN struct _SOUND_DEVICE* SoundDevice,
207 OUT PVOID* Handle);
208
209 typedef MMRESULT (*MMCLOSE_FUNC)(
210 IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
211 IN PVOID Handle); /* not sure about this */
212
213 typedef MMRESULT (*MMWAVEHEADER_FUNC)(
214 IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
215 IN PWAVEHDR WaveHeader);
216
217 typedef MMRESULT (*MMBUFFER_FUNC)(
218 IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
219 IN PVOID Buffer,
220 IN DWORD Length);
221
222 typedef struct _MMFUNCTION_TABLE
223 {
224 union
225 {
226 MMGETCAPS_FUNC GetCapabilities;
227 MMGETWAVEOUTCAPS_FUNC GetWaveOutCapabilities;
228 MMGETWAVEINCAPS_FUNC GetWaveInCapabilities;
229 MMGETMIDIOUTCAPS_FUNC GetMidiOutCapabilities;
230 MMGETMIDIINCAPS_FUNC GetMidiInCapabilities;
231 };
232
233 MMOPEN_FUNC Open;
234 MMCLOSE_FUNC Close;
235
236 MMWAVEQUERYFORMATSUPPORT_FUNC QueryWaveFormatSupport;
237 MMWAVESETFORMAT_FUNC SetWaveFormat;
238
239 WAVE_COMMIT_FUNC CommitWaveBuffer;
240
241 // Redundant
242 //MMWAVEHEADER_FUNC PrepareWaveHeader;
243 //MMWAVEHEADER_FUNC UnprepareWaveHeader;
244 //MMWAVEHEADER_FUNC WriteWaveHeader;
245
246 //MMWAVEHEADER_FUNC SubmitWaveHeaderToDevice;
247 //MMBUFFER_FUNC CompleteBuffer;
248 } MMFUNCTION_TABLE, *PMMFUNCTION_TABLE;
249
250
251
252 typedef MMRESULT (*SOUND_THREAD_REQUEST_HANDLER)(
253 IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
254 IN PVOID Parameter);
255
256 typedef struct _SOUND_THREAD
257 {
258 HANDLE Handle;
259 BOOL Running;
260
261 struct
262 {
263 HANDLE Ready;
264 HANDLE Request;
265 HANDLE Done;
266 } Events;
267
268 struct
269 {
270 SOUND_THREAD_REQUEST_HANDLER Handler;
271 struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance;
272 PVOID Parameter;
273 MMRESULT Result;
274 } Request;
275 } SOUND_THREAD, *PSOUND_THREAD;
276
277 typedef struct _SOUND_DEVICE
278 {
279 struct _SOUND_DEVICE* Next;
280 struct _SOUND_DEVICE_INSTANCE* HeadInstance;
281 struct _SOUND_DEVICE_INSTANCE* TailInstance;
282 MMDEVICE_TYPE Type;
283 PVOID Identifier; /* Path for NT4 drivers */
284 /*PWSTR Path;*/
285 MMFUNCTION_TABLE FunctionTable;
286 } SOUND_DEVICE, *PSOUND_DEVICE;
287
288 typedef struct _SOUND_DEVICE_INSTANCE
289 {
290 struct _SOUND_DEVICE_INSTANCE* Next;
291 struct _SOUND_DEVICE* Device;
292 PVOID Handle;
293 struct _SOUND_THREAD* Thread;
294
295 /* Stuff generously donated to us from WinMM */
296 struct
297 {
298 HDRVR Handle;
299 DWORD Flags;
300 DWORD ClientCallback;
301 DWORD ClientCallbackInstanceData;
302 } WinMM;
303
304 /* DO NOT TOUCH THESE OUTSIDE OF THE SOUND THREAD */
305
306 union
307 {
308 PWAVEHDR HeadWaveHeader;
309 };
310
311 union
312 {
313 PWAVEHDR TailWaveHeader;
314 };
315
316 PWAVEHDR WaveLoopStart;
317 PWAVEHDR CurrentWaveHeader;
318 DWORD OutstandingBuffers;
319 } SOUND_DEVICE_INSTANCE, *PSOUND_DEVICE_INSTANCE;
320
321 /* This lives in WAVEHDR.reserved */
322 typedef struct _WAVEHDR_EXTENSION
323 {
324 DWORD BytesCommitted;
325 DWORD BytesCompleted;
326 } WAVEHDR_EXTENSION, *PWAVEHDR_EXTENSION;
327
328
329 /*
330 reentrancy.c
331 */
332
333 MMRESULT
334 InitEntrypointMutexes();
335
336 VOID
337 CleanupEntrypointMutexes();
338
339 VOID
340 AcquireEntrypointMutex(
341 IN MMDEVICE_TYPE DeviceType);
342
343 VOID
344 ReleaseEntrypointMutex(
345 IN MMDEVICE_TYPE DeviceType);
346
347
348 /*
349 mme.c
350 */
351
352 VOID
353 NotifyMmeClient(
354 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
355 IN DWORD Message,
356 IN DWORD Parameter);
357
358 MMRESULT
359 MmeGetSoundDeviceCapabilities(
360 IN MMDEVICE_TYPE DeviceType,
361 IN DWORD DeviceId,
362 IN PVOID Capabilities,
363 IN DWORD CapabilitiesSize);
364
365 MMRESULT
366 MmeOpenWaveDevice(
367 IN MMDEVICE_TYPE DeviceType,
368 IN DWORD DeviceId,
369 IN LPWAVEOPENDESC OpenParameters,
370 IN DWORD Flags,
371 OUT DWORD* PrivateHandle);
372
373 MMRESULT
374 MmeCloseDevice(
375 IN DWORD PrivateHandle);
376
377 #define MmePrepareWaveHeader(private_handle, header) \
378 PrepareWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
379
380 #define MmeUnprepareWaveHeader(private_handle, header) \
381 UnprepareWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
382
383 #define MmeWriteWaveHeader(private_handle, header) \
384 WriteWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
385
386
387 /*
388 capabilities.c
389 */
390
391 MMRESULT
392 GetSoundDeviceCapabilities(
393 IN PSOUND_DEVICE SoundDevice,
394 OUT PVOID Capabilities,
395 IN DWORD CapabilitiesSize);
396
397
398 /*
399 devicelist.c
400 */
401
402 ULONG
403 GetSoundDeviceCount(
404 IN MMDEVICE_TYPE DeviceType);
405
406 BOOLEAN
407 IsValidSoundDevice(
408 IN PSOUND_DEVICE SoundDevice);
409
410 MMRESULT
411 ListSoundDevice(
412 IN MMDEVICE_TYPE DeviceType,
413 IN PVOID Identifier OPTIONAL,
414 OUT PSOUND_DEVICE* SoundDevice OPTIONAL);
415
416 MMRESULT
417 UnlistSoundDevice(
418 IN MMDEVICE_TYPE DeviceType,
419 IN PSOUND_DEVICE SoundDevice);
420
421 MMRESULT
422 UnlistSoundDevices(
423 IN MMDEVICE_TYPE DeviceType);
424
425 VOID
426 UnlistAllSoundDevices();
427
428 MMRESULT
429 GetSoundDevice(
430 IN MMDEVICE_TYPE DeviceType,
431 IN DWORD DeviceIndex,
432 OUT PSOUND_DEVICE* Device);
433
434 MMRESULT
435 GetSoundDeviceIdentifier(
436 IN PSOUND_DEVICE SoundDevice,
437 OUT PVOID* Identifier);
438
439 MMRESULT
440 GetSoundDeviceType(
441 IN PSOUND_DEVICE SoundDevice,
442 OUT PMMDEVICE_TYPE DeviceType);
443
444
445 /*
446 functiontable.c
447 */
448
449 MMRESULT
450 SetSoundDeviceFunctionTable(
451 IN PSOUND_DEVICE SoundDevice,
452 IN PMMFUNCTION_TABLE FunctionTable);
453
454 MMRESULT
455 GetSoundDeviceFunctionTable(
456 IN PSOUND_DEVICE SoundDevice,
457 OUT PMMFUNCTION_TABLE* FunctionTable);
458
459
460 /*
461 deviceinstance.c
462 */
463
464 BOOLEAN
465 IsValidSoundDeviceInstance(
466 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance);
467
468 MMRESULT
469 CreateSoundDeviceInstance(
470 IN PSOUND_DEVICE SoundDevice,
471 OUT PSOUND_DEVICE_INSTANCE* SoundDeviceInstance);
472
473 MMRESULT
474 DestroySoundDeviceInstance(
475 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance);
476
477 MMRESULT
478 DestroyAllSoundDeviceInstances(
479 IN PSOUND_DEVICE SoundDevice);
480
481 MMRESULT
482 GetSoundDeviceFromInstance(
483 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
484 OUT PSOUND_DEVICE* SoundDevice);
485
486 MMRESULT
487 GetSoundDeviceInstanceHandle(
488 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
489 OUT PVOID* Handle);
490
491 MMRESULT
492 SetSoundDeviceInstanceMmeData(
493 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
494 IN HDRVR MmeHandle,
495 IN DWORD ClientCallback,
496 IN DWORD ClientCallbackData,
497 IN DWORD Flags);
498
499
500 /*
501 thread.c
502 */
503
504 MMRESULT
505 CreateSoundThread(
506 OUT PSOUND_THREAD* Thread);
507
508 MMRESULT
509 DestroySoundThread(
510 IN PSOUND_THREAD Thread);
511
512 MMRESULT
513 CallSoundThread(
514 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
515 IN SOUND_THREAD_REQUEST_HANDLER RequestHandler,
516 IN PVOID Parameter OPTIONAL);
517
518
519 /*
520 utility.c
521 */
522
523 PVOID
524 AllocateMemory(
525 IN UINT Size);
526
527 VOID
528 FreeMemory(
529 IN PVOID Pointer);
530
531 UINT
532 GetMemoryAllocationCount();
533
534 UINT
535 GetDigitCount(
536 IN UINT Number);
537
538 MMRESULT
539 Win32ErrorToMmResult(
540 IN UINT ErrorCode);
541
542 MMRESULT
543 TranslateInternalMmResult(
544 IN MMRESULT Result);
545
546
547 /*
548 wave/format.c
549 */
550
551 MMRESULT
552 QueryWaveDeviceFormatSupport(
553 IN PSOUND_DEVICE SoundDevice,
554 IN LPWAVEFORMATEX Format,
555 IN DWORD FormatSize);
556
557 MMRESULT
558 SetWaveDeviceFormat(
559 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
560 IN LPWAVEFORMATEX Format,
561 IN DWORD FormatSize);
562
563
564 /*
565 wave/header.c
566 */
567
568 MMRESULT
569 EnqueueWaveHeader(
570 PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
571 IN PVOID Parameter);
572
573 VOID
574 CompleteWaveHeader(
575 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
576 IN PWAVEHDR Header);
577
578 MMRESULT
579 PrepareWaveHeader(
580 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
581 IN PWAVEHDR Header);
582
583 MMRESULT
584 UnprepareWaveHeader(
585 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
586 IN PWAVEHDR Header);
587
588 MMRESULT
589 WriteWaveHeader(
590 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
591 IN PWAVEHDR Header);
592
593
594 /*
595 wave/streaming.c
596 */
597
598 VOID
599 DoWaveStreaming(
600 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance);
601
602 VOID CALLBACK
603 CompleteIO(
604 IN DWORD dwErrorCode,
605 IN DWORD dwNumberOfBytesTransferred,
606 IN LPOVERLAPPED lpOverlapped);
607
608 MMRESULT
609 CommitWaveHeaderToKernelDevice(
610 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
611 IN PWAVEHDR Header,
612 IN WAVE_COMMIT_FUNC CommitFunction);
613
614 MMRESULT
615 WriteFileEx_Committer(
616 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
617 IN PVOID OffsetPtr,
618 IN DWORD Length,
619 IN PSOUND_OVERLAPPED Overlap,
620 IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine);
621
622
623 /*
624 kernel.c
625 */
626
627 #if 0
628 #define QueryDevice(h, ctl, o, o_size, xfer, ovl) \
629 Win32ErrorToMmResult( \
630 DeviceIoControl(h, ctl, NULL, 0, o, o_size, xfer, ovl) != 0 \
631 ? ERROR_SUCCESS : GetLastError() \
632 )
633
634 #define ControlDevice(h, ctl, i, i_size, xfer, ovl) \
635 Win32ErrorToMmResult( \
636 DeviceIoControl(h, ctl, i, i_size, NULL, 0, xfer, ovl) != 0 \
637 ? ERROR_SUCCESS : GetLastError() \
638 )
639
640 #define QuerySoundDevice(sd, ctl, o, o_size, xfer) \
641 SoundDeviceIoControl(sd, ctl, NULL, 0, o, o_size, xfer)
642
643 #define ControlSoundDevice(sd, ctl, i, i_size, xfer) \
644 SoundDeviceIoControl(sd, ctl, i, i_size, NULL, 0, xfer)
645 #endif
646
647 MMRESULT
648 OpenKernelSoundDeviceByName(
649 IN PWSTR DevicePath,
650 IN BOOLEAN ReadOnly,
651 OUT PHANDLE Handle);
652
653 MMRESULT
654 OpenKernelSoundDevice(
655 IN PSOUND_DEVICE SoundDevice,
656 IN BOOLEAN ReadOnly,
657 OUT PHANDLE Handle);
658
659 MMRESULT
660 CloseKernelSoundDevice(
661 IN HANDLE Handle);
662
663 MMRESULT
664 SyncOverlappedDeviceIoControl(
665 IN HANDLE SoundDeviceInstance,
666 IN DWORD IoControlCode,
667 IN LPVOID InBuffer,
668 IN DWORD InBufferSize,
669 OUT LPVOID OutBuffer,
670 IN DWORD OutBufferSize,
671 OUT LPDWORD BytesTransferred OPTIONAL);
672
673
674 #if 0
675
676 typedef UCHAR MMDEVICE_TYPE, *PMMDEVICE_TYPE;
677
678 struct _SOUND_DEVICE;
679 struct _SOUND_DEVICE_INSTANCE;
680
681
682 /*
683 Rather than pass caps structures around as a PVOID, this can be
684 used instead.
685 */
686
687 typedef union _UNIVERSAL_CAPS
688 {
689 WAVEOUTCAPS WaveOut;
690 WAVEINCAPS WaveIn;
691 MIDIOUTCAPS MidiOut;
692 MIDIINCAPS MidiIn;
693 } UNIVERSAL_CAPS, *PUNIVERSAL_CAPS;
694
695
696
697 /* New sound thread code */
698
699 typedef MMRESULT (*SOUND_THREAD_REQUEST_HANDLER)(
700 IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
701 IN OPTIONAL PVOID Parameter);
702
703 typedef struct _SOUND_THREAD_REQUEST
704 {
705 /* The sound device instance this request relates to */
706 struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance;
707 /* What function to call */
708 SOUND_THREAD_REQUEST_HANDLER RequestHandler;
709 /* Caller-defined parameter */
710 PVOID Parameter;
711 /* This will contain the return code of the request function */
712 MMRESULT ReturnValue;
713 } SOUND_THREAD_REQUEST, *PSOUND_THREAD_REQUEST;
714
715 typedef VOID (*SOUND_THREAD_IO_COMPLETION_HANDLER)(
716 IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance,
717 IN PVOID Parameter OPTIONAL,
718 IN DWORD BytesWritten);
719
720 typedef struct _SOUND_THREAD_COMPLETED_IO
721 {
722 struct _SOUND_THREAD_COMPLETED_IO* Previous;
723 struct _SOUND_THREAD_COMPLETED_IO* Next;
724
725 struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance;
726 SOUND_THREAD_IO_COMPLETION_HANDLER CompletionHandler;
727 PVOID Parameter;
728 DWORD BytesTransferred;
729 } SOUND_THREAD_COMPLETED_IO, *PSOUND_THREAD_COMPLETED_IO;
730
731 typedef struct _SOUND_THREAD_OVERLAPPED
732 {
733 OVERLAPPED General;
734
735 /* Pointer to structure to fill with completion data */
736 PSOUND_THREAD_COMPLETED_IO CompletionData;
737 } SOUND_THREAD_OVERLAPPED, *PSOUND_THREAD_OVERLAPPED;
738
739 /*
740 Audio device function table
741 */
742
743 typedef MMRESULT (*MMCREATEINSTANCE_FUNC)(
744 IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance);
745
746 typedef VOID (*MMDESTROYINSTANCE_FUNC)(
747 IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance);
748
749 typedef MMRESULT (*MMGETCAPS_FUNC)(
750 IN struct _SOUND_DEVICE* Device,
751 OUT PUNIVERSAL_CAPS Capabilities);
752
753 typedef MMRESULT (*MMWAVEQUERYFORMAT_FUNC)(
754 IN struct _SOUND_DEVICE* Device,
755 IN PWAVEFORMATEX WaveFormat,
756 IN DWORD WaveFormatSize);
757
758 typedef MMRESULT (*MMWAVESETFORMAT_FUNC)(
759 IN struct _SOUND_DEVICE_INSTANCE* Instance,
760 IN PWAVEFORMATEX WaveFormat,
761 IN DWORD WaveFormatSize);
762
763 typedef MMRESULT (*MMWAVEQUEUEBUFFER_FUNC)(
764 IN struct _SOUND_DEVICE_INSTANCE* Instance,
765 IN PWAVEHDR WaveHeader);
766
767 typedef MMRESULT (*MMGETWAVESTATE_FUNC)(
768 IN struct _SOUND_DEVICE_INSTANCE* Instance,
769 OUT PULONG State);
770
771 typedef MMRESULT (*MMSETWAVESTATE_FUNC)(
772 IN struct _SOUND_DEVICE_INSTANCE* Instance);
773
774 typedef struct _MMFUNCTION_TABLE
775 {
776 MMCREATEINSTANCE_FUNC Constructor;
777 MMDESTROYINSTANCE_FUNC Destructor;
778 MMGETCAPS_FUNC GetCapabilities;
779
780 MMWAVEQUERYFORMAT_FUNC QueryWaveFormat;
781 MMWAVESETFORMAT_FUNC SetWaveFormat;
782 MMWAVEQUEUEBUFFER_FUNC QueueWaveBuffer;
783
784 MMGETWAVESTATE_FUNC GetWaveDeviceState;
785 MMSETWAVESTATE_FUNC PauseWaveDevice;
786 MMSETWAVESTATE_FUNC RestartWaveDevice;
787 MMSETWAVESTATE_FUNC ResetWaveDevice;
788 MMSETWAVESTATE_FUNC BreakWaveDeviceLoop;
789 } MMFUNCTION_TABLE, *PMMFUNCTION_TABLE;
790
791
792 /*
793 Represents an audio device
794 */
795
796 #define SOUND_DEVICE_TAG "SndD"
797
798 typedef struct _SOUND_DEVICE
799 {
800 struct _SOUND_DEVICE* Next;
801 struct _SOUND_DEVICE_INSTANCE* FirstInstance;
802 UCHAR DeviceType;
803 LPWSTR DevicePath;
804 MMFUNCTION_TABLE Functions;
805 } SOUND_DEVICE, *PSOUND_DEVICE;
806
807
808 /*
809 Represents an individual instance of an audio device
810 */
811
812 #define WAVE_STREAM_INFO_TAG "WavS"
813
814 typedef struct _WAVE_STREAM_INFO
815 {
816 /* Buffer queue head and tail */
817 PWAVEHDR BufferQueueHead;
818 PWAVEHDR BufferQueueTail;
819 /* The buffer currently being processed */
820 PWAVEHDR CurrentBuffer;
821 /* How far into the current buffer we've gone */
822 DWORD BufferOffset;
823 /* How many I/O operations have been submitted */
824 DWORD BuffersOutstanding;
825 /* Looping */
826 PWAVEHDR LoopHead;
827 DWORD LoopsRemaining;
828 } WAVE_STREAM_INFO, *PWAVE_STREAM_INFO;
829
830
831 #define SOUND_DEVICE_INSTANCE_TAG "SndI"
832
833 typedef struct _SOUND_DEVICE_INSTANCE
834 {
835 struct _SOUND_DEVICE_INSTANCE* Next;
836 PSOUND_DEVICE Device;
837
838 /* The currently opened handle to the device */
839 HANDLE Handle;
840 /* PSOUND_THREAD Thread;*/
841
842
843 /* Device-specific parameters */
844 union
845 {
846 WAVE_STREAM_INFO Wave;
847 } Streaming;
848 } SOUND_DEVICE_INSTANCE, *PSOUND_DEVICE_INSTANCE;
849
850 #endif
851
852 #endif