AudioKit重置AKSequencer currentPosition

时间:2018-09-10 08:41:51

标签: swift audiokit

我有一个从AKKeyboardView记录MIDI数据的应用程序。在录制之前,用户可以使用键盘进行操作,但是当他们想要开始录制时,请单击一个按钮。

点击按钮后会发生以下情况:

let sequencer = AKSequencer()

func buttonClicked() {
    sequencer.rewind()
    sequencer.play()
}

我当前面临的问题是,我想记录键盘数据大约四秒钟,然后如果用户仍在记录键盘的MIDI,则重新启动4秒。

如果currentPosition的节拍大于4,我试图通过使用noteOn函数倒带音序器来修复它,但是效果不佳。我还尝试使用currentRelativePosition代替,但是如果您长时间按住某个键,它将崩溃。

这是我的AKKeyboardDelegate代码:

var noteDict = [MIDINoteNumber: Double]()
var isMIDIRecording = false

func noteOn(note: MIDINoteNumber) {
    var currentPosition = sequencer.currentPosition
    var beats = currentPosition.beats

    self.noteDict[note] = beats
    bank.play(noteNumber: note, velocity: 127)
}

func noteOff(note: MIDINoteNumber) {
    let currentPosition = sequencer.currentPosition
    let endTime = currentPosition.beats

    if let startTime = noteDict[note] {
        let durationInBeats = abs(endTime - startTime)
        let noteDuration = AKDuration(beats: durationInBeats)

        if isMIDIRecording {
            musicTrack.add(noteNumber: note, velocity: 127, position: currentPosition, duration: noteDuration)
        }

        noteDict[note] = nil
    }

    bank.stop(noteNumber: note)
}

这是我用于初始化音序器和AudioKit的代码。

let callbackInstrument = AKCallbackInstrument()

var bank = AKFMOscillatorBank(waveform: AKTable(.triangle), attackDuration: 0.01, decayDuration: 0.03, sustainLevel: 0.02, releaseDuration: 0.01)

AudioKit.output = bank

    do {
        try AudioKit.start()
    } catch {
        print("AudioKit couldn't be started")
        fatalError()
    }

    handleCallbackInstrument()

    // create two tracks for the sequencer
    let metronomeTrack = sequencer.newTrack("metronome track")

    let musicTrack = sequencer.newTrack("music track")
    musicTrack.setMIDIOutput(callbackInstrument.midiIn)

    musicTrack.setLength(AKDuration(beats: 4))

    for i in 0 ..< 4 {
        // this will trigger the sampler on the four down beats
        metronomeTrack?.add(noteNumber: 60, velocity: 100, position: AKDuration(beats: Double(i)), duration: AKDuration(beats: 0.5))
    }

    // get the sequencer ready
    sequencer.enableLooping(AKDuration(beats: 4))
    sequencer.setTempo(120)

非常感谢任何帮助或指针。

0 个答案:

没有答案