在NSSound被证明不能胜任这项任务后,我花了一周的时间进行了一次计划外的旅行,深入麦金塔音响系统的深处。我终于用音频队列服务得到了我的文件,现在只剩下一件小事要做:切换输出设备。
不幸的是,似乎我要么做错了什么,要么你应该传递的设备UID CFStringRef不是核心音频提供的那个。
下面这段代码检索标准输出设备( 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!?
任何帮助都将不胜感激。
发布于 2010-09-02 06:03:55
我已经想出了一个解决方案,并将其发布在这里以供存档:
Apple Developer Services在一个单独的项目中测试了我的代码,它立即为他们运行得很好。不同的是,他们设置了设备的uid,而没有所有繁琐的音频缓冲区和音量设置等。我将设备的uid更改从队列设置的末尾移到了队列创建后的立即位置,并答对了!它工作得很好。
我不是100%确定,但我认为,由于一些硬件驱动程序的限制,您无法在为队列设置增益后更改设备。“参数错误”似乎并不完全指向这个方向,但我认为“太晚了,无法更改设备”错误会更合适。
https://stackoverflow.com/questions/3583852
复制相似问题