【问题标题】:Audio Queue Services: changing output device音频队列服务:更改输出设备
【发布时间】: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


【解决方案1】:

我已经找到了一个解决方案,我将其发布在此处以供存档:

Apple 开发人员服务在一个单独的项目中测试了我的代码,它对他们来说非常好。不同之处在于他们设置了设备 uid,而没有所有繁琐的音频缓冲区和音量设置等。我移动了设备uid 从队列设置结束更改为队列创建后立即更改!它工作得很好。

我不是 100% 确定,但我认为由于某些硬件驱动程序限制,您在设置队列增益后无法更改设备。 “参数错误”似乎并不完全指向那个方向,但我认为“更改设备为时已晚”错误会更合适。

【讨论】:

    猜你喜欢
    • 2021-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多