How to connect AKSequencer to a AKCallbackInstrument?
Asked Answered
C

2

7

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

Czech answered 13/1, 2019 at 16:51 Comment(2)
I get the same error when I plug in your code. Interestingly, when I plug in similar AKCallbackInstrument code from here: audiokitpro.com/get-the-most-out-of-your-aksequencer (after "AKCallbackInstrument Provides A Better Way") I get a similar "has no member 'midiIn'" error. Maybe an issue with the environment we're each building in? I'm on High Sierra 10.13.6, XCode 10.1, AudioKit 4.5.5 here.Chipmunk
Hi, after some days I have found two libraries that seem to do that (take a midi file and read it by sending events at each notes, events being maybe useful for trigerring visual effects in the ui while the music plays) AVFoundation (swift) and mikmidi (obj-C). More precisely for the swift one the class avaudiosequencer seems to do just that : developer.apple.com/documentation/avfoundation/avaudiosequencerCzech
K
3

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.

Kyanite answered 23/1, 2019 at 5:39 Comment(1)
Thanks, it works now ! I will add a comment to my question to pretty-print my new code.Czech
C
5

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)
    }
}
Czech answered 25/1, 2019 at 13:54 Comment(0)
K
3

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.

Kyanite answered 23/1, 2019 at 5:39 Comment(1)
Thanks, it works now ! I will add a comment to my question to pretty-print my new code.Czech

© 2022 - 2024 — McMap. All rights reserved.