CoreAudio:如何检测RemoteIO后面没有设备而不启动它?
Posted
技术标签:
【中文标题】CoreAudio:如何检测RemoteIO后面没有设备而不启动它?【英文标题】:CoreAudio: How to detect there's no device behind RemoteIO without starting it? 【发布时间】:2020-06-25 14:10:47 【问题描述】:我正在尝试在没有麦克风的 Mac 上的 Catalyst 上使用 kAudioUnitSubType_RemoteIO
单元。
问题是,总线 1(即输入)的整个初始化都很好,包括设置格式,甚至启用总线,但随后它在 AudioOutputUnitStart(unit)
失败,出现一些模糊的错误 -66628
,甚至没有列出osstatus.com.
但是,如果我仅使用输出总线 0 启动设备,则它运行良好并播放我的音频。
那么,有没有一种简单的方法可以在没有枚举所有设备的情况下检测 RemoteIO 后面没有设备的情况?只需尝试一些肯定会失败的功能(设置或获取参数?)。
这是我的代码:
// Instantiate the unit
var desc = AudioComponentDescription(componentType: kAudioUnitType_Output, componentSubType: kAudioUnitSubType_RemoteIO, componentManufacturer: kAudioUnitManufacturer_Apple, componentFlags: 0, componentFlagsMask: 0)
let comp = AudioComponentFindNext(nil, &desc)!
var unit: AudioUnit!
NotError(AudioComponentInstanceNew(comp, &unit), 51000)
// Set maximum buffer size as recommended by Apple
var maxFramesPerSlice = UInt32(Self.maxFramesPerSlice)
NotError(AudioUnitSetProperty(unit, kAudioUnitProperty_MaximumFramesPerSlice, kAudioUnitScope_Global, 1, &maxFramesPerSlice, SizeOf(maxFramesPerSlice)), 51003)
// Set format and sample rate to the same as hardware output
var descr = AudiostreamBasicDescription.canonical(isStereo: true, sampleRate: hardwareSampleRate)
NotError(AudioUnitSetProperty(unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &descr, SizeOf(descr)), 51022)
// Set render callback
var callback = AURenderCallbackStruct(inputProc: stereoInputRenderCallback, inputProcRefCon: Bridge(obj: self))
NotError(AudioUnitSetProperty(unit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Output, 1, &callback, SizeOf(callback)), 51008)
// Enable input - required as it's disabled by default
var enable: UInt32 = 1
NotError(AudioUnitSetProperty(unit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enable, SizeOf(enable)), 51021)
NotError(AudioUnitInitialize(unit), 51007)
所以它通过了所有这些并且只在OSStatus(-66628)
这里失败:
NotError(AudioOutputUnitStart(unit), 51009)
我认为在尝试启动设备之前必须有某种方法来检测设备的缺失。
编辑:理想情况下我正在寻找一种跨平台的方式(ioS/macOS)
【问题讨论】:
也许kAudioDevicePropertyStreamConfiguration
在 kAudioObjectPropertyScopeInput
并检查 mBuffers > 0
?
@sbooth 已经做了类似的事情。我在 RemoteIO 的两条总线的硬件端获得了格式描述符。如果总线后面没有设备,则格式结构全为零。例如,在 Mac Pro 和 Catalyst 下,我的麦克风全为零,因此似乎可以正常工作。
太好了,很高兴你能成功。我发布了我的建议作为答案,这样它就不会丢失。
【参考方案1】:
我相信检查为kAudioDevicePropertyStreamConfiguration, kAudioObjectPropertyScopeInput
返回的AudioStreamBasicDescription
是否具有mBuffers > 0
将表明设备是否存在。
【讨论】:
谢谢。虽然这需要一个 deviceID,但我不知道在 iOS、Catalyst 和 macOS 上获取当前输入 deviceID 的任何跨平台方法。有什么建议么?找了一阵子。 您说得对,这需要设备 ID。我不确定如何在 iOS 上获得一个。我知道您可以从AVAudioSessionPortDescription
获得 UID,但我不确定是否可以转换为设备 ID(通常在 macOS 上我会使用 kAudioHardwarePropertyTranslateUIDToDevice
),但我不知道 UID 是否相同。 以上是关于CoreAudio:如何检测RemoteIO后面没有设备而不启动它?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 iPhone 的 Core Audio (Audio Unit/ Remote IO) 中将录制的声音更改为男人的声音