我需要确定任意 CoreAduio AudioDevice 与哪个物理 USB 设备相关(通过 VID/PID/SerialNumber)。 CoreAudio 允许查询各种设备属性,例如传输类型(在我的例子中是 USB)、UID(跨 session 和机器唯一)和一些配置字符串。
IOKit 和 CoreAudio 的音频部分都有音频设备的表示,但我不清楚如何弥合两者之间的差距。 (好像我应该能够查询 AudioDevice 的 IOAudioDevice...)
最佳答案
我找到了以下 post from an Apple CoreAudio engineer描述如何从 AudioDeviceID
获取 IOUSBDeviceInterface
:
There is no direct mapping between the two. But the best way to do it would be:
- get the UID string for the device from the HAL
- Make a matching dictionary that searches for IOAudioEngine objects
- Iterate through the matching services until you find the one with the UID property that matches what you got from the HAL
- Walk the IORegistry from here to find the USB object you are looking for
这就是代码的样子:
#include <IOKit/IOKitLib.h>
#include <IOKit/audio/IOAudioDefines.h>
#include <IOKit/usb/USB.h>
AudioDeviceID deviceID = ...
// get device UID for AudioDevice ID
AudioObjectPropertyAddress address = {kAudioDevicePropertyDeviceUID, kAudioObjectPropertyScopeOutput, 0};
UInt32 size = sizeof(CFStringRef);
CFStringRef uid = NULL;
OSStatus err = AudioObjectGetPropertyData(deviceID, &address, 0, NULL, &size, &uid);
NSNumber *vid, *pid;
// find matching IOAudioEngine object
io_iterator_t it;
if (IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching(kIOAudioEngineClassName), &it) == KERN_SUCCESS) {
io_service_t service;
while ((service = IOIteratorNext(it)) != 0) {
CFStringRef uniqueID = IORegistryEntryCreateCFProperty(service, CFSTR(kIOAudioEngineGlobalUniqueIDKey), kCFAllocatorDefault, 0);
if (uniqueID && CFEqual(uniqueID, uid)) {
vid = CFBridgingRelease(IORegistryEntryCreateCFProperty(service, CFSTR(kUSBVendorID), kCFAllocatorDefault, 0));
pid = CFBridgingRelease(IORegistryEntryCreateCFProperty(service, CFSTR(kUSBProductID), kCFAllocatorDefault, 0));
}
CFRelease(uniqueID);
if (vid || pid) break;
}
IOObjectRelease(it);
}
关于macos - 在 OSX 上查找与 CoreAudio 设备关联的 USB VID/PID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24944614/