【发布时间】:2011-04-04 18:34:13
【问题描述】:
在 NSSound 被证明无法胜任这项任务之后,我在上周计划外探索了 Macintosh 音响系统的深处。我终于用音频队列服务播放了我的文件,现在只有一件小事剩下要做的事:切换输出设备。
不幸的是,我似乎做错了什么,或者您应该通过的设备 UID CFStringRef 不是 Core Audio 给出的那个..
以下代码检索标准输出设备(Audio Queue 无论如何都会默认播放到该设备,但它拒绝更改设备:
UInt32 thePropSize;
AudioDeviceID defaultAudioDevice;
OSStatus result = noErr;
// get the device list
AudioObjectPropertyAddress thePropertyAddress = { kAudioHardwarePropertyDefaultOutputDevice, kAudioObjectPropertyScopeGlobal,
kAudioObjectPropertyElementMaster };
result = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &thePropertyAddress, 0, NULL, &thePropSize);
result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &thePropertyAddress, 0, NULL, &thePropSize, &defaultAudioDevice);
CFStringRef theDeviceName;
// get the device name
thePropSize = sizeof(CFStringRef);
thePropertyAddress.mSelector = kAudioObjectPropertyName;
thePropertyAddress.mScope = kAudioObjectPropertyScopeGlobal;
thePropertyAddress.mElement = kAudioObjectPropertyElementMaster;
// get the name of the device
result = AudioObjectGetPropertyData( (AudioObjectID)defaultAudioDevice,
&thePropertyAddress, 0, NULL, &thePropSize, &theDeviceName);
// get the uid of the device
CFStringRef theDeviceUID;
thePropertyAddress.mSelector = kAudioDevicePropertyDeviceUID;
result = AudioObjectGetPropertyData( (AudioObjectID)defaultAudioDevice,
&thePropertyAddress, 0, NULL, &thePropSize, &theDeviceUID);
result = AudioQueueSetProperty( playerState.mQueue,
kAudioQueueProperty_CurrentDevice,
&theDeviceUID,
sizeof(theDeviceUID));
如果队列正在播放,我会收到错误 kAudioQueueErr_InvalidRunState,告诉我在队列正在播放时您无法设置此属性。如果队列没有播放,我会得到 -50 参数错误。
我的指针有问题吗?还是在某个地方有不同的设备 uid!?
任何帮助将不胜感激。
【问题讨论】:
-
您要做什么 NSSound 无法做到的事情? AudioObjectGetPropertyData 为 DeviceUID 属性返回了什么?
-
NSSound 循环功能不能很好地工作。它会在每次重复之间插入一个轻微但听得见的停顿,在我的上下文中这是不可接受的。我机器上的设备 uid 是:“AppleHDAEngineOutput:1B,0,1,3:0”、“AppleHDAEngineOutput:1B,0,1,4:1”、“AppleHDAEngineOutput:1B,0,1,5:2”这些与 [NSSound setPlaybackDeviceIdentifier:] 一起工作正常。
-
您是在应用程序中的某个地方查找它们,还是通过检查 AudioObjectGetPropertyData 的返回值获得它们?我问是因为早期的函数之一可能返回错误而不是有用的值,这是为最后一个函数提供无效参数的好方法。
-
我发布的代码是简化版,所有状态码都是noErr,值在别处检查并打印出来。它们是相同的设备 ID,在输入 NSSound 时可以正常工作。本质上,要么它们不是传递给音频队列属性的正确值,要么我没有以正确的方式传递它们.. 当然,除非它只是一个错误的 API,它给定非文档的状态是真实的可能性..
标签: iphone cocoa macos core-audio audioqueueservices