You could use something like this:
Control Surface: MIDI Tutorial (see the MIDI routing section at the bottom)
#include <Control_Surface.h>
HardwareSerialMIDI_Interface midi = Serial;
// For testing, use:
// USBDebugMIDI_Interface midi;
// A unidirectional pipe that connects a MIDI source to a MIDI sink.
// Messages coming from the source are handled by the `mapForwardMIDI()`
// function, where they can be altered or filtered out, and then sent
// to the MIDI sink.
struct MyMIDIFilter : MIDI_Pipe {
// Pass on only Note On/Off messages, changing the channel to 5 and
// transposing all notes an octave down.
void mapForwardMIDI(ChannelMessage msg) override {
switch (msg.getMessageType()) {
case MIDIMessageType::NOTE_OFF: // fallthrough
case MIDIMessageType::NOTE_ON:
msg.setChannel(CHANNEL_5);
if (msg.data1 >= 12)
msg.data1 -= 12;
sourceMIDItoSink(msg);
break;
default: break;
}
}
// Do not pass on System Exclusive messages.
void mapForwardMIDI(SysExMessage) override {}
// Do not pass on System Common messages.
void mapForwardMIDI(SysCommonMessage) override {}
// Pass on Real-Time messages without changes.
void mapForwardMIDI(RealTimeMessage msg) override {
sourceMIDItoSink(msg);
}
};
MyMIDIFilter filter;
void setup() {
// (MIDI input) -> (MIDI filter) -> (MIDI output)
// (source) -> (pipe) -> (sink)
midi >> filter >> midi;
midi.begin();
}
void loop() {
midi.update();
}
See also: Control Surface: ChannelMessage Struct Reference
If you use the USBDebugMIDI_Interface, open the Serial monitor (at 115200 baud) and type 98 3C 7F (Note On, channel 9, C4, full velocity). When you press Enter, you'll get back:
Note On Channel: 5 Data 1: 0x30 Data 2: 0x7F
If you try to send a Pitch Bend message, for example, E0 12 34, you'll get nothing back, because the code filters them out.