Here is the code :
public class AudioMixerHelpe r
{
public const int MMSYSERR_NOERRO R = 0;
public const int MAXPNAMELEN = 32;
public const int MIXER_LONG_NAME _CHARS = 64;
public const int MIXER_SHORT_NAM E_CHARS = 16;
public const int MIXER_GETLINEIN FOF_COMPONENTTY PE = 0x3;
public const int MIXER_GETCONTRO LDETAILSF_VALUE = 0x0;
public const int MIXER_GETLINECO NTROLSF_ONEBYTY PE = 0x2;
public const int MIXER_SETCONTRO LDETAILSF_VALUE = 0x0;
public const int MIXERLINE_COMPO NENTTYPE_DST_FI RST = 0x0;
public const int MIXERLINE_COMPO NENTTYPE_SRC_FI RST = 0x1000;
public const int MIXERLINE_COMPO NENTTYPE_DST_SP EAKERS =
(MIXERLINE_COMP ONENTTYPE_DST_F IRST + 4);
public const int MIXERLINE_COMPO NENTTYPE_SRC_MI CROPHONE =
(MIXERLINE_COMP ONENTTYPE_SRC_F IRST + 3);
public const int MIXERLINE_COMPO NENTTYPE_SRC_LI NE =
(MIXERLINE_COMP ONENTTYPE_SRC_F IRST + 2);
public const int MIXERCONTROL_CT _CLASS_FADER = 0x50000000;
public const int MIXERCONTROL_CT _UNITS_UNSIGNED = 0x30000;
public const int MIXERCONTROL_CO NTROLTYPE_FADER =
(MIXERCONTROL_C T_CLASS_FADER | MIXERCONTROL_CT _UNITS_UNSIGNED );
public const int MIXERCONTROL_CO NTROLTYPE_VOLUM E =
(MIXERCONTROL_C ONTROLTYPE_FADE R + 1);
[ DllImport( "winmm.dll" , CharSet=CharSet .Ansi )]
private static extern int mixerClose (int hmx);
[ DllImport( "winmm.dll" , CharSet=CharSet .Ansi )]
private static extern int mixerGetControl DetailsA (int hmxobj,ref
MIXERCONTROLDET AILS pmxcd , int fdwDetails);
[ DllImport( "winmm.dll" , CharSet=CharSet .Ansi )]
private static extern int mixerGetDevCaps A( int uMxId, MIXERCAPS
pmxcaps, int cbmxcaps) ;
[ DllImport( "winmm.dll" , CharSet=CharSet .Ansi )]
private static extern int mixerGetID (int hmxobj, int pumxID, int
fdwId );
[ DllImport( "winmm.dll" , CharSet=CharSet .Ansi )]
private static extern int mixerGetLineCon trolsA (int hmxobj,ref
MIXERLINECONTRO LS pmxlc, int fdwControls);
[ DllImport( "winmm.dll" , CharSet=CharSet .Ansi )]
private static extern int mixerGetLineInf oA (int hmxobj,ref
MIXERLINE pmxl , int fdwInfo);
[ DllImport( "winmm.dll" , CharSet=CharSet .Ansi )]
private static extern int mixerGetNumDevs ();
[ DllImport( "winmm.dll" , CharSet=CharSet .Ansi )]
private static extern int mixerMessage(in t hmx , int uMsg , int
dwParam1 , int dwParam2);
[ DllImport( "winmm.dll" , CharSet=CharSet .Ansi )]
private static extern int mixerOpen (out int phmx , int uMxId ,
int dwCallback , int dwInstance , int fdwOpen);
[ DllImport( "winmm.dll" , CharSet=CharSet .Ansi )]
private static extern int mixerSetControl Details(int hmxobj ,ref
MIXERCONTROLDET AILS pmxcd , int fdwDetails);
public struct MIXERCAPS{
public int wMid ; // manufacturer id
public int wPid ; // product id
public int vDriverVersion ; // version of the driver
[ MarshalAs( UnmanagedType.B yValTStr, SizeConst=MAXPN AMELEN)]
public string szPname ; // product name
public int fdwSupport ; // misc. support bits
public int cDestinations ; // count of destinations
}
public struct MIXERCONTROL{
public int cbStruct ; // size in Byte of MIXERCONTROL
public int dwControlID ; // unique control id for mixer
device
public int dwControlType ; // MIXERCONTROL_CO NTROLpublic
enum _xxx
public int fdwControl ; // MIXERCONTROL_CO NTROLF_xxx
public int cMultipleItems ; // if
MIXERCONTROL_CO NTROLF_MULTIPLE
[ MarshalAs( UnmanagedType.B yValTStr,
SizeConst=MIXER _SHORT_NAME_CHA RS )]
public string szShortName ; // short name of
[ MarshalAs( UnmanagedType.B yValTStr,
SizeConst=MIXER _LONG_NAME_CHAR S )]
public string szName ; // long name of
public int lMinimum ; // Minimum value
public int lMaximum ; // Maximum value
// [ MarshalAs( UnmanagedType.B yValArray, SizeConst=10 )]
[ MarshalAs( UnmanagedType.U 4, SizeConst=10 )]
public int reserved; // replaced // reserved structure space
}
public struct MIXERCONTROLDET AILS{
public int cbStruct ; // size in Byte of MIXERCONTROLDET AILS
public int dwControlID ; // control id to get/set details on
public int cChannels ; // number of channels in paDetails
array
public int item ; // hwndOwner or cMultipleItems
public int cbDetails ; // size of _one_ details_XX struct
public IntPtr paDetails ; // pointer to array of details_XX
structs
}
public struct MIXERCONTROLDET AILS_UNSIGNED{
public int dwValue ; // value of the control
}
public struct MIXERLINE{
public int cbStruct ; // size of MIXERLINE structure
public int dwDestination ; // zero based destination
index
public int dwSource ; // zero based source index (if
// source)
public int dwLineID ; // unique line id for mixer
device
public int fdwLine ; // state/information about
line
public int dwUser ; // driver specific information
public int dwComponentType ; // component public enum
line connects to
public int cChannels ; // number of channels line
supports
public int cConnections ; // number of connections
(possible)
public int cControls ;
[ MarshalAs( UnmanagedType.B yValTStr,
SizeConst=MIXER _SHORT_NAME_CHA RS )] // number of controls at this
line
public string szShortName;
[ MarshalAs( UnmanagedType.B yValTStr,
SizeConst=MIXER _LONG_NAME_CHAR S )]
public string szName;
public int dwType ;
public int dwDeviceID ;
public int wMid ;
public int wPid ;
public int vDriverVersion ;
[ MarshalAs( UnmanagedType.B yValTStr, SizeConst=MAXPN AMELEN)]
public string szPname ;
}
public struct MIXERLINECONTRO LS{
public int cbStruct ; // size in Byte of MIXERLINECONTRO LS
public int dwLineID ; // line id (from MIXERLINE.dwLin eID)
// MIXER_GETLINECO NTROLSF_ONEBYID or
public int dwControl ; // MIXER_GETLINECO NTROLSF_ONEBYpu blic
enum
public int cControls ; // count of controls pmxctrl points to
public int cbmxctrl ; // size in Byte of _one_ MIXERCONTROL
public IntPtr pamxctrl ; // pointer to first MIXERCONTROL
array
}
private static bool GetVolumeContro l(int hmixer ,int componentType,
int ctrlType, out MIXERCONTROL mxc, out int vCurrentVol)
{
// This function attempts to obtain a mixer control.
// Returns True if successful.
MIXERLINECONTRO LS mxlc = new MIXERLINECONTRO LS();
MIXERLINE mxl = new MIXERLINE();
MIXERCONTROLDET AILS pmxcd = new MIXERCONTROLDET AILS();
MIXERCONTROLDET AILS_UNSIGNED du = new
MIXERCONTROLDET AILS_UNSIGNED() ;
mxc = new MIXERCONTROL();
int rc ;
bool retValue;
vCurrentVol = -1;
//mxl.szShortName = new string(' ', MIXER_SHORT_NAM E_CHARS);
//mxl.szName = new string(' ', MIXER_LONG_NAME _CHARS);
mxl.cbStruct = Marshal.SizeOf( mxl);
mxl.dwComponent Type = componentType ;
// Obtain a line corresponding to the component public enum
rc = mixerGetLineInf oA(hmixer,ref mxl,
MIXER_GETLINEIN FOF_COMPONENTTY PE );
if(MMSYSERR_NOE RROR == rc)
{
int sizeofMIXERCONT ROL = 152;
//Marshal.SizeOf( typeof(MIXERCON TROL))
int ctrl = Marshal.SizeOf( typeof(MIXERCON TROL));
mxlc.pamxctrl = Marshal.AllocCo TaskMem(sizeofM IXERCONTROL) ;//new
MIXERCONTROL();
mxlc.cbStruct = Marshal.SizeOf( mxlc);
mxlc.dwLineID = mxl.dwLineID;
mxlc.dwControl = ctrlType;
mxlc.cControls = 1;
mxlc.cbmxctrl = sizeofMIXERCONT ROL;
// Allocate a buffer for the control
mxc.cbStruct = sizeofMIXERCONT ROL;
// Get the control
rc = mixerGetLineCon trolsA(hmixer,r ef mxlc,
MIXER_GETLINECO NTROLSF_ONEBYTY PE);
if(MMSYSERR_NOE RROR == rc)
{
retValue = true;
// Copy the control into the destination structure
mxc = (MIXERCONTROL)M arshal.PtrToStr ucture(mxlc.pam xctrl,typeof(MI XERCONTROL));
}
else
{
retValue = false;
}
int sizeofMIXERCONT ROLDETAILS =
Marshal.SizeOf( typeof(MIXERCON TROLDETAILS));
int sizeofMIXERCONT ROLDETAILS_UNSI GNED =
Marshal.SizeOf( typeof(MIXERCON TROLDETAILS_UNS IGNED));
pmxcd.cbStruct = sizeofMIXERCONT ROLDETAILS;
pmxcd.dwControl ID = mxc.dwControlID ;
pmxcd.paDetails =
Marshal.AllocCo TaskMem(sizeofM IXERCONTROLDETA ILS_UNSIGNED) ;
pmxcd.cChannels = 1;
pmxcd.item = 0;
pmxcd.cbDetails = sizeofMIXERCONT ROLDETAILS_UNSI GNED;
rc = mixerGetControl DetailsA(hmixer ,ref pmxcd,
MIXER_GETCONTRO LDETAILSF_VALUE );
du = (MIXERCONTROLDE TAILS_UNSIGNED) Marshal.PtrToSt ructure(pmxcd.p aDetails,typeof (MIXERCONTROLDE TAILS_UNSIGNED) );
vCurrentVol = du.dwValue;
return retValue;
}
retValue = false;
return retValue;
}
private static bool SetVolumeContro l(int hmixer , MIXERCONTROL mxc ,
int volume )
{
// This function sets the value for a volume control.
// Returns True if successful
bool retValue;
int rc;
MIXERCONTROLDET AILS mxcd = new MIXERCONTROLDET AILS();
MIXERCONTROLDET AILS_UNSIGNED vol = new
MIXERCONTROLDET AILS_UNSIGNED() ;
mxcd.item = 0;
mxcd.dwControlI D = mxc.dwControlID ;
mxcd.cbStruct = Marshal.SizeOf( mxcd);
mxcd.cbDetails = Marshal.SizeOf( vol);
// Allocate a buffer for the control value buffer
mxcd.cChannels = 1;
vol.dwValue = volume;
// Copy the data into the control value buffer
//mxcd.paDetails =
vol;//(MIXERCONTROL)M arshal.PtrToStr ucture(mxlc.pam xctrl,typeof(MI XERCONTROL));
mxcd.paDetails = Marshal.AllocCo TaskMem(Marshal .SizeOf(typeof( MIXERCONTROLDET AILS_UNSIGNED)) );
Marshal.Structu reToPtr(vol, mxcd.paDetails, false);
// Set the control value
rc = mixerSetControl Details(hmixer, ref mxcd,
MIXER_SETCONTRO LDETAILSF_VALUE );
if(MMSYSERR_NOE RROR == rc)
{
retValue = true;
}
else
{
retValue = false;
}
return retValue;
}
public static int GetVolume()
{
int mixer;
MIXERCONTROL volCtrl = new MIXERCONTROL();
int currentVol;
mixerOpen(out mixer,0 ,0 ,0, 0);
int type = MIXERCONTROL_CO NTROLTYPE_VOLUM E;
GetVolumeContro l(mixer,
MIXERLINE_COMPO NENTTYPE_DST_SP EAKERS,type,out volCtrl, out
currentVol);
mixerClose(mixe r);
return currentVol;
}
public static void SetVolume(int vVolume)
{
int mixer;
MIXERCONTROL volCtrl = new MIXERCONTROL();
int currentVol;
mixerOpen(out mixer,0 ,0 ,0, 0);
int type = MIXERCONTROL_CO NTROLTYPE_VOLUM E;
GetVolumeContro l(mixer,
MIXERLINE_COMPO NENTTYPE_DST_SP EAKERS,type,out volCtrl, out
currentVol);
if(vVolume>volC trl.lMaximum) vVolume = volCtrl.lMaximu m;
if(vVolume<volC trl.lMinimum) vVolume = volCtrl.lMinimu m;
SetVolumeContro l(mixer, volCtrl, vVolume);
GetVolumeContro l(mixer,
MIXERLINE_COMPO NENTTYPE_DST_SP EAKERS,type,out volCtrl, out
currentVol);
if(vVolume!=cur rentVol)
{
throw new Exception("Cann ot Set Volume");
}
mixerClose(mixe r);
}
}