11.2.3 音量大小控制
音量控制是多媒体应用的主要部分,在音频采集方面可以起到辅助控制录制效果的作用。使用MCI(The Media Control Interface)接口可以进行音量控制。系统提供了一个音量控制的程序,通过该程序可以控制不同类型音量,音量控制程序运行如图11.6所示。
其中,Volume表示系统总音量,Wave表示波形音量,SW Synth表示SW设备音量,CD Player表示CD控制线,Line In表示磁带设备音量,Microphone表示麦克风音量。
图11.6 音量控制程序
为了实现音量的控制,微软提供了一些与Mixer(混音器)相关的API函数。在控制系统总音量时,首先通过mixerOpen函数打开混音设备,然后通过mixerGetLineInfo函数获取控制线信息取得设备ID号并通过mixerGetLineControls函数得到控制线的控制,最后通过mixerGetControlDetails得到具体的音量信息,通过mixerSetControlDetails函数来设置音量。
(1)mixerOpen函数用于打开指定的混音器设备,并确保在应用程序关闭之前设备不被移除。
语法:
MMRESULT mixerOpen( LPHMIXER phmx, UINT uMxld, DWORD dwCallback, DWORD dwlnstance, DWORD fdwOpen ); |
mixerOpen函数语法中的参数说明如表11.5所示。
表11.5 mixerOpen函数语法中的参数说明
参 数 名 称 描 述
phmx 返回已打开的混音设备的标识句柄
uMxld 指定要打开的混音器设备标识
dwCallback 指定调用窗口句柄
dwlnstance 指定调用实例句柄
fdwOpen 设备打开标志
(2)mixerGetLineInfo函数用于获取混音器设备指定的线路信息。
语法:
MMRESULT mixerGetLinelnfo( HMIXEROBJ hmxobj, LPMIXERLINE pmxl, DWORD fdwlnfo );
|
hmxobj:控制指定音频线路的混音器设备对象句柄。
pmxl:MIXERLINE结构对象。
fdwlnfo:指定要获取的信息标志。
(3)mixerGetLineControls函数用于获取关联音频线路的一个或多个控制器。
语法:
MMRESULT mixerGetLineControls ( HMIXEROBJ hmxobj, LPMIXERLINE CONTROLS pmxlc, DWORD fdwControls );
|
hmxobj:指定要查询的混音器设备对象句柄。
pmxlc:LPMIXERLINE CONTROLS结构对象。
fdwControl:指定要获取的信息标志。
(4)mixerGetControlDetails函数用于获取指定控制器的详细信息。
语法:
MMRESULT mixerGetControlDetails ( HMIXEROBJ hmxobj, LPMIXER CONTROLDETAILS pmxcd, DWORD fdwDetails );
|
hmxobj:指定要查询的混音器设备对象句柄。
pmxcd:LPMIXER CONTROLDETAILS结构对象。
fdwDetails:指定要获取的信息标志。
(5)mixerSetControlDetails函数用于设置指定控制器的详细信息。
语法:
MMRESULT mixerSetControlDetails ( HMIXEROBJ hmxobj, LPMIXER CONTROLDETAILS pmxcd, DWORD fdwDetails );
|
hmxobj:指定要查询的混音器设备对象句柄。
pmxcd:LPMIXER CONTROLDETAILS结构对象。
fdwDetails:指定要获取的信息标志。
下面通过实例来介绍如何控制音量大小。
例如:
控制音量大小的应用程序设计步骤如下。
ch1106实例位置:mr\11\sl\06
(1)新建MFC对话框工程,工程名设置为“ControlSound”。
(2)在对话框上添加一个滑标控件,图片控件和两个静态文本控件。
(3)通过类向导为滑标控件添加成员变量m_control。
(4)在实现文件ControlSoundDlg.cpp中加入多媒体库的头文件引用及多媒体静态库的链接。
#include #pragma comment(lib,"winmm.lib")
|
(5)在头文件中加入类成员变量的定义。
HMIXER m_hMixer; MIXERCAPS m_mxcaps; DWORD m_curvalue; DWORD m_controlid;
|
(6)在对话框初始化工程中可以先获取音量的大小。
BOOL CControlSoundDlg::OnInitDialog() { ……//此处代码省略 MIXERLINE mxl; MIXERCONTROL mxc; MIXERLINECONTROLS mxlc;mixerOpen(&m_hMixer,0,(DWORD)this->GetSafeHwnd(), NULL,MIXER_OBJECTF_MIXER | CALLBACK_WINDOW); mixerGetDevCaps((UINT)m_hMixer, &m_mxcaps, sizeof(MIXERCAPS)); mxl.cbStruct = sizeof(MIXERLINE); mxl.dwComponentType =MIXERLINE_COMPONENTTYPE_DST_SPEAKERS; mixerGetLineInfo((HMIXEROBJ)m_hMixer,&mxl, MIXER_OBJECTF_HMIXER|MIXER_GETLINEINFOF_COMPONENTTYPE);
mxlc.cbStruct=sizeof(MIXERLINECONTROLS); mxlc.dwLineID=mxl.dwLineID; mxlc.dwControlType=MIXERCONTROL_CONTROLTYPE_VOLUME; mxlc.cControls=1;//一般为1 mxlc.cbmxctrl=sizeof(MIXERCONTROL); mxlc.pamxctrl=&mxc; mixerGetLineControls((HMIXEROBJ)m_hMixer,&mxlc, MIXER_OBJECTF_HMIXER|MIXER_GETLINECONTROLSF_ONEBYTYPE); m_controlid=mxc.dwControlID; m_control.SetRange(mxc.Bounds.lMinimum,mxc.Bounds.lMaximum); MIXERCONTROLDETAILS_SIGNED mxcdVolume; MIXERCONTROLDETAILS mxcd; mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS); mxcd.dwControlID = mxc.dwControlID; mxcd.cChannels = 1; mxcd.cMultipleItems = 0; mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_SIGNED); mxcd.paDetails = &mxcdVolume; mixerGetControlDetails((HMIXEROBJ)m_hMixer,&mxcd, MIXER_OBJECTF_HMIXER|MIXER_GETCONTROLDETAILSF_VALUE); m_control.SetPos(mxcdVolume.lValue); return TRUE; }
|
(7)添加滑标控件的WM_HSCROLL消息的实现函数,该函数不能通过类向导添加,需要手动添加,首先在头文件ControlSoundDlg.h进行函数声明。
afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
|
然后在实现文件ControlSoundDlg.cpp中建立消息与函数的映射。
在OnHScroll函数中通过获得滑标的位置变化来对音量进行调节。
void CControlSoundDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { DWORD val; val=((CSliderCtrl*)pScrollBar)->GetPos(); MIXERCONTROLDETAILS_UNSIGNED mxcdVolume = {val}; MIXERCONTROLDETAILS mxcd; mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS); mxcd.dwControlID = m_controlid; mxcd.cChannels = 1; mxcd.cMultipleItems = 0; mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED); mxcd.paDetails = &mxcdVolume;
mixerSetControlDetails((HMIXEROBJ)m_hMixer,&mxcd, MIXER_OBJECTF_HMIXER|MIXER_SETCONTROLDETAILSF_VALUE); CDialog::OnHScroll(nSBCode, nPos, pScrollBar); }
|
(8)当音量发生改变时,系统会向程序发送MM_MIXM_CONTROL_CHANGE消息,可以通过对该消息进行映射,来达到当系统音量改变时应用程序滑标也发生变化。对MM_MIXM_CONTROL_CHANGE消息进行映射首先在头文件中加入函数声明。
afx_msg LONG OnMixerCtrlChange(UINT wParam, LONG lParam);
|
然后在实现文件中建立消息与函数的映射。
ON_MESSAGE(MM_MIXM_CONTROL_CHANGE,OnMixerCtrlChange)
|
在OnMixerCtrlChange函数中参数wParam获取的是音量设备句柄,参数lParam获取的是音量控制行ID值,通过这两个参数就可以获得改变后的音量。
LONG CControlSoundDlg::OnMixerCtrlChange(UINT wParam, LONG lParam) { if ((HMIXER)wParam == m_hMixer && (DWORD)lParam ==m_controlid) { MIXERCONTROLDETAILS_UNSIGNED mxcdVolume; MIXERCONTROLDETAILS mxcd; mxcd.cbStruct = sizeof(MIXERCONTROLDETAILS); mxcd.dwControlID = m_controlid; mxcd.cChannels = 1; mxcd.cMultipleItems = 0; mxcd.cbDetails = sizeof(MIXERCONTROLDETAILS_UNSIGNED); mxcd.paDetails = &mxcdVolume;mixerGetControlDetails((HMIXEROBJ)m_hMixer,&mxcd, MIXER_OBJECTF_HMIXER|MIXER_GETCONTROLDETAILSF_VALUE);
m_control.SetPos(mxcdVolume.dwValue); } return 0L; }
|
(9)程序运行效果如图11.7所示。

【责任编辑:
阚书 TEL:(010)68476606】