How to turn Leonardo with MIDI shield into USB MIDI interface?

I’m trying to use a Leonardo with Spark Fun MIDI shield to connect a MT-32 to a Mac to play classic video games.
This is the shield:

This is the MT32:
http://www.vintagesynth.com/roland/mt32.php
I’ve been messing with the UsbMIDI library, but I can’t figure out how to pass just every event in two directions between USB MIDI and Serial 1. This is my code now, but it does not work.

#include "MIDIUSB.h"
midiEventPacket_t rx;
midiEventPacket_t tx;

void setup() {
  Serial.begin(115200);
  Serial1.begin(32150);
}

void loop() {
  if (MidiUSB.available()) {
    rx=MidiUSB.read();
    if (rx.header != 0) {
      Serial1.write(rx.header);
      Serial1.write(rx.byte1);
      Serial1.write(rx.byte2);
      Serial1.write(rx.byte3);
    }
  }
  if (Serial1.available()){
    tx={Serial1.read()};
    MidiUSB.sendMIDI(tx);
  }
}

I do see the Leonardo appear in the Apple MIDI tool.
What am I doing wrong?
Also a mystery: why is there no setup or begin command for USB midi? How to give the device a custom name for example? Does the library auto-setup when you include it?

Serial MIDI and USB MIDI use different data formats. You can’t simply copy the bytes from one to the other, you need a parser that understands the content of the MIDI messages to be able to convert it to the correct format before sending it from serial to USB and vice versa.

You could use this MIDI routing example: Control Surface: MIDI_Pipes-Routing.ino
You probably don’t need the loopback on USB, so you can just remove that line from the setup and decrease the number of pipes from 3 to 2.

The MIDIUSB library registers itself with the USB stack in its constructor, which runs before the setup function.

Pieter

Thanks, but that example throws a lot of errors:

In file included from /Arduino/libraries/Control-Surface-master/src/AH/STL/type_traits:6:0,
                 from /Arduino/libraries/Control-Surface-master/src/AH/Arduino-Wrapper.h:4,
                 from /Arduino/libraries/Control-Surface-master/src/Control_Surface.h:11,
                 from /Arduino/projects/LeonardoMIDIinterface/LeonardoMIDIinterface.ino:2:
/Arduino/libraries/Control-Surface-master/src/AH/STL/Fallback/type_traits:680:66: error: template argument 2 is invalid
     : public integral_constant<bool, __is_trivially_copyable(_Tp)>
                                                                  ^
/Arduino/libraries/Control-Surface-master/src/AH/STL/Fallback/type_traits:1365:46: error: template argument 2 is invalid
    __is_trivially_constructible(_Tp, _Args...)>>
                                              ^
/Arduino/libraries/Control-Surface-master/src/AH/STL/Fallback/type_traits:1365:47: error: template argument 2 is invalid
    __is_trivially_constructible(_Tp, _Args...)>>
                                               ^
/Arduino/libraries/Control-Surface-master/src/AH/STL/Fallback/type_traits:1409:48: error: template argument 2 is invalid
    __is_trivially_constructible(_Tp, const _Tp&)>>
                                                ^
/Arduino/libraries/Control-Surface-master/src/AH/STL/Fallback/type_traits:1409:49: error: template argument 2 is invalid
    __is_trivially_constructible(_Tp, const _Tp&)>>
                                                 ^
/Arduino/libraries/Control-Surface-master/src/AH/STL/Fallback/type_traits:1417:43: error: template argument 2 is invalid
    __is_trivially_constructible(_Tp, _Tp&&)>>
                                           ^
/Arduino/libraries/Control-Surface-master/src/AH/STL/Fallback/type_traits:1417:44: error: template argument 2 is invalid
    __is_trivially_constructible(_Tp, _Tp&&)>>
                                            ^
/Arduino/libraries/Control-Surface-master/src/AH/STL/Fallback/type_traits:1425:38: error: template argument 2 is invalid
    __is_trivially_assignable(_Tp, _Up)>>
                                      ^
/Arduino/libraries/Control-Surface-master/src/AH/STL/Fallback/type_traits:1425:39: error: template argument 2 is invalid
    __is_trivially_assignable(_Tp, _Up)>>
                                       ^
/Arduino/libraries/Control-Surface-master/src/AH/STL/Fallback/type_traits:1433:46: error: template argument 2 is invalid
    __is_trivially_assignable(_Tp&, const _Tp&)>>
                                              ^
/Arduino/libraries/Control-Surface-master/src/AH/STL/Fallback/type_traits:1433:47: error: template argument 2 is invalid
    __is_trivially_assignable(_Tp&, const _Tp&)>>
                                               ^
/Arduino/libraries/Control-Surface-master/src/AH/STL/Fallback/type_traits:1441:41: error: template argument 2 is invalid
    __is_trivially_assignable(_Tp&, _Tp&&)>>
                                         ^
/Arduino/libraries/Control-Surface-master/src/AH/STL/Fallback/type_traits:1441:42: error: template argument 2 is invalid
    __is_trivially_assignable(_Tp&, _Tp&&)>>
                                          ^
exit status 1
Fout bij het compileren van board Arduino Leonardo

It looks like you're using an ancient version of the Arduino AVR Core. Please upgrade it to the latest version (at least 1.8.x).

Stupid, I accidentally started 1.6.13, in 1.8.13 it works. But not completely. The tones from the games are played now, but the Midi-CC messages that setup the MT32 to have the nice resonant filter instruments loaded prior to the game start don't pass through. So now Space Quest sounds like it runs on crappy general MIDI.

The MIDI routing example doesn't distinguish between Note and CC messages, so if the notes get through, so should the CC messages.

I'm not familiar with classic games etc. but are you sure that the MIDI connection is set up correctly before it starts sending the CC messages in the setup? Maybe it sends those CC messages first, then opens the correct MIDI port and then sends the notes for the music?

Try using a MIDI monitor (e.g. https://www.roxxxtar.com/apps/miditool/) to see if you can control the instruments and effects yourself by sending CC and Note commands to the Arduino manually.

I think it is SysEX commands, not CC.

blnkjns: I think it is SysEX commands, not CC.

Do you know how long these SysEx messages are? If they are longer than 128 bytes they won't fit in the buffer and won't get transmitted.

The best solution is to try the latest development version of the Control Surface library, it can send and receive SysEx messages of any length. You'll have to remove the ~/Arduino/libraries/Control-Surface-master folder and replace it with the new-input version you can download here: https://github.com/tttapa/Control-Surface/tree/new-input

If you don't want to use the latest version, you can change the maximum SysEx size in the settings for the master version you have installed right now: https://github.com/tttapa/Control-Surface/blob/feee931d44d5f20fb7913b171895316e5819549d/src/Settings/Settings.hpp#L50-L54 You'll need quite a bit of RAM for these buffers, don't make them too large.

What is strange though, normally the MT32 has blinking LED's indicating incoming MIDI, and those don't blink at all, not even the first fraction of a second. When I increase the buffer size to 512 it does seem to make the LED blink a few times, but less than with my Firewire MIDI interface I usually use.

Do you know how long the SysEx messages are? Did you inspect them using a MIDI monitor? Have you tried the new-input version of the library?

Wow, it works with the new branch! Excellent. Thank you very much!

blnkjns: Wow, it works with the new branch! Excellent. Thank you very much!

Glad to hear!