Skip to content
Francois Best edited this page Nov 3, 2016 · 1 revision

What is a callback ?

A callback is a function that you wrote and that will be used by the library when a message arrives. You put your message handling code in this function, and tell the library to call it back when the corresponding message is received.

For example, you can have a function named doSomeStuffWithNoteOn, that will look like this:

void doSomeStuffWithNoteOn(byte channel, byte pitch, byte velocity)
{
    // Do some stuff with NoteOn here
}

The arguments of this function are the data from the received message. When the function is called back from within the library, the arguments will contain the info of the message just received, so you can access them more easily than calling MIDI.getData1, etc.. in your main loop.

How to use them ?

First, you need to set up the correct function arguments. These vary from one type to another (because all types have different data). These function must also return nothing (void).

Here is what your function signatures should look like for each type:

void handleNoteOff(byte channel, byte note, byte velocity);
void handleNoteOn(byte channel, byte note, byte velocity);
void handleAfterTouchPoly(byte channel, byte note, byte pressure);
void handleControlChange(byte channel, byte number, byte value);
void handleProgramChange(byte channel, byte number);
void handleAfterTouchChannel(byte channel, byte pressure);
void handlePitchBend(byte channel, int bend);
void handleSystemExclusive(byte* array, unsigned size);
void handleTimeCodeQuarterFrame(byte data);
void handleSongPosition(unsigned int beats);
void handleSongSelect(byte songnumber);
void handleTuneRequest(void);
void handleClock(void);
void handleStart(void);
void handleContinue(void);
void handleStop(void);
void handleActiveSensing(void);
void handleSystemReset(void);

Once you have your function correctly set, you need to tell the library to use it when the corresponding message is received. Let's take back the example of a NoteOn, handled by the doSomeStuffWithNoteOn function we saw earlier:

void doSomeStuffWithNoteOn(byte channel, byte pitch, byte velocity)
{
    // Do some stuff with NoteOn here
}

void setup()
{
    MIDI.begin();
    MIDI.setHandleNoteOn(doSomeStuffWithNoteOn);
}

void loop()
{
    MIDI.read();
}

And that's it! Just put the name of the function, and the library will automatically call it when a NoteOn is received.

If for some reason, you want to disconnect the callback later on in your sketch, you can do it like this:

MIDI.disconnectCallbackFromType(midi::NoteOn);

My sketch is very slow, what's going on ?

First, you need to call MIDI.read() frequently, to have the lowest latency possible. Raw MIDI data is stored in the Serial buffer, but the library can only extract it when you call MIDI.read().

Make sure that your callbacks are not blocking: they should be short and not induce delay (ie: they return as soon as possible), as they are launched from within MIDI.read (thus in the loop).