我正在尝试使用AVAudioEngineAVAudioUnitSamplerAVAudioSequencer创建和测试基本的音频设置;但是,即使是最基本的代码版本也会在下面引发错误,从而导致应用程序彻底崩溃。

谁能告诉我为什么会这样?原因特别是在初始化音序器的行(如果已注释掉该行,则错误停止),但是我不确定为什么。这与步骤的顺序有关,还是我在这里错过了?

它说了有关检索outputNode的内容,但我认为AVAudioEngine具有默认情况下初始化的那些之一。

谢谢。

class TestAudioClass {

    private var audioEngine: AVAudioEngine
    private var sampler: AVAudioUnitSampler
    private var sequencer: AVAudioSequencer

    init() {
        self.audioEngine = AVAudioEngine()
        self.sampler = AVAudioUnitSampler()
        self.sequencer = AVAudioSequencer(audioEngine: audioEngine)
    }
}



  线程1:信号SIGABRT
  
  [avae] AVAEInternal.h:70:_AVAE_Check:所需条件为假:[AVAudioEngineGraph.mm:4474:GetDefaultMusicDevice:(outputNode)]
  
  [avae] AVAEInternal.h:103:_AVAE_CheckNoErr:[AVAudioEngineGraph.mm:4309:SetSequence:(err = MusicSequenceSetAudioGraph(inSequence,_seqGraphImpl)):错误-1
  
  ***由于未捕获的异常'com.apple.coreaudio.avfaudio'而终止应用程序,原因:'错误-1'

最佳答案

因此,在深入研究后,我找到了解决方案:虽然确实是AVAudioEngine附带了outputNode的现成商品,但Apple尚不清楚的是该输出节点并不立即存在。初始化后。

在上面的代码中,排序器一经创建,便尝试访问引擎的输出节点,但发现那里没有任何东西,从而触发了崩溃。

在创建音序器之前,您必须以某种方式(直接或通过outputNode间接访问)访问引擎的mainMixerNode。可以仅通过调用该属性来实现,但是一种好的方法是将任何相关节点(例如AVAudioUnitSampler)连接到该属性。

更正后的代码如下:

class TestAudioClass {

    private var audioEngine: AVAudioEngine
    private var sampler: AVAudioUnitSampler
    private var sequencer: AVAudioSequencer

    init() {
        self.audioEngine = AVAudioEngine()
        self.sampler = AVAudioUnitSampler()
        audioEngine.attach(sampler)
        audioEngine.connect(sampler, to: audioEngine.mainMixerNode, format: nil)
        self.sequencer = AVAudioSequencer(audioEngine: audioEngine)
    }
}


还值得注意的是,如果您直接直接访问outputNode,则不会导致混音器被连接。根据Apple员工here


  “ ...将为您自动创建默认输出,或者连接了混音器(首先访问mainMixerNode),或者仅通过自身(首先访问outputNode)创建。”


注意:在取消初始化此对象期间(例如对另一个ViewController执行解散搜索时),您仍然可能会遇到类似的崩溃。 here中提供了有关如何解决此问题的详细信息。

09-06 10:44