about summary refs log tree commit diff
diff options
context:
space:
mode:
authorShaping The Silence <jareddecook@gmail.com>2025-04-11 12:13:19 -0400
committerZach DeCook <zachdecook@librem.one>2025-04-28 20:26:02 -0400
commit687a997a46589aecea07464ab64939aa591e4035 (patch)
tree887f8418bb729fe1af7e41382bdd1fe7d88ee7b7
parentbb7b5bbc20086e13334e81b3d261246659886c14 (diff)
downloadHexBoard-687a997a46589aecea07464ab64939aa591e4035.tar.gz
MPE message additions - beginning of 1.2
Added channel pressure (mirrors velocity) and configurable CC74 to increase compatibility with MPE synthesizers (EaganMatrix, namely).
-rw-r--r--src/HexBoard.ino48
1 files changed, 44 insertions, 4 deletions
diff --git a/src/HexBoard.ino b/src/HexBoard.ino
index 46494f8..f4e229b 100644
--- a/src/HexBoard.ino
+++ b/src/HexBoard.ino
@@ -80,6 +80,8 @@
 /////////      global variables and defines     ///////////////////////////////////////////////
 
   bool forceEnableMPE = false;
+  bool extraMPE = false;
+  byte CC74value = 0;
   byte defaultMidiChannel = 1;
   byte layoutRotation = 0;
 
