How to control the system audio device such as volume and mute(Win API)

I like to use WIN API to write codes. :)
The following several functions can be used to control audio device.
The mixer- serial system functions must be invoked in your application.  if you are familiar with these functions, you can find its so easy.

1.Initate the audio device to get its handle. mixerOpen function is used.

BOOL InitMixerDev(HMIXER *m_hMixer, HWND hwnd)
{
    
//初始化声音控制
    MIXERCAPS mxcaps;    //混频器容量
    ZeroMemory(&mxcaps, sizeof(MIXERCAPS));
    
if (mixerGetNumDevs() != 0)
    
{
        
if (mixerOpen(m_hMixer,0,(DWORD)hwnd,NULL,MIXER_OBJECTF_MIXER | CALLBACK_WINDOW)!= MMSYSERR_NOERROR)
            
return FALSE;
        
//The mixerGetDevCaps function queries a specified mixer device to determine its capabilities
        if (mixerGetDevCaps((UINT)*m_hMixer, &mxcaps, sizeof(MIXERCAPS))!= MMSYSERR_NOERROR)
            
return FALSE;
    }

    
if (*m_hMixer == NULL) 
        
return FALSE;
    
return TRUE;
}




mixerGetLIneInfo function is to get channel number , control number and lineID.
mixerGetlineControls is to get control ID through channel and line ID.
mixerGetControlsDetails and mixerSetControlDetails are used to control audio device through control and control ID.

It is careful to set MIXERCONTROL, MIXERCONTROLDETAILS struct.

BOOL GetVolume(HMIXER m_hMixer, DWORD dwSrcType, DWORD* pdwLValue, DWORD* pdwRValue, BOOL bMono = FALSE)
{
    MIXERLINE mxl;       
//混频器线路数
    mxl.cbStruct = sizeof(MIXERLINE);//必须初始化
    mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS; 
    
if (mixerGetLineInfo((HMIXEROBJ)m_hMixer,&mxl,
        MIXER_OBJECTF_HMIXER 
|MIXER_GETLINEINFOF_COMPONENTTYPE)!= MMSYSERR_NOERROR)  
        
return FALSE;

    
if(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS!=dwSrcType)
    
{
        DWORD num
=0,connections = mxl.cConnections ;
        DWORD type 
= mxl.dwDestination; 
        
do
        
{
            mxl.cbStruct      
= sizeof(MIXERLINE);
            mxl.dwDestination 
= type;
            mxl.dwSource      
= num++;
            
if(mixerGetLineInfo((HMIXEROBJ)m_hMixer, &mxl, MIXER_GETLINEINFOF_SOURCE|MIXER_OBJECTF_HMIXER)!= MMSYSERR_NOERROR)
            
{
                MessageBox(NULL,_T(
"GetLinInfo Resource faile!"),_T("Error"),MB_OK);
                
return FALSE;
            }


        }
while(num < connections && mxl.dwComponentType != dwSrcType);
    }

    

    DWORD m_controlnum 
= mxl.cChannels; //声道数量
    
    LPMIXERCONTROL pmxc;
    DWORD cbmxctrl 
= sizeof(MIXERCONTROL)*mxl.cControls;
    pmxc 
= (LPMIXERCONTROL)LocalAlloc(LPTR,cbmxctrl);
    MIXERLINECONTROLS mxlc;
    mxlc.cbStruct 
= sizeof(MIXERLINECONTROLS);
    mxlc.dwLineID 
= mxl.dwLineID;
    mxlc.dwControlType 
=MIXERCONTROL_CONTROLTYPE_VOLUME; 
    mxlc.cControls 
=mxl.cControls;
    mxlc.cbmxctrl 
= cbmxctrl;
    mxlc.pamxctrl 
= pmxc;
    
if (mixerGetLineControls((HMIXEROBJ)m_hMixer,
        
&mxlc,MIXER_OBJECTF_HMIXER |MIXER_GETLINECONTROLSF_ONEBYTYPE )!= MMSYSERR_NOERROR)
    
{
        LocalFree(pmxc);
        
return FALSE;
    }

    DWORD m_controlid 
= pmxc->dwControlID;
    
long m_min=pmxc->Bounds.lMinimum; 
    
long m_max= pmxc->Bounds.lMaximum; 
    LocalFree(pmxc);

    MIXERCONTROLDETAILS_SIGNED mxcdVolume[
2];
    MIXERCONTROLDETAILS mxcd;
    mxcd.cbStruct 
= sizeof(MIXERCONTROLDETAILS);
    mxcd.dwControlID 
= m_controlid;
    mxcd.cChannels 
= m_controlnum;
    mxcd.cMultipleItems 
= 0;
    mxcd.cbDetails 
= sizeof(MIXERCONTROLDETAILS_SIGNED);
    mxcd.paDetails 
= mxcdVolume;
    
if (mixerGetControlDetails((HMIXEROBJ)m_hMixer,
        
&mxcd,MIXER_OBJECTF_HMIXER |
        MIXER_GETCONTROLDETAILSF_VALUE)
!= MMSYSERR_NOERROR)          
        
return FALSE;
    
*pdwLValue =mxcdVolume[0].lValue;  
    
if(m_controlnum==2)   
    
{
        
*pdwRValue=mxcdVolume[1].lValue;
    }

    
return TRUE;
}



