如何使用C++控制麦克风增强/ AGC
How to Control Microphone Boost/AGC using C++
我想控制麦克风输入上的增强/AGC 设置。Windows 7音频属性显示它具有AGC选项。
但是,当我尝试通过C++访问它时,它返回说设备上没有AGC。
我正在使用设备拓扑类WASAPI没有任何API来控制AGC功能这是到目前为止的代码:
(大部分摘自 MSDN 论坛示例)
#include <windows.h>
#include <stdio.h>
#include <mmdeviceapi.h>
#include <devicetopology.h>
HRESULT WalkTreeBackwardsFromPart(IPart *pPart, int iTabLevel = 0);
HRESULT DisplayVolume(IAudioVolumeLevel *pVolume, int iTabLevel);
HRESULT DisplayMute(IAudioMute *pMute, int iTabLevel);
void Tab(int iTabLevel);
int __cdecl main(void) {
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr)) {
printf("Failed CoInitializeEx: hr = 0x%08xn", hr);
return __LINE__;
}
// get default render endpoint
IMMDeviceEnumerator *pEnum = NULL;
hr = CoCreateInstance(
__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator),
(void**)&pEnum
);
if (FAILED(hr)) {
printf("Couldn't get device enumerator: hr = 0x%08xn", hr);
CoUninitialize();
return __LINE__;
}
IMMDevice *pDevice = NULL;
hr = pEnum->GetDefaultAudioEndpoint(eCapture, eConsole, &pDevice);
if (FAILED(hr)) {
printf("Couldn't get default render device: hr = 0x%08xn", hr);
pEnum->Release();
CoUninitialize();
return __LINE__;
}
pEnum->Release();
// get device topology object for that endpoint
IDeviceTopology *pDT = NULL;
hr = pDevice->Activate(__uuidof(IDeviceTopology), CLSCTX_ALL, NULL, (void**)&pDT);
if (FAILED(hr)) {
printf("Couldn't get device topology object: hr = 0x%08xn", hr);
pDevice->Release();
CoUninitialize();
return __LINE__;
}
pDevice->Release();
// get the single connector for that endpoint
IConnector *pConnEndpoint = NULL;
hr = pDT->GetConnector(0, &pConnEndpoint);
if (FAILED(hr)) {
printf("Couldn't get the connector on the endpoint: hr = 0x%08xn", hr);
pDT->Release();
CoUninitialize();
return __LINE__;
}
pDT->Release();
// get the connector on the device that is
// connected to
// the connector on the endpoint
IConnector *pConnDevice = NULL;
hr = pConnEndpoint->GetConnectedTo(&pConnDevice);
if (FAILED(hr)) {
printf("Couldn't get the connector on the device: hr = 0x%08xn", hr);
pConnEndpoint->Release();
CoUninitialize();
return __LINE__;
}
pConnEndpoint->Release();
// QI on the device's connector for IPart
IPart *pPart = NULL;
hr = pConnDevice->QueryInterface(__uuidof(IPart), (void**)&pPart);
if (FAILED(hr)) {
printf("Couldn't get the part: hr = 0x%08xn", hr);
pConnDevice->Release();
CoUninitialize();
return __LINE__;
}
pConnDevice->Release();
// all the real work is done in this function
hr = WalkTreeBackwardsFromPart(pPart);
if (FAILED(hr)) {
printf("Couldn't walk the tree: hr = 0x%08xn", hr);
pPart->Release();
CoUninitialize();
return __LINE__;
}
pPart->Release();
CoUninitialize();
system("pause");
return 0;
}
HRESULT WalkTreeBackwardsFromPart(IPart *pPart, int iTabLevel /* = 0 */) {
HRESULT hr = S_OK;
Tab(iTabLevel);
LPWSTR pwszPartName = NULL;
hr = pPart->GetName(&pwszPartName);
if (FAILED(hr)) {
printf("Could not get part name: hr = 0x%08x", hr);
return hr;
}
printf("Part name: %wsn", *pwszPartName ? pwszPartName : L"(Unnamed)");
CoTaskMemFree(pwszPartName);
// Check AGC settings
const IID IID_IAudioAutoGainControl = __uuidof(IAudioAutoGainControl);
IAudioAutoGainControl *aGCcontrol = NULL;
hr = pPart->Activate(CLSCTX_ALL, IID_IAudioAutoGainControl, (void**)&aGCcontrol);
if (E_NOINTERFACE == hr) {
printf("NO AGC CONTROLn");
// not a Microphone node
} else if (FAILED(hr)) {
printf("Unexpected failure trying to activate IAudioAutoGainControl : hr = 0x%08xn", hr);
return hr;
} else {
// it's an AGC node...
printf("HAS AGC CONTROL");
if (FAILED(hr)) {
printf("AGC Failed: hr = 0x%08x", hr);
aGCcontrol->Release();
return hr;
}
aGCcontrol->Release();
}
return S_OK;
}
我终于想出了怎么做。我在上面的示例代码中省略了代码的一些重要部分。
为了帮助那些有同样困境的人,这是解决方案。要编译,只需将 MessageBox 语句替换为 printf。
这里重要的一点是,在枚举部分时,一定要知道它是输入还是输出。否则,您将永远找不到所需的零件。此示例查找电子捕获终结点的可用部分。
这是我的消息来源:http://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/9741bae1-c330-4802-9860-2fd202dba797/enumeration-of-available-levels-for-a-specific-installed-sound-card?forum=windowspro-audiodevelopment
如果您在编译时遇到问题,请告诉我。
#include <windows.h>
#include <stdio.h>
#include <mmdeviceapi.h>
#include <devicetopology.h>
HRESULT WalkTreeBackwardsFromPart(IPart *pPart, int iTabLevel = 0);
HRESULT DisplayVolume(IAudioVolumeLevel *pVolume, int iTabLevel);
HRESULT DisplayMute(IAudioMute *pMute, int iTabLevel);
void Tab(int iTabLevel);
int __cdecl main(void) {
HRESULT hr = CoInitialize(NULL);
if (FAILED(hr)) {
printf("Failed CoInitializeEx: hr = 0x%08xn", hr);
return __LINE__;
}
// get default render endpoint
IMMDeviceEnumerator *pEnum = NULL;
hr = CoCreateInstance(
__uuidof(MMDeviceEnumerator), NULL, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator),
(void**)&pEnum
);
if (FAILED(hr)) {
printf("Couldn't get device enumerator: hr = 0x%08xn", hr);
CoUninitialize();
return __LINE__;
}
IMMDevice *pDevice = NULL;
hr = pEnum->GetDefaultAudioEndpoint(eCapture, eConsole, &pDevice);
if (FAILED(hr)) {
printf("Couldn't get default capture device: hr = 0x%08xn", hr);
pEnum->Release();
CoUninitialize();
return __LINE__;
}
pEnum->Release();
// get device topology object for that endpoint
IDeviceTopology *pDT = NULL;
hr = pDevice->Activate(__uuidof(IDeviceTopology), CLSCTX_ALL, NULL, (void**)&pDT);
if (FAILED(hr)) {
printf("Couldn't get device topology object: hr = 0x%08xn", hr);
pDevice->Release();
CoUninitialize();
return __LINE__;
}
pDevice->Release();
// get the single connector for that endpoint
IConnector *pConnEndpoint = NULL;
hr = pDT->GetConnector(0, &pConnEndpoint);
if (FAILED(hr)) {
printf("Couldn't get the connector on the endpoint: hr = 0x%08xn", hr);
pDT->Release();
CoUninitialize();
return __LINE__;
}
pDT->Release();
// get the connector on the device that is
// connected to
// the connector on the endpoint
IConnector *pConnDevice = NULL;
hr = pConnEndpoint->GetConnectedTo(&pConnDevice);
if (FAILED(hr)) {
printf("Couldn't get the connector on the device: hr = 0x%08xn", hr);
pConnEndpoint->Release();
CoUninitialize();
return __LINE__;
}
pConnEndpoint->Release();
// QI on the device's connector for IPart
IPart *pPart = NULL;
hr = pConnDevice->QueryInterface(__uuidof(IPart), (void**)&pPart);
if (FAILED(hr)) {
printf("Couldn't get the part: hr = 0x%08xn", hr);
pConnDevice->Release();
CoUninitialize();
return __LINE__;
}
pConnDevice->Release();
// all the real work is done in this function
hr = WalkTreeBackwardsFromPart(pPart);
if (FAILED(hr)) {
printf("Couldn't walk the tree: hr = 0x%08xn", hr);
pPart->Release();
CoUninitialize();
return __LINE__;
}
pPart->Release();
CoUninitialize();
system("pause");
return 0;
}
HRESULT WalkTreeBackwardsFromPart(IPart *pPart) {
HRESULT hr = S_OK;
LPWSTR pwszPartName = NULL;
hr = pPart->GetName(&pwszPartName);
if (FAILED(hr)) {
printf("Could not get part name: hr = 0x%08x", hr);
return hr;
}
printf("Part name: %wsn", *pwszPartName ? pwszPartName : L"(Unnamed)");
CoTaskMemFree(pwszPartName);
// Check AGC settings
const IID IID_IAudioAutoGainControl = __uuidof(IAudioAutoGainControl);
IAudioAutoGainControl *aGCcontrol = NULL;
hr = pPart->Activate(CLSCTX_ALL, IID_IAudioAutoGainControl, (void**)&aGCcontrol);
if (E_NOINTERFACE == hr) {
printf("NO AGC CONTROLn");
// not a Microphone node
} else if (FAILED(hr)) {
printf("Unexpected failure trying to activate IAudioAutoGainControl : hr = 0x%08xn", hr);
return hr;
} else {
// it's an AGC node...
printf("HAS AGC CONTROL");
aGCcontrol->SetEnabled(1, NULL); //Activate it
if (FAILED(hr)) {
printf("AGC Failed: hr = 0x%08x", hr);
aGCcontrol->Release();
return hr;
}
aGCcontrol->Release();
}
// get the list of incoming parts
IPartsList *pOutgoingParts = NULL;
hr = pPart->EnumPartsOutgoing(&pOutgoingParts);
if (E_NOTFOUND == hr) {
// not an error... we've just reached the end of the path
MessageBox("No incoming parts at this partn", MB_OK);
}
if (FAILED(hr)) {
MessageBox("Couldn't enum outgoing parts", MB_OK);
}
UINT nParts = 0;
hr = pOutgoingParts->GetCount(&nParts);
if (FAILED(hr)) {
MessageBox("Couldn't get count of outgoing parts", MB_OK);
pOutgoingParts->Release();
return hr;
}
// walk the tree on each incoming part recursively
for (UINT n = 0; n < nParts; n++) {
IPart *pOutgoingPart = NULL;
hr = pOutgoingParts->GetPart(n, &pOutgoingPart);
if (FAILED(hr)) {
MessageBox("Couldn't get part ", MB_OK);
pOutgoingParts->Release();
return hr;
}
hr = WalkTreeBackwardsFromPart(pOutgoingPart);
if (FAILED(hr)) {
MessageBox("Couldn't walk tree on part", MB_OK);
pOutgoingPart->Release();
pOutgoingParts->Release();
return hr;
}
pOutgoingPart->Release();
}
pOutgoingParts->Release();
return S_OK;
}
相关文章:
- 无法将结构注册为增强几何体3D点
- 增强基于 XML class_id的反序列化
- 增强精神解析器规则以检测语句中的特殊结尾
- C++ 使用增强正则表达式库时断言崩溃
- 增强精神 X3:错误:在"..."中没有名为"大小"的类型
- 如何包装(撰写)增强 hana 地图并访问括号运算符(运算符 [])?
- 有没有办法在C ++中检测汉字?(使用增强)
- 如何将增强MSM与增强信号结合使用?
- 如何使用增强::几何计算多边形的旋转固体体积?
- 复制部分文件的C++/增强方式
- 增强 ASIO 和串行端口异步读取
- 增强 Hana index_if和类型
- 增强超几何测试
- 如何修改增强 hana 结构的成员
- 增强纤维work_stealing屏障会导致段错误
- 增强循环缓冲区push_back在前面插入数据
- 彩色增强::日志显示偏移的颜色
- 增强序列化,按基类型加载存档类会产生错误的数据
- C++构建增强 1.57.0 VS2013 x64 本机工具命令提示符
- 如何使用C++控制麦克风增强/ AGC