2 * PROJECT: ReactOS Sound System "MME Buddy" Library
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: lib/drivers/sound/mmebuddy/mmewrap.c
6 * PURPOSE: Interface between MME functions and MME Buddy's own.
8 * PROGRAMMERS: Andrew Greenwood (silverblade@reactos.org)
19 Call the client application when something interesting happens (MME API
20 defines "interesting things" as device open, close, and buffer
25 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance
,
27 IN DWORD_PTR Parameter
)
29 SND_ASSERT( SoundDeviceInstance
);
31 SND_TRACE(L
"MME client callback - message %d, parameter %d\n",
35 if ( SoundDeviceInstance
->WinMM
.ClientCallback
)
37 DriverCallback(SoundDeviceInstance
->WinMM
.ClientCallback
,
38 HIWORD(SoundDeviceInstance
->WinMM
.Flags
),
39 SoundDeviceInstance
->WinMM
.Handle
,
41 SoundDeviceInstance
->WinMM
.ClientCallbackInstanceData
,
48 This is a helper function to alleviate some of the repetition involved with
49 implementing the various MME message functions.
52 MmeGetSoundDeviceCapabilities(
53 IN MMDEVICE_TYPE DeviceType
,
55 IN DWORD_PTR Capabilities
,
56 IN DWORD CapabilitiesSize
)
58 PSOUND_DEVICE SoundDevice
;
61 SND_TRACE(L
"MME *_GETCAPS for device %d of type %d\n", DeviceId
, DeviceType
);
63 /* FIXME: Validate device ID */
64 VALIDATE_MMSYS_PARAMETER( Capabilities
);
65 VALIDATE_MMSYS_PARAMETER( IS_VALID_SOUND_DEVICE_TYPE(DeviceType
) );
67 /* Our parameter checks are done elsewhere */
69 Result
= GetSoundDevice(DeviceType
, DeviceId
, &SoundDevice
);
71 if ( ! MMSUCCESS(Result
) )
74 return GetSoundDeviceCapabilities(SoundDevice
,
82 IN MMDEVICE_TYPE DeviceType
,
84 IN LPWAVEOPENDESC OpenParameters
,
86 OUT SIZE_T
* PrivateHandle
)
90 PSOUND_DEVICE SoundDevice
;
91 PSOUND_DEVICE_INSTANCE SoundDeviceInstance
;
92 LPWAVEFORMATEX Format
;
94 SND_TRACE(L
"Opening wave device (WIDM_OPEN / WODM_OPEN)");
96 VALIDATE_MMSYS_PARAMETER( IS_WAVE_DEVICE_TYPE(DeviceType
) ); /* FIXME? wave in too? */
97 VALIDATE_MMSYS_PARAMETER( OpenParameters
);
99 Format
= OpenParameters
->lpFormat
;
101 Result
= GetSoundDevice(DeviceType
, DeviceId
, &SoundDevice
);
102 if ( ! MMSUCCESS(Result
) )
103 return TranslateInternalMmResult(Result
);
105 /* Does this device support the format? */
106 Result
= QueryWaveDeviceFormatSupport(SoundDevice
, Format
, sizeof(WAVEFORMATEX
));
107 if ( ! MMSUCCESS(Result
) )
109 SND_ERR(L
"Format not supported\n");
110 return TranslateInternalMmResult(Result
);
113 /* If the caller just wanted to know if a format is supported, end here */
114 if ( Flags
& WAVE_FORMAT_QUERY
)
115 return MMSYSERR_NOERROR
;
117 /* Check that winmm gave us a private handle to fill */
118 VALIDATE_MMSYS_PARAMETER( PrivateHandle
);
120 /* Create a sound device instance and open the sound device */
121 Result
= CreateSoundDeviceInstance(SoundDevice
, &SoundDeviceInstance
);
122 if ( ! MMSUCCESS(Result
) )
123 return TranslateInternalMmResult(Result
);
125 Result
= SetWaveDeviceFormat(SoundDeviceInstance
, DeviceId
, Format
, sizeof(WAVEFORMATEX
));
126 if ( ! MMSUCCESS(Result
) )
128 /* TODO: Destroy sound instance */
129 return TranslateInternalMmResult(Result
);
132 /* Store the device instance pointer in the private handle */
133 *PrivateHandle
= (DWORD_PTR
)SoundDeviceInstance
;
135 /* Store the additional information we were given - FIXME: Need flags! */
136 SetSoundDeviceInstanceMmeData(SoundDeviceInstance
,
137 (HDRVR
)OpenParameters
->hWave
,
138 OpenParameters
->dwCallback
,
139 OpenParameters
->dwInstance
,
142 /* Let the application know the device is open */
143 ReleaseEntrypointMutex(DeviceType
);
144 NotifyMmeClient(SoundDeviceInstance
,
145 DeviceType
== WAVE_OUT_DEVICE_TYPE
? WOM_OPEN
: WIM_OPEN
,
148 AcquireEntrypointMutex(DeviceType
);
150 SND_TRACE(L
"Wave device now open\n");
152 return MMSYSERR_NOERROR
;
157 IN SIZE_T PrivateHandle
)
160 PSOUND_DEVICE_INSTANCE SoundDeviceInstance
;
161 PSOUND_DEVICE SoundDevice
;
162 MMDEVICE_TYPE DeviceType
;
164 SND_TRACE(L
"Closing wave device (WIDM_CLOSE / WODM_CLOSE)\n");
166 VALIDATE_MMSYS_PARAMETER( PrivateHandle
);
167 SoundDeviceInstance
= (PSOUND_DEVICE_INSTANCE
) PrivateHandle
;
169 if ( ! IsValidSoundDeviceInstance(SoundDeviceInstance
) )
170 return MMSYSERR_INVALHANDLE
;
172 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
173 if ( ! MMSUCCESS(Result
) )
174 return TranslateInternalMmResult(Result
);
176 Result
= GetSoundDeviceType(SoundDevice
, &DeviceType
);
177 if ( ! MMSUCCESS(Result
) )
178 return TranslateInternalMmResult(Result
);
181 /* TODO: Check device is stopped! */
183 ReleaseEntrypointMutex(DeviceType
);
184 /* TODO: Work with MIDI devices too */
185 NotifyMmeClient(SoundDeviceInstance
,
186 DeviceType
== WAVE_OUT_DEVICE_TYPE
? WOM_CLOSE
: WIM_CLOSE
,
188 AcquireEntrypointMutex(DeviceType
);
190 Result
= DestroySoundDeviceInstance(SoundDeviceInstance
);
196 MmeResetWavePlayback(
197 IN SIZE_T PrivateHandle
)
199 PSOUND_DEVICE_INSTANCE SoundDeviceInstance
;
201 SND_TRACE(L
"Resetting wave device (WODM_RESET)\n");
203 VALIDATE_MMSYS_PARAMETER( PrivateHandle
);
204 SoundDeviceInstance
= (PSOUND_DEVICE_INSTANCE
) PrivateHandle
;
206 return StopStreaming(SoundDeviceInstance
);
211 IN MMDEVICE_TYPE DeviceType
,
213 IN DWORD PrivateHandle
,
218 PSOUND_DEVICE_INSTANCE SoundDeviceInstance
;
219 PSOUND_DEVICE SoundDevice
;
220 PMMFUNCTION_TABLE FunctionTable
;
222 VALIDATE_MMSYS_PARAMETER( PrivateHandle
);
223 SoundDeviceInstance
= (PSOUND_DEVICE_INSTANCE
) PrivateHandle
;
225 if ( ! IsValidSoundDeviceInstance(SoundDeviceInstance
) )
226 return MMSYSERR_INVALHANDLE
;
228 Result
= GetSoundDeviceFromInstance(SoundDeviceInstance
, &SoundDevice
);
229 if ( ! MMSUCCESS(Result
) )
230 return TranslateInternalMmResult(Result
);
232 if ( Size
!= sizeof(MMTIME
) )
233 return MMSYSERR_INVALPARAM
;
235 Result
= GetSoundDeviceFunctionTable(SoundDevice
, &FunctionTable
);
236 if ( ! MMSUCCESS(Result
) )
237 return TranslateInternalMmResult(Result
);
239 if ( FunctionTable
->GetPos
== NULL
)
241 /* This indicates bad practice, really! If you can open, why not close?! */
242 return MMSYSERR_NOTSUPPORTED
;
245 /* Call the driver */
246 Result
= FunctionTable
->GetPos(SoundDeviceInstance
, Time
);