Обрезка MIDI-файла с помощью AudioKit
Я пытаюсь обрезать и зациклить определенную часть файла MIDI, используя AudioKit
,
Я использую секвенсор и нашел пару вещей, которые близки к тому, что мне нужно, но не совсем.
Я нашел метод в AKSequencer
называется clearRange
, С помощью этого метода я могу заставить замолчать те части MIDI, которые мне не нужны, но я не нашел способа обрезать секвенсор и сохранить только ту часть, которая мне интересна. Сейчас звучит только та часть, которую я хочу но я все еще получаю тихие части.
Есть ли способ обрезать секвенсор или создать новый секвенсор только с той частью, которую я хочу сохранить от оригинальной?
Спасибо!
1 ответ
Одно разочаровывающее ограничение Apple MusicSequence
(который AKSequencer
основано на том), что хотя вы можете легко установить "правую сторону" зацикленного участка, левая сторона всегда будет возвращаться к нулю и не может быть изменена. Таким образом, чтобы обрезать с левой стороны, вам нужно изолировать секцию, которую вы хотите зациклить, и сдвинуть ее так, чтобы начало вашего цикла было в нуле.
Начиная с AudioKit 4.2.4 это возможно. Используйте AKMusicTrack's .getMIDINoteData()
чтобы получить массив AKMIDINoteData
структуры, содержимое которых можно редактировать, а затем использовать для замены исходных данных. Если у вас был 16-битный трек, и вы хотели зациклить последние четыре удара, вы могли бы сделать что-то вроде этого:
let loopStart = 12.0
let loopLength = 4.0
// keep track of the original track contents
let originalLength = 16.0
let originalContents = track.getMIDINoteData()
// isolate the segment for looping and shift it to the start of the track
let loopSegment = originalContents.filter { loopStart ..< (loopStart + loopLength) ~= $0.position.beats }
let shiftedSegment = loopSegment.map { AKMIDINoteData(noteNumber: $0.noteNumber,
velocity: $0.velocity,
channel: $0.channel,
duration: $0.duration,
position: AKDuration(beats: $0.position.beats - loopStart))
}
// replace the track contents with the loop, and assert the looping behaviour
track.replaceMIDINoteData(with: shiftedSegment)
seq.setLength(AKDuration(beats: loopLength))
seq.enableLooping()
// and to get back to the original:
track.replaceMIDINoteData(with: originalContents)
seq.setLength(AKDuration(beats: originalLength))
seq.enableLooping()
Если вы хотите зациклить секцию, чтобы повторить для длины оригинальной последовательности, то вы можете использовать shiftedSegment
в качестве шаблона и построить 16-битную последовательность из него.