我正在尝试使用AVAudioEngine
,AVAudioUnitSampler
和AVAudioSequencer
创建和测试基本的音频设置;但是,即使是最基本的代码版本也会在下面引发错误,从而导致应用程序彻底崩溃。
谁能告诉我为什么会这样?原因特别是在初始化音序器的行(如果已注释掉该行,则错误停止),但是我不确定为什么。这与步骤的顺序有关,还是我在这里错过了?
它说了有关检索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中提供了有关如何解决此问题的详细信息。