Reputation: 361
I can connect to the Sequencer
a physical instrument like Shaker
or a callBackInstrument
fine, but not a MIDIInstrument
like SynthKick
var sequencer = Sequencer()
var synthKick = SynthKick()
synthKick.enableMIDI()
var track = sequencer.addTrack(for: synthKick)
track.sequence.add(noteNumber: MIDINoteNumber(60), position: 0, duration: 1)
mixer.addInput(synthKick)
on SynthKick
:
public override func start(noteNumber: MIDINoteNumber,
velocity: MIDIVelocity,
channel: MIDIChannel,
timeStamp: MIDITimeStamp? = nil) {
play(noteNumber: noteNumber)
}
The code above not outputs signal
What I'm doing wrong ?
Upvotes: 0
Views: 225
Reputation: 281
I know its a long time since you posed this question but I was looking at this stuff myself so I decided to answer.
I used the CallbackInstrumentConductor in the following link:
to figure out how to extend MIDIInstrument, I used a synth from DunneAudioKit as the output ,
DunneAudioKit :
https://github.com/AudioKit/DunneAudioKit
The following code worked for me, see if this helps
1: imports
import CoreMIDI
import AudioKit
import DunneAudioKit
import SwiftUI
2: extended MIDIInstrument
class Extended_MidiInstrument : MIDIInstrument{
let synth = Synth()
init(){
super.init()
self.avAudioNode = synth.avAudioNode
}
override func start(noteNumber: MIDINoteNumber, velocity: MIDIVelocity, channel: MIDIChannel, timeStamp: MIDITimeStamp? = nil) {
self.synth.play(noteNumber: noteNumber, velocity: velocity)
}
override func stop(noteNumber: MIDINoteNumber, channel: MIDIChannel, timeStamp: MIDITimeStamp? = nil) {
self.synth.stop(noteNumber: noteNumber)
}
}
3: the Conductor - heavily influenced by the callback conductor.
class Extended_MidiInstrumentConductor: ObservableObject {
let xmidiInst = Extended_MidiInstrument()
let engine = AudioEngine()
var sequencer = AppleSequencer()
var tempo = 120.0
var division = 1
init() {
let seq_Track = sequencer.newTrack()
for i in 0 ..< division {
seq_Track?.add(noteNumber: 40,
velocity: 100,
position: Duration(beats: Double(i) / Double(division)),
duration: Duration(beats: Double(0.1 / Double(division))))
seq_Track?.add(noteNumber: 60,
velocity: 100,
position: Duration(beats: (Double(i) + 0.5) / Double(division)),
duration: Duration(beats: Double(0.1 / Double(division))))
}
seq_Track?.setMIDIOutput(xmidiInst.midiIn)
seq_Track?.setLoopInfo(Duration(beats: 1.0), loopCount: 0)
sequencer.setTempo(tempo)
engine.output = xmidiInst
}
func start_Engine() {
do {
try engine.start()
} catch let err {
Log(err)
}
}
func stop_Engine() {
engine.stop()
}
}
4: (finally) the view for the conductor in (3)
struct Extended_MidiInstrumentView: View {
@StateObject var conductor : Extended_MidiInstrumentConductor
var body: some View {
VStack(spacing: 30) {
Text("Play").onTapGesture {
self.conductor.sequencer.play()
print("play called")
}.foregroundColor(.white)
Text("Pause").onTapGesture {
self.conductor.sequencer.stop()
print("pause called")
}.foregroundColor(.white)
Text("Rewind").onTapGesture {
self.conductor.sequencer.rewind()
print("rewind called")
}.foregroundColor(.white)
}
.onAppear {
self.conductor.start_Engine()
}
.onDisappear {
self.conductor.stop_Engine()
}
}
}
Obviously you don't actually need the print commands, but anyway if that's any help ....
Upvotes: 1