MIDI filter/processor sketch

Hello,

I'm a complete newbie here and planning to do my first Arduino project, so sorry in advance for my possibly stupid questions.

I just ordered an Arduino Uno rev3 and a 3-port MIDI shield (MIDI In, MIDI Out, MIDI Through) and I want to create a sketch that filters/processes MIDI data in a way that only a few predefined MIDI messages are forwarded from the MIDI IN port to the MIDI OUT port, all others should be blocked/filtered. Also, some of the MIDI messages that should be forwarded to the MIDI OUT port may need to be changed (processed), e.g. by changing the MIDI channel, MIDI CC or similar.

Is there anyone who has already implemented something like this and could provide a possibly existing sketch which fulfills these or some of these functions and could possibly be used by me as a starting point for modifications to achieve what I need?

Thanks in advance for any kind of help!


Hallo,

Ich bin ein absoluter Neuling hier und plane, mein erstes Arduino-Projekt zu realisieren, deshalb schon einmal sorry für meine möglicherweise dummen Fragen.

Ich habe gerade einen Arduino Uno rev3 und ein 3-Port-MIDI-Shield (MIDI In, MIDI Out, MIDI Through) bestellt und möchte einen Sketch erstellen, der MIDI-Daten so filtert/verarbeitet, dass nur ein paar vordefinierte MIDI-Nachrichten vom MIDI IN-Port an den MIDI OUT-Port weitergeleitet werden, alle anderen sollten blockiert/gefiltert werden. Außerdem müssen einige der MIDI-Befehle, die an den MIDI-OUT-Port weitergeleitet werden sollen, möglicherweise geändert (verarbeitet) werden, z.B. durch Änderung des MIDI-Kanals, der MIDI-CC oder ähnliches.

Gibt es jemanden, der so etwas schon realisiert hat und einen möglicherweise vorhandenen Sketch zur Verfügung stellen könnte welcher diese oder einige dieser Funktionen erfüllt und ggf. von mir als Ausgangspunkt für Modifikationen verwendet werden kann, um das zu erreichen, was ich brauche?

Vielen Dank im Voraus fĂĽr jede Art von Hilfe!

Yes I have done "something like this", but not exactly like this it is a lot more complex that that.

Basically you need the MIDI library this can search for only the messages you want to intercept and ignore the ones you don't. When a message like "NoteOn" is received you can call a NoteOn function, an example of this comes with the MIDI library. Then in this function you can do things like changing the channel or adjusting the velocity.

My system was more complex because it used a Arduino Micro, not a Uno, and was filtering between the USB connection from the Micro to the outside world. It was doing things like turning a single note into a triad, and altering the volume in response to the breath control signal on my electronic saxophone. So there is a lot of unpicking to do, you are better off starting from scratch.

1 Like

Thanks for the reply, Mike!

Yes I will look into the MIDI library functions, it might probably be the better way trying something by myself from scratch since it will be a good learning exercise for me, but for the sake of time I thought to learn from an existing sketch - let’s see if someone else has a sketch available to guide me into the right direction

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.

1 Like

Thank you!!

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.