AVAudioEngine.connect 上的 CoreAudio 错误和崩溃

Posted

技术标签:

【中文标题】AVAudioEngine.connect 上的 CoreAudio 错误和崩溃【英文标题】:CoreAudio error and crash on AVAudioEngine.connect 【发布时间】:2019-08-06 15:27:34 【问题描述】:

我正在尝试将AVAudioUnitEffect 连接到AVAudioEngine 的实例,如下所示:

required init(inputFormat: AVAudioFormat, outputFormat: AVAudioFormat, andAVAudioEngine avAudioEngine:AVAudioEngine) 
    self.inputFormat = inputFormat
    self.outputFormat = outputFormat

    self.avAudioEngine = avAudioEngine
    self.myAudioUnit = MyAVAudioUnit()

    super.init()

    avAudioEngine.attach(myAudioUnit)
    avAudioEngine.connect(myAudioUnit, to: avAudioEngine.outputNode, format: self.inputFormat)

总体类只是NSObject 的子类,MyAudioUnitAVAudioUnitEffect 的子类。

在看似随机的时间,这个初始化器的最后一行(对connect的调用)会抛出一个带有以下错误的SIGABRT:com.apple.coreaudio.avfaudio: error -10875

相当于kAudioUnitErr_FailedInitialization

谁能解释一下这个错误以及这里可能发生了什么?我认为MyAVAudioUnit 的初始化程序可能失败了,但它的内部初始化程序 (init(audioComponentDescription: AudioComponentDescription)) 不会抛出任何错误并且具有非可选的返回类型。有没有其他人遇到过这个特殊错误?

更新

这里是inputFormat的初始化:

guard let stereoFormat = AVAudioFormat(commonFormat: .pcmFormatFloat32,
                                        sampleRate: 44100,
                                        channels: 2,
                                        interleaved: false) else 
                                            return                                             


let numChannels = UInt32(10)
guard let multiChannelLayout = AVAudioChannelLayout(layoutTag: kAudioChannelLayoutTag_Unknown | numChannels) else 
    return


inputFormat = AVAudioFormat(commonFormat: stereoFormat.commonFormat,
                                   sampleRate: stereoFormat.sampleRate,
                                   interleaved: stereoFormat.isInterleaved,
                                   channelLayout: multiChannelLayout)

MyAVAudioUnit 包含一个额外的自定义参数 (volumeParameter),并按如下方式初始化:

required override init() 
    var componentDescription = AudioComponentDescription()
    componentDescription.componentType = kAudioUnitType_Effect
    componentDescription.componentSubType = xxxxx
    componentDescription.componentManufacturer = xxxxx
    componentDescription.componentFlags = 0
    componentDescription.componentFlagsMask = 0

    AUAudioUnit.registerSubclass(MyAVAudioUnit.self,
                                 as: componentDescription,
                                 name:"MyAVAudioUnit",
                                 version: UInt32.max)

    super.init(audioComponentDescription: componentDescription)

    guard let paramTree = self.auAudioUnit.parameterTree else  return 
    volumeParameter = paramTree.value(forKey: "volumeParameter") as? AUParameter

【问题讨论】:

你传入什么样的inputFormats? 您能显示MyAVAudioUnit 或直接用未分类的AVAudioUnitEffect 复制吗? @RhythmicFistman 更新了原始问题。感谢您的观看。 没问题 - 让 10 频道 AVAudioFormat 正常工作做得很好。你能进一步简化复制吗?如果没有参数,问题是否会重现?用立体声而不是 10 声道?使用内置音频单元而不是自定义?一个可运行的 sn-p 会很棒。 音频引擎最近停止了吗?调用停止后,您是否等待了足够长的时间? (实际上不是同步的) 【参考方案1】:

这就是最终解决此问题的方法。我从崩溃日志中注意到,在尝试连接音频单元之前打印出的音频图显示如下:

“ ________ GraphDescription ________ AVAudioEngineGraph 0x101538ba0: initialized = 1, running = 0, number of nodes = 23 ”

有趣的是,running 为假,initialized。关于此initialized 信息的含义的文档并不多,但我发现它在 AVAudioEngine 之前已启动但暂停时显示为真。现在,我没有从任何地方明确调用avAudioEngine.pause(),但我认为系统可能会在AVAudiosessionRouteChangeNotification 中启动暂停(这是我在整个事件系列中所响应的)。

其中很多都是猜测,但很明显,在引擎的打印输出显示 initialized = 1(或通过推断,引擎已暂停)时调用 avAudioEngine.connect() 会导致此崩溃。

在尝试连接音频单元之前,必须完全停止音频引擎。我的问题是我尝试调用avAudioEngine.stop() 被包裹在if 语句中,如下所示:

if avAudioEngine.isRunning 
    avAudioEngine.stop()

当然,这个if 语句被跳过了,因为音频引擎实际上没有运行。所以stop() 从未被调用过。删除 if 语句并调用 stop() 无疑会在引擎上设置 initialized = 0 并允许连接而不会发生此崩溃。

希望这对其他人有所帮助。我花了很长时间才解开。

【讨论】:

【参考方案2】:

你说这发生在“随机”复数形式。这可能意味着您经常这样做,并且可能在释放或取消初始化单元后不久。请注意,音频单元子系统在不同的完全异步线程中运行,因此在您的应用停止并释放该单元后,该单元可能仍被操作系统使用(短时间内)。如果您在任何停止/释放调用和任何(重新)初始化之间设置足够长的延迟,比如一两秒,它可能会阻止这个问题。

【讨论】:

真正的洞察力。一定会试一试的。谢谢!

以上是关于AVAudioEngine.connect 上的 CoreAudio 错误和崩溃的主要内容,如果未能解决你的问题,请参考以下文章

同一应用程序上的两种不同语言 PHP 和 Java,Apache 上的 PHP 和 Tomcat 上的 Java

UILabel 上的奇怪行为与 StoryBoard 上的 \n

iPhone 上的字体大小比 PC 上的小

怎么把图片上的字去掉啊?

在 Firefox 中不显示边框,表格上的边框折叠,位置:tbody 上的相对或单元格上的背景颜色

键盘上的PERIOD键在啥地方?