Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmmewrap.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Sound System "MME Buddy" Library 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: lib/drivers/sound/mmebuddy/mmewrap.c 00005 * 00006 * PURPOSE: Interface between MME functions and MME Buddy's own. 00007 * 00008 * PROGRAMMERS: Andrew Greenwood (silverblade@reactos.org) 00009 */ 00010 00011 #include "precomp.h" 00012 00013 00014 /* 00015 Sets the device into running or stopped state 00016 */ 00017 00018 MMRESULT 00019 MmeSetState( 00020 IN DWORD_PTR PrivateHandle, 00021 IN BOOL bStart) 00022 { 00023 MMRESULT Result; 00024 PMMFUNCTION_TABLE FunctionTable; 00025 PSOUND_DEVICE SoundDevice; 00026 PSOUND_DEVICE_INSTANCE SoundDeviceInstance; 00027 BOOL OldState; 00028 00029 VALIDATE_MMSYS_PARAMETER( PrivateHandle ); 00030 SoundDeviceInstance = (PSOUND_DEVICE_INSTANCE) PrivateHandle; 00031 00032 VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) ); 00033 00034 Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice); 00035 if ( ! MMSUCCESS(Result) ) 00036 return TranslateInternalMmResult(Result); 00037 00038 /* Get the function table, and validate it */ 00039 Result = GetSoundDeviceFunctionTable(SoundDevice, &FunctionTable); 00040 if ( ! MMSUCCESS(Result) ) 00041 return TranslateInternalMmResult(Result); 00042 00043 SND_ASSERT( FunctionTable->SetState ); 00044 if ( FunctionTable->SetState == NULL ) 00045 { 00046 /* FIXME */ 00047 return MMSYSERR_NOTSUPPORTED; 00048 } 00049 /* Try change state */ 00050 Result = FunctionTable->SetState(SoundDeviceInstance, bStart); 00051 00052 if ( MMSUCCESS(Result) ) 00053 { 00054 /* Get old audio stream state */ 00055 OldState = SoundDeviceInstance->bPaused; 00056 00057 /* Store audio stream pause state */ 00058 SoundDeviceInstance->bPaused = !bStart; 00059 00060 if (SoundDeviceInstance->bPaused == FALSE && OldState == TRUE) 00061 { 00062 InitiateSoundStreaming(SoundDeviceInstance); 00063 } 00064 } 00065 00066 return Result; 00067 } 00068 00069 /* 00070 Call the client application when something interesting happens (MME API 00071 defines "interesting things" as device open, close, and buffer 00072 completion.) 00073 */ 00074 VOID 00075 NotifyMmeClient( 00076 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, 00077 IN UINT Message, 00078 IN DWORD_PTR Parameter) 00079 { 00080 SND_ASSERT( SoundDeviceInstance ); 00081 00082 SND_TRACE(L"MME client callback - message %d, parameter %d\n", 00083 (int) Message, 00084 (int) Parameter); 00085 00086 if ( SoundDeviceInstance->WinMM.ClientCallback ) 00087 { 00088 DriverCallback(SoundDeviceInstance->WinMM.ClientCallback, 00089 HIWORD(SoundDeviceInstance->WinMM.Flags), 00090 SoundDeviceInstance->WinMM.Handle, 00091 Message, 00092 SoundDeviceInstance->WinMM.ClientCallbackInstanceData, 00093 Parameter, 00094 0); 00095 } 00096 } 00097 00098 /* 00099 This is a helper function to alleviate some of the repetition involved with 00100 implementing the various MME message functions. 00101 */ 00102 MMRESULT 00103 MmeGetSoundDeviceCapabilities( 00104 IN MMDEVICE_TYPE DeviceType, 00105 IN DWORD DeviceId, 00106 IN PVOID Capabilities, 00107 IN DWORD CapabilitiesSize) 00108 { 00109 PSOUND_DEVICE SoundDevice; 00110 MMRESULT Result; 00111 00112 SND_TRACE(L"MME *_GETCAPS for device %d of type %d\n", DeviceId, DeviceType); 00113 00114 /* FIXME: Validate device ID */ 00115 VALIDATE_MMSYS_PARAMETER( Capabilities ); 00116 VALIDATE_MMSYS_PARAMETER( IS_VALID_SOUND_DEVICE_TYPE(DeviceType) ); 00117 00118 /* Our parameter checks are done elsewhere */ 00119 00120 Result = GetSoundDevice(DeviceType, DeviceId, &SoundDevice); 00121 00122 if ( ! MMSUCCESS(Result) ) 00123 return Result; 00124 00125 return GetSoundDeviceCapabilities(SoundDevice, 00126 DeviceId, 00127 Capabilities, 00128 CapabilitiesSize); 00129 } 00130 00131 MMRESULT 00132 MmeOpenDevice( 00133 IN MMDEVICE_TYPE DeviceType, 00134 IN UINT DeviceId, 00135 IN LPWAVEOPENDESC OpenParameters, 00136 IN DWORD Flags, 00137 OUT DWORD_PTR* PrivateHandle) 00138 { 00139 MMRESULT Result; 00140 UINT Message; 00141 PSOUND_DEVICE SoundDevice; 00142 PSOUND_DEVICE_INSTANCE SoundDeviceInstance; 00143 LPWAVEFORMATEX Format = NULL; 00144 00145 SND_TRACE(L"Opening device"); 00146 00147 VALIDATE_MMSYS_PARAMETER( IS_WAVE_DEVICE_TYPE(DeviceType) || IS_MIXER_DEVICE_TYPE(DeviceType) || IS_MIDI_DEVICE_TYPE(DeviceType) ); /* FIXME? wave in too? */ 00148 VALIDATE_MMSYS_PARAMETER( OpenParameters ); 00149 00150 Result = GetSoundDevice(DeviceType, DeviceId, &SoundDevice); 00151 if ( ! MMSUCCESS(Result) ) 00152 return TranslateInternalMmResult(Result); 00153 00154 if (DeviceType == WAVE_IN_DEVICE_TYPE || DeviceType == WAVE_OUT_DEVICE_TYPE) 00155 { 00156 Format = OpenParameters->lpFormat; 00157 00158 /* Does this device support the format? */ 00159 Result = QueryWaveDeviceFormatSupport(SoundDevice, Format, sizeof(WAVEFORMATEX)); 00160 if ( ! MMSUCCESS(Result) ) 00161 { 00162 SND_ERR(L"Format not supported\n"); 00163 return TranslateInternalMmResult(Result); 00164 } 00165 00166 /* If the caller just wanted to know if a format is supported, end here */ 00167 if ( Flags & WAVE_FORMAT_QUERY ) 00168 return MMSYSERR_NOERROR; 00169 } 00170 00171 /* Check that winmm gave us a private handle to fill */ 00172 VALIDATE_MMSYS_PARAMETER( PrivateHandle ); 00173 00174 /* Create a sound device instance and open the sound device */ 00175 Result = CreateSoundDeviceInstance(SoundDevice, &SoundDeviceInstance); 00176 if ( ! MMSUCCESS(Result) ) 00177 return TranslateInternalMmResult(Result); 00178 00179 Result = SetWaveDeviceFormat(SoundDeviceInstance, DeviceId, Format, sizeof(WAVEFORMATEX)); 00180 if ( ! MMSUCCESS(Result) ) 00181 { 00182 /* TODO: Destroy sound instance */ 00183 return TranslateInternalMmResult(Result); 00184 } 00185 00186 /* Store the device instance pointer in the private handle */ 00187 *PrivateHandle = (DWORD_PTR)SoundDeviceInstance; 00188 00189 /* Store the additional information we were given - FIXME: Need flags! */ 00190 SetSoundDeviceInstanceMmeData(SoundDeviceInstance, 00191 (HDRVR)OpenParameters->hWave, /* works because LPMIXEROPENDESC/etc has also the handle as first member */ 00192 OpenParameters->dwCallback, 00193 OpenParameters->dwInstance, 00194 Flags); 00195 00196 if (DeviceType == WAVE_OUT_DEVICE_TYPE || DeviceType == WAVE_IN_DEVICE_TYPE || 00197 DeviceType == MIDI_OUT_DEVICE_TYPE || DeviceType == MIDI_IN_DEVICE_TYPE) 00198 { 00199 /* Let the application know the device is open */ 00200 00201 if (DeviceType == WAVE_OUT_DEVICE_TYPE) 00202 Message = WOM_OPEN; 00203 else if (DeviceType == WAVE_IN_DEVICE_TYPE) 00204 Message = WIM_OPEN; 00205 else if (DeviceType == MIDI_IN_DEVICE_TYPE) 00206 Message = MIM_OPEN; 00207 else 00208 Message = MOM_OPEN; 00209 00210 ReleaseEntrypointMutex(DeviceType); 00211 00212 NotifyMmeClient(SoundDeviceInstance, 00213 Message, 00214 0); 00215 00216 AcquireEntrypointMutex(DeviceType); 00217 } 00218 00219 SND_TRACE(L"device now open\n"); 00220 00221 return MMSYSERR_NOERROR; 00222 } 00223 00224 MMRESULT 00225 MmeCloseDevice( 00226 IN DWORD_PTR PrivateHandle) 00227 { 00228 MMRESULT Result; 00229 PSOUND_DEVICE_INSTANCE SoundDeviceInstance; 00230 PSOUND_DEVICE SoundDevice; 00231 MMDEVICE_TYPE DeviceType; 00232 UINT Message = 0; 00233 00234 SND_TRACE(L"Closing wave device (WIDM_CLOSE / WODM_CLOSE)\n"); 00235 00236 VALIDATE_MMSYS_PARAMETER( PrivateHandle ); 00237 SoundDeviceInstance = (PSOUND_DEVICE_INSTANCE) PrivateHandle; 00238 00239 if ( ! IsValidSoundDeviceInstance(SoundDeviceInstance) ) 00240 return MMSYSERR_INVALHANDLE; 00241 00242 Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice); 00243 if ( ! MMSUCCESS(Result) ) 00244 return TranslateInternalMmResult(Result); 00245 00246 Result = GetSoundDeviceType(SoundDevice, &DeviceType); 00247 if ( ! MMSUCCESS(Result) ) 00248 return TranslateInternalMmResult(Result); 00249 00250 00251 /* TODO: Check device is stopped! */ 00252 00253 00254 if (DeviceType != MIXER_DEVICE_TYPE) 00255 { 00256 ReleaseEntrypointMutex(DeviceType); 00257 00258 if (DeviceType == WAVE_OUT_DEVICE_TYPE) 00259 Message = WOM_CLOSE; 00260 else if (DeviceType == WAVE_IN_DEVICE_TYPE) 00261 Message = WIM_CLOSE; 00262 else if (DeviceType == MIDI_IN_DEVICE_TYPE) 00263 Message = MIM_CLOSE; 00264 else if (DeviceType == MIDI_OUT_DEVICE_TYPE) 00265 Message = MOM_CLOSE; 00266 00267 /* TODO: Work with MIDI devices too */ 00268 NotifyMmeClient(SoundDeviceInstance, 00269 Message, 00270 0); 00271 AcquireEntrypointMutex(DeviceType); 00272 } 00273 00274 Result = DestroySoundDeviceInstance(SoundDeviceInstance); 00275 00276 return Result; 00277 } 00278 00279 MMRESULT 00280 MmeResetWavePlayback( 00281 IN DWORD_PTR PrivateHandle) 00282 { 00283 PSOUND_DEVICE_INSTANCE SoundDeviceInstance; 00284 00285 SND_TRACE(L"Resetting wave device (WODM_RESET)\n"); 00286 00287 VALIDATE_MMSYS_PARAMETER( PrivateHandle ); 00288 SoundDeviceInstance = (PSOUND_DEVICE_INSTANCE) PrivateHandle; 00289 00290 return StopStreaming(SoundDeviceInstance); 00291 } 00292 00293 MMRESULT 00294 MmeGetDeviceInterfaceString( 00295 IN MMDEVICE_TYPE DeviceType, 00296 IN DWORD DeviceId, 00297 IN LPWSTR Interface, 00298 IN DWORD InterfaceLength, 00299 OUT DWORD * InterfaceSize) 00300 { 00301 MMRESULT Result; 00302 PSOUND_DEVICE SoundDevice; 00303 PMMFUNCTION_TABLE FunctionTable; 00304 00305 Result = GetSoundDevice(DeviceType, DeviceId, &SoundDevice); 00306 if ( ! MMSUCCESS(Result) ) 00307 return TranslateInternalMmResult(Result); 00308 00309 Result = GetSoundDeviceFunctionTable(SoundDevice, &FunctionTable); 00310 if ( ! MMSUCCESS(Result) ) 00311 return TranslateInternalMmResult(Result); 00312 00313 if ( FunctionTable->GetDeviceInterfaceString == NULL ) 00314 { 00315 /* querying device interface string / size not supported */ 00316 return MMSYSERR_NOTSUPPORTED; 00317 } 00318 00319 /* Call the driver */ 00320 Result = FunctionTable->GetDeviceInterfaceString(DeviceType, DeviceId, Interface, InterfaceLength, InterfaceSize); 00321 00322 return Result; 00323 } 00324 00325 00326 MMRESULT 00327 MmeGetPosition( 00328 IN MMDEVICE_TYPE DeviceType, 00329 IN DWORD DeviceId, 00330 IN DWORD_PTR PrivateHandle, 00331 IN MMTIME* Time, 00332 IN DWORD Size) 00333 { 00334 MMRESULT Result; 00335 PSOUND_DEVICE_INSTANCE SoundDeviceInstance; 00336 PSOUND_DEVICE SoundDevice; 00337 PMMFUNCTION_TABLE FunctionTable; 00338 00339 VALIDATE_MMSYS_PARAMETER( PrivateHandle ); 00340 SoundDeviceInstance = (PSOUND_DEVICE_INSTANCE) PrivateHandle; 00341 00342 if ( ! IsValidSoundDeviceInstance(SoundDeviceInstance) ) 00343 return MMSYSERR_INVALHANDLE; 00344 00345 Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice); 00346 if ( ! MMSUCCESS(Result) ) 00347 return TranslateInternalMmResult(Result); 00348 00349 if ( Size != sizeof(MMTIME) ) 00350 return MMSYSERR_INVALPARAM; 00351 00352 Result = GetSoundDeviceFunctionTable(SoundDevice, &FunctionTable); 00353 if ( ! MMSUCCESS(Result) ) 00354 return TranslateInternalMmResult(Result); 00355 00356 if ( FunctionTable->GetPos == NULL ) 00357 { 00358 /* This indicates bad practice, really! If you can open, why not close?! */ 00359 return MMSYSERR_NOTSUPPORTED; 00360 } 00361 00362 /* Call the driver */ 00363 Result = FunctionTable->GetPos(SoundDeviceInstance, Time); 00364 00365 return Result; 00366 } 00367 Generated on Fri May 25 2012 04:34:39 for ReactOS by
1.7.6.1
|