Audiokit - 应用程序来自后台

时间:2018-05-25 22:24:59

标签: ios audio audiokit

我已经开始尝试使用AudioKit - 可爱的框架,但是我遇到了一些我无法追踪的崩溃。

首先,我想构建一个音序器,然后我按照这个媒体帖子https://medium.com/@oleary.audio/building-a-midi-sequence-in-swift-bed5f5c2bb7d中的示例进行操作,并添加了一些代码,以帮助使用回调乐器可视化在音序器中播放的当前步骤(如这里描述:AudioKit ios AKSamplerMetronome)。

当我在应用程序中时,一切运行正常,但是如果我退出并在后台退出应用并重新进入,它会随机(每4-5次尝试一次)崩溃,堆栈跟踪我不会明白(见下文) enter image description here

我不确定是什么原因造成这种情况,或者可能调用我在调试器中看到的AKMIDIInstrument.enableMIDI函数。任何提示都非常感谢。

编辑:我必须补充一点,这只发生在物理设备上,我无法在模拟器中重现它。

EDIT2:我也尝试将回调乐器的回调函数移到视图控制器之外并设置一个委托来更改视图,认为视图控制器的生命周期可能会以某种方式影响它,但问题仍然存在。

以下是我的代码的简化版本供参考:

class AudioCore {
    static let sharedInstance = AudioCore()
    let osc = AKOscillatorBank()
    let sequencer = AKSequencer()
    let callbackTrack:AKMusicTrack?
    let soundTrack:AKMusicTrack?
    let callbackInstrument = AKCallbackInstrument()
    let midi = AKMIDI()

    init() {
        let midiNode = AKMIDINode(node: osc)
        AudioKit.output = midiNode
        do {
            try AudioKit.start()
        }
        catch {
            AKLog("Audio kit failed to start")
        }

        if let track = sequencer.newTrack(){
            callbackTrack = track
            callbackTrack?.setMIDIOutput(callbackInstrument.midiIn)
        } else {
            callbackTrack = nil
        }

        if let sound = sequencer.newTrack(){
            soundTrack = sound
            soundTrack?.setMIDIOutput(midiNode.midiIn)
        } else {
            soundTrack = nil
        }
    }
}

class ViewController: UIViewController {
    override func viewDidLoad() {
         super.viewDidLoad()
         for i in 0...10 {
            AudioCore.sharedInstance.soundTrack?.add(noteNumber: MIDINoteNumber(pitch), velocity: 127, position: AKDuration(beats: pos), duration: AKDuration(beats: dur))
            AudioCore.sharedInstance.callbackTrack?.add(noteNumber: MIDINoteNumber(i), velocity: 127, position: AKDuration(beats: pos), duration: AKDuration(beats: dur))
         }
         AudioCore.sharedInstance.callbackInstrument.callback = { status, note, vel in
             guard status == .noteOn else { return }
             DispatchQueue.main.async {
                if(note < self.buttons.count) {
                    self.buttons[note].backgroundColor = UIColor.red
                 }
             }

             let dispatchDelay = 1.0 / tempo * 60.0 * noteLength
             DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + dispatchDelay, execute: {
                 if(note < self.buttons.count) {
                    self.buttons[note].backgroundColor = oldColor
                 }
             })
         }
    }
}

0 个答案:

没有答案