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
6 * PURPOSE: Header for the "MME Buddy" helper library (located in
7 * lib/drivers/sound/mmebuddy)
9 * PROGRAMMERS: Andrew Greenwood (silverblade@reactos.org)
11 * HISTORY: 4 July 2008 - Created
12 * 31 Dec 2008 - Split off NT4-specific code into a separate library
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?
20 #ifndef ROS_AUDIO_MMEBUDDY_H
21 #define ROS_AUDIO_MMEBUDDY_H
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); \
36 #define SND_ERR(...) \
38 WCHAR dbg_popup_msg[1024]; \
39 wsprintf(dbg_popup_msg, __VA_ARGS__); \
40 OutputDebugString(dbg_popup_msg); \
42 #define SND_WARN(...) \
44 WCHAR dbg_popup_msg[1024]; \
45 wsprintf(dbg_popup_msg, __VA_ARGS__); \
46 OutputDebugString(dbg_popup_msg); \
48 #define SND_TRACE(...) \
50 WCHAR dbg_popup_msg[1024]; \
51 wsprintf(dbg_popup_msg, __VA_ARGS__); \
52 OutputDebugString(dbg_popup_msg); \
55 #define SND_ASSERT(condition) \
57 if ( ! ( condition ) ) \
59 SND_ERR(L"ASSERT FAILED: %hS\n", #condition); \
60 POPUP(L"ASSERT FAILED: %hS\n", #condition); \
66 #define SND_ERR(...) while ( 0 ) do {}
67 #define SND_WARN(...) while ( 0 ) do {}
68 #define SND_TRACE(...) while ( 0 ) do {}
69 #define SND_ASSERT(condition) while ( 0 ) do {}
73 Some memory allocation helper macros
76 #define AllocateStruct(thing) \
77 (thing*) AllocateMemory(sizeof(thing))
79 #define StringLengthToBytes(chartype, string_length) \
80 ( ( string_length + 1 ) * sizeof(chartype) )
82 #define AllocateWideString(string_length) \
83 (PWSTR) AllocateMemory(StringLengthToBytes(WCHAR, string_length))
85 #define ZeroWideString(string) \
86 ZeroMemory(string, StringLengthToBytes(WCHAR, wcslen(string)))
88 #define CopyWideString(dest, source) \
89 CopyMemory(dest, source, StringLengthToBytes(WCHAR, wcslen(source)))
93 Helps find the minimum/maximum of two values
96 #define MinimumOf(value_a, value_b) \
97 ( value_a < value_b ? value_a : value_b )
99 #define MaximumOf(value_a, value_b) \
100 ( value_a > value_b ? value_a : value_b )
104 Convert a device type into a zero-based array index
107 #define SOUND_DEVICE_TYPE_TO_INDEX(x) \
108 ( x - MIN_SOUND_DEVICE_TYPE )
110 #define INDEX_TO_SOUND_DEVICE_TYPE(x) \
111 ( x + MIN_SOUND_DEVICE_TYPE )
118 #define IsValidSoundDeviceType IS_VALID_SOUND_DEVICE_TYPE
120 #define VALIDATE_MMSYS_PARAMETER(parameter_condition) \
122 if ( ! (parameter_condition) ) \
124 SND_ERR(L"FAILED parameter check: %hS\n", #parameter_condition); \
125 return MMSYSERR_INVALPARAM; \
129 #define MMSUCCESS(result) \
130 ( result == MMSYSERR_NOERROR )
137 typedef UCHAR MMDEVICE_TYPE
, *PMMDEVICE_TYPE
;
138 struct _SOUND_DEVICE
;
139 struct _SOUND_DEVICE_INSTANCE
;
142 #define DEFINE_GETCAPS_FUNCTYPE(func_typename, caps_type) \
143 typedef MMRESULT (*func_typename)( \
144 IN struct _SOUND_DEVICE* SoundDevice, \
145 OUT caps_type Capabilities, \
146 IN DWORD CapabilitiesSize);
148 /* This one is for those of us who don't care */
149 DEFINE_GETCAPS_FUNCTYPE(MMGETCAPS_FUNC
, PVOID
);
151 /* These are for those of us that do */
152 DEFINE_GETCAPS_FUNCTYPE(MMGETWAVEOUTCAPS_FUNC
, LPWAVEOUTCAPS
);
153 DEFINE_GETCAPS_FUNCTYPE(MMGETWAVEINCAPS_FUNC
, LPWAVEINCAPS
);
154 DEFINE_GETCAPS_FUNCTYPE(MMGETMIDIOUTCAPS_FUNC
, LPMIDIOUTCAPS
);
155 DEFINE_GETCAPS_FUNCTYPE(MMGETMIDIINCAPS_FUNC
, LPMIDIINCAPS
);
157 struct _SOUND_DEVICE
;
158 struct _SOUND_DEVICE_INSTANCE
;
160 typedef MMRESULT (*MMWAVEQUERYFORMATSUPPORT_FUNC
)(
161 IN
struct _SOUND_DEVICE
* Device
,
162 IN PWAVEFORMATEX WaveFormat
,
163 IN DWORD WaveFormatSize
);
165 typedef MMRESULT (*MMWAVESETFORMAT_FUNC
)(
166 IN
struct _SOUND_DEVICE_INSTANCE
* Instance
,
167 IN PWAVEFORMATEX WaveFormat
,
168 IN DWORD WaveFormatSize
);
170 typedef MMRESULT (*MMOPEN_FUNC
)(
171 IN
struct _SOUND_DEVICE
* SoundDevice
,
174 typedef MMRESULT (*MMCLOSE_FUNC
)(
175 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
176 IN PVOID Handle
); /* not sure about this */
178 typedef MMRESULT (*MMWAVEHEADER_FUNC
)(
179 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
180 IN PWAVEHDR WaveHeader
);
182 typedef struct _MMFUNCTION_TABLE
186 MMGETCAPS_FUNC GetCapabilities
;
187 MMGETWAVEOUTCAPS_FUNC GetWaveOutCapabilities
;
188 MMGETWAVEINCAPS_FUNC GetWaveInCapabilities
;
189 MMGETMIDIOUTCAPS_FUNC GetMidiOutCapabilities
;
190 MMGETMIDIINCAPS_FUNC GetMidiInCapabilities
;
196 MMWAVEQUERYFORMATSUPPORT_FUNC QueryWaveFormatSupport
;
197 MMWAVESETFORMAT_FUNC SetWaveFormat
;
199 MMWAVEHEADER_FUNC PrepareWaveHeader
;
200 MMWAVEHEADER_FUNC UnprepareWaveHeader
;
201 MMWAVEHEADER_FUNC SubmitWaveHeader
;
202 } MMFUNCTION_TABLE
, *PMMFUNCTION_TABLE
;
204 typedef MMRESULT (*SOUND_THREAD_REQUEST_HANDLER
)(
205 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
208 typedef struct _SOUND_THREAD
222 SOUND_THREAD_REQUEST_HANDLER Handler
;
223 struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
;
227 } SOUND_THREAD
, *PSOUND_THREAD
;
229 typedef struct _SOUND_DEVICE
231 struct _SOUND_DEVICE
* Next
;
232 struct _SOUND_DEVICE_INSTANCE
* HeadInstance
;
233 struct _SOUND_DEVICE_INSTANCE
* TailInstance
;
235 PVOID Identifier
; /* Path for NT4 drivers */
237 MMFUNCTION_TABLE FunctionTable
;
238 } SOUND_DEVICE
, *PSOUND_DEVICE
;
240 typedef struct _SOUND_DEVICE_INSTANCE
242 struct _SOUND_DEVICE_INSTANCE
* Next
;
243 struct _SOUND_DEVICE
* Device
;
245 struct _SOUND_THREAD
* Thread
;
247 /* Stuff generously donated to us from WinMM */
252 DWORD ClientCallback
;
253 DWORD ClientCallbackInstanceData
;
255 } SOUND_DEVICE_INSTANCE
, *PSOUND_DEVICE_INSTANCE
;
262 InitEntrypointMutexes();
265 CleanupEntrypointMutexes();
268 AcquireEntrypointMutex(
269 IN MMDEVICE_TYPE DeviceType
);
272 ReleaseEntrypointMutex(
273 IN MMDEVICE_TYPE DeviceType
);
282 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
287 MmeGetSoundDeviceCapabilities(
288 IN MMDEVICE_TYPE DeviceType
,
290 IN PVOID Capabilities
,
291 IN DWORD CapabilitiesSize
);
295 IN MMDEVICE_TYPE DeviceType
,
297 IN LPWAVEOPENDESC OpenParameters
,
299 OUT DWORD
* PrivateHandle
);
303 IN DWORD PrivateHandle
);
305 #define MmePrepareWaveHeader(private_handle, header) \
306 PrepareWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
308 #define MmeUnprepareWaveHeader(private_handle, header) \
309 UnprepareWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
311 #define MmeEnqueueWaveHeader(private_handle, header) \
312 EnqueueWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
320 GetSoundDeviceCapabilities(
321 IN PSOUND_DEVICE SoundDevice
,
322 OUT PVOID Capabilities
,
323 IN DWORD CapabilitiesSize
);
332 IN MMDEVICE_TYPE DeviceType
);
336 IN PSOUND_DEVICE SoundDevice
);
340 IN MMDEVICE_TYPE DeviceType
,
341 IN PVOID Identifier OPTIONAL
,
342 OUT PSOUND_DEVICE
* SoundDevice OPTIONAL
);
346 IN MMDEVICE_TYPE DeviceType
,
347 IN PSOUND_DEVICE SoundDevice
);
351 IN MMDEVICE_TYPE DeviceType
);
354 UnlistAllSoundDevices();
358 IN MMDEVICE_TYPE DeviceType
,
359 IN DWORD DeviceIndex
,
360 OUT PSOUND_DEVICE
* Device
);
363 GetSoundDeviceIdentifier(
364 IN PSOUND_DEVICE SoundDevice
,
365 OUT PVOID
* Identifier
);
369 IN PSOUND_DEVICE SoundDevice
,
370 OUT PMMDEVICE_TYPE DeviceType
);
378 SetSoundDeviceFunctionTable(
379 IN PSOUND_DEVICE SoundDevice
,
380 IN PMMFUNCTION_TABLE FunctionTable
);
383 GetSoundDeviceFunctionTable(
384 IN PSOUND_DEVICE SoundDevice
,
385 OUT PMMFUNCTION_TABLE
* FunctionTable
);
393 IsValidSoundDeviceInstance(
394 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
);
397 CreateSoundDeviceInstance(
398 IN PSOUND_DEVICE SoundDevice
,
399 OUT PSOUND_DEVICE_INSTANCE
* SoundDeviceInstance
);
402 DestroySoundDeviceInstance(
403 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
);
406 DestroyAllSoundDeviceInstances(
407 IN PSOUND_DEVICE SoundDevice
);
410 GetSoundDeviceFromInstance(
411 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
412 OUT PSOUND_DEVICE
* SoundDevice
);
415 GetSoundDeviceInstanceHandle(
416 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
420 SetSoundDeviceInstanceMmeData(
421 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
423 IN DWORD ClientCallback
,
424 IN DWORD ClientCallbackData
,
434 OUT PSOUND_THREAD
* Thread
);
438 IN PSOUND_THREAD Thread
);
442 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
443 IN SOUND_THREAD_REQUEST_HANDLER RequestHandler
,
444 IN PVOID Parameter OPTIONAL
);
460 GetMemoryAllocationCount();
467 Win32ErrorToMmResult(
471 TranslateInternalMmResult(
480 QueryWaveDeviceFormatSupport(
481 IN PSOUND_DEVICE SoundDevice
,
482 IN LPWAVEFORMATEX Format
,
483 IN DWORD FormatSize
);
487 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
488 IN LPWAVEFORMATEX Format
,
489 IN DWORD FormatSize
);
498 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
503 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
508 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
517 #define QueryDevice(h, ctl, o, o_size, xfer, ovl) \
518 Win32ErrorToMmResult( \
519 DeviceIoControl(h, ctl, NULL, 0, o, o_size, xfer, ovl) != 0 \
520 ? ERROR_SUCCESS : GetLastError() \
523 #define ControlDevice(h, ctl, i, i_size, xfer, ovl) \
524 Win32ErrorToMmResult( \
525 DeviceIoControl(h, ctl, i, i_size, NULL, 0, xfer, ovl) != 0 \
526 ? ERROR_SUCCESS : GetLastError() \
529 #define QuerySoundDevice(sd, ctl, o, o_size, xfer) \
530 SoundDeviceIoControl(sd, ctl, NULL, 0, o, o_size, xfer)
532 #define ControlSoundDevice(sd, ctl, i, i_size, xfer) \
533 SoundDeviceIoControl(sd, ctl, i, i_size, NULL, 0, xfer)
537 OpenKernelSoundDeviceByName(
543 OpenKernelSoundDevice(
544 IN PSOUND_DEVICE SoundDevice
,
549 CloseKernelSoundDevice(
553 SyncOverlappedDeviceIoControl(
554 IN HANDLE SoundDeviceInstance
,
555 IN DWORD IoControlCode
,
557 IN DWORD InBufferSize
,
558 OUT LPVOID OutBuffer
,
559 IN DWORD OutBufferSize
,
560 OUT LPDWORD BytesTransferred OPTIONAL
);
565 typedef UCHAR MMDEVICE_TYPE
, *PMMDEVICE_TYPE
;
567 struct _SOUND_DEVICE
;
568 struct _SOUND_DEVICE_INSTANCE
;
572 Rather than pass caps structures around as a PVOID, this can be
576 typedef union _UNIVERSAL_CAPS
582 } UNIVERSAL_CAPS
, *PUNIVERSAL_CAPS
;
586 /* New sound thread code */
588 typedef MMRESULT (*SOUND_THREAD_REQUEST_HANDLER
)(
589 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
590 IN OPTIONAL PVOID Parameter
);
592 typedef struct _SOUND_THREAD_REQUEST
594 /* The sound device instance this request relates to */
595 struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
;
596 /* What function to call */
597 SOUND_THREAD_REQUEST_HANDLER RequestHandler
;
598 /* Caller-defined parameter */
600 /* This will contain the return code of the request function */
601 MMRESULT ReturnValue
;
602 } SOUND_THREAD_REQUEST
, *PSOUND_THREAD_REQUEST
;
604 typedef VOID (*SOUND_THREAD_IO_COMPLETION_HANDLER
)(
605 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
606 IN PVOID Parameter OPTIONAL
,
607 IN DWORD BytesWritten
);
609 typedef struct _SOUND_THREAD_COMPLETED_IO
611 struct _SOUND_THREAD_COMPLETED_IO
* Previous
;
612 struct _SOUND_THREAD_COMPLETED_IO
* Next
;
614 struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
;
615 SOUND_THREAD_IO_COMPLETION_HANDLER CompletionHandler
;
617 DWORD BytesTransferred
;
618 } SOUND_THREAD_COMPLETED_IO
, *PSOUND_THREAD_COMPLETED_IO
;
620 typedef struct _SOUND_THREAD_OVERLAPPED
624 /* Pointer to structure to fill with completion data */
625 PSOUND_THREAD_COMPLETED_IO CompletionData
;
626 } SOUND_THREAD_OVERLAPPED
, *PSOUND_THREAD_OVERLAPPED
;
629 Audio device function table
632 typedef MMRESULT (*MMCREATEINSTANCE_FUNC
)(
633 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
);
635 typedef VOID (*MMDESTROYINSTANCE_FUNC
)(
636 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
);
638 typedef MMRESULT (*MMGETCAPS_FUNC
)(
639 IN
struct _SOUND_DEVICE
* Device
,
640 OUT PUNIVERSAL_CAPS Capabilities
);
642 typedef MMRESULT (*MMWAVEQUERYFORMAT_FUNC
)(
643 IN
struct _SOUND_DEVICE
* Device
,
644 IN PWAVEFORMATEX WaveFormat
,
645 IN DWORD WaveFormatSize
);
647 typedef MMRESULT (*MMWAVESETFORMAT_FUNC
)(
648 IN
struct _SOUND_DEVICE_INSTANCE
* Instance
,
649 IN PWAVEFORMATEX WaveFormat
,
650 IN DWORD WaveFormatSize
);
652 typedef MMRESULT (*MMWAVEQUEUEBUFFER_FUNC
)(
653 IN
struct _SOUND_DEVICE_INSTANCE
* Instance
,
654 IN PWAVEHDR WaveHeader
);
656 typedef MMRESULT (*MMGETWAVESTATE_FUNC
)(
657 IN
struct _SOUND_DEVICE_INSTANCE
* Instance
,
660 typedef MMRESULT (*MMSETWAVESTATE_FUNC
)(
661 IN
struct _SOUND_DEVICE_INSTANCE
* Instance
);
663 typedef struct _MMFUNCTION_TABLE
665 MMCREATEINSTANCE_FUNC Constructor
;
666 MMDESTROYINSTANCE_FUNC Destructor
;
667 MMGETCAPS_FUNC GetCapabilities
;
669 MMWAVEQUERYFORMAT_FUNC QueryWaveFormat
;
670 MMWAVESETFORMAT_FUNC SetWaveFormat
;
671 MMWAVEQUEUEBUFFER_FUNC QueueWaveBuffer
;
673 MMGETWAVESTATE_FUNC GetWaveDeviceState
;
674 MMSETWAVESTATE_FUNC PauseWaveDevice
;
675 MMSETWAVESTATE_FUNC RestartWaveDevice
;
676 MMSETWAVESTATE_FUNC ResetWaveDevice
;
677 MMSETWAVESTATE_FUNC BreakWaveDeviceLoop
;
678 } MMFUNCTION_TABLE
, *PMMFUNCTION_TABLE
;
682 Represents an audio device
685 #define SOUND_DEVICE_TAG "SndD"
687 typedef struct _SOUND_DEVICE
689 struct _SOUND_DEVICE
* Next
;
690 struct _SOUND_DEVICE_INSTANCE
* FirstInstance
;
693 MMFUNCTION_TABLE Functions
;
694 } SOUND_DEVICE
, *PSOUND_DEVICE
;
698 Represents an individual instance of an audio device
701 #define WAVE_STREAM_INFO_TAG "WavS"
703 typedef struct _WAVE_STREAM_INFO
705 /* Buffer queue head and tail */
706 PWAVEHDR BufferQueueHead
;
707 PWAVEHDR BufferQueueTail
;
708 /* The buffer currently being processed */
709 PWAVEHDR CurrentBuffer
;
710 /* How far into the current buffer we've gone */
712 /* How many I/O operations have been submitted */
713 DWORD BuffersOutstanding
;
716 DWORD LoopsRemaining
;
717 } WAVE_STREAM_INFO
, *PWAVE_STREAM_INFO
;
720 #define SOUND_DEVICE_INSTANCE_TAG "SndI"
722 typedef struct _SOUND_DEVICE_INSTANCE
724 struct _SOUND_DEVICE_INSTANCE
* Next
;
725 PSOUND_DEVICE Device
;
727 /* The currently opened handle to the device */
729 /* PSOUND_THREAD Thread;*/
732 /* Device-specific parameters */
735 WAVE_STREAM_INFO Wave
;
737 } SOUND_DEVICE_INSTANCE
, *PSOUND_DEVICE_INSTANCE
;