我想知道最好的方法是让AKSequencer(实际上是AKMusicTrack)将MIDI输出到外部设备。
我已经开始使用它了,但是我觉得可能有一种更有效的方法。
我做的方式:
我已经制作了AKPolyphonicNode(“ MyPolyphonicNode”)的子类
我已经使用它来初始化AKMIDINode的子类(“ MyMIDINode”),
class MyMIDINode:AKMIDINODE {
init(...) {
...
let myPolyphonicNode = MyPolyphonicNode()
super.init(node: myPolyphonicNode, midiOutputName: "myMIDIOutput")
...
}
//etc
}
并将AKMusicTrack的输出的setMIDIoutput输出到AKMIDINode子类的midiIn:
track.setMIDIOutput(myMIDINode.midiIn)
然后在MyPolyphonicNode子类中,我已覆盖:
override func play(noteNumber: MIDINoteNumber, velocity: MIDIVelocity, frequency: Double) {
myDelegate.myDelegateFunction(noteNumber:MIDINoteNumber, velocity:MIDIVelocity, channel:myChannel)
}
并在其委托人中:
let midi:AKMIDI //set in the init
enableMIDI(midi.client, name: "midiClient") //also in the init
func myDelegateFunction(noteNumber:MIDINoteNumber, velocity:MIDIVelocity, channel:MIDIChannelNumber) {
midi.sendEvent(AKMIDIEvent(noteOn: noteNumber, velocity: velocity, channel: channel))
}
这行得通,但是我想可能有一种方法可以告诉AKMusicTracks直接从外部输出而不进行所有这些操作?
答案 0 :(得分:1)
一个简单的解决方案是使用AKMIDICallbackInstrument
,尽管它是相同的基本思想。设置很简单:
callbackInst = AKMIDICallbackInstrument()
track.setMIDIOutput(callbackInst.midiIn)
您需要提供一个回调函数,该函数将触发外部MIDI:
callbackInst.callback = { statusByte, note, velocity in
// NB: in the next AudioKit release, there will be an easier init for AKMIDIStatus:
// let status = AKMIDIStatus(statusByte: statusByte)
let status = AKMIDIStatus(rawValue: Int(statusByte >> 4))
switch status {
case .noteOn:
midi.sendNoteOnMessage(noteNumber: note, velocity: velocity)
case .noteOff:
midi.sendNoteOffMessage(noteNumber: note, velocity: velocity)
default:
// etc.
}
只要播放AKMusicTrack
上的事件,就会调用此函数