У меня есть приложение, которое записывает данные 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)
Любая помощь или указатели с благодарностью.