USB MIDIをUART MIDIに変換

GM音源、SAM2695を次にような接続でPCから鳴らします。 PCのMIDIシーケンサーはMIDIをUSB-MIDIのフォーマットでArduinoへ投げます。 ArduinoはUSB-MIDIデータを受信すると、これをMIDIに変換してUARTでSAM2695に投げます。





例えば、Note OnメッセージはUSB-MIDIのフォーマットでは 09H 90H 40H 7FHの4バイト UARTで送信するMIDIは、90H 40H 7FHと3バイトのメッセージになります。

ArduinoはAliexpressでPro Microを購入しました。 このArduinoを選択した決め手はMIDIUSBのライブラリを使うこができるCPUがATmega32U4であること。 そしてなんといっても送料込みで1100円ほどで購入できます。

USB-MIDIのフォーマットは、MIDIUSBのライラリでは以下の構造体で受信されます。 詳細は、「USB MIDIのmidiEventPacket_t」に記載しました。

#pragma once
#include <stdint.h>

typedef struct
{
    uint8_t header;
    uint8_t byte1;
    uint8_t byte2;
    uint8_t byte3;
} midiEventPacket_t;

USB MIDIをUARTに変換するためには、headerの下位4ビットに応じて続く3つのbyteのうち、いくつをUARTに送るかを決めます。 プログラムの例を以下に示します。

// Convert USB-MIDI to UART
#include "MIDIUSB.h"

void setup() {
    Serial1.begin(31250);
}

void loop() {
    midiEventPacket_t rx;
    do {
    rx = MidiUSB.read();
        if (rx.header != 0) {
        //send back the received MIDI command
            switch(rx.header&0x0F){
                case 0x0:
                case 0x1:
                    break;

                case 0x5:
                case 0xF:
                    Serial1.write(rx.byte1);
                    break;

                case 0x2:
                case 0x6:
                case 0xC:
                case 0xD:
                    Serial1.write(rx.byte1);
                    Serial1.write(rx.byte2);
                    break;

                case 0x3:
                case 0x4:
                case 0x7:
                case 0x8:
                case 0x9:
                case 0xA:
                case 0xB:
                case 0xE:
                    Serial1.write(rx.byte1);
                    Serial1.write(rx.byte2);
                    Serial1.write(rx.byte3);
                    break;
                }
            MidiUSB.flush();
        }
    } while (rx.header != 0);
}