2

我目前的主要目标是获取有关本地机器的所有音频端点设备的详细信息。那是代表音频外围设备的对象。我希望能够根据某些逻辑(或最终允许用户手动操作)选择要从哪个设备进行录制。

这是我到目前为止所得到的。我对 c++ 很陌生,所以处理所有这些抽象类变得有点棘手,所以也可以随意评论代码质量。

//Create vector of IMMDevices
UINT endpointCount = NULL;
(*pCollection).GetCount(&endpointCount);
std::vector<IMMDevice**> IMMDevicePP;   //IMMDevice seems to contain all endpoint devices, so why have a collection here?
for (UINT i = 0; i < (endpointCount); i++)
{
IMMDevice* pp = NULL;
(*pCollection).Item(i, &pp);
IMMDevicePP.assign(1, &pp);
}

我目前更多的技术目标是获取实现此接口的对象:http: //msdn.microsoft.com/en-us/library/windows/desktop/dd371414 (v=vs.85).aspx 这是一种类型应该代表单个音频端点设备,而IMMDevice似乎包含设备集合。但是IMMEndpoint只包含一个名为的方法GetDataFlow,所以我不确定这是否对我有帮助。同样,目标是轻松选择要从哪个端点设备录制和流式传输音频。

有什么建议么?我是否使用了错误的 API?这个 API 对音频的实际流式传输和采样肯定有很好的命令,但我对如何确保我正在使用所需的设备有点迷茫。

4

2 回答 2

3

WASAPI 将允许您做您需要做的事情,以便您使用正确的 API。您误认为 IMMDevice 代表音频设备的集合,即 IMMDeviceCollection。IMMDevice 表示单个音频设备。通过“设备”,WASAPI 并不像您所期望的那样表示声卡,而是表示此类卡上的单个输入/输出。例如,带有模拟输入/输出 + 数字输出的声卡将显示为 3 个 IMMDevice,每个都有自己的 IMMEndpoint。我不确定您要获取哪些详细信息,但在我看来 IMMDevice 将为您提供所需的一切。基本上,你会想做这样的事情:

  • 创建一个 IMMDeviceEnumerator
  • 调用指定渲染、捕获或两者的 EnumAudioEndpoints,以枚举到 IMMDeviceCollection
  • 从 IMMDeviceCollection 获取单个 IMMDevice 实例
  • 可以使用 OpenPropertyStore ( http://msdn.microsoft.com/en-us/library/windows/desktop/dd370812%28v=vs.85%29.aspx ) 从 IMMDevice 查询设备名称和描述。可以在此处找到其他受支持的设备详细信息:http: //msdn.microsoft.com/en-us/library/windows/desktop/dd370794%28v=vs.85%29.aspx
  • 从 IMMDeviceCollection 获得的 IMMDevice 实例也将是 IMMEndpoint 的实例,使用 QueryInterface 在两者之间切换。但是,正如您所指出的,这只会告诉您是否已使用渲染或捕获设备。在 EnumAudioEndpoints 上直接询问您想要的内容要容易得多。
  • 关于代码质量:使用 x->f() 代替 if (*x).f(),尽管从技术上讲,-> 运算符是通过对象指针调用函数的常用方法
  • 不要使用vector::assign,显然它会在每次调用时替换整个vector的内容,因此无论可用设备的数量如何,最终都会得到一个大小为1的集合。请改用 push_back。
于 2014-09-21T20:00:46.927 回答
1

在枚举您的 IMMDevices 后,如 Sjoerd 所述,必须检索IPropertyStore 设备的信息。从那里你必须PROPVARIANT像这样提取对象:

PROPERTYKEY key;
HRESULT keyResult = (*IMMDeviceProperties[i]).GetAt(p, &key);

然后

PROPVARIANT propVari;
HRESULT propVariResult = (*IMMDeviceProperties[i]).GetValue(key, &propVari);

根据这些文件:

http://msdn.microsoft.com/en-us/library/windows/desktop/bb761471(v=vs.85).aspx http://msdn.microsoft.com/en-us/library/windows/desktop/ aa380072(v=vs.85).aspx

最后,导航大型PROPVARIANT结构以获得音频端点设备的友好名称,只需访问结构的pwszVal成员,PROPVARIANT如下所示:

http://msdn.microsoft.com/en-us/library/windows/desktop/dd316594(v=vs.85).aspx

所有关于找到正确的文档!

于 2014-10-01T16:41:08.207 回答