这个主题已经涉及到Numerous Times,我已经在我以前的应用程序中成功地使用了与旧AKAppleSequencer一起的AKMIDICallbackInstrument。
我开始使用新的AKSequencer,这是绝对惊人的:优雅的界面,易于使用。然而,在我的一生中,我无法弄清楚如何用它处理回调事件。我需要使用回调来触发基于顺序播放的GUI事件。
下面是我的示例代码:
private func setMetronome(bpm: BPM, beats:Int)
{
sequencer = AKSequencer(targetNode: metronomeSampler)
sequencer.tempo = bpm
sequencer.loopEnabled = false
sequencer.length = Double(beats)
metroCallback.callback = {status, noteNumber, velocity in
if let midiStatus = AKMIDIStatus(byte: status), midiStatus.type != .noteOn { return }
//Do callback stuff here
}
let metroCallbackTrack = sequencer.addTrack(for: metroCallback)
for i in 0..<beats
{
if i == 0
{
sequencer.add(noteNumber: MIDINoteNumber(67), position: Double(i), duration: 1.0)
metroCallbackTrack.add(noteNumber: MIDINoteNumber(67), position: Double(i), duration: 1.0)
}
else if (i % 4 == 0)
{
sequencer.add(noteNumber: MIDINoteNumber(67), position: Double(i), duration: 1.0)
metroCallbackTrack.add(noteNumber: MIDINoteNumber(60), position: Double(i), duration: 1.0)
}
else
{
sequencer.add(noteNumber: MIDINoteNumber(60), position: Double(i), duration: 1.0)
metroCallbackTrack.add(noteNumber: MIDINoteNumber(60), position: Double(i), duration: 1.0)
}
print("seq count:\(i)")
}
for track in sequencer.tracks
{
print("Adding track to mixer:\(track.length)")
track >>> mixer
}
}这段代码正确地创建了一个n数的节拍序列,它通过我的AKSampler回放--在这个世界上一切都很好。但不发生回调事件(使用print语句来确认)
思维过程
使用AKAppleSequencer和AKMIDICallbackInstrument,您可以使用midi输入AKMIDICallBackInstrument的AKAppleSequencer来设置globalMIDIOutput。
现在,新的AKSequencer和AKCallbackInstrument没有这些选项,新的AKSequencerTrack也没有(旧的AKAppleSequencer使用可以设置midi输入/输出的AKMusicTrack对象)。在查看新AKSequencer的实现时,它是由AKNode对象驱动的,AKCallbackInstrument是一个AKNode对象,应该能够由带有右midi数据的跟踪驱动。
我向我的排序器添加了一个音轨,并从这个轨道中添加了必要的midi数据,这些数据完全复制了我想要回调的midi事件并执行我的GUI事件。然而,使用这种方法,它似乎不调用回调。
有人知道如何在回调中使用这些新组件吗?我真的不想回到AKAppleSequencer,除非显然没有办法用新的AKSequencer来驱动回调。
发布于 2020-05-01 15:23:01
要使AKCallbackInstrument与新的AKSequencer一起工作,请尝试将您的回调仪器连接到您的输出,例如,
metroCallback >>> mixer不明显,但为我工作过。
编辑:包括使用AKSequencer的新AKCallbackInstrument的最小工作版本
class SequencerWrapper {
var seq: AKSequencer!
var cbInst: AKCallbackInstrument!
var mixer: AKMixer!
init() {
mixer = AKMixer()
AudioKit.output = mixer
seq = AKSequencer()
cbInst = AKCallbackInstrument()
// set up a track
let track = seq.addTrack(for: cbInst)
for i in 0 ..< 4 {
track.add(noteNumber: 60, position: Double(i), duration: 0.5)
}
track.length = 4.0
track.loopEnabled = true
track >>> mixer // must send track to mixer
// set up the callback instrument
cbInst.callback = { status, note, vel in
guard let status = AKMIDIStatus(byte: status),
let type = status.type,
type == .noteOn else { return }
print("note on: \(note)")
// trigger sampler etc from here
}
cbInst >>> mixer // must send callbackInst to mixer
}
func play() {
seq.playFromStart()
}
}发布于 2020-05-22 15:15:14
谢谢你的工作示例@c_booth!只是想为任何像我这样不明白为什么上面的例子不起作用的假人添加,您仍然需要调用AudioKit.start()。
https://stackoverflow.com/questions/61491639
复制相似问题