BOOL SetVolume(HMIXER m_hMixer, DWORD dwSrcType,DWORD dwLValue, DWORD dwRValue, BOOL bMono = FALSE)
{
    MIXERLINE mxl;       
//混频器线路数
    mxl.cbStruct = sizeof(MIXERLINE);//必须初始化
    mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS; 
    
if (mixerGetLineInfo((HMIXEROBJ)m_hMixer,&mxl,
        MIXER_OBJECTF_HMIXER 
|MIXER_GETLINEINFOF_COMPONENTTYPE)!= MMSYSERR_NOERROR)  
        
return FALSE;

    
if(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS!=dwSrcType)
    
{
        DWORD num
=0,connections = mxl.cConnections ;
        DWORD type 
= mxl.dwDestination; 
        
do
        
{
            mxl.cbStruct      
= sizeof(MIXERLINE);
            mxl.dwDestination 
= type;
            mxl.dwSource      
= num++;
            
if(mixerGetLineInfo((HMIXEROBJ)m_hMixer, &mxl, MIXER_GETLINEINFOF_SOURCE|MIXER_OBJECTF_HMIXER)!= MMSYSERR_NOERROR)
            
{
                MessageBox(NULL,_T(
"GetLinInfo Resource faile!"),_T("Error"),MB_OK);
                
return FALSE;
            }


        }
while(num < connections && mxl.dwComponentType != dwSrcType);
    }



    DWORD m_controlnum 
= mxl.cChannels; //声道数量

    LPMIXERCONTROL pmxc;
    DWORD cbmxctrl 
= sizeof(MIXERCONTROL)*mxl.cControls;
    pmxc 
= (LPMIXERCONTROL)LocalAlloc(LPTR,cbmxctrl);
    MIXERLINECONTROLS mxlc;
    mxlc.cbStruct 
= sizeof(MIXERLINECONTROLS);
    mxlc.dwLineID 
= mxl.dwLineID;
    mxlc.dwControlType 
=MIXERCONTROL_CONTROLTYPE_VOLUME; 
    mxlc.cControls 
=mxl.cControls;
    mxlc.cbmxctrl 
=cbmxctrl;
    mxlc.pamxctrl 
= pmxc;
    
if (mixerGetLineControls((HMIXEROBJ)m_hMixer,
        
&mxlc,MIXER_OBJECTF_HMIXER |MIXER_GETLINECONTROLSF_ONEBYTYPE )!= MMSYSERR_NOERROR)
    
{
        LocalFree(pmxc);
        
return FALSE;
    }

    DWORD m_controlid 
= pmxc->dwControlID;
    
long m_min=pmxc->Bounds.lMinimum; 
    
long m_max= pmxc->Bounds.lMaximum; 
    LocalFree(pmxc);

    MIXERCONTROLDETAILS_SIGNED mxcdVolume[
2];
    MIXERCONTROLDETAILS mxcd;
    mxcdVolume[
0].lValue=dwLValue;
    
if(m_controlnum==2)   
            mxcdVolume[
1].lValue=dwRValue;
    mxcd.cbStruct 
= sizeof(MIXERCONTROLDETAILS);
    mxcd.dwControlID 
= m_controlid;
    mxcd.cChannels 
= 2;
    mxcd.cMultipleItems 
= 0;
    mxcd.cbDetails 
= sizeof(MIXERCONTROLDETAILS_SIGNED);
    mxcd.paDetails 
= mxcdVolume;
    
if (mixerSetControlDetails((HMIXEROBJ)m_hMixer,
        
&mxcd,MIXER_OBJECTF_HMIXER |
        MIXER_SETCONTROLDETAILSF_VALUE)
!= MMSYSERR_NOERROR)
        
return FALSE;

    
return TRUE;
}



