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

deviceinstance.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/deviceinstance.c
00005  *
00006  * PURPOSE:     Manages instances of sound devices.
00007  *
00008  * PROGRAMMERS: Andrew Greenwood (silverblade@reactos.org)
00009 */
00010 
00011 #include "precomp.h"
00012 
00013 /*
00014     Restrain ourselves from flooding the kernel device!
00015 */
00016 
00017 #define SOUND_KERNEL_BUFFER_COUNT       10
00018 #define SOUND_KERNEL_BUFFER_SIZE        16384
00019 
00020 MMRESULT
00021 AllocateSoundDeviceInstance(
00022     OUT PSOUND_DEVICE_INSTANCE* SoundDeviceInstance)
00023 {
00024     PSOUND_DEVICE_INSTANCE NewInstance;
00025 
00026     VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance );
00027 
00028     /* Allocate memory for the new instance */
00029     NewInstance = AllocateStruct(SOUND_DEVICE_INSTANCE);
00030 
00031     if ( ! NewInstance )
00032         return MMSYSERR_NOMEM;
00033 
00034     /* Use default frame size */
00035     NewInstance->FrameSize = SOUND_KERNEL_BUFFER_SIZE;
00036     /* Use default buffer count */
00037     NewInstance->BufferCount = SOUND_KERNEL_BUFFER_COUNT;
00038 
00039     /* Provide the caller with the new instance pointer */
00040     *SoundDeviceInstance = NewInstance;
00041 
00042     return MMSYSERR_NOERROR;
00043 }
00044 
00045 VOID
00046 FreeSoundDeviceInstance(
00047     IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance)
00048 {
00049     /*
00050         Device is marked as invalid by now, but we can still do some sanity
00051         checking.
00052     */
00053     SND_ASSERT( SoundDeviceInstance->Thread == NULL );
00054 
00055     ZeroMemory(SoundDeviceInstance, sizeof(SOUND_DEVICE_INSTANCE));
00056     FreeMemory(SoundDeviceInstance);
00057 }
00058 
00059 BOOLEAN
00060 IsValidSoundDeviceInstance(
00061     IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance)
00062 {
00063     PSOUND_DEVICE SoundDevice;
00064     PSOUND_DEVICE_INSTANCE CurrentInstance;
00065 
00066     if ( ! SoundDeviceInstance )
00067         return FALSE;
00068 
00069     /* GetSoundDeviceFromInstance would send us into a recursive loop... */
00070     SoundDevice = SoundDeviceInstance->Device;
00071     SND_ASSERT(SoundDevice);
00072 
00073     CurrentInstance = SoundDevice->HeadInstance;
00074 
00075     while ( CurrentInstance )
00076     {
00077         if ( CurrentInstance == SoundDeviceInstance )
00078             return TRUE;
00079 
00080         CurrentInstance = CurrentInstance->Next;
00081     }
00082 
00083     return FALSE;
00084 }
00085 
00086 MMRESULT
00087 ListSoundDeviceInstance(
00088     IN  PSOUND_DEVICE SoundDevice,
00089     IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance)
00090 {
00091     VALIDATE_MMSYS_PARAMETER( IsValidSoundDevice(SoundDevice) );
00092     VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance );
00093 
00094     SND_TRACE(L"Listing sound device instance\n");
00095 
00096     if ( ! SoundDevice->HeadInstance )
00097     {
00098         /* First entry - assign to head and tail */
00099         SoundDevice->HeadInstance = SoundDeviceInstance;
00100         SoundDevice->TailInstance = SoundDeviceInstance;
00101     }
00102     else
00103     {
00104         /* Attach to the end */
00105         SoundDevice->TailInstance->Next = SoundDeviceInstance;
00106         SoundDevice->TailInstance = SoundDeviceInstance;
00107     }
00108 
00109     return MMSYSERR_NOERROR;
00110 }
00111 
00112 MMRESULT
00113 UnlistSoundDeviceInstance(
00114     IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance)
00115 {
00116     MMRESULT Result;
00117     PSOUND_DEVICE SoundDevice;
00118     PSOUND_DEVICE_INSTANCE CurrentInstance, PreviousInstance;
00119 
00120     VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) );
00121 
00122     SND_TRACE(L"Unlisting sound device instance\n");
00123 
00124     Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
00125     SND_ASSERT( MMSUCCESS(Result) );
00126     if ( ! MMSUCCESS(Result) )
00127         return TranslateInternalMmResult(Result);
00128 
00129     PreviousInstance = NULL;
00130     CurrentInstance = SoundDevice->HeadInstance;
00131 
00132     while ( CurrentInstance )
00133     {
00134         if ( CurrentInstance == SoundDeviceInstance )
00135         {
00136             if ( ! PreviousInstance )
00137             {
00138                 /* This is the head node */
00139                 SoundDevice->HeadInstance = SoundDevice->HeadInstance->Next;
00140             }
00141             else
00142             {
00143                 /* There are nodes before this one - cut ours out */
00144                 PreviousInstance->Next = CurrentInstance->Next;
00145             }
00146 
00147             if ( ! CurrentInstance->Next )
00148             {
00149                 /* This is the tail node */
00150                 SoundDevice->TailInstance = PreviousInstance;
00151             }
00152         }
00153 
00154         PreviousInstance = CurrentInstance;
00155         CurrentInstance = CurrentInstance->Next;
00156     }
00157 
00158     return MMSYSERR_NOERROR;
00159 }
00160 
00161 MMRESULT
00162 CreateSoundDeviceInstance(
00163     IN  PSOUND_DEVICE SoundDevice,
00164     OUT PSOUND_DEVICE_INSTANCE* SoundDeviceInstance)
00165 {
00166     MMRESULT Result;
00167     PMMFUNCTION_TABLE FunctionTable;
00168 
00169     SND_TRACE(L"Creating a sound device instance\n");
00170 
00171     VALIDATE_MMSYS_PARAMETER( IsValidSoundDevice(SoundDevice) );
00172     VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance != NULL );
00173 
00174     Result = AllocateSoundDeviceInstance(SoundDeviceInstance);
00175 
00176     if ( ! MMSUCCESS(Result) )
00177         return TranslateInternalMmResult(Result);
00178 
00179     /* Get the "open" routine from the function table, and validate it */
00180     Result = GetSoundDeviceFunctionTable(SoundDevice, &FunctionTable);
00181     if ( ! MMSUCCESS(Result) )
00182     {
00183         FreeSoundDeviceInstance(*SoundDeviceInstance);
00184         return TranslateInternalMmResult(Result);
00185     }
00186 
00187     if ( FunctionTable->Open == NULL )
00188     {
00189         FreeSoundDeviceInstance(*SoundDeviceInstance);
00190         return MMSYSERR_NOTSUPPORTED;
00191     }
00192 
00193     /* Set up the members of the structure */
00194     (*SoundDeviceInstance)->Next = NULL; 
00195     (*SoundDeviceInstance)->Device = SoundDevice;
00196     (*SoundDeviceInstance)->Handle = NULL;
00197     (*SoundDeviceInstance)->Thread = NULL;
00198 
00199     (*SoundDeviceInstance)->WinMM.Handle = INVALID_HANDLE_VALUE;
00200     (*SoundDeviceInstance)->WinMM.ClientCallback = 0;
00201     (*SoundDeviceInstance)->WinMM.ClientCallbackInstanceData = 0;
00202     (*SoundDeviceInstance)->WinMM.Flags = 0;
00203 
00204     /* Initialise the members of the struct used by the sound thread */
00205     (*SoundDeviceInstance)->HeadWaveHeader = NULL;
00206     (*SoundDeviceInstance)->TailWaveHeader = NULL;
00207 
00208     (*SoundDeviceInstance)->OutstandingBuffers = 0;
00209 
00210     (*SoundDeviceInstance)->LoopsRemaining = 0;
00211 
00212     /* Create the streaming thread (TODO - is this for wave only?) */
00213     Result = CreateSoundThread(&(*SoundDeviceInstance)->Thread);
00214     if ( ! MMSUCCESS(Result) )
00215     {
00216         FreeSoundDeviceInstance(*SoundDeviceInstance);
00217         return TranslateInternalMmResult(Result);
00218     }
00219 
00220     /* Add the instance to the list */
00221     Result = ListSoundDeviceInstance(SoundDevice, *SoundDeviceInstance);
00222     if ( ! MMSUCCESS(Result) )
00223     {
00224         FreeSoundDeviceInstance(*SoundDeviceInstance);
00225         return TranslateInternalMmResult(Result);
00226     }
00227 
00228     /* Try and open the device */
00229     Result = FunctionTable->Open(SoundDevice, (&(*SoundDeviceInstance)->Handle));
00230     if ( ! MMSUCCESS(Result) )
00231     {
00232         UnlistSoundDeviceInstance(*SoundDeviceInstance);
00233         FreeSoundDeviceInstance(*SoundDeviceInstance);
00234         return TranslateInternalMmResult(Result);
00235     }
00236 
00237     return MMSYSERR_NOERROR;
00238 }
00239 
00240 MMRESULT
00241 DestroySoundDeviceInstance(
00242     IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance)
00243 {
00244     MMRESULT Result;
00245     PMMFUNCTION_TABLE FunctionTable;
00246     PSOUND_DEVICE SoundDevice;
00247     PVOID Handle;
00248 
00249     SND_TRACE(L"Destroying a sound device instance\n");
00250 
00251     VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) );
00252 
00253     Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
00254     if ( ! MMSUCCESS(Result) )
00255         return TranslateInternalMmResult(Result);
00256 
00257     Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
00258     if ( ! MMSUCCESS(Result) )
00259         return TranslateInternalMmResult(Result);
00260 
00261     /* Get the "close" routine from the function table, and validate it */
00262     Result = GetSoundDeviceFunctionTable(SoundDevice, &FunctionTable);
00263     if ( ! MMSUCCESS(Result) )
00264         return TranslateInternalMmResult(Result);
00265 
00266     SND_ASSERT( FunctionTable->Close );
00267     if ( FunctionTable->Close == NULL )
00268     {
00269         /* This indicates bad practice, really! If you can open, why not close?! */
00270         return MMSYSERR_NOTSUPPORTED;
00271     }
00272 
00273     /* Stop the streaming thread */
00274     if ( SoundDeviceInstance->Thread )
00275     {
00276         Result = DestroySoundThread(SoundDeviceInstance->Thread);
00277         SND_ASSERT( MMSUCCESS(Result) );    /* It should succeed! */
00278         if ( ! MMSUCCESS(Result ) )
00279         {
00280             return TranslateInternalMmResult(Result);
00281         }
00282     }
00283 
00284     /* Blank this out here */
00285     SoundDeviceInstance->Thread = NULL;
00286 
00287     /* Try and close the device */
00288     Result = FunctionTable->Close(SoundDeviceInstance, Handle);
00289     SND_ASSERT( MMSUCCESS(Result) );    /* It should succeed! */
00290     if ( ! MMSUCCESS(Result) )
00291         return TranslateInternalMmResult(Result);
00292 
00293     /* Drop it from the list */
00294     Result = UnlistSoundDeviceInstance(SoundDeviceInstance);
00295     SND_ASSERT( MMSUCCESS(Result) );    /* It should succeed! */
00296     if ( ! MMSUCCESS(Result) )
00297         return TranslateInternalMmResult(Result);
00298 
00299     FreeSoundDeviceInstance(SoundDeviceInstance);
00300 
00301     return MMSYSERR_NOERROR;
00302 }
00303 
00304 MMRESULT
00305 DestroyAllSoundDeviceInstances(
00306     IN  PSOUND_DEVICE SoundDevice)
00307 {
00308     MMRESULT Result;
00309     PSOUND_DEVICE_INSTANCE SoundDeviceInstance;
00310 
00311     SoundDeviceInstance = SoundDevice->HeadInstance;
00312 
00313     while ( SoundDeviceInstance )
00314     {
00315         Result = DestroySoundDeviceInstance(SoundDeviceInstance);
00316         SND_ASSERT( MMSUCCESS(Result) );
00317         SoundDeviceInstance = SoundDeviceInstance->Next;
00318     }
00319 
00320     return MMSYSERR_NOERROR;
00321 }
00322 
00323 MMRESULT
00324 GetSoundDeviceFromInstance(
00325     IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
00326     OUT PSOUND_DEVICE* SoundDevice)
00327 {
00328     VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) );
00329     VALIDATE_MMSYS_PARAMETER( SoundDevice );
00330 
00331     *SoundDevice = SoundDeviceInstance->Device;
00332 
00333     return MMSYSERR_NOERROR;
00334 }
00335 
00336 MMRESULT
00337 GetSoundDeviceInstanceHandle(
00338     IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
00339     OUT PVOID* Handle)
00340 {
00341     VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) );
00342     VALIDATE_MMSYS_PARAMETER( Handle );
00343 
00344     *Handle = SoundDeviceInstance->Handle;
00345 
00346     return MMSYSERR_NOERROR;
00347 }
00348 
00349 MMRESULT
00350 SetSoundDeviceInstanceMmeData(
00351     IN  PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
00352     IN  HDRVR MmeHandle,
00353     IN  DWORD_PTR ClientCallback,
00354     IN  DWORD_PTR ClientCallbackData,
00355     IN  DWORD Flags)
00356 {
00357     VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) );
00358 
00359     SND_TRACE(L"Setting MME data - handle %x, callback %x, instance data %x, flags %x\n",
00360               MmeHandle, ClientCallback, ClientCallbackData, Flags);
00361 
00362     SoundDeviceInstance->WinMM.Handle = MmeHandle;
00363     SoundDeviceInstance->WinMM.ClientCallback = ClientCallback;
00364     SoundDeviceInstance->WinMM.ClientCallbackInstanceData = ClientCallbackData;
00365     SoundDeviceInstance->WinMM.Flags = Flags;
00366 
00367     return MMSYSERR_NOERROR;
00368 }

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.