2009-12-20 00:55:55 +00:00
/*
* COPYRIGHT : See COPYING in the top level directory
* PROJECT : ReactOS Kernel Streaming
2009-12-22 18:08:51 +00:00
* FILE : lib / drivers / sound / mmixer / wave . c
* PURPOSE : Wave Handling Functions
2009-12-20 00:55:55 +00:00
* PROGRAMMER : Johannes Anderwald
*/
2014-02-04 10:36:20 +00:00
# include "precomp.h"
2009-12-20 00:55:55 +00:00
2014-01-04 10:17:22 +00:00
# define YDEBUG
# include <debug.h>
2009-12-23 02:49:18 +00:00
const GUID KSPROPSETID_Connection = { 0x1D58C920L , 0xAC9B , 0x11CF , { 0xA5 , 0xD6 , 0x28 , 0xDB , 0x04 , 0xC1 , 0x00 , 0x00 } } ;
2009-12-20 00:55:55 +00:00
const GUID KSDATAFORMAT_SPECIFIER_WAVEFORMATEX = { 0x05589f81L , 0xc356 , 0x11ce , { 0xbf , 0x01 , 0x00 , 0xaa , 0x00 , 0x55 , 0x59 , 0x5a } } ;
const GUID KSDATAFORMAT_SUBTYPE_PCM = { 0x00000001L , 0x0000 , 0x0010 , { 0x80 , 0x00 , 0x00 , 0xaa , 0x00 , 0x38 , 0x9b , 0x71 } } ;
const GUID KSDATAFORMAT_TYPE_AUDIO = { 0x73647561L , 0x0000 , 0x0010 , { 0x80 , 0x00 , 0x00 , 0xaa , 0x00 , 0x38 , 0x9b , 0x71 } } ;
const GUID KSINTERFACESETID_Standard = { 0x1A8766A0L , 0x62CE , 0x11CF , { 0xA5 , 0xD6 , 0x28 , 0xDB , 0x04 , 0xC1 , 0x00 , 0x00 } } ;
const GUID KSMEDIUMSETID_Standard = { 0x4747B320L , 0x62CE , 0x11CF , { 0xA5 , 0xD6 , 0x28 , 0xDB , 0x04 , 0xC1 , 0x00 , 0x00 } } ;
typedef struct
{
ULONG SampleRate ;
ULONG Bit8Mono ;
ULONG Bit8Stereo ;
ULONG Bit16Mono ;
ULONG Bit16Stereo ;
} AUDIO_RANGE ;
# define AUDIO_TEST_RANGE (5)
static AUDIO_RANGE TestRange [ AUDIO_TEST_RANGE ] =
{
{
11025 ,
WAVE_FORMAT_1M08 ,
WAVE_FORMAT_1S08 ,
WAVE_FORMAT_1M16 ,
WAVE_FORMAT_1S16
} ,
{
22050 ,
WAVE_FORMAT_2M08 ,
WAVE_FORMAT_2S08 ,
WAVE_FORMAT_2M16 ,
WAVE_FORMAT_2S16
} ,
{
44100 ,
WAVE_FORMAT_4M08 ,
WAVE_FORMAT_4S08 ,
WAVE_FORMAT_4M16 ,
WAVE_FORMAT_4S16
} ,
{
48000 ,
WAVE_FORMAT_48M08 ,
WAVE_FORMAT_48S08 ,
WAVE_FORMAT_48M16 ,
WAVE_FORMAT_48S16
} ,
{
96000 ,
WAVE_FORMAT_96M08 ,
WAVE_FORMAT_96S08 ,
WAVE_FORMAT_96M16 ,
WAVE_FORMAT_96S16
}
} ;
PKSPIN_CONNECT
MMixerAllocatePinConnect (
IN PMIXER_CONTEXT MixerContext ,
ULONG DataFormatSize )
{
return MixerContext - > Alloc ( sizeof ( KSPIN_CONNECT ) + DataFormatSize ) ;
}
MIXER_STATUS
MMixerGetWaveInfoByIndexAndType (
IN PMIXER_LIST MixerList ,
IN ULONG DeviceIndex ,
IN ULONG bWaveInType ,
OUT LPWAVE_INFO * OutWaveInfo )
{
ULONG Index = 0 ;
PLIST_ENTRY Entry , ListHead ;
LPWAVE_INFO WaveInfo ;
if ( bWaveInType )
ListHead = & MixerList - > WaveInList ;
else
ListHead = & MixerList - > WaveOutList ;
/* get first entry */
Entry = ListHead - > Flink ;
while ( Entry ! = ListHead )
{
WaveInfo = ( LPWAVE_INFO ) CONTAINING_RECORD ( Entry , WAVE_INFO , Entry ) ;
if ( Index = = DeviceIndex )
{
* OutWaveInfo = WaveInfo ;
return MM_STATUS_SUCCESS ;
}
Index + + ;
Entry = Entry - > Flink ;
}
return MM_STATUS_INVALID_PARAMETER ;
}
2010-10-31 14:34:41 +00:00
2009-12-20 00:55:55 +00:00
VOID
MMixerInitializeDataFormat (
IN PKSDATAFORMAT_WAVEFORMATEX DataFormat ,
LPWAVEFORMATEX WaveFormatEx )
{
DataFormat - > WaveFormatEx . wFormatTag = WaveFormatEx - > wFormatTag ;
DataFormat - > WaveFormatEx . nChannels = WaveFormatEx - > nChannels ;
DataFormat - > WaveFormatEx . nSamplesPerSec = WaveFormatEx - > nSamplesPerSec ;
DataFormat - > WaveFormatEx . nBlockAlign = WaveFormatEx - > nBlockAlign ;
DataFormat - > WaveFormatEx . nAvgBytesPerSec = WaveFormatEx - > nAvgBytesPerSec ;
DataFormat - > WaveFormatEx . wBitsPerSample = WaveFormatEx - > wBitsPerSample ;
DataFormat - > WaveFormatEx . cbSize = 0 ;
DataFormat - > DataFormat . FormatSize = sizeof ( KSDATAFORMAT ) + sizeof ( WAVEFORMATEX ) ;
DataFormat - > DataFormat . Flags = 0 ;
DataFormat - > DataFormat . Reserved = 0 ;
DataFormat - > DataFormat . MajorFormat = KSDATAFORMAT_TYPE_AUDIO ;
DataFormat - > DataFormat . SubFormat = KSDATAFORMAT_SUBTYPE_PCM ;
DataFormat - > DataFormat . Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX ;
DataFormat - > DataFormat . SampleSize = 4 ;
}
MIXER_STATUS
MMixerGetAudioPinDataRanges (
IN PMIXER_CONTEXT MixerContext ,
IN HANDLE hDevice ,
IN ULONG PinId ,
IN OUT PKSMULTIPLE_ITEM * OutMultipleItem )
{
KSP_PIN PinProperty ;
ULONG BytesReturned = 0 ;
MIXER_STATUS Status ;
PKSMULTIPLE_ITEM MultipleItem ;
/* retrieve size of data ranges buffer */
PinProperty . Reserved = 0 ;
PinProperty . PinId = PinId ;
PinProperty . Property . Set = KSPROPSETID_Pin ;
PinProperty . Property . Id = KSPROPERTY_PIN_DATARANGES ;
PinProperty . Property . Flags = KSPROPERTY_TYPE_GET ;
Status = MixerContext - > Control ( hDevice , IOCTL_KS_PROPERTY , ( PVOID ) & PinProperty , sizeof ( KSP_PIN ) , ( PVOID ) NULL , 0 , & BytesReturned ) ;
if ( Status ! = MM_STATUS_MORE_ENTRIES )
{
return Status ;
}
MultipleItem = MixerContext - > Alloc ( BytesReturned ) ;
if ( ! MultipleItem )
{
/* not enough memory */
return MM_STATUS_NO_MEMORY ;
}
Status = MixerContext - > Control ( hDevice , IOCTL_KS_PROPERTY , ( PVOID ) & PinProperty , sizeof ( KSP_PIN ) , ( PVOID ) MultipleItem , BytesReturned , & BytesReturned ) ;
if ( Status ! = MM_STATUS_SUCCESS )
{
/* failed */
MixerContext - > Free ( MultipleItem ) ;
return Status ;
}
/* save result */
* OutMultipleItem = MultipleItem ;
return Status ;
}
MIXER_STATUS
MMixerFindAudioDataRange (
PKSMULTIPLE_ITEM MultipleItem ,
PKSDATARANGE_AUDIO * OutDataRangeAudio )
{
ULONG Index ;
PKSDATARANGE_AUDIO DataRangeAudio ;
PKSDATARANGE DataRange ;
DataRange = ( PKSDATARANGE ) ( MultipleItem + 1 ) ;
for ( Index = 0 ; Index < MultipleItem - > Count ; Index + + )
{
if ( DataRange - > FormatSize = = sizeof ( KSDATARANGE_AUDIO ) )
{
DataRangeAudio = ( PKSDATARANGE_AUDIO ) DataRange ;
if ( IsEqualGUIDAligned ( & DataRangeAudio - > DataRange . MajorFormat , & KSDATAFORMAT_TYPE_AUDIO ) & &
IsEqualGUIDAligned ( & DataRangeAudio - > DataRange . SubFormat , & KSDATAFORMAT_SUBTYPE_PCM ) & &
IsEqualGUIDAligned ( & DataRangeAudio - > DataRange . Specifier , & KSDATAFORMAT_SPECIFIER_WAVEFORMATEX ) )
{
DPRINT ( " Min Sample %u Max Sample %u Min Bits %u Max Bits %u Max Channel %u \n " , DataRangeAudio - > MinimumSampleFrequency , DataRangeAudio - > MaximumSampleFrequency ,
DataRangeAudio - > MinimumBitsPerSample , DataRangeAudio - > MaximumBitsPerSample , DataRangeAudio - > MaximumChannels ) ;
* OutDataRangeAudio = DataRangeAudio ;
return MM_STATUS_SUCCESS ;
}
}
DataRange = ( PKSDATARANGE ) ( ( ULONG_PTR ) DataRange + DataRange - > FormatSize ) ;
}
return MM_STATUS_UNSUCCESSFUL ;
}
MIXER_STATUS
MMixerOpenWavePin (
IN PMIXER_CONTEXT MixerContext ,
IN PMIXER_LIST MixerList ,
IN ULONG DeviceId ,
IN ULONG PinId ,
IN LPWAVEFORMATEX WaveFormatEx ,
IN ACCESS_MASK DesiredAccess ,
2010-02-11 21:04:57 +00:00
IN PIN_CREATE_CALLBACK CreateCallback ,
IN PVOID Context ,
2009-12-20 00:55:55 +00:00
OUT PHANDLE PinHandle )
{
PKSPIN_CONNECT PinConnect ;
PKSDATAFORMAT_WAVEFORMATEX DataFormat ;
LPMIXER_DATA MixerData ;
NTSTATUS Status ;
2010-02-11 21:04:57 +00:00
MIXER_STATUS MixerStatus ;
2009-12-20 00:55:55 +00:00
MixerData = MMixerGetDataByDeviceId ( MixerList , DeviceId ) ;
if ( ! MixerData )
return MM_STATUS_INVALID_PARAMETER ;
/* allocate pin connect */
PinConnect = MMixerAllocatePinConnect ( MixerContext , sizeof ( KSDATAFORMAT_WAVEFORMATEX ) ) ;
if ( ! PinConnect )
{
/* no memory */
return MM_STATUS_NO_MEMORY ;
}
/* initialize pin connect struct */
MMixerInitializePinConnect ( PinConnect , PinId ) ;
/* get offset to dataformat */
DataFormat = ( PKSDATAFORMAT_WAVEFORMATEX ) ( PinConnect + 1 ) ;
/* initialize with requested wave format */
MMixerInitializeDataFormat ( DataFormat , WaveFormatEx ) ;
2010-02-11 21:04:57 +00:00
if ( CreateCallback )
{
/* let the callback handle the creation */
MixerStatus = CreateCallback ( Context , DeviceId , PinId , MixerData - > hDevice , PinConnect , DesiredAccess , PinHandle ) ;
}
else
{
/* now create the pin */
Status = KsCreatePin ( MixerData - > hDevice , PinConnect , DesiredAccess , PinHandle ) ;
/* normalize status */
if ( Status = = STATUS_SUCCESS )
MixerStatus = MM_STATUS_SUCCESS ;
else
MixerStatus = MM_STATUS_UNSUCCESSFUL ;
}
2009-12-20 00:55:55 +00:00
/* free create info */
MixerContext - > Free ( PinConnect ) ;
2010-02-11 21:04:57 +00:00
/* done */
return MixerStatus ;
2009-12-20 00:55:55 +00:00
}
VOID
MMixerCheckFormat (
IN PKSDATARANGE_AUDIO DataRangeAudio ,
IN LPWAVE_INFO WaveInfo ,
IN ULONG bInput )
{
ULONG Index , SampleFrequency ;
ULONG Result = 0 ;
for ( Index = 0 ; Index < AUDIO_TEST_RANGE ; Index + + )
{
SampleFrequency = TestRange [ Index ] . SampleRate ;
if ( DataRangeAudio - > MinimumSampleFrequency < = SampleFrequency & & DataRangeAudio - > MaximumSampleFrequency > = SampleFrequency )
{
/* the audio adapter supports the sample frequency */
if ( DataRangeAudio - > MinimumBitsPerSample < = 8 & & DataRangeAudio - > MaximumBitsPerSample > = 8 )
{
Result | = TestRange [ Index ] . Bit8Mono ;
if ( DataRangeAudio - > MaximumChannels > 1 )
{
/* check if pin supports the sample rate in 8-Bit Stereo */
Result | = TestRange [ Index ] . Bit8Stereo ;
}
}
if ( DataRangeAudio - > MinimumBitsPerSample < = 16 & & DataRangeAudio - > MaximumBitsPerSample > = 16 )
{
/* check if pin supports the sample rate in 16-Bit Mono */
Result | = TestRange [ Index ] . Bit16Mono ;
if ( DataRangeAudio - > MaximumChannels > 1 )
{
/* check if pin supports the sample rate in 16-Bit Stereo */
Result | = TestRange [ Index ] . Bit16Stereo ;
}
}
}
}
if ( bInput )
WaveInfo - > u . InCaps . dwFormats = Result ;
else
WaveInfo - > u . OutCaps . dwFormats = Result ;
DPRINT ( " Format %lx bInput %u \n " , Result , bInput ) ;
}
MIXER_STATUS
MMixerInitializeWaveInfo (
IN PMIXER_CONTEXT MixerContext ,
IN PMIXER_LIST MixerList ,
IN LPMIXER_DATA MixerData ,
IN LPWSTR DeviceName ,
IN ULONG bWaveIn ,
2010-10-15 00:20:15 +00:00
IN ULONG PinCount ,
IN PULONG Pins )
2009-12-20 00:55:55 +00:00
{
MIXER_STATUS Status ;
PKSMULTIPLE_ITEM MultipleItem ;
PKSDATARANGE_AUDIO DataRangeAudio ;
LPWAVE_INFO WaveInfo ;
WaveInfo = ( LPWAVE_INFO ) MixerContext - > Alloc ( sizeof ( WAVE_INFO ) ) ;
if ( ! WaveInfo )
return MM_STATUS_NO_MEMORY ;
2010-10-16 12:39:49 +00:00
if ( PinCount > 1 )
{
/* FIXME support multiple pins for wave device */
DPRINT1 ( " Implement support for multiple pins \n " ) ;
//ASSERT(PinCount == 1);
}
2010-10-15 00:20:15 +00:00
2009-12-20 00:55:55 +00:00
/* initialize wave info */
WaveInfo - > DeviceId = MixerData - > DeviceId ;
2010-10-15 00:20:15 +00:00
WaveInfo - > PinId = Pins [ 0 ] ;
2009-12-20 00:55:55 +00:00
2010-10-15 00:20:15 +00:00
/* sanity check */
2010-10-31 14:34:41 +00:00
ASSERT ( wcslen ( DeviceName ) + 1 < MAXPNAMELEN ) ;
2010-04-02 13:49:10 +00:00
/* copy device name */
if ( bWaveIn )
{
wcscpy ( WaveInfo - > u . InCaps . szPname , DeviceName ) ;
}
else
{
wcscpy ( WaveInfo - > u . OutCaps . szPname , DeviceName ) ;
}
2009-12-20 00:55:55 +00:00
/* FIXME determine manufacturer / product id */
if ( bWaveIn )
{
WaveInfo - > u . InCaps . wMid = MM_MICROSOFT ;
WaveInfo - > u . InCaps . wPid = MM_PID_UNMAPPED ;
WaveInfo - > u . InCaps . vDriverVersion = 1 ;
}
else
{
WaveInfo - > u . OutCaps . wMid = MM_MICROSOFT ;
WaveInfo - > u . OutCaps . wPid = MM_PID_UNMAPPED ;
WaveInfo - > u . OutCaps . vDriverVersion = 1 ;
}
/* get audio pin data ranges */
2010-10-15 00:20:15 +00:00
Status = MMixerGetAudioPinDataRanges ( MixerContext , MixerData - > hDevice , Pins [ 0 ] , & MultipleItem ) ;
2009-12-20 00:55:55 +00:00
if ( Status ! = MM_STATUS_SUCCESS )
{
/* failed to get audio pin data ranges */
MixerContext - > Free ( WaveInfo ) ;
return MM_STATUS_UNSUCCESSFUL ;
}
/* find an KSDATARANGE_AUDIO range */
Status = MMixerFindAudioDataRange ( MultipleItem , & DataRangeAudio ) ;
if ( Status ! = MM_STATUS_SUCCESS )
{
/* failed to find audio pin data range */
MixerContext - > Free ( MultipleItem ) ;
MixerContext - > Free ( WaveInfo ) ;
return MM_STATUS_UNSUCCESSFUL ;
}
/* store channel count */
if ( bWaveIn )
{
WaveInfo - > u . InCaps . wChannels = DataRangeAudio - > MaximumChannels ;
}
else
{
WaveInfo - > u . OutCaps . wChannels = DataRangeAudio - > MaximumChannels ;
}
/* get all supported formats */
MMixerCheckFormat ( DataRangeAudio , WaveInfo , bWaveIn ) ;
/* free dataranges buffer */
MixerContext - > Free ( MultipleItem ) ;
if ( bWaveIn )
{
InsertTailList ( & MixerList - > WaveInList , & WaveInfo - > Entry ) ;
MixerList - > WaveInListCount + + ;
}
else
{
InsertTailList ( & MixerList - > WaveOutList , & WaveInfo - > Entry ) ;
MixerList - > WaveOutListCount + + ;
}
return MM_STATUS_SUCCESS ;
}
MIXER_STATUS
MMixerOpenWave (
IN PMIXER_CONTEXT MixerContext ,
IN ULONG DeviceIndex ,
IN ULONG bWaveIn ,
IN LPWAVEFORMATEX WaveFormat ,
2010-02-11 21:04:57 +00:00
IN PIN_CREATE_CALLBACK CreateCallback ,
IN PVOID Context ,
2009-12-20 00:55:55 +00:00
OUT PHANDLE PinHandle )
{
PMIXER_LIST MixerList ;
MIXER_STATUS Status ;
LPWAVE_INFO WaveInfo ;
ACCESS_MASK DesiredAccess = 0 ;
2010-10-15 00:20:15 +00:00
/* verify mixer context */
2009-12-20 00:55:55 +00:00
Status = MMixerVerifyContext ( MixerContext ) ;
if ( Status ! = MM_STATUS_SUCCESS )
{
2010-10-15 00:20:15 +00:00
/* invalid context passed */
2009-12-20 00:55:55 +00:00
return Status ;
}
2010-10-15 00:20:15 +00:00
/* grab mixer list */
2009-12-20 00:55:55 +00:00
MixerList = ( PMIXER_LIST ) MixerContext - > MixerContext ;
if ( WaveFormat - > wFormatTag ! = WAVE_FORMAT_PCM )
{
2010-10-15 00:20:15 +00:00
/* not implemented */
2009-12-20 00:55:55 +00:00
return MM_STATUS_NOT_IMPLEMENTED ;
}
/* find destination wave */
Status = MMixerGetWaveInfoByIndexAndType ( MixerList , DeviceIndex , bWaveIn , & WaveInfo ) ;
if ( Status ! = MM_STATUS_SUCCESS )
{
/* failed to find wave info */
return MM_STATUS_INVALID_PARAMETER ;
}
/* get desired access */
if ( bWaveIn )
{
DesiredAccess | = GENERIC_READ ;
}
else
{
DesiredAccess | = GENERIC_WRITE ;
}
/* now try open the pin */
2010-02-11 21:04:57 +00:00
return MMixerOpenWavePin ( MixerContext , MixerList , WaveInfo - > DeviceId , WaveInfo - > PinId , WaveFormat , DesiredAccess , CreateCallback , Context , PinHandle ) ;
2009-12-20 00:55:55 +00:00
}
MIXER_STATUS
MMixerWaveInCapabilities (
IN PMIXER_CONTEXT MixerContext ,
IN ULONG DeviceIndex ,
OUT LPWAVEINCAPSW Caps )
{
PMIXER_LIST MixerList ;
MIXER_STATUS Status ;
LPWAVE_INFO WaveInfo ;
2010-10-15 00:20:15 +00:00
/* verify mixer context */
2009-12-20 00:55:55 +00:00
Status = MMixerVerifyContext ( MixerContext ) ;
if ( Status ! = MM_STATUS_SUCCESS )
{
2010-10-15 00:20:15 +00:00
/* invalid context passed */
2009-12-20 00:55:55 +00:00
return Status ;
}
2010-10-15 00:20:15 +00:00
/* grab mixer list */
2009-12-20 00:55:55 +00:00
MixerList = ( PMIXER_LIST ) MixerContext - > MixerContext ;
/* find destination wave */
Status = MMixerGetWaveInfoByIndexAndType ( MixerList , DeviceIndex , TRUE , & WaveInfo ) ;
if ( Status ! = MM_STATUS_SUCCESS )
{
/* failed to find wave info */
return MM_STATUS_UNSUCCESSFUL ;
}
2010-10-15 00:20:15 +00:00
/* copy capabilities */
2009-12-20 00:55:55 +00:00
MixerContext - > Copy ( Caps , & WaveInfo - > u . InCaps , sizeof ( WAVEINCAPSW ) ) ;
return MM_STATUS_SUCCESS ;
}
MIXER_STATUS
MMixerWaveOutCapabilities (
IN PMIXER_CONTEXT MixerContext ,
IN ULONG DeviceIndex ,
OUT LPWAVEOUTCAPSW Caps )
{
PMIXER_LIST MixerList ;
MIXER_STATUS Status ;
LPWAVE_INFO WaveInfo ;
2010-10-15 00:20:15 +00:00
/* verify mixer context */
2009-12-20 00:55:55 +00:00
Status = MMixerVerifyContext ( MixerContext ) ;
if ( Status ! = MM_STATUS_SUCCESS )
{
2010-10-15 00:20:15 +00:00
/* invalid context passed */
2009-12-20 00:55:55 +00:00
return Status ;
}
2010-10-15 00:20:15 +00:00
/* grab mixer list */
2009-12-20 00:55:55 +00:00
MixerList = ( PMIXER_LIST ) MixerContext - > MixerContext ;
/* find destination wave */
Status = MMixerGetWaveInfoByIndexAndType ( MixerList , DeviceIndex , FALSE , & WaveInfo ) ;
if ( Status ! = MM_STATUS_SUCCESS )
{
/* failed to find wave info */
return MM_STATUS_UNSUCCESSFUL ;
}
2010-10-15 00:20:15 +00:00
/* copy capabilities */
2009-12-20 00:55:55 +00:00
MixerContext - > Copy ( Caps , & WaveInfo - > u . OutCaps , sizeof ( WAVEOUTCAPSW ) ) ;
return MM_STATUS_SUCCESS ;
}
ULONG
MMixerGetWaveInCount (
IN PMIXER_CONTEXT MixerContext )
{
PMIXER_LIST MixerList ;
MIXER_STATUS Status ;
2010-10-15 00:20:15 +00:00
/* verify mixer context */
2009-12-20 00:55:55 +00:00
Status = MMixerVerifyContext ( MixerContext ) ;
if ( Status ! = MM_STATUS_SUCCESS )
{
2010-10-15 00:20:15 +00:00
/* invalid context passed */
return Status ;
2009-12-20 00:55:55 +00:00
}
2010-10-15 00:20:15 +00:00
/* grab mixer list */
2009-12-20 00:55:55 +00:00
MixerList = ( PMIXER_LIST ) MixerContext - > MixerContext ;
return MixerList - > WaveInListCount ;
}
ULONG
MMixerGetWaveOutCount (
IN PMIXER_CONTEXT MixerContext )
{
PMIXER_LIST MixerList ;
MIXER_STATUS Status ;
2010-10-15 00:20:15 +00:00
/* verify mixer context */
2009-12-20 00:55:55 +00:00
Status = MMixerVerifyContext ( MixerContext ) ;
if ( Status ! = MM_STATUS_SUCCESS )
{
2010-10-15 00:20:15 +00:00
/* invalid context passed */
return Status ;
2009-12-20 00:55:55 +00:00
}
2010-10-15 00:20:15 +00:00
/* grab mixer list */
2009-12-20 00:55:55 +00:00
MixerList = ( PMIXER_LIST ) MixerContext - > MixerContext ;
return MixerList - > WaveOutListCount ;
}
2009-12-23 02:49:18 +00:00
MIXER_STATUS
MMixerSetWaveStatus (
IN PMIXER_CONTEXT MixerContext ,
IN HANDLE PinHandle ,
IN KSSTATE State )
{
KSPROPERTY Property ;
ULONG Length ;
2010-12-10 06:14:10 +00:00
MIXER_STATUS Status ;
/* verify mixer context */
Status = MMixerVerifyContext ( MixerContext ) ;
if ( Status ! = MM_STATUS_SUCCESS )
{
/* invalid context passed */
return Status ;
}
2009-12-23 02:49:18 +00:00
/* setup property request */
Property . Set = KSPROPSETID_Connection ;
Property . Id = KSPROPERTY_CONNECTION_STATE ;
Property . Flags = KSPROPERTY_TYPE_SET ;
return MixerContext - > Control ( PinHandle , IOCTL_KS_PROPERTY , & Property , sizeof ( KSPROPERTY ) , & State , sizeof ( KSSTATE ) , & Length ) ;
}
2010-02-12 06:18:31 +00:00
2010-12-10 06:14:10 +00:00
MIXER_STATUS
MMixerSetWaveResetState (
IN PMIXER_CONTEXT MixerContext ,
IN HANDLE PinHandle ,
IN ULONG bBegin )
{
ULONG Length ;
MIXER_STATUS Status ;
KSRESET Reset ;
/* verify mixer context */
Status = MMixerVerifyContext ( MixerContext ) ;
if ( Status ! = MM_STATUS_SUCCESS )
{
/* invalid context passed */
return Status ;
}
/* begin / stop reset */
Reset = ( bBegin ? KSRESET_BEGIN : KSRESET_END ) ;
return MixerContext - > Control ( PinHandle , IOCTL_KS_RESET_STATE , & Reset , sizeof ( KSRESET ) , NULL , 0 , & Length ) ;
}
2010-02-12 06:18:31 +00:00
MIXER_STATUS
MMixerGetWaveDevicePath (
IN PMIXER_CONTEXT MixerContext ,
IN ULONG bWaveIn ,
IN ULONG DeviceId ,
OUT LPWSTR * DevicePath )
{
PMIXER_LIST MixerList ;
LPMIXER_DATA MixerData ;
LPWAVE_INFO WaveInfo ;
ULONG Length ;
MIXER_STATUS Status ;
2010-10-15 00:20:15 +00:00
/* verify mixer context */
2010-02-12 06:18:31 +00:00
Status = MMixerVerifyContext ( MixerContext ) ;
if ( Status ! = MM_STATUS_SUCCESS )
{
2010-10-15 00:20:15 +00:00
/* invalid context passed */
2010-02-12 06:18:31 +00:00
return Status ;
}
2010-10-15 00:20:15 +00:00
/* grab mixer list */
2010-02-12 06:18:31 +00:00
MixerList = ( PMIXER_LIST ) MixerContext - > MixerContext ;
/* find destination wave */
Status = MMixerGetWaveInfoByIndexAndType ( MixerList , DeviceId , bWaveIn , & WaveInfo ) ;
if ( Status ! = MM_STATUS_SUCCESS )
{
/* failed to find wave info */
return MM_STATUS_INVALID_PARAMETER ;
}
/* get associated device id */
MixerData = MMixerGetDataByDeviceId ( MixerList , WaveInfo - > DeviceId ) ;
if ( ! MixerData )
return MM_STATUS_INVALID_PARAMETER ;
/* calculate length */
Length = wcslen ( MixerData - > DeviceName ) + 1 ;
/* allocate destination buffer */
* DevicePath = MixerContext - > Alloc ( Length * sizeof ( WCHAR ) ) ;
if ( ! * DevicePath )
{
/* no memory */
return MM_STATUS_NO_MEMORY ;
}
/* copy device path */
MixerContext - > Copy ( * DevicePath , MixerData - > DeviceName , Length * sizeof ( WCHAR ) ) ;
/* done */
return MM_STATUS_SUCCESS ;
}