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 {} 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
;
369 } SOUND_DEVICE_INSTANCE
, *PSOUND_DEVICE_INSTANCE
;
371 /* This lives in WAVEHDR.reserved */
372 typedef struct _WAVEHDR_EXTENSION
374 DWORD BytesCommitted
;
375 DWORD BytesCompleted
;
376 } WAVEHDR_EXTENSION
, *PWAVEHDR_EXTENSION
;
384 InitEntrypointMutexes();
387 CleanupEntrypointMutexes();
390 AcquireEntrypointMutex(
391 IN MMDEVICE_TYPE DeviceType
);
394 ReleaseEntrypointMutex(
395 IN MMDEVICE_TYPE DeviceType
);
404 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
406 IN DWORD_PTR Parameter
);
409 MmeGetSoundDeviceCapabilities(
410 IN MMDEVICE_TYPE DeviceType
,
412 IN PVOID Capabilities
,
413 IN DWORD CapabilitiesSize
);
417 IN MMDEVICE_TYPE DeviceType
,
419 IN LPWAVEOPENDESC OpenParameters
,
421 OUT DWORD_PTR
* PrivateHandle
);
425 IN DWORD_PTR PrivateHandle
);
429 IN MMDEVICE_TYPE DeviceType
,
431 IN DWORD_PTR PrivateHandle
,
436 MmeGetDeviceInterfaceString(
437 IN MMDEVICE_TYPE DeviceType
,
440 IN DWORD InterfaceLength
,
441 OUT DWORD
* InterfaceSize
);
446 IN DWORD_PTR PrivateHandle
,
450 #define MmePrepareWaveHeader(private_handle, header) \
451 PrepareWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
453 #define MmeUnprepareWaveHeader(private_handle, header) \
454 UnprepareWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
456 #define MmeWriteWaveHeader(private_handle, header) \
457 WriteWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
460 MmeResetWavePlayback(
461 IN DWORD_PTR PrivateHandle
);
469 GetSoundDeviceCapabilities(
470 IN PSOUND_DEVICE SoundDevice
,
472 OUT PVOID Capabilities
,
473 IN DWORD CapabilitiesSize
);
482 IN MMDEVICE_TYPE DeviceType
);
486 IN PSOUND_DEVICE SoundDevice
);
490 IN MMDEVICE_TYPE DeviceType
,
491 IN PVOID Identifier OPTIONAL
,
492 OUT PSOUND_DEVICE
* SoundDevice OPTIONAL
);
496 IN MMDEVICE_TYPE DeviceType
,
497 IN PSOUND_DEVICE SoundDevice
);
501 IN MMDEVICE_TYPE DeviceType
);
504 UnlistAllSoundDevices();
508 IN MMDEVICE_TYPE DeviceType
,
509 IN DWORD DeviceIndex
,
510 OUT PSOUND_DEVICE
* Device
);
513 GetSoundDeviceIdentifier(
514 IN PSOUND_DEVICE SoundDevice
,
515 OUT PVOID
* Identifier
);
519 IN PSOUND_DEVICE SoundDevice
,
520 OUT PMMDEVICE_TYPE DeviceType
);
528 SetSoundDeviceFunctionTable(
529 IN PSOUND_DEVICE SoundDevice
,
530 IN PMMFUNCTION_TABLE FunctionTable
);
533 GetSoundDeviceFunctionTable(
534 IN PSOUND_DEVICE SoundDevice
,
535 OUT PMMFUNCTION_TABLE
* FunctionTable
);
543 IsValidSoundDeviceInstance(
544 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
);
547 CreateSoundDeviceInstance(
548 IN PSOUND_DEVICE SoundDevice
,
549 OUT PSOUND_DEVICE_INSTANCE
* SoundDeviceInstance
);
552 DestroySoundDeviceInstance(
553 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
);
556 DestroyAllSoundDeviceInstances(
557 IN PSOUND_DEVICE SoundDevice
);
560 GetSoundDeviceFromInstance(
561 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
562 OUT PSOUND_DEVICE
* SoundDevice
);
565 GetSoundDeviceInstanceHandle(
566 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
570 SetSoundDeviceInstanceMmeData(
571 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
573 IN DWORD_PTR ClientCallback
,
574 IN DWORD_PTR ClientCallbackData
,
584 OUT PSOUND_THREAD
* Thread
);
588 IN PSOUND_THREAD Thread
);
592 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
593 IN SOUND_THREAD_REQUEST_HANDLER RequestHandler
,
594 IN PVOID Parameter OPTIONAL
);
610 GetMemoryAllocationCount();
617 Win32ErrorToMmResult(
621 TranslateInternalMmResult(
630 QueryWaveDeviceFormatSupport(
631 IN PSOUND_DEVICE SoundDevice
,
632 IN LPWAVEFORMATEX Format
,
633 IN DWORD FormatSize
);
637 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
639 IN LPWAVEFORMATEX Format
,
640 IN DWORD FormatSize
);
649 PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
654 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
659 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
664 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
669 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
679 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
);
683 IN DWORD dwErrorCode
,
684 IN DWORD dwNumberOfBytesTransferred
,
685 IN LPOVERLAPPED lpOverlapped
);
688 CommitWaveHeaderToKernelDevice(
689 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
691 IN WAVE_COMMIT_FUNC CommitFunction
);
694 WriteFileEx_Committer(
695 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
698 IN PSOUND_OVERLAPPED Overlap
,
699 IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine
);
703 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
);
711 OpenKernelSoundDeviceByName(
717 OpenKernelSoundDevice(
718 IN PSOUND_DEVICE SoundDevice
,
723 CloseKernelSoundDevice(
727 SyncOverlappedDeviceIoControl(
728 IN HANDLE SoundDeviceInstance
,
729 IN DWORD IoControlCode
,
731 IN DWORD InBufferSize
,
732 OUT LPVOID OutBuffer
,
733 IN DWORD OutBufferSize
,
734 OUT LPDWORD BytesTransferred OPTIONAL
);