mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 22:33:00 +00:00
Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys.
This commit is contained in:
parent
b94e2d8ca0
commit
c2c66aff7d
24198 changed files with 0 additions and 37285 deletions
369
sdk/lib/drivers/sound/mmebuddy/deviceinstance.c
Normal file
369
sdk/lib/drivers/sound/mmebuddy/deviceinstance.c
Normal file
|
@ -0,0 +1,369 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Sound System "MME Buddy" Library
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: lib/drivers/sound/mmebuddy/deviceinstance.c
|
||||
*
|
||||
* PURPOSE: Manages instances of sound devices.
|
||||
*
|
||||
* PROGRAMMERS: Andrew Greenwood (silverblade@reactos.org)
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
/*
|
||||
Restrain ourselves from flooding the kernel device!
|
||||
*/
|
||||
|
||||
#define SOUND_KERNEL_BUFFER_COUNT 10
|
||||
#define SOUND_KERNEL_BUFFER_SIZE 16384
|
||||
|
||||
MMRESULT
|
||||
AllocateSoundDeviceInstance(
|
||||
OUT PSOUND_DEVICE_INSTANCE* SoundDeviceInstance)
|
||||
{
|
||||
PSOUND_DEVICE_INSTANCE NewInstance;
|
||||
|
||||
VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance );
|
||||
|
||||
/* Allocate memory for the new instance */
|
||||
NewInstance = AllocateStruct(SOUND_DEVICE_INSTANCE);
|
||||
|
||||
if ( ! NewInstance )
|
||||
return MMSYSERR_NOMEM;
|
||||
|
||||
/* Use default frame size */
|
||||
NewInstance->FrameSize = SOUND_KERNEL_BUFFER_SIZE;
|
||||
/* Use default buffer count */
|
||||
NewInstance->BufferCount = SOUND_KERNEL_BUFFER_COUNT;
|
||||
|
||||
/* Provide the caller with the new instance pointer */
|
||||
*SoundDeviceInstance = NewInstance;
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
VOID
|
||||
FreeSoundDeviceInstance(
|
||||
IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance)
|
||||
{
|
||||
/*
|
||||
Device is marked as invalid by now, but we can still do some sanity
|
||||
checking.
|
||||
*/
|
||||
SND_ASSERT( SoundDeviceInstance->Thread == NULL );
|
||||
|
||||
ZeroMemory(SoundDeviceInstance, sizeof(SOUND_DEVICE_INSTANCE));
|
||||
FreeMemory(SoundDeviceInstance);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
IsValidSoundDeviceInstance(
|
||||
IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance)
|
||||
{
|
||||
PSOUND_DEVICE SoundDevice;
|
||||
PSOUND_DEVICE_INSTANCE CurrentInstance;
|
||||
|
||||
if ( ! SoundDeviceInstance )
|
||||
return FALSE;
|
||||
|
||||
/* GetSoundDeviceFromInstance would send us into a recursive loop... */
|
||||
SoundDevice = SoundDeviceInstance->Device;
|
||||
SND_ASSERT(SoundDevice);
|
||||
|
||||
CurrentInstance = SoundDevice->HeadInstance;
|
||||
|
||||
while ( CurrentInstance )
|
||||
{
|
||||
if ( CurrentInstance == SoundDeviceInstance )
|
||||
return TRUE;
|
||||
|
||||
CurrentInstance = CurrentInstance->Next;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
MMRESULT
|
||||
ListSoundDeviceInstance(
|
||||
IN PSOUND_DEVICE SoundDevice,
|
||||
IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance)
|
||||
{
|
||||
VALIDATE_MMSYS_PARAMETER( IsValidSoundDevice(SoundDevice) );
|
||||
VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance );
|
||||
|
||||
SND_TRACE(L"Listing sound device instance\n");
|
||||
|
||||
if ( ! SoundDevice->HeadInstance )
|
||||
{
|
||||
/* First entry - assign to head and tail */
|
||||
SoundDevice->HeadInstance = SoundDeviceInstance;
|
||||
SoundDevice->TailInstance = SoundDeviceInstance;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Attach to the end */
|
||||
SoundDevice->TailInstance->Next = SoundDeviceInstance;
|
||||
SoundDevice->TailInstance = SoundDeviceInstance;
|
||||
}
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
MMRESULT
|
||||
UnlistSoundDeviceInstance(
|
||||
IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance)
|
||||
{
|
||||
MMRESULT Result;
|
||||
PSOUND_DEVICE SoundDevice;
|
||||
PSOUND_DEVICE_INSTANCE CurrentInstance, PreviousInstance;
|
||||
|
||||
VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) );
|
||||
|
||||
SND_TRACE(L"Unlisting sound device instance\n");
|
||||
|
||||
Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
|
||||
SND_ASSERT( MMSUCCESS(Result) );
|
||||
if ( ! MMSUCCESS(Result) )
|
||||
return TranslateInternalMmResult(Result);
|
||||
|
||||
PreviousInstance = NULL;
|
||||
CurrentInstance = SoundDevice->HeadInstance;
|
||||
|
||||
while ( CurrentInstance )
|
||||
{
|
||||
if ( CurrentInstance == SoundDeviceInstance )
|
||||
{
|
||||
if ( ! PreviousInstance )
|
||||
{
|
||||
/* This is the head node */
|
||||
SoundDevice->HeadInstance = SoundDevice->HeadInstance->Next;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* There are nodes before this one - cut ours out */
|
||||
PreviousInstance->Next = CurrentInstance->Next;
|
||||
}
|
||||
|
||||
if ( ! CurrentInstance->Next )
|
||||
{
|
||||
/* This is the tail node */
|
||||
SoundDevice->TailInstance = PreviousInstance;
|
||||
}
|
||||
}
|
||||
|
||||
PreviousInstance = CurrentInstance;
|
||||
CurrentInstance = CurrentInstance->Next;
|
||||
}
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
MMRESULT
|
||||
CreateSoundDeviceInstance(
|
||||
IN PSOUND_DEVICE SoundDevice,
|
||||
OUT PSOUND_DEVICE_INSTANCE* SoundDeviceInstance)
|
||||
{
|
||||
MMRESULT Result;
|
||||
PMMFUNCTION_TABLE FunctionTable;
|
||||
|
||||
SND_TRACE(L"Creating a sound device instance\n");
|
||||
|
||||
VALIDATE_MMSYS_PARAMETER( IsValidSoundDevice(SoundDevice) );
|
||||
VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance != NULL );
|
||||
|
||||
Result = AllocateSoundDeviceInstance(SoundDeviceInstance);
|
||||
|
||||
if ( ! MMSUCCESS(Result) )
|
||||
return TranslateInternalMmResult(Result);
|
||||
|
||||
/* Get the "open" routine from the function table, and validate it */
|
||||
Result = GetSoundDeviceFunctionTable(SoundDevice, &FunctionTable);
|
||||
if ( ! MMSUCCESS(Result) )
|
||||
{
|
||||
FreeSoundDeviceInstance(*SoundDeviceInstance);
|
||||
return TranslateInternalMmResult(Result);
|
||||
}
|
||||
|
||||
if ( FunctionTable->Open == NULL )
|
||||
{
|
||||
FreeSoundDeviceInstance(*SoundDeviceInstance);
|
||||
return MMSYSERR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
/* Set up the members of the structure */
|
||||
(*SoundDeviceInstance)->Next = NULL;
|
||||
(*SoundDeviceInstance)->Device = SoundDevice;
|
||||
(*SoundDeviceInstance)->Handle = NULL;
|
||||
(*SoundDeviceInstance)->Thread = NULL;
|
||||
|
||||
(*SoundDeviceInstance)->WinMM.Handle = INVALID_HANDLE_VALUE;
|
||||
(*SoundDeviceInstance)->WinMM.ClientCallback = 0;
|
||||
(*SoundDeviceInstance)->WinMM.ClientCallbackInstanceData = 0;
|
||||
(*SoundDeviceInstance)->WinMM.Flags = 0;
|
||||
|
||||
/* Initialise the members of the struct used by the sound thread */
|
||||
(*SoundDeviceInstance)->HeadWaveHeader = NULL;
|
||||
(*SoundDeviceInstance)->TailWaveHeader = NULL;
|
||||
|
||||
(*SoundDeviceInstance)->OutstandingBuffers = 0;
|
||||
|
||||
(*SoundDeviceInstance)->LoopsRemaining = 0;
|
||||
|
||||
/* Create the streaming thread (TODO - is this for wave only?) */
|
||||
Result = CreateSoundThread(&(*SoundDeviceInstance)->Thread);
|
||||
if ( ! MMSUCCESS(Result) )
|
||||
{
|
||||
FreeSoundDeviceInstance(*SoundDeviceInstance);
|
||||
return TranslateInternalMmResult(Result);
|
||||
}
|
||||
|
||||
/* Add the instance to the list */
|
||||
Result = ListSoundDeviceInstance(SoundDevice, *SoundDeviceInstance);
|
||||
if ( ! MMSUCCESS(Result) )
|
||||
{
|
||||
FreeSoundDeviceInstance(*SoundDeviceInstance);
|
||||
return TranslateInternalMmResult(Result);
|
||||
}
|
||||
|
||||
/* Try and open the device */
|
||||
Result = FunctionTable->Open(SoundDevice, (&(*SoundDeviceInstance)->Handle));
|
||||
if ( ! MMSUCCESS(Result) )
|
||||
{
|
||||
UnlistSoundDeviceInstance(*SoundDeviceInstance);
|
||||
FreeSoundDeviceInstance(*SoundDeviceInstance);
|
||||
return TranslateInternalMmResult(Result);
|
||||
}
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
MMRESULT
|
||||
DestroySoundDeviceInstance(
|
||||
IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance)
|
||||
{
|
||||
MMRESULT Result;
|
||||
PMMFUNCTION_TABLE FunctionTable;
|
||||
PSOUND_DEVICE SoundDevice;
|
||||
PVOID Handle;
|
||||
|
||||
SND_TRACE(L"Destroying a sound device instance\n");
|
||||
|
||||
VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) );
|
||||
|
||||
Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice);
|
||||
if ( ! MMSUCCESS(Result) )
|
||||
return TranslateInternalMmResult(Result);
|
||||
|
||||
Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle);
|
||||
if ( ! MMSUCCESS(Result) )
|
||||
return TranslateInternalMmResult(Result);
|
||||
|
||||
/* Get the "close" routine from the function table, and validate it */
|
||||
Result = GetSoundDeviceFunctionTable(SoundDevice, &FunctionTable);
|
||||
if ( ! MMSUCCESS(Result) )
|
||||
return TranslateInternalMmResult(Result);
|
||||
|
||||
SND_ASSERT( FunctionTable->Close );
|
||||
if ( FunctionTable->Close == NULL )
|
||||
{
|
||||
/* This indicates bad practice, really! If you can open, why not close?! */
|
||||
return MMSYSERR_NOTSUPPORTED;
|
||||
}
|
||||
|
||||
/* Stop the streaming thread */
|
||||
if ( SoundDeviceInstance->Thread )
|
||||
{
|
||||
Result = DestroySoundThread(SoundDeviceInstance->Thread);
|
||||
SND_ASSERT( MMSUCCESS(Result) ); /* It should succeed! */
|
||||
if ( ! MMSUCCESS(Result ) )
|
||||
{
|
||||
return TranslateInternalMmResult(Result);
|
||||
}
|
||||
}
|
||||
|
||||
/* Blank this out here */
|
||||
SoundDeviceInstance->Thread = NULL;
|
||||
|
||||
/* Try and close the device */
|
||||
Result = FunctionTable->Close(SoundDeviceInstance, Handle);
|
||||
SND_ASSERT( MMSUCCESS(Result) ); /* It should succeed! */
|
||||
if ( ! MMSUCCESS(Result) )
|
||||
return TranslateInternalMmResult(Result);
|
||||
|
||||
/* Drop it from the list */
|
||||
Result = UnlistSoundDeviceInstance(SoundDeviceInstance);
|
||||
SND_ASSERT( MMSUCCESS(Result) ); /* It should succeed! */
|
||||
if ( ! MMSUCCESS(Result) )
|
||||
return TranslateInternalMmResult(Result);
|
||||
|
||||
FreeSoundDeviceInstance(SoundDeviceInstance);
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
MMRESULT
|
||||
DestroyAllSoundDeviceInstances(
|
||||
IN PSOUND_DEVICE SoundDevice)
|
||||
{
|
||||
MMRESULT Result;
|
||||
PSOUND_DEVICE_INSTANCE SoundDeviceInstance, NextDeviceInstance;
|
||||
|
||||
SoundDeviceInstance = SoundDevice->HeadInstance;
|
||||
|
||||
while ( SoundDeviceInstance )
|
||||
{
|
||||
NextDeviceInstance = SoundDeviceInstance->Next;
|
||||
Result = DestroySoundDeviceInstance(SoundDeviceInstance);
|
||||
SND_ASSERT( MMSUCCESS(Result) );
|
||||
SoundDeviceInstance = NextDeviceInstance;
|
||||
}
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
MMRESULT
|
||||
GetSoundDeviceFromInstance(
|
||||
IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
|
||||
OUT PSOUND_DEVICE* SoundDevice)
|
||||
{
|
||||
VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) );
|
||||
VALIDATE_MMSYS_PARAMETER( SoundDevice );
|
||||
|
||||
*SoundDevice = SoundDeviceInstance->Device;
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
MMRESULT
|
||||
GetSoundDeviceInstanceHandle(
|
||||
IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
|
||||
OUT PVOID* Handle)
|
||||
{
|
||||
VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) );
|
||||
VALIDATE_MMSYS_PARAMETER( Handle );
|
||||
|
||||
*Handle = SoundDeviceInstance->Handle;
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
||||
|
||||
MMRESULT
|
||||
SetSoundDeviceInstanceMmeData(
|
||||
IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance,
|
||||
IN HDRVR MmeHandle,
|
||||
IN DWORD_PTR ClientCallback,
|
||||
IN DWORD_PTR ClientCallbackData,
|
||||
IN DWORD Flags)
|
||||
{
|
||||
VALIDATE_MMSYS_PARAMETER( IsValidSoundDeviceInstance(SoundDeviceInstance) );
|
||||
|
||||
SND_TRACE(L"Setting MME data - handle %x, callback %x, instance data %x, flags %x\n",
|
||||
MmeHandle, ClientCallback, ClientCallbackData, Flags);
|
||||
|
||||
SoundDeviceInstance->WinMM.Handle = MmeHandle;
|
||||
SoundDeviceInstance->WinMM.ClientCallback = ClientCallback;
|
||||
SoundDeviceInstance->WinMM.ClientCallbackInstanceData = ClientCallbackData;
|
||||
SoundDeviceInstance->WinMM.Flags = Flags;
|
||||
|
||||
return MMSYSERR_NOERROR;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue