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
;
188 DWORD OriginalBufferSize
;
189 LPOVERLAPPED_COMPLETION_ROUTINE OriginalCompletionRoutine
;
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
;
367 } SOUND_DEVICE_INSTANCE
, *PSOUND_DEVICE_INSTANCE
;
369 /* This lives in WAVEHDR.reserved */
370 typedef struct _WAVEHDR_EXTENSION
372 DWORD BytesCommitted
;
373 DWORD BytesCompleted
;
374 } WAVEHDR_EXTENSION
, *PWAVEHDR_EXTENSION
;
382 InitEntrypointMutexes();
385 CleanupEntrypointMutexes();
388 AcquireEntrypointMutex(
389 IN MMDEVICE_TYPE DeviceType
);
392 ReleaseEntrypointMutex(
393 IN MMDEVICE_TYPE DeviceType
);
402 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
407 MmeGetSoundDeviceCapabilities(
408 IN MMDEVICE_TYPE DeviceType
,
410 IN PVOID Capabilities
,
411 IN DWORD CapabilitiesSize
);
415 IN MMDEVICE_TYPE DeviceType
,
417 IN LPWAVEOPENDESC OpenParameters
,
419 OUT DWORD
* PrivateHandle
);
423 IN DWORD PrivateHandle
);
427 IN MMDEVICE_TYPE DeviceType
,
429 IN DWORD PrivateHandle
,
434 MmeGetDeviceInterfaceString(
435 IN MMDEVICE_TYPE DeviceType
,
438 IN DWORD InterfaceLength
,
439 OUT DWORD
* InterfaceSize
);
444 IN DWORD PrivateHandle
,
448 #define MmePrepareWaveHeader(private_handle, header) \
449 PrepareWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
451 #define MmeUnprepareWaveHeader(private_handle, header) \
452 UnprepareWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
454 #define MmeWriteWaveHeader(private_handle, header) \
455 WriteWaveHeader((PSOUND_DEVICE_INSTANCE)private_handle, (PWAVEHDR)header)
458 MmeResetWavePlayback(
459 IN DWORD PrivateHandle
);
467 GetSoundDeviceCapabilities(
468 IN PSOUND_DEVICE SoundDevice
,
470 OUT PVOID Capabilities
,
471 IN DWORD CapabilitiesSize
);
480 IN MMDEVICE_TYPE DeviceType
);
484 IN PSOUND_DEVICE SoundDevice
);
488 IN MMDEVICE_TYPE DeviceType
,
489 IN PVOID Identifier OPTIONAL
,
490 OUT PSOUND_DEVICE
* SoundDevice OPTIONAL
);
494 IN MMDEVICE_TYPE DeviceType
,
495 IN PSOUND_DEVICE SoundDevice
);
499 IN MMDEVICE_TYPE DeviceType
);
502 UnlistAllSoundDevices();
506 IN MMDEVICE_TYPE DeviceType
,
507 IN DWORD DeviceIndex
,
508 OUT PSOUND_DEVICE
* Device
);
511 GetSoundDeviceIdentifier(
512 IN PSOUND_DEVICE SoundDevice
,
513 OUT PVOID
* Identifier
);
517 IN PSOUND_DEVICE SoundDevice
,
518 OUT PMMDEVICE_TYPE DeviceType
);
526 SetSoundDeviceFunctionTable(
527 IN PSOUND_DEVICE SoundDevice
,
528 IN PMMFUNCTION_TABLE FunctionTable
);
531 GetSoundDeviceFunctionTable(
532 IN PSOUND_DEVICE SoundDevice
,
533 OUT PMMFUNCTION_TABLE
* FunctionTable
);
541 IsValidSoundDeviceInstance(
542 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
);
545 CreateSoundDeviceInstance(
546 IN PSOUND_DEVICE SoundDevice
,
547 OUT PSOUND_DEVICE_INSTANCE
* SoundDeviceInstance
);
550 DestroySoundDeviceInstance(
551 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
);
554 DestroyAllSoundDeviceInstances(
555 IN PSOUND_DEVICE SoundDevice
);
558 GetSoundDeviceFromInstance(
559 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
560 OUT PSOUND_DEVICE
* SoundDevice
);
563 GetSoundDeviceInstanceHandle(
564 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
568 SetSoundDeviceInstanceMmeData(
569 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
571 IN DWORD_PTR ClientCallback
,
572 IN DWORD_PTR ClientCallbackData
,
582 OUT PSOUND_THREAD
* Thread
);
586 IN PSOUND_THREAD Thread
);
590 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
591 IN SOUND_THREAD_REQUEST_HANDLER RequestHandler
,
592 IN PVOID Parameter OPTIONAL
);
608 GetMemoryAllocationCount();
615 Win32ErrorToMmResult(
619 TranslateInternalMmResult(
628 QueryWaveDeviceFormatSupport(
629 IN PSOUND_DEVICE SoundDevice
,
630 IN LPWAVEFORMATEX Format
,
631 IN DWORD FormatSize
);
635 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
637 IN LPWAVEFORMATEX Format
,
638 IN DWORD FormatSize
);
647 PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
652 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
657 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
662 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
667 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
677 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
);
681 IN DWORD dwErrorCode
,
682 IN DWORD dwNumberOfBytesTransferred
,
683 IN LPOVERLAPPED lpOverlapped
);
686 CommitWaveHeaderToKernelDevice(
687 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
689 IN WAVE_COMMIT_FUNC CommitFunction
);
692 WriteFileEx_Committer(
693 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
696 IN PSOUND_OVERLAPPED Overlap
,
697 IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine
);
701 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
);
709 OpenKernelSoundDeviceByName(
715 OpenKernelSoundDevice(
716 IN PSOUND_DEVICE SoundDevice
,
721 CloseKernelSoundDevice(
725 SyncOverlappedDeviceIoControl(
726 IN HANDLE SoundDeviceInstance
,
727 IN DWORD IoControlCode
,
729 IN DWORD InBufferSize
,
730 OUT LPVOID OutBuffer
,
731 IN DWORD OutBufferSize
,
732 OUT LPDWORD BytesTransferred OPTIONAL
);