2009-12-07 10:28:49 +00:00
/*
* COPYRIGHT : See COPYING in the top level directory
* PROJECT : ReactOS Kernel Streaming
* FILE : lib / drivers / sound / mmixer / mmixer . c
* PURPOSE : Mixer Handling Functions
* PROGRAMMER : Johannes Anderwald
*/
# include "priv.h"
2009-12-09 09:51:39 +00:00
ULONG
MMixerGetCount (
IN PMIXER_CONTEXT MixerContext )
{
PMIXER_LIST MixerList ;
MIXER_STATUS Status ;
// verify mixer context
Status = MMixerVerifyContext ( MixerContext ) ;
if ( Status ! = MM_STATUS_SUCCESS )
{
// invalid context passed
return Status ;
}
// grab mixer list
MixerList = ( PMIXER_LIST ) MixerContext - > MixerContext ;
// return number of mixers
return MixerList - > MixerListCount ;
}
MIXER_STATUS
MMixerGetCapabilities (
IN PMIXER_CONTEXT MixerContext ,
IN ULONG MixerIndex ,
OUT LPMIXERCAPSW MixerCaps )
{
MIXER_STATUS Status ;
LPMIXER_INFO MixerInfo ;
// verify mixer context
Status = MMixerVerifyContext ( MixerContext ) ;
if ( Status ! = MM_STATUS_SUCCESS )
{
// invalid context passed
return Status ;
}
// get mixer info
MixerInfo = MMixerGetMixerInfoByIndex ( MixerContext , MixerIndex ) ;
if ( ! MixerInfo )
{
// invalid device index
return MM_STATUS_INVALID_PARAMETER ;
}
MixerCaps - > wMid = MixerInfo - > MixCaps . wMid ;
MixerCaps - > wPid = MixerInfo - > MixCaps . wPid ;
MixerCaps - > vDriverVersion = MixerInfo - > MixCaps . vDriverVersion ;
MixerCaps - > fdwSupport = MixerInfo - > MixCaps . fdwSupport ;
MixerCaps - > cDestinations = MixerInfo - > MixCaps . cDestinations ;
wcscpy ( MixerCaps - > szPname , MixerInfo - > MixCaps . szPname ) ;
return MM_STATUS_SUCCESS ;
}
MIXER_STATUS
MMixerOpen (
IN PMIXER_CONTEXT MixerContext ,
2009-12-09 16:00:28 +00:00
IN ULONG MixerId ,
2009-12-09 09:51:39 +00:00
IN PVOID MixerEvent ,
IN PMIXER_EVENT MixerEventRoutine ,
OUT PHANDLE MixerHandle )
{
MIXER_STATUS Status ;
2009-12-09 16:00:28 +00:00
LPMIXER_INFO MixerInfo ;
2009-12-09 09:51:39 +00:00
// verify mixer context
Status = MMixerVerifyContext ( MixerContext ) ;
if ( Status ! = MM_STATUS_SUCCESS )
{
// invalid context passed
return Status ;
}
2009-12-09 16:00:28 +00:00
MixerInfo = ( LPMIXER_INFO ) MMixerGetMixerInfoByIndex ( MixerContext , MixerId ) ;
if ( ! MixerInfo )
{
// invalid mixer id
return MM_STATUS_INVALID_PARAMETER ;
}
// FIXME
// handle event notification
2010-01-02 01:52:12 +00:00
Status = MMixerAddEvents ( MixerContext , MixerInfo ) ;
2009-12-09 16:00:28 +00:00
// store result
* MixerHandle = ( HANDLE ) MixerInfo ;
return MM_STATUS_SUCCESS ;
2009-12-09 09:51:39 +00:00
}
MIXER_STATUS
MMixerGetLineInfo (
IN PMIXER_CONTEXT MixerContext ,
IN HANDLE MixerHandle ,
IN ULONG Flags ,
OUT LPMIXERLINEW MixerLine )
{
MIXER_STATUS Status ;
2009-12-09 16:00:28 +00:00
LPMIXER_INFO MixerInfo ;
LPMIXERLINE_EXT MixerLineSrc ;
2009-12-09 09:51:39 +00:00
// verify mixer context
Status = MMixerVerifyContext ( MixerContext ) ;
if ( Status ! = MM_STATUS_SUCCESS )
{
// invalid context passed
return Status ;
}
2009-12-09 16:00:28 +00:00
// clear hmixer from flags
Flags & = ~ MIXER_OBJECTF_HMIXER ;
if ( Flags = = MIXER_GETLINEINFOF_DESTINATION )
{
// cast to mixer info
MixerInfo = ( LPMIXER_INFO ) MixerHandle ;
if ( MixerLine - > dwDestination ! = 0 )
{
// destination line member must be zero
return MM_STATUS_INVALID_PARAMETER ;
}
MixerLineSrc = MMixerGetSourceMixerLineByLineId ( MixerInfo , DESTINATION_LINE ) ;
ASSERT ( MixerLineSrc ) ;
MixerContext - > Copy ( MixerLine , & MixerLineSrc - > Line , sizeof ( MIXERLINEW ) ) ;
return MM_STATUS_SUCCESS ;
}
else if ( Flags = = MIXER_GETLINEINFOF_SOURCE )
{
// cast to mixer info
MixerInfo = ( LPMIXER_INFO ) MixerHandle ;
MixerLineSrc = MMixerGetSourceMixerLineByLineId ( MixerInfo , DESTINATION_LINE ) ;
ASSERT ( MixerLineSrc ) ;
if ( MixerLine - > dwSource > = MixerLineSrc - > Line . cConnections )
{
DPRINT1 ( " dwSource %u > Destinations %u \n " , MixerLine - > dwSource , MixerLineSrc - > Line . cConnections ) ;
// invalid parameter
return MM_STATUS_INVALID_PARAMETER ;
}
2010-01-02 01:52:12 +00:00
MixerLineSrc = MMixerGetSourceMixerLineByLineId ( MixerInfo , MixerLine - > dwSource * 0x10000 ) ;
2009-12-09 16:00:28 +00:00
if ( MixerLineSrc )
{
DPRINT ( " Line %u Name %S \n " , MixerLineSrc - > Line . dwSource , MixerLineSrc - > Line . szName ) ;
MixerContext - > Copy ( MixerLine , & MixerLineSrc - > Line , sizeof ( MIXERLINEW ) ) ;
return MM_STATUS_SUCCESS ;
}
return MM_STATUS_UNSUCCESSFUL ;
}
else if ( Flags = = MIXER_GETLINEINFOF_LINEID )
{
// cast to mixer info
MixerInfo = ( LPMIXER_INFO ) MixerHandle ;
MixerLineSrc = MMixerGetSourceMixerLineByLineId ( MixerInfo , MixerLine - > dwLineID ) ;
if ( ! MixerLineSrc )
{
// invalid parameter
return MM_STATUS_INVALID_PARAMETER ;
}
/* copy cached data */
MixerContext - > Copy ( MixerLine , & MixerLineSrc - > Line , sizeof ( MIXERLINEW ) ) ;
return MM_STATUS_SUCCESS ;
}
else if ( Flags = = MIXER_GETLINEINFOF_COMPONENTTYPE )
{
// cast to mixer info
MixerInfo = ( LPMIXER_INFO ) MixerHandle ;
MixerLineSrc = MMixerGetSourceMixerLineByComponentType ( MixerInfo , MixerLine - > dwComponentType ) ;
if ( ! MixerLineSrc )
{
DPRINT1 ( " Failed to find component type %x \n " , MixerLine - > dwComponentType ) ;
return MM_STATUS_UNSUCCESSFUL ;
}
ASSERT ( MixerLineSrc ) ;
/* copy cached data */
MixerContext - > Copy ( MixerLine , & MixerLineSrc - > Line , sizeof ( MIXERLINEW ) ) ;
return MM_STATUS_SUCCESS ;
}
2009-12-09 09:51:39 +00:00
return MM_STATUS_NOT_IMPLEMENTED ;
}
MIXER_STATUS
MMixerGetLineControls (
IN PMIXER_CONTEXT MixerContext ,
IN HANDLE MixerHandle ,
IN ULONG Flags ,
2009-12-20 00:55:55 +00:00
OUT LPMIXERLINECONTROLSW MixerLineControls )
2009-12-09 09:51:39 +00:00
{
2009-12-09 16:00:28 +00:00
LPMIXER_INFO MixerInfo ;
LPMIXERLINE_EXT MixerLineSrc ;
LPMIXERCONTROLW MixerControl ;
2009-12-09 09:51:39 +00:00
MIXER_STATUS Status ;
2009-12-09 16:00:28 +00:00
ULONG Index ;
2009-12-09 09:51:39 +00:00
// verify mixer context
Status = MMixerVerifyContext ( MixerContext ) ;
if ( Status ! = MM_STATUS_SUCCESS )
{
// invalid context passed
return Status ;
}
2009-12-09 16:00:28 +00:00
Flags & = ~ MIXER_OBJECTF_HMIXER ;
if ( Flags = = MIXER_GETLINECONTROLSF_ALL )
{
// cast to mixer info
MixerInfo = ( LPMIXER_INFO ) MixerHandle ;
MixerLineSrc = MMixerGetSourceMixerLineByLineId ( MixerInfo , MixerLineControls - > dwLineID ) ;
if ( ! MixerLineSrc )
{
// invalid line id
return MM_STATUS_INVALID_PARAMETER ;
}
// copy line control(s)
MixerContext - > Copy ( MixerLineControls - > pamxctrl , MixerLineSrc - > LineControls , min ( MixerLineSrc - > Line . cControls , MixerLineControls - > cControls ) * sizeof ( MIXERCONTROLW ) ) ;
return MM_STATUS_SUCCESS ;
}
else if ( Flags = = MIXER_GETLINECONTROLSF_ONEBYTYPE )
{
// cast to mixer info
MixerInfo = ( LPMIXER_INFO ) MixerHandle ;
MixerLineSrc = MMixerGetSourceMixerLineByLineId ( MixerInfo , MixerLineControls - > dwLineID ) ;
if ( ! MixerLineSrc )
{
// invalid line id
return MM_STATUS_INVALID_PARAMETER ;
}
ASSERT ( MixerLineSrc ) ;
Index = 0 ;
for ( Index = 0 ; Index < MixerLineSrc - > Line . cControls ; Index + + )
{
DPRINT ( " dwControlType %x \n " , MixerLineSrc - > LineControls [ Index ] . dwControlType ) ;
if ( MixerLineControls - > dwControlType = = MixerLineSrc - > LineControls [ Index ] . dwControlType )
{
// found a control with that type
MixerContext - > Copy ( MixerLineControls - > pamxctrl , & MixerLineSrc - > LineControls [ Index ] , sizeof ( MIXERCONTROLW ) ) ;
return MM_STATUS_SUCCESS ;
}
}
DPRINT ( " DeviceInfo->u.MixControls.dwControlType %x not found in Line %x cControls %u \n " , MixerLineControls - > dwControlType , MixerLineControls - > dwLineID , MixerLineSrc - > Line . cControls ) ;
return MM_STATUS_UNSUCCESSFUL ;
}
else if ( Flags = = MIXER_GETLINECONTROLSF_ONEBYID )
{
// cast to mixer info
MixerInfo = ( LPMIXER_INFO ) MixerHandle ;
Status = MMixerGetMixerControlById ( MixerInfo , MixerLineControls - > dwControlID , NULL , & MixerControl , NULL ) ;
if ( Status ! = MM_STATUS_SUCCESS )
{
// invalid parameter
return MM_STATUS_INVALID_PARAMETER ;
}
// copy the controls
MixerContext - > Copy ( MixerLineControls - > pamxctrl , MixerControl , sizeof ( MIXERCONTROLW ) ) ;
return MM_STATUS_SUCCESS ;
}
2009-12-09 09:51:39 +00:00
return MM_STATUS_NOT_IMPLEMENTED ;
}
MIXER_STATUS
MMixerSetControlDetails (
IN PMIXER_CONTEXT MixerContext ,
IN HANDLE MixerHandle ,
IN ULONG Flags ,
OUT LPMIXERCONTROLDETAILS MixerControlDetails )
{
MIXER_STATUS Status ;
2009-12-09 16:00:28 +00:00
ULONG NodeId ;
LPMIXER_INFO MixerInfo ;
LPMIXERLINE_EXT MixerLine ;
LPMIXERCONTROLW MixerControl ;
2009-12-09 09:51:39 +00:00
// verify mixer context
Status = MMixerVerifyContext ( MixerContext ) ;
if ( Status ! = MM_STATUS_SUCCESS )
{
// invalid context passed
return Status ;
}
2009-12-09 16:00:28 +00:00
// get mixer info
MixerInfo = ( LPMIXER_INFO ) MixerHandle ;
// get mixer control
Status = MMixerGetMixerControlById ( MixerInfo , MixerControlDetails - > dwControlID , & MixerLine , & MixerControl , & NodeId ) ;
// check for success
if ( Status ! = MM_STATUS_SUCCESS )
{
// failed to find control id
return MM_STATUS_INVALID_PARAMETER ;
}
switch ( MixerControl - > dwControlType )
{
case MIXERCONTROL_CONTROLTYPE_MUTE :
Status = MMixerSetGetMuteControlDetails ( MixerContext , MixerInfo - > hMixer , NodeId , MixerLine - > Line . dwLineID , MixerControlDetails , TRUE ) ;
break ;
case MIXERCONTROL_CONTROLTYPE_VOLUME :
Status = MMixerSetGetVolumeControlDetails ( MixerContext , MixerInfo - > hMixer , NodeId , TRUE , MixerControl , MixerControlDetails , MixerLine ) ;
break ;
default :
Status = MM_STATUS_NOT_IMPLEMENTED ;
}
return Status ;
2009-12-09 09:51:39 +00:00
}
MIXER_STATUS
MMixerGetControlDetails (
IN PMIXER_CONTEXT MixerContext ,
IN HANDLE MixerHandle ,
IN ULONG Flags ,
OUT LPMIXERCONTROLDETAILS MixerControlDetails )
{
MIXER_STATUS Status ;
2009-12-09 16:00:28 +00:00
ULONG NodeId ;
LPMIXER_INFO MixerInfo ;
LPMIXERLINE_EXT MixerLine ;
LPMIXERCONTROLW MixerControl ;
2009-12-09 09:51:39 +00:00
// verify mixer context
Status = MMixerVerifyContext ( MixerContext ) ;
if ( Status ! = MM_STATUS_SUCCESS )
{
// invalid context passed
return Status ;
}
2009-12-09 16:00:28 +00:00
// get mixer info
MixerInfo = ( LPMIXER_INFO ) MixerHandle ;
// get mixer control
Status = MMixerGetMixerControlById ( MixerInfo , MixerControlDetails - > dwControlID , & MixerLine , & MixerControl , & NodeId ) ;
// check for success
if ( Status ! = MM_STATUS_SUCCESS )
{
// failed to find control id
return MM_STATUS_INVALID_PARAMETER ;
}
switch ( MixerControl - > dwControlType )
{
case MIXERCONTROL_CONTROLTYPE_MUTE :
Status = MMixerSetGetMuteControlDetails ( MixerContext , MixerInfo - > hMixer , NodeId , MixerLine - > Line . dwLineID , MixerControlDetails , FALSE ) ;
break ;
case MIXERCONTROL_CONTROLTYPE_VOLUME :
Status = MMixerSetGetVolumeControlDetails ( MixerContext , MixerInfo - > hMixer , NodeId , FALSE , MixerControl , MixerControlDetails , MixerLine ) ;
break ;
default :
Status = MM_STATUS_NOT_IMPLEMENTED ;
}
return Status ;
2009-12-09 09:51:39 +00:00
}
2009-12-07 10:28:49 +00:00
MIXER_STATUS
MMixerInitialize (
2009-12-08 21:10:02 +00:00
IN PMIXER_CONTEXT MixerContext ,
2009-12-07 10:28:49 +00:00
IN PMIXER_ENUM EnumFunction ,
IN PVOID EnumContext )
{
MIXER_STATUS Status ;
2009-12-18 10:25:41 +00:00
HANDLE hMixer , hKey ;
2009-12-07 10:28:49 +00:00
ULONG DeviceIndex , Count ;
LPWSTR DeviceName ;
2009-12-18 10:25:41 +00:00
LPMIXER_DATA MixerData ;
2009-12-09 09:51:39 +00:00
PMIXER_LIST MixerList ;
2009-12-18 10:25:41 +00:00
PLIST_ENTRY Entry ;
2009-12-07 10:28:49 +00:00
if ( ! MixerContext | | ! EnumFunction | | ! EnumContext )
{
// invalid parameter
return MM_STATUS_INVALID_PARAMETER ;
}
2010-01-02 01:52:12 +00:00
if ( ! MixerContext - > Alloc | | ! MixerContext - > Control | | ! MixerContext - > Free | | ! MixerContext - > Open | |
! MixerContext - > AllocEventData | | ! MixerContext - > FreeEventData | |
2009-12-18 10:25:41 +00:00
! MixerContext - > Close | | ! MixerContext - > OpenKey | | ! MixerContext - > QueryKeyValue | | ! MixerContext - > CloseKey )
2009-12-07 10:28:49 +00:00
{
// invalid parameter
return MM_STATUS_INVALID_PARAMETER ;
}
2009-12-09 09:51:39 +00:00
// allocate a mixer list
MixerList = ( PMIXER_LIST ) MixerContext - > Alloc ( sizeof ( MIXER_LIST ) ) ;
if ( ! MixerList )
{
// no memory
return MM_STATUS_NO_MEMORY ;
}
//initialize mixer list
MixerList - > MixerListCount = 0 ;
2009-12-18 10:25:41 +00:00
MixerList - > MixerDataCount = 0 ;
2009-12-20 00:55:55 +00:00
MixerList - > WaveInListCount = 0 ;
MixerList - > WaveOutListCount = 0 ;
2009-12-09 09:51:39 +00:00
InitializeListHead ( & MixerList - > MixerList ) ;
2009-12-18 10:25:41 +00:00
InitializeListHead ( & MixerList - > MixerData ) ;
2009-12-20 00:55:55 +00:00
InitializeListHead ( & MixerList - > WaveInList ) ;
InitializeListHead ( & MixerList - > WaveOutList ) ;
2009-12-07 10:28:49 +00:00
2009-12-10 12:27:16 +00:00
// store mixer list
MixerContext - > MixerContext = ( PVOID ) MixerList ;
2009-12-07 10:28:49 +00:00
// start enumerating all available devices
Count = 0 ;
DeviceIndex = 0 ;
do
{
// enumerate a device
2009-12-18 10:25:41 +00:00
Status = EnumFunction ( EnumContext , DeviceIndex , & DeviceName , & hMixer , & hKey ) ;
2009-12-07 10:28:49 +00:00
if ( Status ! = MM_STATUS_SUCCESS )
{
//check error code
2009-12-10 12:27:16 +00:00
if ( Status = = MM_STATUS_NO_MORE_DEVICES )
2009-12-07 10:28:49 +00:00
{
2009-12-10 12:27:16 +00:00
// enumeration has finished
break ;
2009-12-07 10:28:49 +00:00
}
}
2009-12-10 12:27:16 +00:00
else
{
2009-12-18 10:25:41 +00:00
// create a mixer data entry
Status = MMixerCreateMixerData ( MixerContext , MixerList , DeviceIndex , DeviceName , hMixer , hKey ) ;
if ( Status ! = MM_STATUS_SUCCESS )
break ;
2009-12-10 12:27:16 +00:00
}
2009-12-07 10:28:49 +00:00
// increment device index
DeviceIndex + + ;
} while ( TRUE ) ;
2009-12-18 10:25:41 +00:00
//now all filters have been pre-opened
// lets enumerate the filters
Entry = MixerList - > MixerData . Flink ;
while ( Entry ! = & MixerList - > MixerData )
{
MixerData = ( LPMIXER_DATA ) CONTAINING_RECORD ( Entry , MIXER_DATA , Entry ) ;
MMixerSetupFilter ( MixerContext , MixerList , MixerData , & Count ) ;
Entry = Entry - > Flink ;
}
2009-12-07 10:28:49 +00:00
// done
2009-12-10 12:27:16 +00:00
return MM_STATUS_SUCCESS ;
2009-12-07 10:28:49 +00:00
}