Simple USB-MIDI foot controller

Dependencies:   PinDetect USBDevice_STM32F103 mbed-STM32F103C8T6

Revision:
8:75c5ec68765e
Parent:
7:553836a26221
Child:
9:d5fa853818dd
--- a/midiswitch.cpp	Fri Aug 04 04:20:37 2017 +0200
+++ b/midiswitch.cpp	Fri Aug 04 05:22:22 2017 +0200
@@ -1,9 +1,9 @@
 #include "mbed.h"
 #include "midiswitch.h"
 
-SwitchHandler::SwitchHandler(EventQueue * queue, MIDI_CB cb, SwitchConfig * sw) :
-    queue(queue), write_cb(cb), btn(sw->pin), control(sw->control), channel(sw->channel), on_value(sw->on_value), off_value(sw->off_value) {
-    btn.mode(Pullup);
+SwitchHandler::SwitchHandler(EventQueue * queue, MIDI_CB cb, SwitchConfig sw) :
+    queue(queue), write_cb(cb), btn(sw.pin), cfg(sw) {
+    btn.mode(PullUp);
     btn.setAssertValue(0);
     btn.attach_asserted(this, &SwitchHandler::handle_pressed);
     btn.attach_deasserted(this, &SwitchHandler::handle_released);
@@ -11,9 +11,54 @@
 };
 
 void SwitchHandler::handle_pressed(void) {
-    queue->call(write_cb, MIDIMessage::ControlChange((int) control, (int) on_value, (int) (channel - 1)));
+    if (cfg.on_value >= 0) {
+        if (make_message(true)) {
+            queue->call(write_cb, msg);
+        }
+    }
 };
 
 void SwitchHandler::handle_released(void) {
-    queue->call(write_cb, MIDIMessage::ControlChange((int) control, (int) off_value, (int) (channel - 1)));
+    if (cfg.off_value >= 0) {
+        if (make_message(false)) {
+            queue->call(write_cb, msg);
+        }
+    }
 };
+
+bool SwitchHandler::make_message(bool onoff) {
+    uint8_t value = (onoff ? cfg.on_value : cfg.off_value) & 0x7F;
+    msg.data[0] = CABLE_NUM | cfg.type;
+    msg.data[1] = cfg.type;
+
+    switch(cfg.type) {
+        case 0xFA:  // START
+        case 0xFB:  // CONTINUE
+        case 0xFC:  // STOP
+            msg.data[2] = 0x00;
+            msg.data[3] = 0x00;
+            break;
+        case 0xC0:  // Program change
+        case 0xD0:  // Channel Aftertouch
+            msg.data[1] = msg.data[1] | (cfg.channel & 0x0F);
+            msg.data[2] = value;
+            msg.data[3] = 0x00;
+            break;
+        case 0x80:  // Note off
+        case 0x90:  // Note on
+            msg.data[1] = msg.data[1] | (cfg.channel & 0x0F);
+            msg.data[3] = value;
+            msg.data[2] = cfg.data1;
+            break;
+        case 0xA0:  // Poly pressure
+        case 0xB0:  // Control change
+        case 0xE0:  // PitchBend
+            msg.data[1] = msg.data[1] | (cfg.channel & 0x0F);
+            msg.data[2] = cfg.data1;
+            msg.data[3] = value;
+            break;
+        default:
+            return false;
+    }
+    return true;
+};