about summary refs log tree commit diff
path: root/HexBoard.ino
diff options
context:
space:
mode:
authorZach DeCook <zachdecook@librem.one>2024-06-15 07:24:19 -0400
committerZach DeCook <zachdecook@librem.one>2024-06-15 09:16:53 -0400
commitbd56c069ab1eee7735a6dfb268bc4ef746362a35 (patch)
tree886f96f2690b7f91b3d22e7c83e47983402a2417 /HexBoard.ino
parent7e21c52bc226d58d96718f69617009ef13eba4ae (diff)
downloadHexBoard-bd56c069ab1eee7735a6dfb268bc4ef746362a35.tar.gz
Enable additional midi output on unreleased hardware revision
Diffstat (limited to 'HexBoard.ino')
-rw-r--r--HexBoard.ino73
1 files changed, 55 insertions, 18 deletions
diff --git a/HexBoard.ino b/HexBoard.ino
index aa93b84..fa5ec1a 100644
--- a/HexBoard.ino
+++ b/HexBoard.ino
@@ -3,7 +3,6 @@
     HexBoard
     Copyright 2022-2023 Jared DeCook and Zach DeCook
     with help from Nicholas Fox
-    Firmware v1.0.0 2024-05-17
     Licensed under the GNU GPL Version 3.
 
     Hardware information:
@@ -1347,24 +1346,39 @@
     and attach usb_midi as the transport.
   */
   Adafruit_USBD_MIDI usb_midi;
-  MIDI_CREATE_INSTANCE(Adafruit_USBD_MIDI, usb_midi, MIDI);
+  MIDI_CREATE_INSTANCE(Adafruit_USBD_MIDI, usb_midi, UMIDI);
+  MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, SMIDI);
+  // midiD takes the following bitwise flags
+  #define MIDID_NONE 0
+  #define MIDID_USB 1
+  #define MIDID_SER 2
+  #define MIDID_BOTH 3
+  byte midiD = MIDID_USB | MIDID_SER;
+
   std::queue<byte> MPEchQueue;
   byte MPEpitchBendsNeeded; 
 
   float freqToMIDI(float Hz) {             // formula to convert from Hz to MIDI note
     return 69.0 + 12.0 * log2f(Hz / 440.0);
   }
