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, \
160 OUT caps_type Capabilities, \
161 IN DWORD CapabilitiesSize);
163 /* This one is for those of us who don't care */
164 DEFINE_GETCAPS_FUNCTYPE(MMGETCAPS_FUNC
, PVOID
);
166 /* These are for those of us that do */
167 DEFINE_GETCAPS_FUNCTYPE(MMGETWAVEOUTCAPS_FUNC
, LPWAVEOUTCAPS
);
168 DEFINE_GETCAPS_FUNCTYPE(MMGETWAVEINCAPS_FUNC
, LPWAVEINCAPS
);
169 DEFINE_GETCAPS_FUNCTYPE(MMGETMIDIOUTCAPS_FUNC
, LPMIDIOUTCAPS
);
170 DEFINE_GETCAPS_FUNCTYPE(MMGETMIDIINCAPS_FUNC
, LPMIDIINCAPS
);
172 struct _SOUND_DEVICE
;
173 struct _SOUND_DEVICE_INSTANCE
;
177 By extending the OVERLAPPED structure, it becomes possible to provide the
178 I/O completion routines with additional information.
181 typedef struct _SOUND_OVERLAPPED
184 struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
;
186 BOOL PerformCompletion
;
187 } SOUND_OVERLAPPED
, *PSOUND_OVERLAPPED
;
189 typedef MMRESULT (*WAVE_COMMIT_FUNC
)(
190 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
193 IN PSOUND_OVERLAPPED Overlap
,
194 IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine
);
198 typedef MMRESULT (*MMWAVEQUERYFORMATSUPPORT_FUNC
)(
199 IN
struct _SOUND_DEVICE
* Device
,
200 IN PWAVEFORMATEX WaveFormat
,
201 IN DWORD WaveFormatSize
);
203 typedef MMRESULT (*MMWAVESETFORMAT_FUNC
)(
204 IN
struct _SOUND_DEVICE_INSTANCE
* Instance
,
206 IN PWAVEFORMATEX WaveFormat
,
207 IN DWORD WaveFormatSize
);
209 typedef MMRESULT (*MMOPEN_FUNC
)(
210 IN
struct _SOUND_DEVICE
* SoundDevice
,
213 typedef MMRESULT (*MMCLOSE_FUNC
)(
214 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
215 IN PVOID Handle
); /* not sure about this */
217 typedef MMRESULT (*MMWAVEHEADER_FUNC
)(
218 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
219 IN PWAVEHDR WaveHeader
);
221 typedef MMRESULT (*MMBUFFER_FUNC
)(
222 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
226 typedef MMRESULT(*MMGETPOS_FUNC
)(
227 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
230 typedef struct _MMFUNCTION_TABLE
234 MMGETCAPS_FUNC GetCapabilities
;
235 MMGETWAVEOUTCAPS_FUNC GetWaveOutCapabilities
;
236 MMGETWAVEINCAPS_FUNC GetWaveInCapabilities
;
237 MMGETMIDIOUTCAPS_FUNC GetMidiOutCapabilities
;
238 MMGETMIDIINCAPS_FUNC GetMidiInCapabilities
;
244 MMWAVEQUERYFORMATSUPPORT_FUNC QueryWaveFormatSupport
;
245 MMWAVESETFORMAT_FUNC SetWaveFormat
;
247 WAVE_COMMIT_FUNC CommitWaveBuffer
;
249 MMGETPOS_FUNC GetPos
;
252 //MMWAVEHEADER_FUNC PrepareWaveHeader;
253 //MMWAVEHEADER_FUNC UnprepareWaveHeader;
254 //MMWAVEHEADER_FUNC WriteWaveHeader;
256 //MMWAVEHEADER_FUNC SubmitWaveHeaderToDevice;
257 //MMBUFFER_FUNC CompleteBuffer;
258 } MMFUNCTION_TABLE
, *PMMFUNCTION_TABLE
;
262 typedef MMRESULT (*SOUND_THREAD_REQUEST_HANDLER
)(
263 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
266 typedef struct _SOUND_THREAD
280 SOUND_THREAD_REQUEST_HANDLER Handler
;
281 struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
;
285 } SOUND_THREAD
, *PSOUND_THREAD
;
287 typedef struct _SOUND_DEVICE
289 struct _SOUND_DEVICE
* Next
;
290 struct _SOUND_DEVICE_INSTANCE
* HeadInstance
;
291 struct _SOUND_DEVICE_INSTANCE
* TailInstance
;
293 PVOID Identifier
; /* Path for NT4 drivers */
295 MMFUNCTION_TABLE FunctionTable
;
296 } SOUND_DEVICE
, *PSOUND_DEVICE
;
298 typedef struct _SOUND_DEVICE_INSTANCE
300 struct _SOUND_DEVICE_INSTANCE
* Next
;
301 struct _SOUND_DEVICE
* Device
;
303 struct _SOUND_THREAD
* Thread
;
305 /* Stuff generously donated to us from WinMM */
310 DWORD ClientCallback
;
311 DWORD ClientCallbackInstanceData
;
314 /* DO NOT TOUCH THESE OUTSIDE OF THE SOUND THREAD */
318 PWAVEHDR HeadWaveHeader
;
323 PWAVEHDR TailWaveHeader
;
326 PWAVEHDR WaveLoopStart
;
327 //PWAVEHDR CurrentWaveHeader;
328 DWORD OutstandingBuffers
;
329 DWORD LoopsRemaining
;
332 } SOUND_DEVICE_INSTANCE
, *PSOUND_DEVICE_INSTANCE
;
334 /* This lives in WAVEHDR.reserved */
335 typedef struct _WAVEHDR_EXTENSION
337 DWORD BytesCommitted
;
338 DWORD BytesCompleted
;
339 } WAVEHDR_EXTENSION
, *PWAVEHDR_EXTENSION
;
347 InitEntrypointMutexes();
350 CleanupEntrypointMutexes();
353 AcquireEntrypointMutex(
354 IN MMDEVICE_TYPE DeviceType
);
357 ReleaseEntrypointMutex(
358 IN MMDEVICE_TYPE DeviceType
);
367 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
372 MmeGetSoundDeviceCapabilities(
373 IN MMDEVICE_TYPE DeviceType
,
375 IN PVOID Capabilities
,
376 IN DWORD CapabilitiesSize
);
380 IN MMDEVICE_TYPE DeviceType
,
382 IN LPWAVEOPENDESC OpenParameters
,
384 OUT DWORD
* PrivateHandle
);
388 IN DWORD PrivateHandle
);
392 IN MMDEVICE_TYPE DeviceType
,
394 IN DWORD PrivateHandle
,
399 #define MmePrepareWaveHeader(private_handle, header) \
400 PrepareWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
402 #define MmeUnprepareWaveHeader(private_handle, header) \
403 UnprepareWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
405 #define MmeWriteWaveHeader(private_handle, header) \
406 WriteWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
409 MmeResetWavePlayback(
410 IN DWORD PrivateHandle
);
418 GetSoundDeviceCapabilities(
419 IN PSOUND_DEVICE SoundDevice
,
421 OUT PVOID Capabilities
,
422 IN DWORD CapabilitiesSize
);
431 IN MMDEVICE_TYPE DeviceType
);
435 IN PSOUND_DEVICE SoundDevice
);
439 IN MMDEVICE_TYPE DeviceType
,
440 IN PVOID Identifier OPTIONAL
,
441 OUT PSOUND_DEVICE
* SoundDevice OPTIONAL
);
445 IN MMDEVICE_TYPE DeviceType
,
446 IN PSOUND_DEVICE SoundDevice
);
450 IN MMDEVICE_TYPE DeviceType
);
453 UnlistAllSoundDevices();
457 IN MMDEVICE_TYPE DeviceType
,
458 IN DWORD DeviceIndex
,
459 OUT PSOUND_DEVICE
* Device
);
462 GetSoundDeviceIdentifier(
463 IN PSOUND_DEVICE SoundDevice
,
464 OUT PVOID
* Identifier
);
468 IN PSOUND_DEVICE SoundDevice
,
469 OUT PMMDEVICE_TYPE DeviceType
);
477 SetSoundDeviceFunctionTable(
478 IN PSOUND_DEVICE SoundDevice
,
479 IN PMMFUNCTION_TABLE FunctionTable
);
482 GetSoundDeviceFunctionTable(
483 IN PSOUND_DEVICE SoundDevice
,
484 OUT PMMFUNCTION_TABLE
* FunctionTable
);
492 IsValidSoundDeviceInstance(
493 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
);
496 CreateSoundDeviceInstance(
497 IN PSOUND_DEVICE SoundDevice
,
498 OUT PSOUND_DEVICE_INSTANCE
* SoundDeviceInstance
);
501 DestroySoundDeviceInstance(
502 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
);
505 DestroyAllSoundDeviceInstances(
506 IN PSOUND_DEVICE SoundDevice
);
509 GetSoundDeviceFromInstance(
510 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
511 OUT PSOUND_DEVICE
* SoundDevice
);
514 GetSoundDeviceInstanceHandle(
515 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
519 SetSoundDeviceInstanceMmeData(
520 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
522 IN DWORD ClientCallback
,
523 IN DWORD ClientCallbackData
,
533 OUT PSOUND_THREAD
* Thread
);
537 IN PSOUND_THREAD Thread
);
541 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
542 IN SOUND_THREAD_REQUEST_HANDLER RequestHandler
,
543 IN PVOID Parameter OPTIONAL
);
559 GetMemoryAllocationCount();
566 Win32ErrorToMmResult(
570 TranslateInternalMmResult(
579 QueryWaveDeviceFormatSupport(
580 IN PSOUND_DEVICE SoundDevice
,
581 IN LPWAVEFORMATEX Format
,
582 IN DWORD FormatSize
);
586 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
588 IN LPWAVEFORMATEX Format
,
589 IN DWORD FormatSize
);
598 PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
603 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
608 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
613 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
618 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
628 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
);
632 IN DWORD dwErrorCode
,
633 IN DWORD dwNumberOfBytesTransferred
,
634 IN LPOVERLAPPED lpOverlapped
);
637 CommitWaveHeaderToKernelDevice(
638 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
640 IN WAVE_COMMIT_FUNC CommitFunction
);
643 WriteFileEx_Committer(
644 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
647 IN PSOUND_OVERLAPPED Overlap
,
648 IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine
);
652 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
);
660 OpenKernelSoundDeviceByName(
666 OpenKernelSoundDevice(
667 IN PSOUND_DEVICE SoundDevice
,
672 CloseKernelSoundDevice(
676 SyncOverlappedDeviceIoControl(
677 IN HANDLE SoundDeviceInstance
,
678 IN DWORD IoControlCode
,
680 IN DWORD InBufferSize
,
681 OUT LPVOID OutBuffer
,
682 IN DWORD OutBufferSize
,
683 OUT LPDWORD BytesTransferred OPTIONAL
);