BOOL SetMute(HMIXER m_hMixer,DWORD dwSrcType, BOOL bValue)
{
    MIXERLINE mxl;       
//混频器线路数
    mxl.cbStruct = sizeof(MIXERLINE);//必须初始化
    mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS; 
    
if (mixerGetLineInfo((HMIXEROBJ)m_hMixer,&mxl,
        MIXER_OBJECTF_HMIXER 
|MIXER_GETLINEINFOF_COMPONENTTYPE)!= MMSYSERR_NOERROR)  
        
return FALSE;

    
if(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS!=dwSrcType)
    
{
        DWORD num
=0,connections = mxl.cConnections ;
        DWORD type 
= mxl.dwDestination; 
        
do
        
{
            mxl.cbStruct      
= sizeof(MIXERLINE);
            mxl.dwDestination 
= type;
            mxl.dwSource      
= num++;
            
if(mixerGetLineInfo((HMIXEROBJ)m_hMixer, &mxl, MIXER_GETLINEINFOF_SOURCE|MIXER_OBJECTF_HMIXER)!= MMSYSERR_NOERROR)
            
{
                MessageBox(NULL,_T(
"GetLinInfo Resource faile!"),_T("Error"),MB_OK);
                
return FALSE;
            }


        }
while(num < connections && mxl.dwComponentType != dwSrcType);
    }



    DWORD m_Channelnum 
= mxl.cChannels; //声道数量

    LPMIXERCONTROL pmxc;
    DWORD cbmxctrl 
= sizeof(MIXERCONTROL)*mxl.cControls;
    pmxc 
= (LPMIXERCONTROL)LocalAlloc(LPTR,cbmxctrl);
    MIXERLINECONTROLS mxlc;
    mxlc.cbStruct 
= sizeof(MIXERLINECONTROLS);
    mxlc.dwLineID 
= mxl.dwLineID;
    mxlc.dwControlType 
=MIXERCONTROL_CONTROLTYPE_MUTE; 
    mxlc.cControls 
=mxl.cControls;
    mxlc.cbmxctrl 
= cbmxctrl;
    mxlc.pamxctrl 
= pmxc;
    
if (mixerGetLineControls((HMIXEROBJ)m_hMixer,
        
&mxlc,MIXER_OBJECTF_HMIXER |MIXER_GETLINECONTROLSF_ONEBYTYPE )!= MMSYSERR_NOERROR)
    
{
        LocalFree(pmxc);
        
return FALSE;
    }


    DWORD m_controlid 
= pmxc->dwControlID;
    LocalFree(pmxc);

    
    MIXERCONTROLDETAILS_BOOLEAN  mxcd_f; mxcd_f.fValue 
= bValue;
    MIXERCONTROLDETAILS mxcd;
    mxcd.cbStruct 
= sizeof(MIXERCONTROLDETAILS);
    mxcd.dwControlID 
= m_controlid;
    mxcd.cChannels 
= 1;
    mxcd.cMultipleItems 
= 0;
    mxcd.cbDetails 
= sizeof(MIXERCONTROLDETAILS_BOOLEAN);
    mxcd.paDetails 
= &mxcd_f;
    
if (mixerSetControlDetails((HMIXEROBJ)m_hMixer,
        
&mxcd,MIXER_OBJECTF_HMIXER |
        MIXER_SETCONTROLDETAILSF_VALUE)
!= MMSYSERR_NOERROR)  
    
{

        
return FALSE;
    }


    
return TRUE;
}







