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, \
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 {(void)(condition);} 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 at File %S Line %lu\n", #parameter_condition, __FILE__, __LINE__); \
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
;
188 LPOVERLAPPED_COMPLETION_ROUTINE OriginalCompletionRoutine
;
189 PVOID CompletionContext
;
191 } SOUND_OVERLAPPED
, *PSOUND_OVERLAPPED
;
193 typedef MMRESULT (*WAVE_COMMIT_FUNC
)(
194 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
197 IN PSOUND_OVERLAPPED Overlap
,
198 IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine
);
200 typedef MMRESULT (*MMMIXERQUERY_FUNC
) (
201 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
207 typedef MMRESULT (*MMWAVEQUERYFORMATSUPPORT_FUNC
)(
208 IN
struct _SOUND_DEVICE
* Device
,
209 IN PWAVEFORMATEX WaveFormat
,
210 IN DWORD WaveFormatSize
);
212 typedef MMRESULT (*MMWAVESETFORMAT_FUNC
)(
213 IN
struct _SOUND_DEVICE_INSTANCE
* Instance
,
215 IN PWAVEFORMATEX WaveFormat
,
216 IN DWORD WaveFormatSize
);
218 typedef MMRESULT (*MMOPEN_FUNC
)(
219 IN
struct _SOUND_DEVICE
* SoundDevice
,
222 typedef MMRESULT (*MMCLOSE_FUNC
)(
223 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
224 IN PVOID Handle
); /* not sure about this */
226 typedef MMRESULT (*MMWAVEHEADER_FUNC
)(
227 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
228 IN PWAVEHDR WaveHeader
);
230 typedef MMRESULT (*MMBUFFER_FUNC
)(
231 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
235 typedef MMRESULT(*MMGETPOS_FUNC
)(
236 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
240 typedef MMRESULT(*MMSETSTATE_FUNC
)(
241 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
245 typedef MMRESULT(*MMQUERYDEVICEINTERFACESTRING_FUNC
)(
246 IN MMDEVICE_TYPE DeviceType
,
249 IN DWORD InterfaceLength
,
250 OUT DWORD
* InterfaceSize
);
252 typedef MMRESULT(*MMRESETSTREAM_FUNC
)(
253 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
254 IN MMDEVICE_TYPE DeviceType
,
255 IN BOOLEAN bStartReset
);
257 typedef struct _MMFUNCTION_TABLE
261 MMGETCAPS_FUNC GetCapabilities
;
262 MMGETWAVEOUTCAPS_FUNC GetWaveOutCapabilities
;
263 MMGETWAVEINCAPS_FUNC GetWaveInCapabilities
;
264 MMGETMIDIOUTCAPS_FUNC GetMidiOutCapabilities
;
265 MMGETMIDIINCAPS_FUNC GetMidiInCapabilities
;
271 MMWAVEQUERYFORMATSUPPORT_FUNC QueryWaveFormatSupport
;
272 MMWAVESETFORMAT_FUNC SetWaveFormat
;
274 MMMIXERQUERY_FUNC QueryMixerInfo
;
276 WAVE_COMMIT_FUNC CommitWaveBuffer
;
278 MMGETPOS_FUNC GetPos
;
279 MMSETSTATE_FUNC SetState
;
280 MMQUERYDEVICEINTERFACESTRING_FUNC GetDeviceInterfaceString
;
281 MMRESETSTREAM_FUNC ResetStream
;
284 //MMWAVEHEADER_FUNC PrepareWaveHeader;
285 //MMWAVEHEADER_FUNC UnprepareWaveHeader;
286 //MMWAVEHEADER_FUNC WriteWaveHeader;
288 //MMWAVEHEADER_FUNC SubmitWaveHeaderToDevice;
289 //MMBUFFER_FUNC CompleteBuffer;
290 } MMFUNCTION_TABLE
, *PMMFUNCTION_TABLE
;
294 typedef MMRESULT (*SOUND_THREAD_REQUEST_HANDLER
)(
295 IN
struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
,
298 typedef struct _SOUND_THREAD
312 SOUND_THREAD_REQUEST_HANDLER Handler
;
313 struct _SOUND_DEVICE_INSTANCE
* SoundDeviceInstance
;
317 } SOUND_THREAD
, *PSOUND_THREAD
;
319 typedef struct _SOUND_DEVICE
321 struct _SOUND_DEVICE
* Next
;
322 struct _SOUND_DEVICE_INSTANCE
* HeadInstance
;
323 struct _SOUND_DEVICE_INSTANCE
* TailInstance
;
325 PVOID Identifier
; /* Path for NT4 drivers */
327 MMFUNCTION_TABLE FunctionTable
;
328 } SOUND_DEVICE
, *PSOUND_DEVICE
;
330 typedef struct _SOUND_DEVICE_INSTANCE
332 struct _SOUND_DEVICE_INSTANCE
* Next
;
333 struct _SOUND_DEVICE
* Device
;
335 struct _SOUND_THREAD
* Thread
;
337 /* Stuff generously donated to us from WinMM */
342 DWORD_PTR ClientCallback
;
343 DWORD_PTR ClientCallbackInstanceData
;
346 /* DO NOT TOUCH THESE OUTSIDE OF THE SOUND THREAD */
350 PWAVEHDR HeadWaveHeader
;
355 PWAVEHDR TailWaveHeader
;
358 PWAVEHDR WaveLoopStart
;
359 //PWAVEHDR CurrentWaveHeader;
360 DWORD OutstandingBuffers
;
361 DWORD LoopsRemaining
;
364 WAVEFORMATEX WaveFormatEx
;
368 BOOL ResetInProgress
;
370 } SOUND_DEVICE_INSTANCE
, *PSOUND_DEVICE_INSTANCE
;
372 /* This lives in WAVEHDR.reserved */
373 typedef struct _WAVEHDR_EXTENSION
375 DWORD BytesCommitted
;
376 DWORD BytesCompleted
;
377 } WAVEHDR_EXTENSION
, *PWAVEHDR_EXTENSION
;
385 InitEntrypointMutexes(VOID
);
388 CleanupEntrypointMutexes(VOID
);
391 AcquireEntrypointMutex(
392 IN MMDEVICE_TYPE DeviceType
);
395 ReleaseEntrypointMutex(
396 IN MMDEVICE_TYPE DeviceType
);
405 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
407 IN DWORD_PTR Parameter
);
410 MmeGetSoundDeviceCapabilities(
411 IN MMDEVICE_TYPE DeviceType
,
413 IN PVOID Capabilities
,
414 IN DWORD CapabilitiesSize
);
418 IN MMDEVICE_TYPE DeviceType
,
420 IN LPWAVEOPENDESC OpenParameters
,
422 OUT DWORD_PTR
* PrivateHandle
);
426 IN DWORD_PTR PrivateHandle
);
430 IN MMDEVICE_TYPE DeviceType
,
432 IN DWORD_PTR PrivateHandle
,
437 MmeGetDeviceInterfaceString(
438 IN MMDEVICE_TYPE DeviceType
,
441 IN DWORD InterfaceLength
,
442 OUT DWORD
* InterfaceSize
);
447 IN DWORD_PTR PrivateHandle
,
451 #define MmePrepareWaveHeader(private_handle, header) \
452 PrepareWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
454 #define MmeUnprepareWaveHeader(private_handle, header) \
455 UnprepareWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
457 #define MmeWriteWaveHeader(private_handle, header) \
458 WriteWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
461 MmeResetWavePlayback(
462 IN DWORD_PTR PrivateHandle
);
470 GetSoundDeviceCapabilities(
471 IN PSOUND_DEVICE SoundDevice
,
473 OUT PVOID Capabilities
,
474 IN DWORD CapabilitiesSize
);
483 IN MMDEVICE_TYPE DeviceType
);
487 IN PSOUND_DEVICE SoundDevice
);
491 IN MMDEVICE_TYPE DeviceType
,
492 IN PVOID Identifier OPTIONAL
,
493 OUT PSOUND_DEVICE
* SoundDevice OPTIONAL
);
497 IN MMDEVICE_TYPE DeviceType
,
498 IN PSOUND_DEVICE SoundDevice
);
502 IN MMDEVICE_TYPE DeviceType
);
505 UnlistAllSoundDevices(VOID
);
509 IN MMDEVICE_TYPE DeviceType
,
510 IN DWORD DeviceIndex
,
511 OUT PSOUND_DEVICE
* Device
);
514 GetSoundDeviceIdentifier(
515 IN PSOUND_DEVICE SoundDevice
,
516 OUT PVOID
* Identifier
);
520 IN PSOUND_DEVICE SoundDevice
,
521 OUT PMMDEVICE_TYPE DeviceType
);
529 SetSoundDeviceFunctionTable(
530 IN PSOUND_DEVICE SoundDevice
,
531 IN PMMFUNCTION_TABLE FunctionTable
);
534 GetSoundDeviceFunctionTable(
535 IN PSOUND_DEVICE SoundDevice
,
536 OUT PMMFUNCTION_TABLE
* FunctionTable
);
544 IsValidSoundDeviceInstance(
545 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
);
548 CreateSoundDeviceInstance(
549 IN PSOUND_DEVICE SoundDevice
,
550 OUT PSOUND_DEVICE_INSTANCE
* SoundDeviceInstance
);
553 DestroySoundDeviceInstance(
554 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
);
557 DestroyAllSoundDeviceInstances(
558 IN PSOUND_DEVICE SoundDevice
);
561 GetSoundDeviceFromInstance(
562 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
563 OUT PSOUND_DEVICE
* SoundDevice
);
566 GetSoundDeviceInstanceHandle(
567 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
571 SetSoundDeviceInstanceMmeData(
572 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
574 IN DWORD_PTR ClientCallback
,
575 IN DWORD_PTR ClientCallbackData
,
585 OUT PSOUND_THREAD
* Thread
);
589 IN PSOUND_THREAD Thread
);
593 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
594 IN SOUND_THREAD_REQUEST_HANDLER RequestHandler
,
595 IN PVOID Parameter OPTIONAL
);
611 GetMemoryAllocationCount(VOID
);
618 Win32ErrorToMmResult(
622 TranslateInternalMmResult(
631 QueryWaveDeviceFormatSupport(
632 IN PSOUND_DEVICE SoundDevice
,
633 IN LPWAVEFORMATEX Format
,
634 IN DWORD FormatSize
);
638 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
640 IN LPWAVEFORMATEX Format
,
641 IN DWORD FormatSize
);
650 PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
655 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
660 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
665 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
670 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
680 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
);
684 IN DWORD dwErrorCode
,
685 IN DWORD dwNumberOfBytesTransferred
,
686 IN LPOVERLAPPED lpOverlapped
);
689 CommitWaveHeaderToKernelDevice(
690 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
692 IN WAVE_COMMIT_FUNC CommitFunction
);
695 WriteFileEx_Committer(
696 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
699 IN PSOUND_OVERLAPPED Overlap
,
700 IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine
);
704 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
);
707 InitiateSoundStreaming(
708 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
);
715 OpenKernelSoundDeviceByName(
721 OpenKernelSoundDevice(
722 IN PSOUND_DEVICE SoundDevice
,
727 CloseKernelSoundDevice(
731 SyncOverlappedDeviceIoControl(
732 IN HANDLE SoundDeviceInstance
,
733 IN DWORD IoControlCode
,
735 IN DWORD InBufferSize
,
736 OUT LPVOID OutBuffer
,
737 IN DWORD OutBufferSize
,
738 OUT LPDWORD BytesTransferred OPTIONAL
);