上一节我们重点介绍了Core Audio APIs扬声器方面的设置,这一节我们重点介绍麦克风方面的设置,包括麦克风音量大小以及麦克风增强的设置,麦克风音量大小的设置也包括系统音量的设置和应用程序会话音量大小的设置,因为麦克风音量大小设置和扬声器音量大小的设置相似,只是获取的设备对象不同,因此音量大小的设置只是简单给出示例代码,如有疑问可以参考上一节扬声器音量大小设置,本节重点介绍一下麦克风增强方面的设置。
1.首先还是先定义用到的接口对象:
CComPtr<IMMDeviceEnumerator > m_pIMMEnumerator; //主要用于枚举设备接口
CComPtr<IAudioEndpointVolume> m_pMicEndptVol; //麦克风音量控制接口
CComPtr<IAudioVolumeLevel> m_pMicBoost; //麦克风硬件增强接口
CComPtr<IAudioAutoGainControl> m_pAGC; //麦克风自动增益接口
下面是麦克风设置主音量和会话音量大小的示例代码,和上一节扬声器设置基本相同,包括获取设备部分,因此不再详细说明,直接列出示例代码:
HRESULT hr = S_OK;
hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER, IID_IMMDeviceEnumerator, (void**)&m_pIMMEnumerator);
if(FAILED(hr)) return;
CComPtr<IMMDevice> pIMMDeivce = NULL;
//strEndPointID为string类型的设备ID
if(strEndPointID.empty())
{
hr = m_pIMMEnumerator->GetDefaultAudioEndpoint(eCapture, eConsole, &pIMMDeivce);
}
else
{
hr = m_pIMMEnumerator->GetDevice(strEndPointID.c_str(), &pIMMDeivce);
}
if(FAILED(hr)) return;
hr = pIMMDeivce->Activate(IID_IAudioEndpointVolume, CLSCTX_ALL, NULL, (void**)&m_pMicEndptVol);
if(FAILED(hr)) return;
//获取麦克风音量
float level = 0.0f;
hr = m_pMicEndptVol->GetMasterVolumeLevelScalar(&level);
//设置麦克风音量
float level = 0.5f;
hr = m_pMicEndptVol->SetMasterVolumeLevelScalar(level, NULL);
//设置系统麦克风静音
BOOL bMute = TRUE;
hr = m_pRenderSimpleVol->SetMute(bMute, NULL);
//获取系统麦克风静音状态
BOOL bMute = FALSE;
hr = m_pRenderSimpleVol->GetMute(&bMute);
2.设置系统麦克风硬件加强功能
首先我们要获取IDeviceTopology接口,获取到这个接口后我们就可以直接访问音频适配器中的硬件数据通路的拓扑特性,还是要通过之前已经取得pIMMDeivce来激活IDeviceTopology接口。获取到IDeviceTopology接口后我们接着要通过这个接口对象获取IConnector接口,所谓IConnector指的是一个连接器,所谓一个连接器可以指一个硬件上的音频插孔,也可以指到一个内部连接的音频终端(例如,在一台笔记本电脑内置的麦克风)等等。获取到IConnector接口我们还需要获取IPart接口,IPart接口代表的是一个设备拓扑的一部分,亦指一个连接器或者一个亚单位,获取到IPart接口后,我们就可以通过IPart接口设备名称,本地ID,全局ID,以及连接器或亚单位的类型等信息,然后我们就可以根据一些条件选择自己想要的接口信息,比如可以根据名字“麦克风增强”来获取系统麦克风增强对用的接口对象,然后用获取的这些接口就可以进行自己想要的各种参数设置了,下面让我们一步步用代码完成这些步骤。
2.1 我们用pIMMDeivce接口对象来激活IDeviceTopology接口
CComPtr<IDeviceTopology> pTopo = NULL;
hr = pIMMDeivce->Activate(IID_IDeviceTopology, CLSCTX_INPROC_SERVER, 0, (void**)&pTopo);
if(FAILED(hr)) return;
2.2 然后我们再通过IDeviceTopology接口中的GetConnector()来获取IConnector接口
CComPtr<IConnector> pConn = NULL;
hr = pTopo->GetConnector(0, &pConn);
if(FAILED(hr)) return;
2.3 获取到IConnector接口后,我们就可以根据IConnector接口获取相应IPart接口,注意有可能我们获取IPart接口本身又是一个连接器,那么我们就要再次通过这个连接器往里面获取IPart接口,直至获取到一个IPart接口,然后获取相应名字和我们需要名字比对,根据结果来确定是不是我们要找的接口对象。
while(pConn)
{
CComPtr<IConnector> pConnNext = NULL;
hr = pConn->GetConnectedTo(&pConnNext);
if(FAILED(hr)) break;
CComPtr<IPart> pPart = NULL;
hr = pConnNext->QueryInterface(IID_IPart, (void**)&pPart);
pConn = NULL;
while(pPart)
{
CComPtr<IPartsList> pPartsList = NULL;
CComPtr<IPart> pPartNext = NULL;
hr = pPart->EnumPartsOutgoing(&pPartsList);
if(FAILED(hr)) break;
hr = pPartsList->GetPart(0, &pPartNext);
if(FAILED(hr)) break;
PartType pt;
LPWSTR name = NULL;
pPartNext->GetName(&name);
pPartNext->GetPartType(&pt);
if(Connector == pt)
{
pConn = NULL;
hr = pPartNext->QueryInterface(IID_IConnector, (void**)&pConn);
CoTaskMemFree(name);
if(FAILED(hr)) return;
break;
}
CComPtr<IAudioVolumeLevel> pAL = NULL;
hr = pPartNext->Activate(CLSCTX_INPROC_SERVER, IID_IAudioVolumeLevel, (void**)&pAL);
if(SUCCEEDED(hr))
{
if (strcmp("麦克风增强",name) == 0)
{
m_pMicBoost = pAL;
CoTaskMemFree(name);
return;
}
pPart = pPartNext;
}
}
}
2.4 获取到系统麦克风增强IAudioVolumeLevel接口m_pMicBoost,我们就可以用这个接口的方法来设置麦克风增强参数了
获取麦克风增强参数信息:
float fLevel = 0.0f;
float fMin = 0.0f;
float fMax = 0.0f;
float fStep = 0.0f;
//获取麦克风增强级别
hr = m_pMicBoost->GetLevel(0, &fLevel);
//获取麦克风增强最大最小值,以及步长
hr = m_pMicBoost->GetLevelRange(0, &fMin, &fMax, &fStep);
设置麦克风增强参数:
float fLevel = 0.0f;
float fMin = 0.0f;
float fMax = 0.0f;
float fStep = 0.0f;
//获取麦克风增强的最小最大值,步长
hr = m_pMicBoost->GetLevelRange(0, &fMin, &fMax, &fStep);
//根据步长计算新的值
fLevel = ((int)((fMax - fMin ) / fStep)+1) * fStep;
//设置麦克风增强新的值
hr = m_pMicBoost->SetLevelUniform(fLevel, NULL);
2.5 使用声卡自动增益功能,有的麦克风声卡提供自动增益功能,因此这些声卡我们可以使用自动增益功能来达到麦克风加强功能。要使用麦克风自动增益功能,我们需要使用IAudioAutoGainControl接口,该接口提供了访问硬件的自动增益功能,要获取IAudioAutoGainControl这个接口,我们需要通过上面已经获得IPart::Activate()方法来激活IAudioAutoGainControl这个接口,注意如果获取接口指针为空说明硬件不支持这个功能。这个接口提供了两个方法用于设置和获取麦克风增益的状态。
首先我们用上面已经获得IPart接口来激活IAudioAutoGainControl接口:
hr = pPartNext->Activate(CLSCTX_INPROC_SERVER, IID_IAudioAutoGainControl, (void**)&m_pAGC);
if(SUCCEEDED(hr) && m_pAGC)
{
//硬件支持麦克风自动增益功能
}
else
{
//硬件不支持麦克风自动增益功能
}
获取到IAudioAutoGainControl接口后我们就可以直接使用该接口的GetEnabled()和SetEnabled()来设置麦克风自动增益的打开和关闭了,示例代码如下:
//获取麦克风自动增益是否打开
BOOL bEnable = FALSE;
hr = m_pAGC->GetEnabled(&bEnable);
//打开麦克风自动增益
BOOL bEnable = TRUE;
hr = m_pAGC->SetEnabled(bEnable, NULL);