在AudioKit v5中使用音序器控制振荡器

在AudioKit v5中使用音序器控制振荡器,audiokit,Audiokit,我试图用AudioKit v5的音序器控制振荡器,但遇到了一个障碍。我正在对MIDI乐器进行子类化,但我不确定这是否正确。请参阅下面的代码 我在启动时遇到以下错误: AVAEInternal.h:76所需条件为假: [AVAudioEngine.mm:413:AttachNode:(节点!=nil)] 之前有一篇关于AK旧版本的帖子,这有点帮助,但是没有一个链接指向它中的示例: 你能给我指一下正确的方向吗?非常感谢 编辑:轻微的进展?我误解了AudioEngine函数,有两个实例,因此我删除了

我试图用AudioKit v5的音序器控制振荡器,但遇到了一个障碍。我正在对MIDI乐器进行子类化,但我不确定这是否正确。请参阅下面的代码

我在启动时遇到以下错误:

AVAEInternal.h:76所需条件为假: [AVAudioEngine.mm:413:AttachNode:(节点!=nil)]

之前有一篇关于AK旧版本的帖子,这有点帮助,但是没有一个链接指向它中的示例:

你能给我指一下正确的方向吗?非常感谢

编辑:轻微的进展?我误解了
AudioEngine
函数,有两个实例,因此我删除了一个,从而清除了错误。并添加
track!。setMIDIOutput(instrument.midin)
现在记录了4个音符,但仍然没有声音
MIDIInstrument
似乎接受一个
MIDIClientRef
,但我在sequencer类中看不到对它的引用

import AudioKit
import CAudioKit

class Test2 {

    var instrument: OscMIDIInstrument
    var sequencer: AppleSequencer
    
    init() {

        instrument = OscMIDIInstrument()
        sequencer = AppleSequencer()
        sequencer.setGlobalMIDIOutput(instrument.midiIn)
        instrument.enableMIDI()
                
        let track = sequencer.newTrack()
        track!.setMIDIOutput(instrument.midiIn)
        for i in 0 ..< 4 {
            track!.add(noteNumber: 60, velocity: 64, position: Duration(seconds: Double(i)), duration: Duration(seconds: 0.5))
        }

    }
    
    func testButton() {
        if sequencer.isPlaying {
            sequencer.stop()
        } else {
            sequencer.rewind()
            sequencer.play()
        }
    }
    
}

class OscMIDIInstrument: MIDIInstrument {
    
    var akEngine: AudioEngine
    var osc: Oscillator
    
    init() {
        akEngine = AudioEngine()
        osc = Oscillator()
        super.init()
        akEngine.output = osc
        osc.amplitude = 0.1
        osc.frequency = 440.0
        do {
            try akEngine.start()
        } catch {
            print("Couldn't start AudioEngine.")
        }
    }
    
    override func receivedMIDINoteOn(noteNumber: MIDINoteNumber, velocity: MIDIVelocity, channel: MIDIChannel, portID: MIDIUniqueID? = nil, offset: MIDITimeStamp = 0) {
        osc.play()
    }
    
    override func receivedMIDINoteOff(noteNumber: MIDINoteNumber, velocity: MIDIVelocity, channel: MIDIChannel, portID: MIDIUniqueID? = nil, offset: MIDITimeStamp = 0) {
        osc.stop()
    }
    
}
导入音频套件
进口尾箱
类Test2{
var仪器:OSC仪器
var序列器:AppleSequencer
init(){
仪器=OSCMIDI仪器()
sequencer=AppleSequencer()
sequencer.SetGlobalMidiOut(仪器MIDIN)
文书.使能IDI()
let track=sequencer.newTrack()
track!.setMIDI输出(instrument.midin)
对于0..<4中的i{
轨迹!添加(注意编号:60,速度:64,位置:持续时间(秒:双(i)),持续时间:持续时间(秒:0.5))
}
}
func testButton(){
如果sequencer.isPlaying{
sequencer.stop()
}否则{
sequencer.rewind()
音序器播放()
}
}
}
乐器类别:MIDI乐器{
var akEngine:音频引擎
无功振荡器
init(){
akEngine=AudioEngine()
osc=振荡器()
super.init()
akEngine.output=osc
osc.振幅=0.1
osc.frequency=440.0
做{
试试akEngine.start()
}抓住{
打印(“无法启动音频引擎”)
}
}
重写func receivedMIDINoteOn(noteNumber:MIDINoteNumber,velocity:MIDIVelocity,channel:MIDIChannel,portID:MIDIUniqueID?=nil,offset:MIDITimeStamp=0){
osc.play()
}
重写func receivedMIDINoteOff(noteNumber:MIDINoteNumber,velocity:MIDIVelocity,channel:MIDIChannel,portID:MIDIUniqueID?=nil,offset:MIDITimeStamp=0){
osc.stop()
}
}

多少让它工作起来了。我找到了这个示例,它指向
midiallbackinstrument

剩下的问题是,您显然无法以这种方式实现sysex消息,我想这是因为回调消息被限制为3个字节

因此,如果有人能提供帮助,我仍在寻找更好的解决方案

非常感谢

class Test {

    let akEngine = AudioEngine()
    let sequencer = AppleSequencer()
    let osc = Oscillator()
        
    init() {

        let callbackInstrument = MIDICallbackInstrument { [self] status, note, _ in
            guard let midiStatus = MIDIStatusType.from(byte: status) else {
                return
            }
                if midiStatus == .noteOn {
                    print("NoteOn \(note) at \(sequencer.currentPosition.seconds)")
                    osc.play()
                } else if midiStatus == .noteOff {
                    print("NoteOff \(note) at \(sequencer.currentPosition.seconds)")
                    osc.stop()
                }
            }

        let track = sequencer.newTrack()
        for i in 0..< 4 {
            track!.add(noteNumber: 60, velocity: 64, position: Duration(seconds: Double(i)), duration: Duration(seconds: 0.25))
        }
        track?.setMIDIOutput(callbackInstrument.midiIn)

        akEngine.output = osc
        
        do {
            try akEngine.start()
        } catch {
            print("Couldn't start AudioEngine.")
        }

    }
    
    func play() {
        if sequencer.isPlaying {
            sequencer.stop()
        } else {
            sequencer.rewind()
            sequencer.play()
        }
    }
    
}
类测试{
设akEngine=AudioEngine()
让sequencer=AppleSequencer()
设osc=振荡器()
init(){
让callbackInstrument=midiallbackinstrument{[self]状态,注意,uu in
guard let midiStatus=MIDIStatusType.from(字节:status)else{
返回
}
如果midiStatus==.noteOn{
打印(“在\(sequencer.currentPosition.seconds)处的注释\(注释)”)
osc.play()
}如果midiStatus=.noteOff,则为else{
打印(“在\(sequencer.currentPosition.seconds)处记录\(注)\)
osc.stop()
}
}
let track=sequencer.newTrack()
对于0..<4中的i{
轨迹!添加(注意编号:60,速度:64,位置:持续时间(秒:双(i)),持续时间:持续时间(秒:0.25))
}
track?.setMIDI输出(callbackInstrument.midin)
akEngine.output=osc
做{
试试akEngine.start()
}抓住{
打印(“无法启动音频引擎”)
}
}
func play(){
如果sequencer.isPlaying{
sequencer.stop()
}否则{
sequencer.rewind()
音序器播放()
}
}
}