更改 AKSequencer 的长度:奇怪的行为
Change length of AKSequencer: weird behavior
我有一个启用循环的 aksequencer,我想在播放期间更改长度。我已经用 setLength() 和 setLoopInfo() 试过了,但似乎都不能正常工作。
预期行为:如果我有一个 16 拍序列,并且调用 changeSequenceToLength(12),我希望循环从 1-12 拍开始播放,然后重复。 (当然,我应该处理在第 12 拍后更改长度的情况,但你明白了)。
实际行为:鱼龙混杂。当我使用 setLength(endbeat) 时,它只是删除了 endbeat 之后的 midi 事件,但循环仍然是 16 拍。当我调用 setLoopInfo(duration, numloops) 时,它缩短了循环,但从错误的一侧开始。所以它不是玩 1-12,而是玩 4-16。当我第一次更改循环持续时间时,它也会出现一些奇怪的卡顿现象。
如有任何关于如何解决此问题的建议,我们将不胜感激!我也查看了支持苹果 MusicSequence 的文档,但它非常稀疏。
我的代码大致如下所示:
import AudioKit
import AudioKitUI
final class Sequencer: AKSequencer {
static let shared = Sequencer() //Singleton
var numBeats = 16 // Number of spaces in the grid
var beatLength = 1/4.0
var sequenceDuration: AKDuration {
get {
return AKDuration(beats: (numBeats * beatLength))
}
}
private override init() {
super.init()
setTempo(120.0)
for _ in 0..<8 {
let track = newTrack()
}
let callback = AKCallbackInstrument() { status, note, velocity in
//send midi messages...
}
let midiNode = AKMIDINode(node: callback)
setLength(sequenceDuration)
AudioKit.output = midiNode
AudioKit.start()
midiNode.enableMIDI(Midi.shared.client, name: "midiNode midi in")
enableLooping()
}
func changeSequenceToLength(length: Int) {
numBeats = length
setLength(sequenceDuration)
// setLoopInfo(sequenceDuration, numberOfLoops: 50)
}
}
edit:所以我找到了 AKMusicTrack.setLengthSoft(),所以当我缩短序列时我的 midi 序列不会被删除。我还阅读了 setLoopInfo 的代码,它确实应该从末尾向后创建一个循环(它不应该使用 startTime 和偏移量吗??)。但是当我改变序列长度时,我仍然遇到播放卡顿的问题。
调用 setLength()
后,您需要通过调用 enableLooping()
重新断言循环行为(或者您可以使用 setloopInfo
,这两个操作将一步完成)。但是基本上在音序器 运行 时改变循环长度将是一个问题。
了解 AKSequencer
本质上是 CoreMIDI MusicSequence
的 Swift 包装器很重要,因此它基本上继承了 MusicSequence
的大部分怪癖和限制。这些限制之一是虽然您可以设置循环范围的 'left side',但您不能设置 'right side' - 它总是循环回到 MusicTimeStamp 0。调用 setLoopinfo
(或者调用setLength()
后跟 enableLooping()
) 实际上并没有像你说的那样从错误的一侧缩短循环(尽管起初我也认为它是这样做的)。它正确设置了循环长度,但也将播放头传送到距离 'old loop length' 节拍 'new loop length' 的位置。因此,如果您将 16 拍循环更改为 12 拍循环,MusicSequence
将从 0 循环到 12,但它会将播放头移动到第 4 拍 (16 - 12 = 4)。它不会从 4 到 16 播放,而是从 4 到 12,它们从 0 到 12 循环播放。有时你可以 你可以在播放时完成这项工作,但大多数情况下这是一种痛苦。最佳解决方案是在更改循环长度时停止播放。 CoreMIDI'a MusicSequence
不太擅长动态处理变化。
我有一个启用循环的 aksequencer,我想在播放期间更改长度。我已经用 setLength() 和 setLoopInfo() 试过了,但似乎都不能正常工作。
预期行为:如果我有一个 16 拍序列,并且调用 changeSequenceToLength(12),我希望循环从 1-12 拍开始播放,然后重复。 (当然,我应该处理在第 12 拍后更改长度的情况,但你明白了)。
实际行为:鱼龙混杂。当我使用 setLength(endbeat) 时,它只是删除了 endbeat 之后的 midi 事件,但循环仍然是 16 拍。当我调用 setLoopInfo(duration, numloops) 时,它缩短了循环,但从错误的一侧开始。所以它不是玩 1-12,而是玩 4-16。当我第一次更改循环持续时间时,它也会出现一些奇怪的卡顿现象。
如有任何关于如何解决此问题的建议,我们将不胜感激!我也查看了支持苹果 MusicSequence 的文档,但它非常稀疏。
我的代码大致如下所示:
import AudioKit
import AudioKitUI
final class Sequencer: AKSequencer {
static let shared = Sequencer() //Singleton
var numBeats = 16 // Number of spaces in the grid
var beatLength = 1/4.0
var sequenceDuration: AKDuration {
get {
return AKDuration(beats: (numBeats * beatLength))
}
}
private override init() {
super.init()
setTempo(120.0)
for _ in 0..<8 {
let track = newTrack()
}
let callback = AKCallbackInstrument() { status, note, velocity in
//send midi messages...
}
let midiNode = AKMIDINode(node: callback)
setLength(sequenceDuration)
AudioKit.output = midiNode
AudioKit.start()
midiNode.enableMIDI(Midi.shared.client, name: "midiNode midi in")
enableLooping()
}
func changeSequenceToLength(length: Int) {
numBeats = length
setLength(sequenceDuration)
// setLoopInfo(sequenceDuration, numberOfLoops: 50)
}
}
edit:所以我找到了 AKMusicTrack.setLengthSoft(),所以当我缩短序列时我的 midi 序列不会被删除。我还阅读了 setLoopInfo 的代码,它确实应该从末尾向后创建一个循环(它不应该使用 startTime 和偏移量吗??)。但是当我改变序列长度时,我仍然遇到播放卡顿的问题。
调用 setLength()
后,您需要通过调用 enableLooping()
重新断言循环行为(或者您可以使用 setloopInfo
,这两个操作将一步完成)。但是基本上在音序器 运行 时改变循环长度将是一个问题。
了解 AKSequencer
本质上是 CoreMIDI MusicSequence
的 Swift 包装器很重要,因此它基本上继承了 MusicSequence
的大部分怪癖和限制。这些限制之一是虽然您可以设置循环范围的 'left side',但您不能设置 'right side' - 它总是循环回到 MusicTimeStamp 0。调用 setLoopinfo
(或者调用setLength()
后跟 enableLooping()
) 实际上并没有像你说的那样从错误的一侧缩短循环(尽管起初我也认为它是这样做的)。它正确设置了循环长度,但也将播放头传送到距离 'old loop length' 节拍 'new loop length' 的位置。因此,如果您将 16 拍循环更改为 12 拍循环,MusicSequence
将从 0 循环到 12,但它会将播放头移动到第 4 拍 (16 - 12 = 4)。它不会从 4 到 16 播放,而是从 4 到 12,它们从 0 到 12 循环播放。有时你可以 MusicSequence
不太擅长动态处理变化。