用AudioKit v5中的定序器控制振荡器



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

我在启动时收到这个错误:

AVAIinternal.h:76所需条件为false:[AAudioEngine.mm:413:AttachNode:(node!=nil(]

以前有一篇关于这一点的文章,使用了一个旧的AK版本,这有点帮助,但其中的示例链接都不起作用:如何控制振荡器';s频率与序列发生器

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

编辑:略有进展?我误解了AudioEngine函数,有两个实例,所以我删除了一个,这消除了错误。添加track!.setMIDIOutput(instrument.midiIn)可以记录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()
}

}

有点工作。我发现了这个例子,它将我引向MIDICallbackInstrument:https://github.com/AudioKit/Cookbook/blob/main/Cookbook/Cookbook/Recipes/CallbackInstrument.swift

剩下的问题是,您显然不能以这种方式实现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()
}
}

}

最新更新