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.
19 #ifndef ROS_AUDIO_MMEBUDDY_H
20 #define ROS_AUDIO_MMEBUDDY_H
28 WCHAR dbg_popup_msg[1024], dbg_popup_title[256]; \
29 wsprintf(dbg_popup_title, L"%hS(%d)", __FILE__, __LINE__); \
30 wsprintf(dbg_popup_msg, __VA_ARGS__); \
31 MessageBox(0, dbg_popup_msg, dbg_popup_title, MB_OK | MB_TASKMODAL); \
35 #define SND_ERR(...) \
37 WCHAR dbg_popup_msg[1024]; \
38 wsprintf(dbg_popup_msg, __VA_ARGS__); \
39 OutputDebugString(dbg_popup_msg); \
41 #define SND_WARN(...) \
43 WCHAR dbg_popup_msg[1024]; \
44 wsprintf(dbg_popup_msg, __VA_ARGS__); \
45 OutputDebugString(dbg_popup_msg); \
47 #define SND_TRACE(...) \
49 WCHAR dbg_popup_msg[1024]; \
50 wsprintf(dbg_popup_msg, __VA_ARGS__); \
51 OutputDebugString(dbg_popup_msg); \
54 #define SND_ASSERT(condition) \
56 if ( ! ( condition ) ) \
58 SND_ERR(L"ASSERT FAILED: %hS\n", #condition); \
59 POPUP(L"ASSERT FAILED: %hS\n", #condition); \
65 #define SND_ERR(...) while ( 0 ) do {}
66 #define SND_WARN(...) while ( 0 ) do {}
67 #define SND_TRACE(...) while ( 0 ) do {}
68 #define SND_ASSERT(condition) while ( 0 ) do {}
72 Some memory allocation helper macros
75 #define AllocateStruct(thing) \
76 (thing*) AllocateMemory(sizeof(thing))
78 #define StringLengthToBytes(chartype, string_length) \
79 ( ( string_length + 1 ) * sizeof(chartype) )
81 #define AllocateWideString(string_length) \
82 (PWSTR) AllocateMemory(StringLengthToBytes(WCHAR, string_length))
84 #define ZeroWideString(string) \
85 ZeroMemory(string, StringLengthToBytes(WCHAR, wcslen(string)))
87 #define CopyWideString(dest, source) \
88 CopyMemory(dest, source, StringLengthToBytes(WCHAR, wcslen(source)))
92 Helps find the minimum/maximum of two values
95 #define MinimumOf(value_a, value_b) \
96 ( value_a < value_b ? value_a : value_b )
98 #define MaximumOf(value_a, value_b) \
99 ( value_a > value_b ? value_a : value_b )
103 Convert a device type into a zero-based array index
106 #define SOUND_DEVICE_TYPE_TO_INDEX(x) \
107 ( x - MIN_SOUND_DEVICE_TYPE )
109 #define INDEX_TO_SOUND_DEVICE_TYPE(x) \
110 ( x + MIN_SOUND_DEVICE_TYPE )
117 #define IsValidSoundDeviceType IS_VALID_SOUND_DEVICE_TYPE
119 #define VALIDATE_MMSYS_PARAMETER(parameter_condition) \
121 if ( ! (parameter_condition) ) \
123 SND_ERR(L"FAILED parameter check: %hS\n", #parameter_condition); \
124 return MMSYSERR_INVALPARAM; \
128 #define MMSUCCESS(result) \
129 ( result == MMSYSERR_NOERROR )
136 typedef UCHAR MMDEVICE_TYPE
, *PMMDEVICE_TYPE
;
137 struct _SOUND_DEVICE
;
138 struct _SOUND_DEVICE_INSTANCE
;
141 #define DEFINE_GETCAPS_FUNCTYPE(func_typename, caps_type) \
142 typedef MMRESULT (*func_typename)( \
143 IN struct _SOUND_DEVICE* SoundDevice, \
144 OUT caps_type Capabilities, \
145 IN DWORD CapabilitiesSize);
147 /* This one is for those of us who don't care */
148 DEFINE_GETCAPS_FUNCTYPE(MMGETCAPS_FUNC
, PVOID
);
150 /* These are for those of us that do */
151 DEFINE_GETCAPS_FUNCTYPE(MMGETWAVEOUTCAPS_FUNC
, LPWAVEOUTCAPS
);
152 DEFINE_GETCAPS_FUNCTYPE(MMGETWAVEINCAPS_FUNC
, LPWAVEINCAPS
);
153 DEFINE_GETCAPS_FUNCTYPE(MMGETMIDIOUTCAPS_FUNC
, LPMIDIOUTCAPS
);
154 DEFINE_GETCAPS_FUNCTYPE(MMGETMIDIINCAPS_FUNC
, LPMIDIINCAPS
);
156 struct _SOUND_DEVICE
;
157 struct _SOUND_DEVICE_INSTANCE
;
159 typedef MMRESULT (*MMWAVEQUERYFORMATSUPPORT_FUNC
)(
160 IN
struct _SOUND_DEVICE
* Device
,
161 IN PWAVEFORMATEX WaveFormat
,
162 IN DWORD WaveFormatSize
);
164 typedef MMRESULT (*MMWAVESETFORMAT_FUNC
)(
165 IN
struct _SOUND_DEVICE_INSTANCE
* Instance
,
166 IN PWAVEFORMATEX WaveFormat
,
167 IN DWORD WaveFormatSize
);
169 typedef MMRESULT (*MMOPEN_FUNC
)(
170 IN
struct _SOUND_DEVICE
* SoundDevice
,
173 typedef MMRESULT (*MMCLOSE_FUNC
)(
174 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
175 IN PVOID Handle
); /* not sure about this */
177 typedef MMRESULT (*MMWAVEHEADER_FUNC
)(
178 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
179 IN PWAVEHDR WaveHeader
);
181 typedef struct _MMFUNCTION_TABLE
185 MMGETCAPS_FUNC GetCapabilities
;
186 MMGETWAVEOUTCAPS_FUNC GetWaveOutCapabilities
;
187 MMGETWAVEINCAPS_FUNC GetWaveInCapabilities
;
188 MMGETMIDIOUTCAPS_FUNC GetMidiOutCapabilities
;
189 MMGETMIDIINCAPS_FUNC GetMidiInCapabilities
;
195 MMWAVEQUERYFORMATSUPPORT_FUNC QueryWaveFormatSupport
;
196 MMWAVESETFORMAT_FUNC SetWaveFormat
;
198 MMWAVEHEADER_FUNC PrepareWaveHeader
;
199 MMWAVEHEADER_FUNC UnprepareWaveHeader
;
200 MMWAVEHEADER_FUNC SubmitWaveHeader
;
201 } MMFUNCTION_TABLE
, *PMMFUNCTION_TABLE
;
203 typedef MMRESULT (*SOUND_THREAD_REQUEST_HANDLER
)(
204 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
207 typedef struct _SOUND_THREAD
221 SOUND_THREAD_REQUEST_HANDLER Handler
;
222 struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
;
226 } SOUND_THREAD
, *PSOUND_THREAD
;
228 typedef struct _SOUND_DEVICE
230 struct _SOUND_DEVICE
* Next
;
231 struct _SOUND_DEVICE_INSTANCE
* HeadInstance
;
232 struct _SOUND_DEVICE_INSTANCE
* TailInstance
;
234 PVOID Identifier
; /* Path for NT4 drivers */
236 MMFUNCTION_TABLE FunctionTable
;
237 } SOUND_DEVICE
, *PSOUND_DEVICE
;
239 typedef struct _SOUND_DEVICE_INSTANCE
241 struct _SOUND_DEVICE_INSTANCE
* Next
;
242 struct _SOUND_DEVICE
* Device
;
244 struct _SOUND_THREAD
* Thread
;
246 /* Stuff generously donated to us from WinMM */
251 DWORD ClientCallback
;
252 DWORD ClientCallbackInstanceData
;
254 } SOUND_DEVICE_INSTANCE
, *PSOUND_DEVICE_INSTANCE
;
261 InitEntrypointMutexes();
264 CleanupEntrypointMutexes();
267 AcquireEntrypointMutex(
268 IN MMDEVICE_TYPE DeviceType
);
271 ReleaseEntrypointMutex(
272 IN MMDEVICE_TYPE DeviceType
);
281 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
286 MmeGetSoundDeviceCapabilities(
287 IN MMDEVICE_TYPE DeviceType
,
289 IN PVOID Capabilities
,
290 IN DWORD CapabilitiesSize
);
294 IN MMDEVICE_TYPE DeviceType
,
296 IN LPWAVEOPENDESC OpenParameters
,
298 OUT DWORD
* PrivateHandle
);
302 IN DWORD PrivateHandle
);
304 #define MmePrepareWaveHeader(private_handle, header) \
305 PrepareWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
307 #define MmeUnprepareWaveHeader(private_handle, header) \
308 UnprepareWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
310 #define MmeEnqueueWaveHeader(private_handle, header) \
311 EnqueueWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
319 GetSoundDeviceCapabilities(
320 IN PSOUND_DEVICE SoundDevice
,
321 OUT PVOID Capabilities
,
322 IN DWORD CapabilitiesSize
);
331 IN MMDEVICE_TYPE DeviceType
);
335 IN PSOUND_DEVICE SoundDevice
);
339 IN MMDEVICE_TYPE DeviceType
,
340 IN PVOID Identifier OPTIONAL
,
341 OUT PSOUND_DEVICE
* SoundDevice OPTIONAL
);
345 IN MMDEVICE_TYPE DeviceType
,
346 IN PSOUND_DEVICE SoundDevice
);
350 IN MMDEVICE_TYPE DeviceType
);
353 UnlistAllSoundDevices();
357 IN MMDEVICE_TYPE DeviceType
,
358 IN DWORD DeviceIndex
,
359 OUT PSOUND_DEVICE
* Device
);
362 GetSoundDeviceIdentifier(
363 IN PSOUND_DEVICE SoundDevice
,
364 OUT PVOID
* Identifier
);
368 IN PSOUND_DEVICE SoundDevice
,
369 OUT PMMDEVICE_TYPE DeviceType
);
377 SetSoundDeviceFunctionTable(
378 IN PSOUND_DEVICE SoundDevice
,
379 IN PMMFUNCTION_TABLE FunctionTable
);
382 GetSoundDeviceFunctionTable(
383 IN PSOUND_DEVICE SoundDevice
,
384 OUT PMMFUNCTION_TABLE
* FunctionTable
);
392 IsValidSoundDeviceInstance(
393 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
);
396 CreateSoundDeviceInstance(
397 IN PSOUND_DEVICE SoundDevice
,
398 OUT PSOUND_DEVICE_INSTANCE
* SoundDeviceInstance
);
401 DestroySoundDeviceInstance(
402 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
);
405 DestroyAllSoundDeviceInstances(
406 IN PSOUND_DEVICE SoundDevice
);
409 GetSoundDeviceFromInstance(
410 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
411 OUT PSOUND_DEVICE
* SoundDevice
);
414 GetSoundDeviceInstanceHandle(
415 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
419 SetSoundDeviceInstanceMmeData(
420 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
422 IN DWORD ClientCallback
,
423 IN DWORD ClientCallbackData
,
433 OUT PSOUND_THREAD
* Thread
);
437 IN PSOUND_THREAD Thread
);
441 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
442 IN SOUND_THREAD_REQUEST_HANDLER RequestHandler
,
443 IN PVOID Parameter OPTIONAL
);
459 GetMemoryAllocationCount();
466 Win32ErrorToMmResult(
470 TranslateInternalMmResult(
479 QueryWaveDeviceFormatSupport(
480 IN PSOUND_DEVICE SoundDevice
,
481 IN LPWAVEFORMATEX Format
,
482 IN DWORD FormatSize
);
486 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
487 IN LPWAVEFORMATEX Format
,
488 IN DWORD FormatSize
);
497 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
502 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
507 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
516 #define QueryDevice(h, ctl, o, o_size, xfer, ovl) \
517 Win32ErrorToMmResult( \
518 DeviceIoControl(h, ctl, NULL, 0, o, o_size, xfer, ovl) != 0 \
519 ? ERROR_SUCCESS : GetLastError() \
522 #define ControlDevice(h, ctl, i, i_size, xfer, ovl) \
523 Win32ErrorToMmResult( \
524 DeviceIoControl(h, ctl, i, i_size, NULL, 0, xfer, ovl) != 0 \
525 ? ERROR_SUCCESS : GetLastError() \
528 #define QuerySoundDevice(sd, ctl, o, o_size, xfer) \
529 SoundDeviceIoControl(sd, ctl, NULL, 0, o, o_size, xfer)
531 #define ControlSoundDevice(sd, ctl, i, i_size, xfer) \
532 SoundDeviceIoControl(sd, ctl, i, i_size, NULL, 0, xfer)
536 OpenKernelSoundDeviceByName(
542 OpenKernelSoundDevice(
543 IN PSOUND_DEVICE SoundDevice
,
548 CloseKernelSoundDevice(
552 SyncOverlappedDeviceIoControl(
553 IN HANDLE SoundDeviceInstance
,
554 IN DWORD IoControlCode
,
556 IN DWORD InBufferSize
,
557 OUT LPVOID OutBuffer
,
558 IN DWORD OutBufferSize
,
559 OUT LPDWORD BytesTransferred OPTIONAL
);
564 typedef UCHAR MMDEVICE_TYPE
, *PMMDEVICE_TYPE
;
566 struct _SOUND_DEVICE
;
567 struct _SOUND_DEVICE_INSTANCE
;
571 Rather than pass caps structures around as a PVOID, this can be
575 typedef union _UNIVERSAL_CAPS
581 } UNIVERSAL_CAPS
, *PUNIVERSAL_CAPS
;
585 /* New sound thread code */
587 typedef MMRESULT (*SOUND_THREAD_REQUEST_HANDLER
)(
588 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
589 IN OPTIONAL PVOID Parameter
);
591 typedef struct _SOUND_THREAD_REQUEST
593 /* The sound device instance this request relates to */
594 struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
;
595 /* What function to call */
596 SOUND_THREAD_REQUEST_HANDLER RequestHandler
;
597 /* Caller-defined parameter */
599 /* This will contain the return code of the request function */
600 MMRESULT ReturnValue
;
601 } SOUND_THREAD_REQUEST
, *PSOUND_THREAD_REQUEST
;
603 typedef VOID (*SOUND_THREAD_IO_COMPLETION_HANDLER
)(
604 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
605 IN PVOID Parameter OPTIONAL
,
606 IN DWORD BytesWritten
);
608 typedef struct _SOUND_THREAD_COMPLETED_IO
610 struct _SOUND_THREAD_COMPLETED_IO
* Previous
;
611 struct _SOUND_THREAD_COMPLETED_IO
* Next
;
613 struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
;
614 SOUND_THREAD_IO_COMPLETION_HANDLER CompletionHandler
;
616 DWORD BytesTransferred
;
617 } SOUND_THREAD_COMPLETED_IO
, *PSOUND_THREAD_COMPLETED_IO
;
619 typedef struct _SOUND_THREAD_OVERLAPPED
623 /* Pointer to structure to fill with completion data */
624 PSOUND_THREAD_COMPLETED_IO CompletionData
;
625 } SOUND_THREAD_OVERLAPPED
, *PSOUND_THREAD_OVERLAPPED
;
628 Audio device function table
631 typedef MMRESULT (*MMCREATEINSTANCE_FUNC
)(
632 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
);
634 typedef VOID (*MMDESTROYINSTANCE_FUNC
)(
635 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
);
637 typedef MMRESULT (*MMGETCAPS_FUNC
)(
638 IN
struct _SOUND_DEVICE
* Device
,
639 OUT PUNIVERSAL_CAPS Capabilities
);
641 typedef MMRESULT (*MMWAVEQUERYFORMAT_FUNC
)(
642 IN
struct _SOUND_DEVICE
* Device
,
643 IN PWAVEFORMATEX WaveFormat
,
644 IN DWORD WaveFormatSize
);
646 typedef MMRESULT (*MMWAVESETFORMAT_FUNC
)(
647 IN
struct _SOUND_DEVICE_INSTANCE
* Instance
,
648 IN PWAVEFORMATEX WaveFormat
,
649 IN DWORD WaveFormatSize
);
651 typedef MMRESULT (*MMWAVEQUEUEBUFFER_FUNC
)(
652 IN
struct _SOUND_DEVICE_INSTANCE
* Instance
,
653 IN PWAVEHDR WaveHeader
);
655 typedef MMRESULT (*MMGETWAVESTATE_FUNC
)(
656 IN
struct _SOUND_DEVICE_INSTANCE
* Instance
,
659 typedef MMRESULT (*MMSETWAVESTATE_FUNC
)(
660 IN
struct _SOUND_DEVICE_INSTANCE
* Instance
);
662 typedef struct _MMFUNCTION_TABLE
664 MMCREATEINSTANCE_FUNC Constructor
;
665 MMDESTROYINSTANCE_FUNC Destructor
;
666 MMGETCAPS_FUNC GetCapabilities
;
668 MMWAVEQUERYFORMAT_FUNC QueryWaveFormat
;
669 MMWAVESETFORMAT_FUNC SetWaveFormat
;
670 MMWAVEQUEUEBUFFER_FUNC QueueWaveBuffer
;
672 MMGETWAVESTATE_FUNC GetWaveDeviceState
;
673 MMSETWAVESTATE_FUNC PauseWaveDevice
;
674 MMSETWAVESTATE_FUNC RestartWaveDevice
;
675 MMSETWAVESTATE_FUNC ResetWaveDevice
;
676 MMSETWAVESTATE_FUNC BreakWaveDeviceLoop
;
677 } MMFUNCTION_TABLE
, *PMMFUNCTION_TABLE
;
681 Represents an audio device
684 #define SOUND_DEVICE_TAG "SndD"
686 typedef struct _SOUND_DEVICE
688 struct _SOUND_DEVICE
* Next
;
689 struct _SOUND_DEVICE_INSTANCE
* FirstInstance
;
692 MMFUNCTION_TABLE Functions
;
693 } SOUND_DEVICE
, *PSOUND_DEVICE
;
697 Represents an individual instance of an audio device
700 #define WAVE_STREAM_INFO_TAG "WavS"
702 typedef struct _WAVE_STREAM_INFO
704 /* Buffer queue head and tail */
705 PWAVEHDR BufferQueueHead
;
706 PWAVEHDR BufferQueueTail
;
707 /* The buffer currently being processed */
708 PWAVEHDR CurrentBuffer
;
709 /* How far into the current buffer we've gone */
711 /* How many I/O operations have been submitted */
712 DWORD BuffersOutstanding
;
715 DWORD LoopsRemaining
;
716 } WAVE_STREAM_INFO
, *PWAVE_STREAM_INFO
;
719 #define SOUND_DEVICE_INSTANCE_TAG "SndI"
721 typedef struct _SOUND_DEVICE_INSTANCE
723 struct _SOUND_DEVICE_INSTANCE
* Next
;
724 PSOUND_DEVICE Device
;
726 /* The currently opened handle to the device */
728 /* PSOUND_THREAD Thread;*/
731 /* Device-specific parameters */
734 WAVE_STREAM_INFO Wave
;
736 } SOUND_DEVICE_INSTANCE
, *PSOUND_DEVICE_INSTANCE
;