Easy Midi Translator

Easy Midi Translator

January 25, 2020 DIY / Maker 0

#midi translator box, for @dj_dad_shirt easy octave up action, or other transposing/channel filtering kinda stuff that may arise, programmable via usb. Swipe through the post below to see video of it in action, and pictures of the guts.

Above is a picture of the way it was mounted, which wasn’t in the post.

Script works with Arduino Uno using the normal midi shield, but in my case I used a Spark Fun Pro Micro, and pins 0/1.

// midi translator by woz.lol for Terbo Ted

#include <MIDI.h>
#define buttonpin 20
#define led1 19
#define led2 18
MIDI_CREATE_DEFAULT_INSTANCE() ;

int transpose = 12;  // this sets the default to be transpose up one octave (12 semitones)
int lastnote;
int chan;
bool mode;  // one octave up or two octaves up mode setting

void setup() {
  MIDI.setHandleNoteOn(handleNoteOn);
  MIDI.setHandleNoteOff(handleNoteOff);
  MIDI.begin(MIDI_CHANNEL_OMNI) ;
  MIDI.turnThruOff();
  pinMode(buttonpin, INPUT_PULLUP);   //  when this pin is grounded it's activated
  pinMode(led1, OUTPUT);     // led pins
  pinMode(led2, OUTPUT);    // led is bi-color, red one polarity, green the other
  digitalWrite(led2, HIGH);
  digitalWrite(led1, LOW);
}

void loop() {
  doMidi();
  if (!digitalRead(buttonpin)) {  // triggered when false, false when button pushed
    MIDI.sendNoteOff(lastnote, 0, chan);
    delay(6);
    if (mode) {
      mode = false;
      digitalWrite(led2, HIGH);
      digitalWrite(led1, LOW);
    } else {
      mode = true;
      digitalWrite(led1, HIGH);
      digitalWrite(led2, LOW);
    }
    while (!digitalRead(buttonpin)) {  //debounce
      delay(1);
    }
  }
}

void MidiSendAsIs()                 //Send MIDI to out and blink once if debug is enabled
{
  MIDI.send(MIDI.getType(),
            MIDI.getData1(),
            MIDI.getData2(),
            MIDI.getChannel());
}

void handleNoteOff(byte channel, byte pitch, byte velocity) {
  MIDI.send(MIDI.getType(),
            pitch + transpose + (mode * 12),
            MIDI.getData2(),
            MIDI.getChannel());
  if (mode) {
    digitalWrite(led2, LOW);
  } else {
    digitalWrite(led1, LOW);
  }
}

void handleNoteOn(byte channel, byte pitch, byte velocity) {
  lastnote = pitch + transpose + (mode * 12);  // if mode is true, we go up another octave
  MIDI.send(MIDI.getType(),
            lastnote,
            MIDI.getData2(),
            MIDI.getChannel());
  chan = channel;
  if (mode) {
    digitalWrite(led2, HIGH);
  } else {
    digitalWrite(led1, HIGH);
  }
}

void doMidi() {

  if (MIDI.read())                // Is there a MIDI message incoming ?
  {
    switch (MIDI.getType())
    {
      case midi::NoteOn : {}      //  notes are handled elsewhere by the interrupt
        break;
      case midi::NoteOff : {}
        break;
      default: {
          MidiSendAsIs();
        }
        break;
    }
  }
}