AudioKit сбрасывает AKSequencer currentPosition - PullRequest
0 голосов
/ 10 сентября 2018

У меня есть приложение, которое записывает данные MIDI из AKKeyboardView. Перед записью пользователь может поиграть с клавиатурой, но когда он хочет начать запись, он нажимает кнопку.

Вот что происходит при нажатии кнопки:

let sequencer = AKSequencer()

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

Проблема, с которой я сейчас сталкиваюсь, заключается в том, что я хотел бы записать данные клавиатуры, возможно, на четыре секунды, а затем перезапустить 4 секунды, если пользователь все еще записывает MIDI клавиатуры.

Я попытался исправить это, используя функцию noteOn для перемотки секвенсора, если ритм currentPosition больше 4, но это не так хорошо работает. Я также попытался использовать 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)

Любая помощь или указатели с благодарностью.

...