您的位置:首页 > 其它

获取、设置声卡音量的方法

2014-08-06 19:48 253 查看
在Windows XP中:

获取音量的方法:

第一步:获取线路的信息:

<pre name="code" class="cpp">	MIXERLINE mxl;
<span style="white-space:pre">	</span>MMRESULT rc;
ZeroMemory(&mxl,sizeof(MIXERLINE));
mxl.cbStruct = sizeof(MIXERLINE);
mxl.dwComponentType = MIXERLINE_COMPONENTTYPE_DST_SPEAKERS;
rc = mixerGetLineInfo((HMIXEROBJ)hMixer, &mxl,
MIXER_GETLINEINFOF_COMPONENTTYPE);
if (MMSYSERR_NOERROR != rc) {
mixerClose(hMixer);
return LUCE_DRV_FAIL;
}




传入的第二个参数,mxl设置类型为MIXERLINE_COMPONENTTYPE_DST_SPEAKERS,表示线路中的控件类型是音量控件。第三个参数,设置为MIXER_GETLINEINFOF_COMPONENTTYPE,表示根据类型去获取线路信息。获取成功,则返回MMSYSERR_NOERROR。

第二步,获取该线路的控制信息:

MIXERCONTROL mxc;         /* Holds the mixer control data */
/* Get the control */
ZeroMemory(&mxc, sizeof(MIXERCONTROL));
mxc.cbStruct = sizeof(mxc);
ZeroMemory(&mxlc, sizeof(MIXERLINECONTROLS));
mxlc.cbStruct = sizeof(mxlc);
mxlc.dwLineID = mxl.dwLineID;
mxlc.dwControlType = MIXERCONTROL_CONTROLTYPE_VOLUME;
mxlc.cControls = 1;
mxlc.pamxctrl = &mxc;
mxlc.cbmxctrl = sizeof(mxc);
rc = mixerGetLineControls((HMIXEROBJ)hMixer,&mxlc, MIXER_GETLINECONTROLSF_ONEBYTYPE);
if (MMSYSERR_NOERROR != rc) {
mixerClose(hMixer);
/* Couldn't get the control*/
return LUCE_DRV_FAIL;
}
用mixerGetLineControls获取线路中的控件信息。将上一步获取的到线路信息设置到mxlc中,直接获取一个控件,第三个设置为MIXER_GETLINECONTROLSF_ONEBYTYPE也是通过类型是检索控件。调用之后相关的控制信息,会设置到mxlc的pamxctrl,即mxc中。

第三步:

ZeroMemory(&mxcd, sizeof(mxcd));
mxcd.cbStruct = sizeof(mxcd);
mxcd.cbDetails = sizeof(unsigned long);
mxcd.dwControlID = mxc.dwControlID;
mxcd.paDetails = &volStruct;
mxcd.cChannels = MIXERCONTROL_CONTROLF_UNIFORM;
mxcd.cMultipleItems = 0;

/* Get the current value of the peakmeter control. Typically, you
would set a timer in your program to query the volume every 10th
of a second or so.
*/
rc = mixerGetControlDetails((HMIXEROBJ)hMixer, &mxcd,
MIXER_GETCONTROLDETAILSF_VALUE);
if (MMSYSERR_NOERROR != rc) {
mixerClose(hMixer);
/* Couldn't get the current volume */
return LUCE_DRV_FAIL;
}

用mixerGetControlDetails获取控件的详细信息,获取到的信息,放在mxcd的paDetails中。MIXERCONTROL_CONTROLF_UNIFORM 表示 所有线路的通道只有一个共同的音量控制。

设置音量的方法:

前三步和获取音量的方法一样,区别是:第四步,获取到当前的音量之后,把将要设置的音量值传给paDetails。再调用mixerSetControlDetails将值设置到系统中。

volStruct.lValue= lVol;
rc = mixerSetControlDetails((HMIXEROBJ)hMixer, &mxcd,
MIXER_GETCONTROLDETAILSF_VALUE);
if (MMSYSERR_NOERROR != rc) {
mixerClose(hMixer);
/* Couldn't get the current volume */
return LUCE_DRV_FAIL;
}


在Windows Vista之后的系统中,MS换了API,直接贴代码吧~BOOL Volume_set(DWORD dwVolume,BOOL IsMixer/*TRUE*/)
{
HRESULT hr = S_OK;
IMMDeviceCollection *pMultiDevice = NULL;
IMMDevice *pDevice = NULL;
IAudioSessionEnumerator *pSessionEnum = NULL;

if (IsMixer)
{
// 播放
hr = m_pEnumerator->EnumAudioEndpoints(eRender,DEVICE_STATE_ACTIVE, &pMultiDevice);
}
else
{
// 录音
hr = m_pEnumerator->EnumAudioEndpoints(eCapture,DEVICE_STATE_ACTIVE, &pMultiDevice);
}
if(FAILED(hr))
return FALSE;
UINT deviceCount = 0;
hr = pMultiDevice->GetCount(&deviceCount);
if(FAILED(hr))
return FALSE;

if((int)dwVolume < 0)
dwVolume = 0;
if((int)dwVolume > 100)
dwVolume = 100;
for (UINT ii=0; ii<deviceCount; ii++)
{
IAudioEndpointVolume *pEndptVolCtrl = NULL;
pDevice = NULL;
hr = pMultiDevice->Item(ii,&pDevice);
if(FAILED(hr))
return FALSE;
hr = pDevice->Activate(__uuidof(IAudioEndpointVolume),CLSCTX_ALL, NULL, (void**)&pEndptVolCtrl);
if(FAILED(hr))
return FALSE;
// 使用 IAudioEndpintVolume 的方法获取音量,设置音量,设置静音等
HRESULT hr = pEndptVolCtrl->SetMasterVolumeLevelScalar((float)dwVolume / 100, &m_guidMyContext);

if(FAILED(hr))
return FALSE;
SAFE_RELEASE(pDevice);
}
return TRUE;
}
其中,<pre name="code" class="cpp"><pre name="code" class="cpp">#define SAFE_RELEASE(punk) \
if ((punk) != NULL) \
{ (punk)->Release(); (punk) = NULL; }


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: