cs-midi-docs/docs/manual/02-midi/03-receiving-messages.md

2.3 KiB

Receiving MIDI Messages

Original: Receiving MIDI messages

With MIDI_Callbacks

Register a callback object on the interface to handle incoming messages:

#include "pico/stdlib.h"
#include "pico/cyw43_arch.h"
#include <cs_midi.h>

using namespace cs;

BluetoothMIDI_Interface midi;

struct MyCallbacks : MIDI_Callbacks {
    void onChannelMessage(MIDI_Interface &, ChannelMessage msg) override {
        auto type = msg.getMessageType();
        Channel ch = msg.getChannel();
        uint8_t d1 = msg.getData1();
        uint8_t d2 = msg.getData2();
        (void)type; (void)ch; (void)d1; (void)d2;
    }
} cb;

int main() {
    stdio_init_all();
    if (cyw43_arch_init()) return 1;
    midi.begin();
    midi.setCallbacks(cb);
    while (true) {
        midi.update();
        sleep_ms(1);
    }
}

midi.update() reads incoming data and dispatches to callbacks.

With FineGrainedMIDI_Callbacks

For per-message-type handlers, use the CRTP pattern:

struct Handlers : FineGrainedMIDI_Callbacks<Handlers> {
    void onNoteOn(Channel ch, uint8_t note, uint8_t velocity, Cable cable) {
        (void)ch; (void)note; (void)velocity; (void)cable;
    }
    void onControlChange(Channel ch, uint8_t cc, uint8_t value, Cable cable) {
        (void)ch; (void)cc; (void)value; (void)cable;
    }
};

Handlers handlers;
// midi.setCallbacks(handlers);

Available overrides: onNoteOn, onNoteOff, onKeyPressure, onControlChange, onProgramChange, onChannelPressure, onPitchBend, onSystemExclusive, onTimeCodeQuarterFrame, onSongPosition, onSongSelect, onTuneRequest, onClock, onStart, onContinue, onStop, onActiveSensing, onSystemReset.

ChannelMessage accessors

Method Returns
getMessageType() MIDIMessageType enum
getChannel() Channel
getData1() First data byte (note/CC number)
getData2() Second data byte (velocity/value)
getData14bit() 14-bit value (Pitch Bend)
getCable() Cable

With the element system

MIDI input elements (CCValue, NoteLED, etc.) handle message matching and state management automatically — no callbacks needed. They update on each Control_Surface.loop() call.