Raspberry Pi Pico MIDI Channel Muter

This project uses a Pimoroni RGB Keypad with a Raspberry Pi Pico to create 16 “mute” switches for MIDI, one for each MIDI channel.

Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

These are the key tutorials for the main concepts used in this project:

If you are new to microcontrollers, see the Getting Started pages.

Parts list

The Circuit

IMG_6626

I’m using the keypad and “expander” back-to-back, similar to how I’ve used them in the past.

If you are using an independent MIDI interface then it will need connecting to 3V3_OUT and GND for power and GP0 (RX) for MIDI IN and GP1 (TX) for MIDI OUT.

Naturally your source of MIDI data should be connected to MIDI IN and the sounding device to MIDI OUT.IMG_6625

The Code

There are two main threads of operation within the code:

  • MIDI receiving, decoding, and re-transmitting.
  • Keypad checking and LED updating.

The MIDI side uses my SimpleMIDIDecoder and passes any received MIDI messages into the decoder for handling by some callback functions.  Each callback calls a new midiChannelRouter function that determines if the message is for passing on or not.

def midiChannelMuter (ch, cmd, d1, d2):
  if (not MIDICH[ch-1]):
    return

  if (d2 == -1):
    uart.write(ustruct.pack("bb",cmd+ch-1,d1))
  else:
    uart.write(ustruct.pack("bbb",cmd+ch-1,d1,d2))

The MIDICH array has one element per MIDI channel which will be True if the channel is to be passed through or False if it is to be muted.  This is using direct byte-writes to the hardware UART and knows if the message will be two or three bytes long (the decoder returns “-1” for the second byte if not used).

One thing to be careful of.  If a MIDI channel is muted between a NoteOn and NoteOff message (which is probably quite likely!) then the notes will hang.  To cope with this I send an “All Notes Off” message on that channel when the corresponding mute button is pressed.

Also it should be noted that whilst the decoder is quite happy receiving MIDI Running Status, it passes messages on as single messages.  This means it will eventually have a performance hit if there is a lot of MIDI traffic.

The keypad handling basically comes from the Pimoroni demo code and does the following:

while True:
  Check the keypad states
  IF a button is pressed THEN
    Toggle the MIDICH state for that button
    IF channel now muted THEN
      Send AllNotesOff on that MIDI channel*

  FOREACH channel
    IF MIDICH is True THEN
      Turn on the corresponding key RGB
    ELSE
      Turn off the corresponding key RGB

Find it on GitHub here.

Closing Thoughts

My short demo video (above) starts with just channel 1 sounding, then I gradually turn on more channels.  It then finishes by showing what happens if you don’t send the AllNotesOff. My receiving Arduinos don’t listen for that message, so the notes just hang there.

As already mentioned there may be a performance hit from expanding out any Running Status messages as part of the routing process, but apart from that, it seems to work quite well!

Kevin

2 thoughts on “Raspberry Pi Pico MIDI Channel Muter

Leave a comment