音频队列服务:更改输出设备
上周,在 NSSound 被证明无法胜任这项任务后,我进行了一次计划外的 Macintosh 音响系统深处的旅行。我终于用音频队列服务播放了我的文件,现在只剩下一件小事要做了:切换输出设备。
不幸的是,看来我要么做错了什么,要么你应该传递的设备 UID CFStringRef 不是 Core Audio 给出的那个。
下面的代码片段检索标准输出设备(音频到该设备)无论如何,队列都会默认播放,但它拒绝更改设备:
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!?
任何帮助将不胜感激。
I've spent the last week on an unplanned excursion into the depths of the Macintosh sound system after NSSound proved to be unequal to the task.. I finally got my file playing with Audio Queue Services and now there's only one little thing left to do: switch output devices.
Unfortunately, it seems that I'm either doing something wrong or the device UID CFStringRef that you're supposed to pass is not the one that Core Audio gives out..
The piece of code below retrieves the standard output device (to which the Audio Queue will be playing by default anyway, but it refuses to change devices:
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));
If the queue is playing, I get an error kAudioQueueErr_InvalidRunState, telling me that you can't set this property while the queue is playing. If the queue is not playing, I get the -50 parameter error.
I'm I doing something wrong with the pointers? or is there a different device uid somewhere!?
Any help would be greatly appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我已经找到了一个解决方案,我将其发布在这里以供存档:
Apple Developer Services 在一个单独的项目中测试了我的代码,它立即对他们来说运行得非常好.. 不同之处在于他们设置了设备 uid 而没有使用所有繁琐的音频缓冲区和音量设置等。我将设备 uid 更改从队列设置的末尾移动到创建队列后立即,宾果游戏!它工作得很好。
我不是 100% 确定,但我认为由于某些硬件驱动程序限制,在设置队列增益后您无法更改设备。 “参数错误”似乎并不完全指向这个方向,但我认为“太晚了,无法更改设备”错误会更合适。
I've figured out a solution and I'm posting it here for the archives:
Apple Developer Services tested my code in a separate project and it ran just great for them straight away.. the difference was that they set the device uid without all the tedious audio buffers and volume setup, etc.. I moved the device uid change from the end of the queue setup to immediately after the queue is created and bingo! it works just fine.
I'm not 100% certain but I think you just can't change the device after you set the gain for the queue due to some hardware driver restrictions. "parameter error" doesn't seem to quite point in that direction but I think a "too late to change device" error would be more appropriate.