Max*_*Max 2 ios swift audiokit aksequencer
这个话题已经被覆盖了无数次,我已经在我以前的应用程序中成功地使用了AKMIDICallbackInstrument旧的AKAppleSequencer。
我开始使用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
}
}
Run Code Online (Sandbox Code Playgroud)
这段代码正确地创建了一系列n节拍数,它通过我的AKSampler一切都很好地播放。除了没有回调事件发生(使用打印语句确认)
思考过程
随着AKAppleSequencer与AKMIDICallbackInstrument,你可以设置globalMIDIOutput与AKAppleSequencer使用的MIDI输入AKMIDICallBackInstrument。
现在新的AKSequencer和AKCallbackInstrument没有这些选项,新的也没有AKSequencerTrack(旧的AKAppleSequencer将使用AKMusicTrack可以设置 MIDI 输入/输出的对象)。在查看 new 的实现时AKSequencer,它由AKNode对象驱动,AKCallbackInstrument 是一个AKNode对象,应该能够由具有正确 MIDI 数据的轨道驱动。
我向我的音序器添加了一个音轨,并从该音轨中添加了必要的 MIDI 数据,这些数据完全复制了我想要回调的 MIDI 事件并执行我的 GUI 事件。但是,使用这种方法,它似乎不会调用回调。
有没有人知道如何通过回调使用这些新组件?我真的不想回去,AKAppleSequencer除非显然没有办法用新的AKSequencer.
要AKCallbackInstrument使用新的AKSequencer,请尝试将您的回调工具连接到您的输出,例如,
metroCallback >>> mixer
Run Code Online (Sandbox Code Playgroud)
不明显,但对我有用。
编辑:包括新的最小工作版本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()
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
489 次 |
| 最近记录: |