X-TOUCH to djay bridge

Dependencies:   mbed mbed-rtos FATFileSystem

Revision:
1:0dac72ab5910
Parent:
0:0fd787d62a99
--- a/main.cpp	Wed Jan 03 08:07:31 2018 +0000
+++ b/main.cpp	Wed Jun 05 04:54:37 2019 +0000
@@ -1,91 +1,194 @@
+/*
+ * BEHRINGER X-TOUCH to DJAY bridge
+ *   for mbed LPC1768
+ *
+ * X-TOUCH (MC/USB) <---USB---> LPC1768 <---UART MIDI---> MD-BT01 (YAMAHA, BLE MIDI)
+ */
+
 #include "mbed.h"
+#include "USBHostHub.h"
 #include "USBHostMIDI.h"
+#include "MIDI.h"
+#include "CBuffer.h"
 
 Serial pc(USBTX, USBRX);
 DigitalOut led1(LED1);
 PwmOut led2(LED2), led3(LED3), led4(LED4);
+USBHostHub hub;
 USBHostMIDI midi;
+MIDI midi2(p28, p27);
 
-volatile int sendNoteOn = -1, sendNoteOff = -1, sendControlChange = -1;
+CircBuffer <uint32_t>midi_out(20);
+
 
+void systemExclusive (uint8_t *buffer, uint16_t length, bool flag) {
+    midi2.sendSysEx(length, buffer, flag);
+}
 void noteOn(uint8_t channel, uint8_t note, uint8_t velocity) {
-    pc.printf("noteOn %02x %02x %02x\r\n", channel, note, velocity);
-    switch (note) {
-    case 0:
-        led2 = (float)velocity / 127.0;
-        break;
-    case 1:
-        led3 = (float)velocity / 127.0;
-        break;
-    case 2:
-        led4 = (float)velocity / 127.0;
-        break;
-    }
-    sendNoteOn = (channel << 16) | (note << 8) | velocity;
+    midi_out.queue(((uint32_t)NoteOn << 24) | ((uint32_t)channel << 16) | (note << 8) | velocity);
+}
+void noteOff(uint8_t channel, uint8_t note, uint8_t velocity) {
+    midi_out.queue(((uint32_t)NoteOff << 24) | ((uint32_t)channel << 16) | (note << 8) | velocity);
+}
+void controlChange(uint8_t channel, uint8_t key, uint8_t value) {
+    midi_out.queue(((uint32_t)ControlChange << 24) | ((uint32_t)channel << 16) | (key << 8) | value);
+}
+void programChange (uint8_t channel, uint8_t progra) {
+    midi_out.queue(((uint32_t)ProgramChange << 24) | ((uint32_t)channel << 16) | (progra << 8));
+}
+void pitchBend (uint8_t channel, uint16_t value) {
+    midi_out.queue(((uint32_t)PitchBend << 24) | ((uint32_t)channel << 16) | value);
 }
 
