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
,
205 IN PWAVEFORMATEX WaveFormat
,
206 IN DWORD WaveFormatSize
);
208 typedef MMRESULT (*MMOPEN_FUNC
)(
209 IN
struct _SOUND_DEVICE
* SoundDevice
,
212 typedef MMRESULT (*MMCLOSE_FUNC
)(
213 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
214 IN PVOID Handle
); /* not sure about this */
216 typedef MMRESULT (*MMWAVEHEADER_FUNC
)(
217 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
218 IN PWAVEHDR WaveHeader
);
220 typedef MMRESULT (*MMBUFFER_FUNC
)(
221 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
225 typedef MMRESULT(*MMGETPOS_FUNC
)(
226 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
229 typedef struct _MMFUNCTION_TABLE
233 MMGETCAPS_FUNC GetCapabilities
;
234 MMGETWAVEOUTCAPS_FUNC GetWaveOutCapabilities
;
235 MMGETWAVEINCAPS_FUNC GetWaveInCapabilities
;
236 MMGETMIDIOUTCAPS_FUNC GetMidiOutCapabilities
;
237 MMGETMIDIINCAPS_FUNC GetMidiInCapabilities
;
243 MMWAVEQUERYFORMATSUPPORT_FUNC QueryWaveFormatSupport
;
244 MMWAVESETFORMAT_FUNC SetWaveFormat
;
246 WAVE_COMMIT_FUNC CommitWaveBuffer
;
248 MMGETPOS_FUNC GetPos
;
251 //MMWAVEHEADER_FUNC PrepareWaveHeader;
252 //MMWAVEHEADER_FUNC UnprepareWaveHeader;
253 //MMWAVEHEADER_FUNC WriteWaveHeader;
255 //MMWAVEHEADER_FUNC SubmitWaveHeaderToDevice;
256 //MMBUFFER_FUNC CompleteBuffer;
257 } MMFUNCTION_TABLE
, *PMMFUNCTION_TABLE
;
261 typedef MMRESULT (*SOUND_THREAD_REQUEST_HANDLER
)(
262 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
265 typedef struct _SOUND_THREAD
279 SOUND_THREAD_REQUEST_HANDLER Handler
;
280 struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
;
284 } SOUND_THREAD
, *PSOUND_THREAD
;
286 typedef struct _SOUND_DEVICE
288 struct _SOUND_DEVICE
* Next
;
289 struct _SOUND_DEVICE_INSTANCE
* HeadInstance
;
290 struct _SOUND_DEVICE_INSTANCE
* TailInstance
;
292 PVOID Identifier
; /* Path for NT4 drivers */
294 MMFUNCTION_TABLE FunctionTable
;
295 } SOUND_DEVICE
, *PSOUND_DEVICE
;
297 typedef struct _SOUND_DEVICE_INSTANCE
299 struct _SOUND_DEVICE_INSTANCE
* Next
;
300 struct _SOUND_DEVICE
* Device
;
302 struct _SOUND_THREAD
* Thread
;
304 /* Stuff generously donated to us from WinMM */
309 DWORD ClientCallback
;
310 DWORD ClientCallbackInstanceData
;
313 /* DO NOT TOUCH THESE OUTSIDE OF THE SOUND THREAD */
317 PWAVEHDR HeadWaveHeader
;
322 PWAVEHDR TailWaveHeader
;
325 PWAVEHDR WaveLoopStart
;
326 //PWAVEHDR CurrentWaveHeader;
327 DWORD OutstandingBuffers
;
328 DWORD LoopsRemaining
;
329 } SOUND_DEVICE_INSTANCE
, *PSOUND_DEVICE_INSTANCE
;
331 /* This lives in WAVEHDR.reserved */
332 typedef struct _WAVEHDR_EXTENSION
334 DWORD BytesCommitted
;
335 DWORD BytesCompleted
;
336 } WAVEHDR_EXTENSION
, *PWAVEHDR_EXTENSION
;
344 InitEntrypointMutexes();
347 CleanupEntrypointMutexes();
350 AcquireEntrypointMutex(
351 IN MMDEVICE_TYPE DeviceType
);
354 ReleaseEntrypointMutex(
355 IN MMDEVICE_TYPE DeviceType
);
364 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
369 MmeGetSoundDeviceCapabilities(
370 IN MMDEVICE_TYPE DeviceType
,
372 IN PVOID Capabilities
,
373 IN DWORD CapabilitiesSize
);
377 IN MMDEVICE_TYPE DeviceType
,
379 IN LPWAVEOPENDESC OpenParameters
,
381 OUT DWORD
* PrivateHandle
);
385 IN DWORD PrivateHandle
);
389 IN MMDEVICE_TYPE DeviceType
,
391 IN DWORD PrivateHandle
,
396 #define MmePrepareWaveHeader(private_handle, header) \
397 PrepareWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
399 #define MmeUnprepareWaveHeader(private_handle, header) \
400 UnprepareWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
402 #define MmeWriteWaveHeader(private_handle, header) \
403 WriteWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
406 MmeResetWavePlayback(
407 IN DWORD PrivateHandle
);
415 GetSoundDeviceCapabilities(
416 IN PSOUND_DEVICE SoundDevice
,
417 OUT PVOID Capabilities
,
418 IN DWORD CapabilitiesSize
);
427 IN MMDEVICE_TYPE DeviceType
);
431 IN PSOUND_DEVICE SoundDevice
);
435 IN MMDEVICE_TYPE DeviceType
,
436 IN PVOID Identifier OPTIONAL
,
437 OUT PSOUND_DEVICE
* SoundDevice OPTIONAL
);
441 IN MMDEVICE_TYPE DeviceType
,
442 IN PSOUND_DEVICE SoundDevice
);
446 IN MMDEVICE_TYPE DeviceType
);
449 UnlistAllSoundDevices();
453 IN MMDEVICE_TYPE DeviceType
,
454 IN DWORD DeviceIndex
,
455 OUT PSOUND_DEVICE
* Device
);
458 GetSoundDeviceIdentifier(
459 IN PSOUND_DEVICE SoundDevice
,
460 OUT PVOID
* Identifier
);
464 IN PSOUND_DEVICE SoundDevice
,
465 OUT PMMDEVICE_TYPE DeviceType
);
473 SetSoundDeviceFunctionTable(
474 IN PSOUND_DEVICE SoundDevice
,
475 IN PMMFUNCTION_TABLE FunctionTable
);
478 GetSoundDeviceFunctionTable(
479 IN PSOUND_DEVICE SoundDevice
,
480 OUT PMMFUNCTION_TABLE
* FunctionTable
);
488 IsValidSoundDeviceInstance(
489 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
);
492 CreateSoundDeviceInstance(
493 IN PSOUND_DEVICE SoundDevice
,
494 OUT PSOUND_DEVICE_INSTANCE
* SoundDeviceInstance
);
497 DestroySoundDeviceInstance(
498 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
);
501 DestroyAllSoundDeviceInstances(
502 IN PSOUND_DEVICE SoundDevice
);
505 GetSoundDeviceFromInstance(
506 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
507 OUT PSOUND_DEVICE
* SoundDevice
);
510 GetSoundDeviceInstanceHandle(
511 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
515 SetSoundDeviceInstanceMmeData(
516 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
518 IN DWORD ClientCallback
,
519 IN DWORD ClientCallbackData
,
529 OUT PSOUND_THREAD
* Thread
);
533 IN PSOUND_THREAD Thread
);
537 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
538 IN SOUND_THREAD_REQUEST_HANDLER RequestHandler
,
539 IN PVOID Parameter OPTIONAL
);
555 GetMemoryAllocationCount();
562 Win32ErrorToMmResult(
566 TranslateInternalMmResult(
575 QueryWaveDeviceFormatSupport(
576 IN PSOUND_DEVICE SoundDevice
,
577 IN LPWAVEFORMATEX Format
,
578 IN DWORD FormatSize
);
582 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
584 IN LPWAVEFORMATEX Format
,
585 IN DWORD FormatSize
);
594 PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
599 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
604 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
609 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
614 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
624 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
);
628 IN DWORD dwErrorCode
,
629 IN DWORD dwNumberOfBytesTransferred
,
630 IN LPOVERLAPPED lpOverlapped
);
633 CommitWaveHeaderToKernelDevice(
634 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
636 IN WAVE_COMMIT_FUNC CommitFunction
);
639 WriteFileEx_Committer(
640 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
643 IN PSOUND_OVERLAPPED Overlap
,
644 IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine
);
648 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
);
656 OpenKernelSoundDeviceByName(
662 OpenKernelSoundDevice(
663 IN PSOUND_DEVICE SoundDevice
,
668 CloseKernelSoundDevice(
672 SyncOverlappedDeviceIoControl(
673 IN HANDLE SoundDeviceInstance
,
674 IN DWORD IoControlCode
,
676 IN DWORD InBufferSize
,
677 OUT LPVOID OutBuffer
,
678 IN DWORD OutBufferSize
,
679 OUT LPDWORD BytesTransferred OPTIONAL
);