Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to connect AKSequencer to a AKCallbackInstrument?

Tags:

swift

audiokit

I want to read a midi file and display things when note events are triggered. I found this stackoverflow question, where the second answer suggests to use AudioKit : How Do I Get Reliable Timing for my Audio App? More precisely, the suggestion is to use AKSequencer to absorb the midi file in the app, and then to link it to a AKCallbackInstrument to trigger the events and call a function for each midi note event.

I installed AudioKit 4.5.5 using this tutorial https://www.youtube.com/watch?v=iUvWxWvRvo8 Then I managed to run the code of the tutorial, so I know AudioKit is properly included in the project.

Then I wrote my own code :

let sequencer = AKSequencer(filename: "myMidiFile.mid")
let callbackInstr = AKCallbackInstrument()

callbackInstr.callback = myCallBack
sequencer.setGlobalMIDIOutput(callbackInstr.midiIn)

func myCallBack(a:UInt8, b:MIDINoteNumber, c:MIDIVelocity){
    print(b)
}

func test() {
    do {
        try AudioKit.start()
    }
    catch {
        print("Oops! AudioKit didn't start!")
    }

    sequencer.play()
}

When I try to build my project, there is an error on the line sequencer.setGlobalMIDIOutput(callbackInstr.midiIn)

The error is Value of type 'AKCallbackInstrument' has no member 'midiIn'

I tried to clean the project and re-build but the error is still here.

Can you explain me why do I get this error ? What should I do to solve it ? Because on the AudioKit doc, I found that AKCallbackInstrument is a subclass of AKMIDIInstrument, which does have a property called 'midiIn'. https://audiokit.io/docs/Classes/AKCallbackInstrument.html https://audiokit.io/docs/Classes/AKMIDIInstrument.html

like image 408
Nicolas Klarsfeld Avatar asked Jan 13 '19 16:01

Nicolas Klarsfeld


2 Answers

typewriter found the solution to my problem. Here is the code which works now, printing the midi number of the note each time it is played (but I didn't add sound yet) :

// dont write the .mid extension in filename :
let sequencer = AKSequencer(filename:"coucou") 
let callbackInstr = AKMIDICallbackInstrument()
callbackInstr.callback = myCallBack
sequencer.setGlobalMIDIOutput(callbackInstr.midiIn)
sequencer.play()

func myCallBack(a:UInt8, b:MIDINoteNumber, c:MIDIVelocity) -> () {
    if (a == 144) {  // if noteOn
        print(b)
    }
}
like image 98
Nicolas Klarsfeld Avatar answered Oct 19 '22 03:10

Nicolas Klarsfeld


True, the class AKCallbackInstrument does not have a property midiIn, although the documentation does show it being used that way. Instead of using AKCallbackInstrument, use AKMIDICallbackInstrument. That class has midiIn, and seems to work fine.

like image 21
Typewriter Avatar answered Oct 19 '22 03:10

Typewriter