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 File %hS Line %u\n", #condition, __FILE__, __LINE__); \
60 POPUP(L"ASSERT FAILED: %hS\n", #condition); \
65 #define DUMP_WAVEHDR_QUEUE(sound_device_instance) \
67 PWAVEHDR CurrDumpHdr = sound_device_instance->HeadWaveHeader; \
68 SND_TRACE(L"-- Current wave header list --\n"); \
69 while ( CurrDumpHdr ) \
71 SND_TRACE(L"%x | %d bytes | flags: %x\n", CurrDumpHdr->lpData, \
72 CurrDumpHdr->dwBufferLength, \
73 CurrDumpHdr->dwFlags); \
74 CurrDumpHdr = CurrDumpHdr->lpNext; \
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 #define DUMP_WAVEHDR_QUEUE(condition) do {} while ( 0 )
87 Some memory allocation helper macros
90 #define AllocateStruct(thing) \
91 (thing*) AllocateMemory(sizeof(thing))
93 #define StringLengthToBytes(chartype, string_length) \
94 ( ( string_length + 1 ) * sizeof(chartype) )
96 #define AllocateWideString(string_length) \
97 (PWSTR) AllocateMemory(StringLengthToBytes(WCHAR, string_length))
99 #define ZeroWideString(string) \
100 ZeroMemory(string, StringLengthToBytes(WCHAR, wcslen(string)))
102 #define CopyWideString(dest, source) \
103 CopyMemory(dest, source, StringLengthToBytes(WCHAR, wcslen(source)))
107 Helps find the minimum/maximum of two values
110 #define MinimumOf(value_a, value_b) \
111 ( value_a < value_b ? value_a : value_b )
113 #define MaximumOf(value_a, value_b) \
114 ( value_a > value_b ? value_a : value_b )
118 Convert a device type into a zero-based array index
121 #define SOUND_DEVICE_TYPE_TO_INDEX(x) \
122 ( x - MIN_SOUND_DEVICE_TYPE )
124 #define INDEX_TO_SOUND_DEVICE_TYPE(x) \
125 ( x + MIN_SOUND_DEVICE_TYPE )
132 #define IsValidSoundDeviceType IS_VALID_SOUND_DEVICE_TYPE
134 #define VALIDATE_MMSYS_PARAMETER(parameter_condition) \
136 if ( ! (parameter_condition) ) \
138 SND_ERR(L"FAILED parameter check: %hS\n", #parameter_condition); \
139 return MMSYSERR_INVALPARAM; \
143 #define MMSUCCESS(result) \
144 ( result == MMSYSERR_NOERROR )
151 typedef UCHAR MMDEVICE_TYPE
, *PMMDEVICE_TYPE
;
152 struct _SOUND_DEVICE
;
153 struct _SOUND_DEVICE_INSTANCE
;
156 #define DEFINE_GETCAPS_FUNCTYPE(func_typename, caps_type) \
157 typedef MMRESULT (*func_typename)( \
158 IN struct _SOUND_DEVICE* SoundDevice, \
159 OUT caps_type Capabilities, \
160 IN DWORD CapabilitiesSize);
162 /* This one is for those of us who don't care */
163 DEFINE_GETCAPS_FUNCTYPE(MMGETCAPS_FUNC
, PVOID
);
165 /* These are for those of us that do */
166 DEFINE_GETCAPS_FUNCTYPE(MMGETWAVEOUTCAPS_FUNC
, LPWAVEOUTCAPS
);
167 DEFINE_GETCAPS_FUNCTYPE(MMGETWAVEINCAPS_FUNC
, LPWAVEINCAPS
);
168 DEFINE_GETCAPS_FUNCTYPE(MMGETMIDIOUTCAPS_FUNC
, LPMIDIOUTCAPS
);
169 DEFINE_GETCAPS_FUNCTYPE(MMGETMIDIINCAPS_FUNC
, LPMIDIINCAPS
);
171 struct _SOUND_DEVICE
;
172 struct _SOUND_DEVICE_INSTANCE
;
176 By extending the OVERLAPPED structure, it becomes possible to provide the
177 I/O completion routines with additional information.
180 typedef struct _SOUND_OVERLAPPED
183 struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
;
185 BOOL PerformCompletion
;
186 } SOUND_OVERLAPPED
, *PSOUND_OVERLAPPED
;
188 typedef MMRESULT (*WAVE_COMMIT_FUNC
)(
189 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
192 IN PSOUND_OVERLAPPED Overlap
,
193 IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine
);
197 typedef MMRESULT (*MMWAVEQUERYFORMATSUPPORT_FUNC
)(
198 IN
struct _SOUND_DEVICE
* Device
,
199 IN PWAVEFORMATEX WaveFormat
,
200 IN DWORD WaveFormatSize
);
202 typedef MMRESULT (*MMWAVESETFORMAT_FUNC
)(
203 IN
struct _SOUND_DEVICE_INSTANCE
* Instance
,
204 IN PWAVEFORMATEX WaveFormat
,
205 IN DWORD WaveFormatSize
);
207 typedef MMRESULT (*MMOPEN_FUNC
)(
208 IN
struct _SOUND_DEVICE
* SoundDevice
,
211 typedef MMRESULT (*MMCLOSE_FUNC
)(
212 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
213 IN PVOID Handle
); /* not sure about this */
215 typedef MMRESULT (*MMWAVEHEADER_FUNC
)(
216 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
217 IN PWAVEHDR WaveHeader
);
219 typedef MMRESULT (*MMBUFFER_FUNC
)(
220 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
224 typedef struct _MMFUNCTION_TABLE
228 MMGETCAPS_FUNC GetCapabilities
;
229 MMGETWAVEOUTCAPS_FUNC GetWaveOutCapabilities
;
230 MMGETWAVEINCAPS_FUNC GetWaveInCapabilities
;
231 MMGETMIDIOUTCAPS_FUNC GetMidiOutCapabilities
;
232 MMGETMIDIINCAPS_FUNC GetMidiInCapabilities
;
238 MMWAVEQUERYFORMATSUPPORT_FUNC QueryWaveFormatSupport
;
239 MMWAVESETFORMAT_FUNC SetWaveFormat
;
241 WAVE_COMMIT_FUNC CommitWaveBuffer
;
244 //MMWAVEHEADER_FUNC PrepareWaveHeader;
245 //MMWAVEHEADER_FUNC UnprepareWaveHeader;
246 //MMWAVEHEADER_FUNC WriteWaveHeader;
248 //MMWAVEHEADER_FUNC SubmitWaveHeaderToDevice;
249 //MMBUFFER_FUNC CompleteBuffer;
250 } MMFUNCTION_TABLE
, *PMMFUNCTION_TABLE
;
254 typedef MMRESULT (*SOUND_THREAD_REQUEST_HANDLER
)(
255 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
258 typedef struct _SOUND_THREAD
272 SOUND_THREAD_REQUEST_HANDLER Handler
;
273 struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
;
277 } SOUND_THREAD
, *PSOUND_THREAD
;
279 typedef struct _SOUND_DEVICE
281 struct _SOUND_DEVICE
* Next
;
282 struct _SOUND_DEVICE_INSTANCE
* HeadInstance
;
283 struct _SOUND_DEVICE_INSTANCE
* TailInstance
;
285 PVOID Identifier
; /* Path for NT4 drivers */
287 MMFUNCTION_TABLE FunctionTable
;
288 } SOUND_DEVICE
, *PSOUND_DEVICE
;
290 typedef struct _SOUND_DEVICE_INSTANCE
292 struct _SOUND_DEVICE_INSTANCE
* Next
;
293 struct _SOUND_DEVICE
* Device
;
295 struct _SOUND_THREAD
* Thread
;
297 /* Stuff generously donated to us from WinMM */
302 DWORD ClientCallback
;
303 DWORD ClientCallbackInstanceData
;
306 /* DO NOT TOUCH THESE OUTSIDE OF THE SOUND THREAD */
310 PWAVEHDR HeadWaveHeader
;
315 PWAVEHDR TailWaveHeader
;
318 PWAVEHDR WaveLoopStart
;
319 //PWAVEHDR CurrentWaveHeader;
320 DWORD OutstandingBuffers
;
321 DWORD LoopsRemaining
;
322 } SOUND_DEVICE_INSTANCE
, *PSOUND_DEVICE_INSTANCE
;
324 /* This lives in WAVEHDR.reserved */
325 typedef struct _WAVEHDR_EXTENSION
327 DWORD BytesCommitted
;
328 DWORD BytesCompleted
;
329 } WAVEHDR_EXTENSION
, *PWAVEHDR_EXTENSION
;
337 InitEntrypointMutexes();
340 CleanupEntrypointMutexes();
343 AcquireEntrypointMutex(
344 IN MMDEVICE_TYPE DeviceType
);
347 ReleaseEntrypointMutex(
348 IN MMDEVICE_TYPE DeviceType
);
357 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
359 IN DWORD_PTR Parameter
);
362 MmeGetSoundDeviceCapabilities(
363 IN MMDEVICE_TYPE DeviceType
,
365 IN DWORD_PTR Capabilities
,
366 IN DWORD CapabilitiesSize
);
370 IN MMDEVICE_TYPE DeviceType
,
372 IN LPWAVEOPENDESC OpenParameters
,
374 OUT SIZE_T
* PrivateHandle
);
378 IN DWORD_PTR PrivateHandle
);
380 #define MmePrepareWaveHeader(private_handle, header) \
381 PrepareWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
383 #define MmeUnprepareWaveHeader(private_handle, header) \
384 UnprepareWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
386 #define MmeWriteWaveHeader(private_handle, header) \
387 WriteWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
390 MmeResetWavePlayback(
391 IN SIZE_T PrivateHandle
);
399 GetSoundDeviceCapabilities(
400 IN PSOUND_DEVICE SoundDevice
,
401 OUT DWORD_PTR Capabilities
,
402 IN DWORD CapabilitiesSize
);
411 IN MMDEVICE_TYPE DeviceType
);
415 IN PSOUND_DEVICE SoundDevice
);
419 IN MMDEVICE_TYPE DeviceType
,
420 IN PVOID Identifier OPTIONAL
,
421 OUT PSOUND_DEVICE
* SoundDevice OPTIONAL
);
425 IN MMDEVICE_TYPE DeviceType
,
426 IN PSOUND_DEVICE SoundDevice
);
430 IN MMDEVICE_TYPE DeviceType
);
433 UnlistAllSoundDevices();
437 IN MMDEVICE_TYPE DeviceType
,
438 IN DWORD DeviceIndex
,
439 OUT PSOUND_DEVICE
* Device
);
442 GetSoundDeviceIdentifier(
443 IN PSOUND_DEVICE SoundDevice
,
444 OUT PVOID
* Identifier
);
448 IN PSOUND_DEVICE SoundDevice
,
449 OUT PMMDEVICE_TYPE DeviceType
);
457 SetSoundDeviceFunctionTable(
458 IN PSOUND_DEVICE SoundDevice
,
459 IN PMMFUNCTION_TABLE FunctionTable
);
462 GetSoundDeviceFunctionTable(
463 IN PSOUND_DEVICE SoundDevice
,
464 OUT PMMFUNCTION_TABLE
* FunctionTable
);
472 IsValidSoundDeviceInstance(
473 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
);
476 CreateSoundDeviceInstance(
477 IN PSOUND_DEVICE SoundDevice
,
478 OUT PSOUND_DEVICE_INSTANCE
* SoundDeviceInstance
);
481 DestroySoundDeviceInstance(
482 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
);
485 DestroyAllSoundDeviceInstances(
486 IN PSOUND_DEVICE SoundDevice
);
489 GetSoundDeviceFromInstance(
490 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
491 OUT PSOUND_DEVICE
* SoundDevice
);
494 GetSoundDeviceInstanceHandle(
495 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
499 SetSoundDeviceInstanceMmeData(
500 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
502 IN DWORD ClientCallback
,
503 IN DWORD ClientCallbackData
,
513 OUT PSOUND_THREAD
* Thread
);
517 IN PSOUND_THREAD Thread
);
521 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
522 IN SOUND_THREAD_REQUEST_HANDLER RequestHandler
,
523 IN PVOID Parameter OPTIONAL
);
539 GetMemoryAllocationCount();
546 Win32ErrorToMmResult(
550 TranslateInternalMmResult(
559 QueryWaveDeviceFormatSupport(
560 IN PSOUND_DEVICE SoundDevice
,
561 IN LPWAVEFORMATEX Format
,
562 IN DWORD FormatSize
);
566 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
567 IN LPWAVEFORMATEX Format
,
568 IN DWORD FormatSize
);
577 PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
582 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
587 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
592 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
597 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
607 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
);
611 IN DWORD dwErrorCode
,
612 IN DWORD dwNumberOfBytesTransferred
,
613 IN LPOVERLAPPED lpOverlapped
);
616 CommitWaveHeaderToKernelDevice(
617 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
619 IN WAVE_COMMIT_FUNC CommitFunction
);
622 WriteFileEx_Committer(
623 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
626 IN PSOUND_OVERLAPPED Overlap
,
627 IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine
);
631 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
);
639 OpenKernelSoundDeviceByName(
645 OpenKernelSoundDevice(
646 IN PSOUND_DEVICE SoundDevice
,
651 CloseKernelSoundDevice(
655 SyncOverlappedDeviceIoControl(
656 IN HANDLE SoundDeviceInstance
,
657 IN DWORD IoControlCode
,
659 IN DWORD InBufferSize
,
660 OUT LPVOID OutBuffer
,
661 IN DWORD OutBufferSize
,
662 OUT LPDWORD BytesTransferred OPTIONAL
);