Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 音频队列服务:更改输出设备_Iphone_Cocoa_Macos_Core Audio_Audioqueueservices - Fatal编程技术网

Iphone 音频队列服务:更改输出设备

Iphone 音频队列服务:更改输出设备,iphone,cocoa,macos,core-audio,audioqueueservices,Iphone,Cocoa,Macos,Core Audio,Audioqueueservices,在NSSound被证明不能胜任这项任务后,我花了一周的时间进行了一次无计划的深入Macintosh音响系统的探索。。我终于用音频队列服务播放了我的文件,现在只剩下一件事要做:切换输出设备 不幸的是,看起来我不是做错了什么,就是你应该通过的设备UID CFStringRef不是核心音频发出的 下面的代码检索标准输出设备(默认情况下音频队列仍将播放到该设备,但它拒绝更改设备): UInt32 thePropSize; AudioDeviceID defaultAudioDevice; OSStat

在NSSound被证明不能胜任这项任务后,我花了一周的时间进行了一次无计划的深入Macintosh音响系统的探索。。我终于用音频队列服务播放了我的文件,现在只剩下一件事要做:切换输出设备

不幸的是,看起来我不是做错了什么,就是你应该通过的设备UID CFStringRef不是核心音频发出的

下面的代码检索标准输出设备(默认情况下音频队列仍将播放到该设备,但它拒绝更改设备):

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));
如果队列正在播放,我会收到一个错误kaudioqueerr_InvalidRunState,告诉我不能在队列播放时设置此属性。如果队列未播放,我会收到-50参数错误

我的指针有问题吗?或者某个地方有不同的设备uid


任何帮助都将不胜感激。

我已经想出了一个解决方案,我将其发布在这里,以供存档:

Apple Developer Services在一个单独的项目中测试了我的代码,它很快就为他们运行了。区别在于,他们在设置设备uid时没有所有繁琐的音频缓冲区和音量设置等。我将设备uid更改从队列设置的末尾移到队列创建后立即进行,结果是这样的不好


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

您试图做什么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,给出了非文件化是很有可能的。。