-  float MIDItoFreq(float MIDI) {           // formula to convert from MIDI note to Hz
-    return 440.0 * exp2((MIDI - 69.0) / 12.0);
+  float MIDItoFreq(float midi) {           // formula to convert from MIDI note to Hz
+    return 440.0 * exp2((midi - 69.0) / 12.0);
   }
   float stepsToMIDI(int16_t stepsFromA) {  // return the MIDI pitch associated
     return freqToMIDI(CONCERT_A_HZ) + ((float)stepsFromA * (float)current.tuning().stepSize / 100.0);
   }
 
   void setPitchBendRange(byte Ch, byte semitones) {
-    MIDI.beginRpn(0, Ch);
-    MIDI.sendRpnValue(semitones << 7, Ch);
-    MIDI.endRpn(Ch);
+    if (midiD&MIDID_USB) {
+        UMIDI.beginRpn(0, Ch);
+        UMIDI.sendRpnValue(semitones << 7, Ch);
+        UMIDI.endRpn(Ch);
+    }
+    if (midiD&MIDID_SER) {
+        SMIDI.beginRpn(0, Ch);
+        SMIDI.sendRpnValue(semitones << 7, Ch);
+        SMIDI.endRpn(Ch);
+    }
     sendToLog(
       "set pitch bend range on ch " +
       std::to_string(Ch) + " to be " + 
@@ -1373,9 +1387,16 @@
   }
 
   void setMPEzone(byte masterCh, byte sizeOfZone) {
-    MIDI.beginRpn(6, masterCh);
-    MIDI.sendRpnValue(sizeOfZone << 7, masterCh);
-    MIDI.endRpn(masterCh);
+    if (midiD&MIDID_USB) {
+        UMIDI.beginRpn(6, masterCh);
+        UMIDI.sendRpnValue(sizeOfZone << 7, masterCh);
+        UMIDI.endRpn(masterCh);
+    }
+    if (midiD&MIDID_SER) {
+        SMIDI.beginRpn(6, masterCh);
+        SMIDI.sendRpnValue(sizeOfZone << 7, masterCh);
+        SMIDI.endRpn(masterCh);
+    }
     sendToLog(
       "tried sending MIDI msg to set MPE zone, master ch " +
       std::to_string(masterCh) + ", zone of this size: " + std::to_string(sizeOfZone)
@@ -1416,18 +1437,21 @@
     }
     // force pitch bend back to the expected range of 2 semitones.
     for (byte i = 1; i <= 16; i++) {
-      MIDI.sendControlChange(123, 0, i);
+      if(midiD&MIDID_USB)UMIDI.sendControlChange(123, 0, i);
+      if(midiD&MIDID_SER)SMIDI.sendControlChange(123, 0, i);
       setPitchBendRange(i, PITCH_BEND_SEMIS);   
     }
   }
 
   void sendMIDImodulationToCh1() {
-    MIDI.sendControlChange(1, modWheel.curValue, 1);
+    if(midiD&MIDID_USB)UMIDI.sendControlChange(1, modWheel.curValue, 1);
+    if(midiD&MIDID_SER)SMIDI.sendControlChange(1, modWheel.curValue, 1);
     sendToLog("sent mod value " + std::to_string(modWheel.curValue) + " to ch 1");
   }
 
   void sendMIDIpitchBendToCh1() {
-    MIDI.sendPitchBend(pbWheel.curValue, 1);
+    if(midiD&MIDID_USB)UMIDI.sendPitchBend(pbWheel.curValue, 1);
+    if(midiD&MIDID_SER)SMIDI.sendPitchBend(pbWheel.curValue, 1);
     sendToLog("sent pb wheel value " + std::to_string(pbWheel.curValue) + " to ch 1");
   }
   
@@ -1449,8 +1473,11 @@
         }
       }
       if (h[x].MIDIch) {
-        MIDI.sendNoteOn(h[x].note, velWheel.curValue, h[x].MIDIch); // ch 1-16
-        MIDI.sendPitchBend(h[x].bend, h[x].MIDIch); // ch 1-16
+        if(midiD&MIDID_USB)UMIDI.sendNoteOn(h[x].note, velWheel.curValue, h[x].MIDIch); // ch 1-16
+        if(midiD&MIDID_SER)SMIDI.sendNoteOn(h[x].note, velWheel.curValue, h[x].MIDIch); // ch 1-16
+
+        if(midiD&MIDID_USB)UMIDI.sendPitchBend(h[x].bend, h[x].MIDIch); // ch 1-16
+        if(midiD&MIDID_SER)SMIDI.sendPitchBend(h[x].bend, h[x].MIDIch); // ch 1-16
         sendToLog(
           "sent MIDI noteOn: " + std::to_string(h[x].note) +
           " pb "  + std::to_string(h[x].bend) +
@@ -1465,7 +1492,8 @@
     // this gets called on any non-command hex
     // that is not scale-locked.
     if (h[x].MIDIch) {    // but just in case, check
-      MIDI.sendNoteOff(h[x].note, velWheel.curValue, h[x].MIDIch);    
+      if(midiD&MIDID_USB)UMIDI.sendNoteOff(h[x].note, velWheel.curValue, h[x].MIDIch);
+      if(midiD&MIDID_SER)SMIDI.sendNoteOff(h[x].note, velWheel.curValue, h[x].MIDIch);
       sendToLog(
         "sent note off: " + std::to_string(h[x].note) +
         " pb " + std::to_string(h[x].bend) +
@@ -1482,7 +1510,8 @@
 
   void setupMIDI() {
     usb_midi.setStringDescriptor("HexBoard MIDI");  // Initialize MIDI, and listen to all MIDI channels
-    MIDI.begin(MIDI_CHANNEL_OMNI);                  // This will also call usb_midi's begin()
+    UMIDI.begin(MIDI_CHANNEL_OMNI);                 // This will also call usb_midi's begin()
+    SMIDI.begin(MIDI_CHANNEL_OMNI);
     resetTuningMIDI();
     sendToLog("setupMIDI okay");
   }
@@ -1809,7 +1838,8 @@
   }
   
   void updateSynthWithNewFreqs() {
-    MIDI.sendPitchBend(pbWheel.curValue, 1);
+    if(midiD&MIDID_USB)UMIDI.sendPitchBend(pbWheel.curValue, 1);
+    if(midiD&MIDID_SER)SMIDI.sendPitchBend(pbWheel.curValue, 1);
     for (byte i = 0; i < BTN_COUNT; i++) {
       if (!(h[i].isCmd)) {
         if (h[i].synthCh) {
@@ -2086,6 +2116,7 @@
         break;
       case HARDWARE_V1_2:
         Hardware_Version = h[x].note;
+        setupHardware();
         break;
       default:
         // the rest should all be taken care of within the wheelDef structure
@@ -2690,6 +2721,12 @@
     }
   }
 
+  void setupHardware() {
+    if (Hardware_Version == HARDWARE_V1_2) {
+        midiD = MIDID_USB | MIDID_SER;
+    }
+  }
+
 // @mainLoop
   /*
     An Arduino program runs