Firmware for HexBoard MIDI controller
Diffstat (limited to 'src/HexBoard.ino')
-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);