用Mixer API函数调节控制面板的音频设置
来源:互联网 发布:基地 知乎 编辑:程序博客网 时间:2024/05/02 03:07
这里提供了两个函数,GetMute用来获取系统设置中是否对某个音频线路进行了静音操作,SetMute是用来对系统的某个音频线路进行静音操作。
BOOL CMixer::SetMute(DWORD dwSrcType, BOOL bValue)
{
MIXERLINE mxl;
if (! GetLineInfo(&mxl, MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, dwSrcType))
return FALSE;
MIXERCONTROL mxc;
if (! GetLineControl(&mxc, &mxl, MIXERCONTROL_CONTROLTYPE_MUTE))
return FALSE;
MIXERCONTROLDETAILS mxcd;
MIXERCONTROLDETAILS_BOOLEAN mxcd_f;
mxcd.cbStruct = sizeof(mxcd);
mxcd.dwControlID = mxc.dwControlID;
mxcd.cChannels = 1;
mxcd.cMultipleItems = 0;
mxcd.cbDetails = sizeof(mxcd_f);
mxcd.paDetails = &mxcd_f;
mxcd_f.fValue = bValue;
if (! SetControlDetails(&mxcd, MIXER_OBJECTF_MIXER))
return FALSE;
return TRUE;
}
BOOL CMixer::GetMute(DWORD dwSrcType, BOOL* pbValue)
{
MIXERLINE mxl;
if (! GetLineInfo(&mxl, MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, dwSrcType))
return FALSE;
MIXERCONTROL mxc;
if (! GetLineControl(&mxc, &mxl, MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT ))
return FALSE;
MIXERCONTROLDETAILS mxcd;
MIXERCONTROLDETAILS_BOOLEAN mxcd_f;
mxcd.cbStruct = sizeof(mxcd);
mxcd.dwControlID = mxc.dwControlID;
mxcd.cChannels = 1;
mxcd.cMultipleItems = 0;
mxcd.cbDetails = sizeof(mxcd_f);
mxcd.paDetails = &mxcd_f;
if (! GetControlDetails(&mxcd, MIXER_GETCONTROLDETAILSF_VALUE))
return FALSE;
*pbValue = mxcd_f.fValue;
return TRUE;
}
如果用这两个函数呢,下面我演示了如何设置和获取Volume音频线路的静音操作。
BOOL bValue = TRUE;
SetMute(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, bValue);
GetMute(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, &bValue);
4、下面看看当系统的设置改变时,mixer是如何通知我们的吧。
还记得我前面讲过的,当我们调用mixeropen时可以传递一个窗口的句柄作为回调窗口,当系统的设置改变,比如音量改变,某个音频线路被静音时,mixer都会给我们的回调窗口发送消息的。
一般只有两个消息,如下
afx_msg void OnMLChange(WPARAM wParam, LPARAM lParam);
afx_msg void OnMCChange(WPARAM wParam, LPARAM lParam);
ON_MESSAGE(MM_MIXM_LINE_CHANGE, OnMLChange)
ON_MESSAGE(MM_MIXM_CONTROL_CHANGE, OnMCChange)
其中MM_MIXM_CONTROL_CHANGE 消息中,发送消息的两个参数代表的意思如下
wParam = (WPARAM) hMixer
lParam = (LPARAM) dwControlID
在MM_MIXM_LINE_CHANGE 消息中,发送消息的参数代表的意思如下
wParam = (WPARAM) hMixer
lParam = (LPARAM) dwLineID
在我们的应用程序中,我们可以在这两个消息处理函数中调整我们的设置,以对应于系统的改变,比如你的代码可以这样写:
void CMixerControlDlg::OnMCChange(WPARAM wParam, LPARAM lParam)
{
DWORD dwLValue;
DWORD dwRValue;
GetVolume(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, &dwLValue,&dwRValue);
//GetVolume函数的定义见下面,然后根据返回的值调整滑动条的位置
m_SliderVolR.SetPos(MAX_VOL_VALUE - dwLValue);
m_SliderVolL.SetPos(MAX_VOL_VALUE - dwRValue);
//你也可以在这里调用GetMute查看Volume是否被静音,
}
如此你的程序就可以自动的响应系统设置的改变了。
关于mixer API的应用开发就介绍到这里,记着最后要关闭mixer如此:mixerClose(m_hmx);
关于工程的建立我就不多少了,很简单的,就是一个基于对话框的工程,上面放了一些控件。下面我主要讲一下每个功能是如何实现的。主要有三个功能1 如何调整左右声道音量的大小,2 如何将某个设备静音,3 如何选择录音设备。
这里关于mixer函数的用法还要先唠叨几句。一般来说,对音频线路的操作流程如下:
1、通过GetLineInfo获取指定音频线路的信息,返回一个MIXERLINE结构
2、然后通过GetLineControl获取音频线路相关的控制的通用信息,通过MIXERCONTROL结构返回。
3、通过GetConrolDetails获取指定控制的属性值
4、通过SetControlDetails设置指定控制的属性值,
对于每个线路设备,mixer都用一个类型值来标示,比如:
Volume对应的值 MIXERLINE_COMPONENTTYPE_DST_SPEAKERS
CD 对于的值 MIXERLINE_COMPONENTTYPE_SRC_COMPACTDISC
Midi对应的值为 MIXERLINE_COMPONENTTYPE_SRC_SYNTHESIZER
Wave对应的值为 MIXERLINE_COMPONENTTYPE_SRC_WAVEOUT
Line in对应的值为 MIXERLINE_COMPONENTTYPE_SRC_LINE
Microphone对应的值为 MIXERLINE_COMPONENTTYPE_SRC_MICROPHONE
我们可以通过音频线路的类型值获得相应的线路的信息,也可以通过音频线路的设备ID来获取相应的线路的信息。
下面开始我们编程吧。
首先定义三个变量
HWND m_hWnd; //回调窗口句柄
HMIXER m_hmx; //
然后就是要打开mixer,可以在对话的初始化中作这些工作。
#define MAX_VOL_VALUE 65535
if (MMSYSERR_NOERROR != mixerOpen(&m_hmx, m_uMxId,(DWORD)m_hWnd, 0, CALLBACK_WINDOW))
{
return FALSE;
}
if (MMSYSERR_NOERROR == mixerGetID((HMIXEROBJ)m_hmx, &m_uMxId, MIXER_OBJECTF_HMIXER))
{
return m_uMxId;
}
//设置Volume的滑动条的范围这里只以Volume为例。
m_SliderWaveL.SetRange(0, MAX_VOL_VALUE, TRUE);
m_SliderWaveR.SetRange(0, MAX_VOL_VALUE, TRUE);
接着我先演示一下如何获取和设置录音设备的左右声道的音量值,以及如何静音放音设备,这里以Volume为例,其他的设备类似,你可以照着我的代码,套用即可。
1、如何获取Volume设备的音量大小
DWORD dwLValue;
DWORD dwRValue;
GetVolume(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, &dwLValue,&dwRValue);
//GetVolume函数的定义见下面,然后根据返回的值调整滑动条的位置
m_SliderVolR.SetPos(MAX_VOL_VALUE - dwLValue);
m_SliderVolL.SetPos(MAX_VOL_VALUE - dwRValue);
2、如何根据滑动条的位置来调整系统音量的大小
void CMixerControlDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// m_dwSpkR和m_dwSpkL是用来记录Volume左右声道的音量值,0~~65535
CSliderCtrl *pSlider = (CSliderCtrl *)pScrollBar;
int nValue = MAX_VOL_VALUE - pSlider->GetPos(); //获取滑动条的位置pos
else if (m_SliderVolR.m_hWnd == pSlider->m_hWnd)
{
//如果拖动的是Volume的左声道
m_dwSpkR = nValue;
// 设置Volume的音量值
SetVolume(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, m_dwSpkL, m_dwSpkR);
}
else if (m_SliderVolL.m_hWnd == pSlider->m_hWnd)
{
//Volume右声道
m_dwSpkL = nValue;
// 设置Volume的音量值
SetVolume(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, m_dwSpkL, m_dwSpkR);
}
//其他音频线路可以依次类推在下面添加
}
GetVolume和SetVolume函数的定义下面给出
BOOL CMixer::SetVolume(DWORD dwSrcType, DWORD dwLValue, DWORD dwRValue, BOOL bMono)
{
MIXERLINE mxl;
if (! GetLineInfo(&mxl, MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, dwSrcType))
return FALSE;
MIXERCONTROL mxc;
if (! GetLineControl(&mxc, &mxl, MIXERCONTROL_CONTROLTYPE_VOLUME))
return FALSE;
MIXERCONTROLDETAILS mxcd;
MIXERCONTROLDETAILS_UNSIGNED mxcd_u1;
MIXERCONTROLDETAILS_UNSIGNED mxcd_u[2];
mxcd.cbStruct = sizeof(mxcd);
mxcd.dwControlID = mxc.dwControlID;
mxcd.cMultipleItems = 0;
if (bMono)
{
mxcd.cChannels = 1;
mxcd.cbDetails = sizeof(mxcd_u1);
mxcd.paDetails = &mxcd_u1;
mxcd_u1.dwValue = dwLValue;
}
else
{
mxcd.cChannels = mxl.cChannels;
mxcd.cbDetails = sizeof(*mxcd_u);
mxcd.paDetails = mxcd_u;
mxcd_u[0].dwValue = dwLValue;
mxcd_u[1].dwValue = dwRValue;
}
if (! SetControlDetails(&mxcd, MIXER_OBJECTF_MIXER))
return FALSE;
return TRUE;
}
BOOL CMixer::GetVolume(DWORD dwSrcType, DWORD* pdwLValue, DWORD* pdwRValue, BOOL bMono)
{
MIXERLINE mxl;
if (! GetLineInfo(&mxl, MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, dwSrcType))
return FALSE;
MIXERCONTROL mxc;
if (! GetLineControl(&mxc, &mxl, MIXERCONTROL_CONTROLTYPE_VOLUME))
return FALSE;
MIXERCONTROLDETAILS mxcd;
MIXERCONTROLDETAILS_UNSIGNED mxcd_u1;
MIXERCONTROLDETAILS_UNSIGNED mxcd_u[2];
mxcd.cbStruct = sizeof(mxcd);
mxcd.dwControlID = mxc.dwControlID;
mxcd.cMultipleItems = 0;
if (bMono)
{
mxcd.cChannels = 1;
mxcd.cbDetails = sizeof(mxcd_u1);
mxcd.paDetails = &mxcd_u1;
if (! GetControlDetails(&mxcd, MIXER_GETCONTROLDETAILSF_VALUE))
return FALSE;
*pdwLValue = mxcd_u1.dwValue;
}
else
{
mxcd.cChannels = mxl.cChannels;
mxcd.cbDetails = sizeof(*mxcd_u);
mxcd.paDetails = mxcd_u;
if (! GetControlDetails(&mxcd, MIXER_GETCONTROLDETAILSF_VALUE))
return FALSE;
*pdwLValue = mxcd_u[0].dwValue;
*pdwRValue = mxcd_u[1].dwValue;
}
return TRUE;
}
BOOL GetLineInfo(LPMIXERLINE pmxl, DWORD dwDstType, DWORD dwSrcType)
{
MIXERCAPS mxcaps;
if (! GetDevCaps(&mxcaps))
return FALSE;
UINT u=0;
do
{
pmxl->cbStruct = sizeof(*pmxl);
pmxl->dwDestination = u;
u++;
if (MMSYSERR_NOERROR != mixerGetLineControls((HMIXEROBJ)m_uMxId, pmxl, MIXER_GETLINEINFOF_DESTINATION))
{
return FALSE;
}
} while ((u < mxcaps.cDestinations) && (pmxl->dwComponentType != dwDstType));
if (u > mxcaps.cDestinations)
return FALSE;
if (dwDstType == dwSrcType)
return TRUE;
pmxl->dwDestination = u;
UINT cConnections = (UINT)pmxl->cConnections;
UINT v=0;
u--;
do
{
pmxl->cbStruct = sizeof(*pmxl);
pmxl->dwDestination = u;
pmxl->dwSource = v;
v++;
if (MMSYSERR_NOERROR != mixerGetLineControls((HMIXEROBJ)m_uMxId, pmxl, MIXER_GETLINEINFOF_SOURCE))
{
return FALSE;
}
} while ((v < cConnections) && (pmxl->dwComponentType != dwSrcType));
if((v > cConnections) || (pmxl->dwComponentType !=dwSrcType))
return FALSE;
return TRUE;
}
BOOL GetLineControl(LPMIXERCONTROL pmxc, LPMIXERLINE pmxl, DWORD dwType)
{
LPMIXERCONTROL pamxctrl;
DWORD cbmxctrls = sizeof(*pamxctrl) * (UINT)pmxl->cControls;
pamxctrl = (LPMIXERCONTROL)LocalAlloc(LPTR, cbmxctrls);
MIXERLINECONTROLS mxlc;
mxlc.cbStruct = sizeof(mxlc);
mxlc.dwLineID = pmxl->dwLineID;
mxlc.dwControlType = dwType;
mxlc.cControls = pmxl->cControls;
mxlc.cbmxctrl = sizeof(*pamxctrl);
mxlc.pamxctrl = pamxctrl;
if (MMSYSERR_NOERROR != mixerGetControlDetails((HMIXEROBJ)m_uMxId, &mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE))
{
return FALSE;
}
memcpy(pmxc, pamxctrl, sizeof(*pamxctrl));
LocalFree(pamxctrl);
return TRUE;
}
3、下面演示一下如何设置Volume设备的静音
这里提供了两个函数,GetMute用来获取系统设置中是否对某个音频线路进行了静音操作,SetMute是用来对系统的某个音频线路进行静音操作。
BOOL CMixer::SetMute(DWORD dwSrcType, BOOL bValue)
{
MIXERLINE mxl;
if (! GetLineInfo(&mxl, MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, dwSrcType))
return FALSE;
MIXERCONTROL mxc;
if (! GetLineControl(&mxc, &mxl, MIXERCONTROL_CONTROLTYPE_MUTE))
return FALSE;
MIXERCONTROLDETAILS mxcd;
MIXERCONTROLDETAILS_BOOLEAN mxcd_f;
mxcd.cbStruct = sizeof(mxcd);
mxcd.dwControlID = mxc.dwControlID;
mxcd.cChannels = 1;
mxcd.cMultipleItems = 0;
mxcd.cbDetails = sizeof(mxcd_f);
mxcd.paDetails = &mxcd_f;
mxcd_f.fValue = bValue;
if (! SetControlDetails(&mxcd, MIXER_OBJECTF_MIXER))
return FALSE;
return TRUE;
}
BOOL CMixer::GetMute(DWORD dwSrcType, BOOL* pbValue)
{
MIXERLINE mxl;
if (! GetLineInfo(&mxl, MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, dwSrcType))
return FALSE;
MIXERCONTROL mxc;
if (! GetLineControl(&mxc, &mxl, MIXERCONTROL_CONTROLTYPE_MULTIPLESELECT ))
return FALSE;
MIXERCONTROLDETAILS mxcd;
MIXERCONTROLDETAILS_BOOLEAN mxcd_f;
mxcd.cbStruct = sizeof(mxcd);
mxcd.dwControlID = mxc.dwControlID;
mxcd.cChannels = 1;
mxcd.cMultipleItems = 0;
mxcd.cbDetails = sizeof(mxcd_f);
mxcd.paDetails = &mxcd_f;
if (! GetControlDetails(&mxcd, MIXER_GETCONTROLDETAILSF_VALUE))
return FALSE;
*pbValue = mxcd_f.fValue;
return TRUE;
}
如果用这两个函数呢,下面我演示了如何设置和获取Volume音频线路的静音操作。
BOOL bValue = TRUE;
SetMute(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, bValue);
GetMute(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, &bValue);
4、下面看看当系统的设置改变时,mixer是如何通知我们的吧。
还记得我前面讲过的,当我们调用mixeropen时可以传递一个窗口的句柄作为回调窗口,当系统的设置改变,比如音量改变,某个音频线路被静音时,mixer都会给我们的回调窗口发送消息的。
一般只有两个消息,如下
afx_msg void OnMLChange(WPARAM wParam, LPARAM lParam);
afx_msg void OnMCChange(WPARAM wParam, LPARAM lParam);
ON_MESSAGE(MM_MIXM_LINE_CHANGE, OnMLChange)
ON_MESSAGE(MM_MIXM_CONTROL_CHANGE, OnMCChange)
其中MM_MIXM_CONTROL_CHANGE 消息中,发送消息的两个参数代表的意思如下
wParam = (WPARAM) hMixer
lParam = (LPARAM) dwControlID
在MM_MIXM_LINE_CHANGE 消息中,发送消息的参数代表的意思如下
wParam = (WPARAM) hMixer
lParam = (LPARAM) dwLineID
在我们的应用程序中,我们可以在这两个消息处理函数中调整我们的设置,以对应于系统的改变,比如你的代码可以这样写:
void CMixerControlDlg::OnMCChange(WPARAM wParam, LPARAM lParam)
{
DWORD dwLValue;
DWORD dwRValue;
GetVolume(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS, &dwLValue,&dwRValue);
//GetVolume函数的定义见下面,然后根据返回的值调整滑动条的位置
m_SliderVolR.SetPos(MAX_VOL_VALUE - dwLValue);
m_SliderVolL.SetPos(MAX_VOL_VALUE - dwRValue);
//你也可以在这里调用GetMute查看Volume是否被静音,
}
如此你的程序就可以自动的响应系统设置的改变了。
关于mixer API的应用开发就介绍到这里,记着最后要关闭mixer如此:mixerClose(m_hmx);
- 用Mixer API函数调节控制面板的音频设置
- 用Mixer API函数调节控制面板的音频设置
- 用Mixer API函数调节控制面板的音频设置
- 用Mixer API函数调节控制面板的音频设置
- 用Mixer API函数调节控制面板的音频设置
- 用Mixer API函数调节控制面板的音频设置
- 用Mixer API函数调节控制面板的音频设置
- 用Mixer API函数调节控制面板的音频设置
- 用Mixer API函数调节控制面板的音频设置
- 用Mixer API函数调节控制面板的音频设置
- 用Mixer API函数调节控制面板的音频设置
- 用Mixer API函数实现音频设置
- 使用Windows混音器MIXER的API开发音频控制面板【参考文章】
- 音频的mixer
- 按照控制面板区域设置显示时间的格式函数
- 声音控制Mixer API〔转〕
- 控制面板命令,设置控制面板快捷键的方法
- Android音频子系统,音量的调节控制(七)
- Google Web Toolkit 入门
- 解决JDk1.6无法安装得问题
- 写第一篇文章
- 三层架构各层关系分析比较及其约定
- 有没有网络连接
- 用Mixer API函数调节控制面板的音频设置
- 今日偶得7/22
- 一个老程序员的心里话说到人的心坎
- 受伤的男人学抽烟是否就会留的住男人的尊严?
- 西直门
- Java 常用地址
- ERP的机会和挑战
- 名词解释(收集整理)
- 将Java *.Class 打包成可执行的*.jar文件