-void noteOff(uint8_t channel, uint8_t note, uint8_t velocity) {
-    pc.printf("noteOff %02x %02x %02x\r\n", channel, note, velocity);
-    sendNoteOff = (channel << 16) | (note << 8) | velocity;
-}
+
+void printLcd (int x, int y, char *buf) {
+    int i, len;
+    uint8_t msg[40] = {0xf0, 0x00, 0x00, 0x66, 0x14,  0x12, 0x00};
 
-void controlChange(uint8_t channel, uint8_t key, uint8_t value) {
-    pc.printf("controlChange %02x %02x %02x\r\n", channel, key, value);
-    switch (key) {
-    case 0:
-    case 0x4d:
-        led2 = (float)value / 127.0;
-        break;
-    case 1:
-    case 0x4e:
-        led3 = (float)value / 127.0;
-        break;
-    case 2:
-    case 0x4f:
-        led4 = (float)value / 127.0;
-        break;
+    msg[6] = (7 * x) + (0x38 * y);
+    len = 7;
+    for (i = 0; i < strlen(buf); i ++) {
+        msg[len ++] = buf[i];
     }
-    sendControlChange = (channel << 16) | (key << 8) | value;
+    msg[len ++] = 0xf7;
+    midi.sendSystemExclusive(msg, len);
 }
 
 void midi_task(void const*) {
     int i;
-    USBHostMIDI midi;
-    
+
+//    hub = new USBHostHub;
+//    midi = new USBHostMIDI;
+
     // attach midi event callbacks
+    midi.attachSystemExclusive(systemExclusive);
     midi.attachNoteOn(noteOn);
     midi.attachNoteOff(noteOff);
     midi.attachControlChange(controlChange);
+    midi.attachProgramChange(programChange);
+    midi.attachPitchBend(pitchBend);
+    
     pc.printf("begin\r\n");
 
+    uint32_t m;
+    int channel, data1, data2;
     for (;;) {
         // try to connect a midi device
         while(!midi.connect()) {
             Thread::wait(500);
             led1 = !led1;
         }
-        Thread::wait(1000);
-        midi.sendControlChange(0, 41, 127); // LED on (nanoKONTROL2)
-        midi.sendNoteOn(0, 0x29, 127); // LED on (Launch Control XL)
+        Thread::wait(500);
+
+        pc.printf("detected\r\n");
+        for (i = 0; i < 9; i ++) {
+            midi.sendPitchBend(i, 0); // fader 0
+        }
+        for (i = 0; i < 0x7f; i ++) {
+            midi.sendNoteOn(0, i, 0); // led off
+        }
+
+        // LCD
+        printLcd(0, 0, " High");
+        printLcd(1, 0, "  Mid");
+        printLcd(2, 0, "  Low");
+        printLcd(3, 0, " Gain");
+        printLcd(4, 0, " Gain");
+        printLcd(5, 0, "  Low");
+        printLcd(6, 0, "  Mid");
+        printLcd(7, 0, " High");
+        printLcd(2, 1, " Speed");
+        printLcd(3, 1, "   1  <");
+        printLcd(4, 1, ">  2   ");
+        printLcd(5, 1, " Speed");
+        // 7segment LED
+        midi.sendControlChange(0, 0x43, 'D' & 0x1f);
+        midi.sendControlChange(0, 0x42, 'J' & 0x1f);
+        midi.sendControlChange(0, 0x41, 'A' & 0x1f);
+        midi.sendControlChange(0, 0x40, 'Y' & 0x1f);
+
         led1 = 1;
-
         for (;;) {
             if (!midi.connected()) {
                 pc.printf("disconnected\r\n");
                 break;
             }
 
-            if (sendNoteOn != -1) {
-                midi.sendNoteOn(sendNoteOn >> 16, sendNoteOn >> 8, sendNoteOn);
-                sendNoteOn = -1;
+            if (!midi_out.isEmpty()) {
+                // USB -> uart
+                midi_out.dequeue(&m);
+                channel = (m >> 16) & 0x7f;
+                data1 = (m >> 8) & 0x7f;
+                data2 = m & 0x7f;
+                
+                switch (m >> 24) {
+                case NoteOn:
+                    midi2.sendNoteOn(data1, data2, channel);
+//                    pc.printf("noteOn %02x %02x %02x\r\n", channel, data1, data2);
+                    break;
+                case NoteOff:
+                    midi2.sendNoteOff(data1, data2, channel);
+//                    pc.printf("noteOff %02x %02x %02x\r\n", channel, data1, data2);
+                    break;
+                case ControlChange:
+                    if ((data1 >= 0x10 && data1 <= 0x17) || data1 == 0x3c) {
+                        midi2.sendControlChange(data1, data2 < 0x40 ? data2 : 0x80 - (data2 - 0x40), channel);
+                    } else {
+                        midi2.sendControlChange(data1, data2, channel);
+                    }
+//                    pc.printf("controlChange %02x %02x %02x\r\n", channel, data1, data2);
+                    break;
+                case ProgramChange:
+                    midi2.sendProgramChange(data1, channel);
+//                    pc.printf("programChange %02x %02x\r\n", channel, data1);
+                    break;
+                case PitchBend:
+                    data1 = m & 0x3fff;
+                    midi.sendPitchBend(channel, data1);
+                    midi2.sendControlChange(channel, data1 >> 7, 0);
+//                    pc.printf("pitchBend %02x %04x\r\n", channel, data1);
+                    break;
+                }
             }
-            if (sendNoteOff != -1) {
-                midi.sendNoteOff(sendNoteOff >> 16, sendNoteOff >> 8, sendNoteOff);
-                sendNoteOff = -1;
-            }
-            if (sendControlChange != -1) {
-                midi.sendControlChange(sendControlChange >> 16, sendControlChange >> 8, sendControlChange);
-                sendControlChange = -1;
+
+            if (midi2.read()) {
+                // uart -> USB
+                channel = midi2.getChannel();
+                data1 = midi2.getData1();
+                data2 = midi2.getData2();
+
+                switch (midi2.getType()) {
+                case NoteOn:
+                    midi.sendNoteOn(channel, data1, data2);
+//                    pc.printf(" noteOn %02x %02x %02x\r\n", channel, data1, data2);
+                    break;
+                case NoteOff:
+                    midi.sendNoteOff(channel, data1, data2);
+//                    pc.printf(" noteOff %02x %02x %02x\r\n", channel, data1, data2);
+                    break;
+                case ControlChange:
+                    if (data1 < 0x10) {
+                        midi.sendPitchBend(data1, (data2 << 7) | data2);
+                    } else
+                    if (data1 >= 0x10 && data1 <= 0x17) {
+                        midi.sendControlChange(channel, 0x30 | (data1 & 0x0f), (data2 * 0x0c) / 0x7f);
+                    } else {
+                        midi.sendControlChange(channel, data1, data2);
+                    }
+//                    pc.printf(" controlChange %02x %02x %02x\r\n", channel, data1, data2);
+                    break;
+                case ProgramChange:
+                    midi.sendProgramChange(channel, data1);
+//                    pc.printf(" programChange %02x %02x\r\n", channel, data1);
+                    break;
+                case PitchBend:
+//                    pc.printf(" pitchBend %02x %04x\r\n", channel, data1);
+                    break;
+                case SystemExclusive:
+                    midi.sendSystemExclusive((uint8_t *)midi2.getSysExArray(), midi2.getSysExArrayLength());
+//                    pc.printf(" SystemExclusive\r\n");
+                    break;
+                }
             }
         }
     }
@@ -95,8 +198,12 @@
     pc.baud(115200);
     pc.printf("*** USB Host MIDI\r\n");
 
-    Thread midiTask(midi_task);
+    midi2.begin(MIDI_CHANNEL_OMNI);
+    midi2.turnThruOff();
+
+//    Thread midiTask(midi_task, NULL, osPriorityNormal, 5120);
     for (;;) {
-        Thread::wait(100);
+        midi_task(NULL);
+//        Thread::wait(100);
     }
 }