Я хочу записать миди-аудио с помощью AudioKit.Мне удалось это сделать, но когда я воспроизводил записанные ноты, возникают задержки, и время ноты не всегда хорошее, особенно когда я играю быстро во время записи.
Вот как я это сделал: У меня есть три кнопки, одна для Do (Midi номер 60), одна для Re (Midi номер 62), одна для Mi (64).Когда кнопка нажата, я отправляю записку и сохраняю время в 88 таблицах с плавающей точкой.Когда кнопка нажата вверх, я отправляю событие noteOff и сохраняю заметку в файле midi.Я могу определить длину сохраняемой заметки, выполнив (timeNoteOff-timeNoteOn).
Вот мой код:
var sequencer : AKSequencer = AKSequencer()
var track = AKMusicTrack()
var lastNoteOn:[AKDuration] = Array(repeating: AKDuration(seconds: 0), count: 88)
var sampler : AKAppleSampler = AKAppleSampler()
@IBAction func startRecordClick(_ sender: Any) {
track.clear()
sequencer.rewind()
sequencer.play()
}
@IBAction func stopRecordClick(_ sender: Any) {
if(sequencer.isPlaying){
sequencer.stop()
}
}
@IBAction func playClick(_ sender: Any) {
sequencer.rewind()
sequencer.play()
let list = sequencer.tracks[0].getMIDINoteData()
print(list)
}
@IBAction func doClick(_ sender: Any) {
jouerDown(a:144, b:60, c:80) // 60 means midi number 60, ie C4
}
@IBAction func doUp(_ sender: Any) {
jouerUp(a:144, b:60, c:80)
}
override func viewDidLoad() {
super.viewDidLoad()
do{try
sampler.loadMelodicSoundFont("TimGM6mb", preset: 0)
} catch {
print("couldn't load sf2 file")
}
AudioKit.output = sampler
let callbackInstr = AKMIDICallbackInstrument()
callbackInstr.callback = myCallBack
track = sequencer.newTrack()!
sequencer.setGlobalMIDIOutput(callbackInstr.midiIn)
sequencer.preroll()
try! AudioKit.start()
}
func jouerDown(a:UInt8, b:MIDINoteNumber, c:MIDIVelocity){
lastNoteOn[Int(b)] = sequencer.currentPosition
try! sampler.play(noteNumber: b,velocity: c,channel: 0)
}
func jouerUp(a:UInt8, b:MIDINoteNumber, c:MIDIVelocity){
let x = sequencer.currentPosition
try! sampler.stop(noteNumber: b, channel: 0)
if(sequencer.isPlaying){
track.add(noteNumber: b, velocity: c, position: x, duration: x - lastNoteOn[Int(b)] , channel: 0)
}
}
func myCallBack(a:UInt8, b:MIDINoteNumber, c:MIDIVelocity) {
switch(a){
case 144, 157:
try! sampler.play(noteNumber: b,velocity: c,channel: 0)
print("\(a) \(b)")
break;
default:
try! sampler.stop(noteNumber: b, channel: 0)
break;
}
}
Вот мой быстрый проект для этого выпадающего списка дляВы должны проверить и изменить: https://www.dropbox.com/sh/vnn7soa8aq0180z/AAAzs9PDzND3KPjFIhVobLMya?dl=0
Есть ли способ избежать несоблюдения синхронизации в итоговой записи?Например, используя более нестандартную технику из AudioKit, вместо изменения дорожки вручную при каждом событии заметки?