如何让 AKSequencer 在到达序列末尾时自动停止?
How to make AKSequencer to stop automatically if it reached the end of the sequence?
我注意到 AKSequencer 会继续播放(AKSequencer.isPlaying 是正确的),即使序列中没有更多音符可播放。是否可以让它在序列结束时自动停止?
您可以使用 AKMIDICallbackInstrument
根据音序器正在播放的内容触发代码。在这种情况下,添加一个额外的轨道并将其输出设置为 AKMIDICalllbackInstrument
。在您希望音序器停止的位置向此轨道添加一个事件(如果您不知道它有多长,可以使用 sequencer.length
)。然后设置callback instrument的回调函数,在接收到事件时停止sequencer。
var seq = AKSequencer()
var callbackInst: AKMIDICallbackInstrument!
var controlTrack: AKMusicTrack!
func setUpCallback() {
// set up a control track
controlTrack = seq.newTrack()
// add an event at the end
// we don't care about anything here other than the position
controlTrack.add(noteNumber: 60,
velocity: 60,
position: seq.length,
duration: AKDuration(beats: 1))
// set up the MIDI callback instrument
callbackInst = AKMIDICallbackInstrument()
controlTrack?.setMIDIOutput(callbackInst.midiIn)
// stop the sequencer when the control track's event's noteOn is recieved
callbackInst.callback = { statusByte, _, _ in
guard let status = AKMIDIStatus(statusByte: statusByte) else { return }
if status == .noteOn {
self.seq.stop()
}
}
}
我注意到 AKSequencer 会继续播放(AKSequencer.isPlaying 是正确的),即使序列中没有更多音符可播放。是否可以让它在序列结束时自动停止?
您可以使用 AKMIDICallbackInstrument
根据音序器正在播放的内容触发代码。在这种情况下,添加一个额外的轨道并将其输出设置为 AKMIDICalllbackInstrument
。在您希望音序器停止的位置向此轨道添加一个事件(如果您不知道它有多长,可以使用 sequencer.length
)。然后设置callback instrument的回调函数,在接收到事件时停止sequencer。
var seq = AKSequencer()
var callbackInst: AKMIDICallbackInstrument!
var controlTrack: AKMusicTrack!
func setUpCallback() {
// set up a control track
controlTrack = seq.newTrack()
// add an event at the end
// we don't care about anything here other than the position
controlTrack.add(noteNumber: 60,
velocity: 60,
position: seq.length,
duration: AKDuration(beats: 1))
// set up the MIDI callback instrument
callbackInst = AKMIDICallbackInstrument()
controlTrack?.setMIDIOutput(callbackInst.midiIn)
// stop the sequencer when the control track's event's noteOn is recieved
callbackInst.callback = { statusByte, _, _ in
guard let status = AKMIDIStatus(statusByte: statusByte) else { return }
if status == .noteOn {
self.seq.stop()
}
}
}