ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

mmewrap.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.