BOOL GetMute(HMIXER m_hMixer,DWORD dwSrcType, BOOL* PbValue)
{
    MIXERLINE mxl;       
//混频器线路数
    mxl.cbStruct = sizeof(MIXERLINE);//必须初始化
    mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS; 
    
if (mixerGetLineInfo((HMIXEROBJ)m_hMixer,&mxl,
        MIXER_OBJECTF_HMIXER 
|MIXER_GETLINEINFOF_COMPONENTTYPE)!= MMSYSERR_NOERROR)  
        
return FALSE;

    
if(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS!=dwSrcType)
    
{
        DWORD num
=0,connections = mxl.cConnections ;
        DWORD type 
= mxl.dwDestination; 
        
do
        
{
            mxl.cbStruct      
= sizeof(MIXERLINE);
            mxl.dwDestination 
= type;
            mxl.dwSource      
= num++;
            
if(mixerGetLineInfo((HMIXEROBJ)m_hMixer, &mxl, MIXER_GETLINEINFOF_SOURCE|MIXER_OBJECTF_HMIXER)!= MMSYSERR_NOERROR)
            
{
                MessageBox(NULL,_T(
"GetLinInfo Resource faile!"),_T("Error"),MB_OK);
                
return FALSE;
            }


        }
while(num < connections && mxl.dwComponentType != dwSrcType);
    }



    DWORD m_controlnum 
= mxl.cChannels; //声道数量

    LPMIXERCONTROL pmxc;
    DWORD cbmxctrl 
= sizeof(MIXERCONTROL)*mxl.cControls;
    pmxc 
= (LPMIXERCONTROL)LocalAlloc(LPTR,cbmxctrl);
    MIXERLINECONTROLS mxlc;
    mxlc.cbStruct 
= sizeof(MIXERLINECONTROLS);
    mxlc.dwLineID 
= mxl.dwLineID;
    mxlc.dwControlType 
=MIXERCONTROL_CONTROLTYPE_MUTE; 
    mxlc.cControls 
=mxl.cControls;
    mxlc.cbmxctrl 
=cbmxctrl;
    mxlc.pamxctrl 
= pmxc;
    
if (mixerGetLineControls((HMIXEROBJ)m_hMixer,
        
&mxlc,MIXER_OBJECTF_HMIXER |MIXER_GETLINECONTROLSF_ONEBYTYPE )!= MMSYSERR_NOERROR)
    
{
        LocalFree(pmxc);
        
return FALSE;
    }

    DWORD m_controlid 
= pmxc->dwControlID;
    LocalFree(pmxc);

    MIXERCONTROLDETAILS_BOOLEAN  mxcd_f;

    MIXERCONTROLDETAILS mxcd;
    mxcd.cbStruct 
= sizeof(MIXERCONTROLDETAILS);
    mxcd.dwControlID 
= m_controlid;
    mxcd.cChannels 
= m_controlnum;
    mxcd.cMultipleItems 
= 0;
    mxcd.cbDetails 
= sizeof(MIXERCONTROLDETAILS_BOOLEAN);
    mxcd.paDetails 
= &mxcd_f;
    
if (mixerGetControlDetails((HMIXEROBJ)m_hMixer,
        
&mxcd,MIXER_OBJECTF_HMIXER |
        MIXER_GETCONTROLDETAILSF_VALUE)
!= MMSYSERR_NOERROR)          
        
return FALSE;
    
*PbValue = mxcd_f.fValue;
    
return TRUE;
}

posted @ 2006-07-29 19:03  J's Blog  阅读(1536)  评论(0)    收藏  举报