使用AudioKit裁剪MIDI文件

时间:2017-10-26 17:15:36

标签: ios midi sequencing audiokit

我正在尝试使用AudioKit裁剪并循环播放MIDI文件的某个部分。

我正在使用音序器,发现了一些接近我需要的东西,但并不完全正确。

我在AKSequencer中找到了一个名为clearRange的方法。通过这种方法,我能够使我不想要的MIDI部分静音,但是我还没有找到一种方法来修剪音序器,只保留我感兴趣的部分。现在只有我想要的部分有声音但我仍然得到了沉默的部分。

有没有办法修剪一个音序器或创建一个新的音序器,只有我想要保留原音序列?

谢谢!

1 个答案:

答案 0 :(得分:1)

Apple的MusicSequenceAKSequencer所基于的)的一个令人沮丧的限制是,尽管您可以轻松设置循环部分的“右侧”,但左侧将始终循环回零并且无法改变。因此,要从左侧裁剪,您需要隔离要循环的部分并将其移位,以便循环的开始为零。

从AudioKit 4.2.4开始,这是可能的。使用AKMusicTrack的.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拍序列。