@@ -2556,10 +2558,15 @@ void tryMIDInoteOn(byte x) {
             pressedKeyIDs.push_back(x); // Dynamic JI pressed key tracking
             // First, send the pitch bend (if applicable)
             if (MPEpitchBendsNeeded != 1) {
-                if (midiD & MIDID_USB) UMIDI.sendPitchBend(h[x].bend + justIntonationRetune(x), h[x].MIDIch); // ch 1-16
-                if (midiD & MIDID_SER) SMIDI.sendPitchBend(h[x].bend + justIntonationRetune(x), h[x].MIDIch); // ch 1-16
+              if (midiD & MIDID_USB) UMIDI.sendPitchBend(h[x].bend + justIntonationRetune(x), h[x].MIDIch); // ch 1-16
+              if (midiD & MIDID_SER) SMIDI.sendPitchBend(h[x].bend + justIntonationRetune(x), h[x].MIDIch); // ch 1-16
+              if(extraMPE) { //if the extra MPE messages are enabled
+                if (midiD & MIDID_USB) UMIDI.sendAfterTouch(velWheel.curValue, h[x].MIDIch); // Channel Pressure
+                if (midiD & MIDID_SER) SMIDI.sendAfterTouch(velWheel.curValue, h[x].MIDIch); // Channel Pressure
+                if (midiD & MIDID_USB) UMIDI.sendControlChange(74, CC74value, h[x].MIDIch); // CC74 (Timbre)
+                if (midiD & MIDID_SER) SMIDI.sendControlChange(74, CC74value, h[x].MIDIch); // CC74 (Timbre)
+              }
             }
-
             // Then, send the note-on message
             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
@@ -2591,6 +2598,12 @@ void tryMIDInoteOn(byte x) {
         " ch " + std::to_string(h[x].MIDIch)
       );
       if (MPEpitchBendsNeeded > 15 && h[x].MIDIch > 1) {
+        if(extraMPE) { //if the extra MPE messages are enabled
+          if (midiD & MIDID_USB) UMIDI.sendAfterTouch(0, h[x].MIDIch); // Channel Pressure
+          if (midiD & MIDID_SER) SMIDI.sendAfterTouch(0, h[x].MIDIch); // Channel Pressure
+          if (midiD & MIDID_USB) UMIDI.sendControlChange(74, CC74value, h[x].MIDIch); // CC74 (Timbre)
+          if (midiD & MIDID_SER) SMIDI.sendControlChange(74, CC74value, h[x].MIDIch); // CC74 (Timbre)
+              }
         MPEchQueue.push(h[x].MIDIch);
         sendToLog("pushed " + std::to_string(h[x].MIDIch) + " on the MPE queue");
       }
@@ -3446,7 +3459,7 @@ void animateStaticBeams() {
     To be honest I don't know how to get just a plain text line to show here other than this!
   */
   void fakeButton() {}
-  GEMItem  menuItemVersion("Firmware 1.1", fakeButton);
+  GEMItem  menuItemVersion("Firmware 1.2-alpha1", fakeButton);
   SelectOptionByte optionByteHardware[] =  {
     { "V1.1", HARDWARE_UNKNOWN }, { "V1.1" , HARDWARE_V1_1 },
     { "V1.2", HARDWARE_V1_2 }
@@ -4201,6 +4214,31 @@ void animateStaticBeams() {
   // MIDI force MPE option toggle
   GEMItem menuItemToggleForceMPEChannels ("Force MPE", forceEnableMPE, resetTuningMIDI);
 
+  // Toggle additional MPE messages (CC74 + Channel Pressure)
+  GEMItem menuItemToggleExtraMPE ("Extra MPE", extraMPE);
+
+   // MIDI Channel selection
+  SelectOptionByte optionByteCC74value[] = {
+    {"   0",   0}, {"   1",   1}, {"   2",   2}, {"   3",   3}, {"   4",   4}, {"   5",   5}, {"   6",   6}, {"   7",   7},
+    {"   8",   8}, {"   9",   9}, {"  10",  10}, {"  11",  11}, {"  12",  12}, {"  13",  13}, {"  14",  14}, {"  15",  15},
+    {"  16",  16}, {"  17",  17}, {"  18",  18}, {"  19",  19}, {"  20",  20}, {"  21",  21}, {"  22",  22}, {"  23",  23},
+    {"  24",  24}, {"  25",  25}, {"  26",  26}, {"  27",  27}, {"  28",  28}, {"  29",  29}, {"  30",  30}, {"  31",  31},
+    {"  32",  32}, {"  33",  33}, {"  34",  34}, {"  35",  35}, {"  36",  36}, {"  37",  37}, {"  38",  38}, {"  39",  39},
+    {"  40",  40}, {"  41",  41}, {"  42",  42}, {"  43",  43}, {"  44",  44}, {"  45",  45}, {"  46",  46}, {"  47",  47},
+    {"  48",  48}, {"  49",  49}, {"  50",  50}, {"  51",  51}, {"  52",  52}, {"  53",  53}, {"  54",  54}, {"  55",  55},
+    {"  56",  56}, {"  57",  57}, {"  58",  58}, {"  59",  59}, {"  60",  60}, {"  61",  61}, {"  62",  62}, {"  63",  63},
+    {"  64",  64}, {"  65",  65}, {"  66",  66}, {"  67",  67}, {"  68",  68}, {"  69",  69}, {"  70",  70}, {"  71",  71},
+    {"  72",  72}, {"  73",  73}, {"  74",  74}, {"  75",  75}, {"  76",  76}, {"  77",  77}, {"  78",  78}, {"  79",  79},
+    {"  80",  80}, {"  81",  81}, {"  82",  82}, {"  83",  83}, {"  84",  84}, {"  85",  85}, {"  86",  86}, {"  87",  87},
+    {"  88",  88}, {"  89",  89}, {"  90",  90}, {"  91",  91}, {"  92",  92}, {"  93",  93}, {"  94",  94}, {"  95",  95},
+    {"  96",  96}, {"  97",  97}, {"  98",  98}, {"  99",  99}, {" 100", 100}, {" 101", 101}, {" 102", 102}, {" 103", 103},
+    {" 104", 104}, {" 105", 105}, {" 106", 106}, {" 107", 107}, {" 108", 108}, {" 109", 109}, {" 110", 110}, {" 111", 111},
+    {" 112", 112}, {" 113", 113}, {" 114", 114}, {" 115", 115}, {" 116", 116}, {" 117", 117}, {" 118", 118}, {" 119", 119},
+    {" 120", 120}, {" 121", 121}, {" 122", 122}, {" 123", 123}, {" 124", 124}, {" 125", 125}, {" 126", 126}, {" 127", 127}
+  };
+  GEMSelect selectCC74value(128,optionByteCC74value);
+  GEMItem menuItemSelectCC74value( "CC 74 Value", CC74value, selectCC74value);
+
   // Layout rotation selection
   SelectOptionByte optionByteLayoutRotation[] = {{"0 Deg",0},{"60 Deg",1},{"120 Deg",2},{"180 Deg",3},{"240 Deg",4},{"300 Deg",5}};
   GEMSelect selectLayoutRotation(6,optionByteLayoutRotation);
@@ -4472,6 +4510,8 @@ void animateStaticBeams() {
       menuPageMIDI.addMenuItem(menuItemRolandMT32);
       menuPageMIDI.addMenuItem(menuItemGeneralMidi);
       menuPageMIDI.addMenuItem(menuItemToggleForceMPEChannels);
+      menuPageMIDI.addMenuItem(menuItemToggleExtraMPE);
+      menuPageMIDI.addMenuItem(menuItemSelectCC74value);
     menuPageMain.addMenuItem(menuItemTransposeSteps);
     menuPageMain.addMenuItem(menuGotoAdvanced);
       menuPageAdvanced.addMenuItem(menuItemVersion);