diff --git a/NuEVI/NuEVI.ino b/NuEVI/NuEVI.ino index 6d80d85..c7a06fe 100644 --- a/NuEVI/NuEVI.ino +++ b/NuEVI/NuEVI.ino @@ -88,6 +88,8 @@ unsigned short priority; // mono priority for rotator chords unsigned short extraCT2; // OFF:1-127 unsigned short levelCC; // 0-127 unsigned short levelVal; // 0-127 +unsigned short fingering; // 0-4 EWI,EWX,SAX,EVI,EVR +unsigned short lpinky3; // 0-25 (OFF, -12 - MOD - +12) unsigned short vibSens = 2; // vibrato sensitivity unsigned short vibRetn = 2; // vibrato return speed @@ -228,6 +230,36 @@ const unsigned short* const curves[] = { curveP3, curveP4 , curveS1, curveS2, curveZ1, curveZ2 }; +// NuRAD Sax fingering +// LH1, LHb, LH2, LH3, LHp1, -LHp2-, -RHsx-, RH1, RH2, RH3, RHp1, RHp2, RHp3 -excluded- LHp2 always -1, RHs always +1 +// 0 = not touched, 1 = touched, 2 = whatever + +const byte saxFingerMatch[17][11] = +{ + {1, 2, 1, 1, 2, 1, 1, 1, 2, 1, 1}, // B (-14 semis) + {1, 2, 1, 1, 0, 1, 1, 1, 2, 0, 1}, // C (-13 semis) + {1, 2, 1, 1, 1, 1, 1, 1, 2, 0, 1}, // C# (-12 semis) + {1, 2, 1, 1, 2, 1, 1, 1, 2, 1, 0}, // C# (-12 semis) + {1, 2, 1, 1, 2, 1, 1, 1, 0, 0, 0}, // D (-11 semis) + {1, 2, 1, 1, 2, 1, 1, 1, 1, 0, 0}, // D# (-10 semis) + {1, 2, 1, 1, 2, 1, 1, 0, 2, 2, 2}, // E (-9 semis) + {1, 2, 1, 1, 2, 1, 0, 2, 2, 2, 2}, // F (-8 semis) + {1, 2, 1, 1, 2, 0, 1, 2, 2, 2, 2}, // F# (-7 semis) + {1, 2, 1, 1, 0, 0, 0, 2, 2, 2, 2}, // G (-6 semis) + {1, 2, 1, 1, 1, 0, 0, 2, 2, 2, 2}, // G# (-5 semis) + {1, 2, 1, 0, 2, 2, 2, 2, 2, 2, 2}, // A (-4 semis) + {1, 2, 0, 2, 2, 1, 2, 2, 2, 2, 2}, // A# (-3 semis) + {1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2}, // A# (-3 semis) + {1, 0, 0, 2, 2, 0, 2, 2, 2, 2, 2}, // B (-2 semis) + {0, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2}, // C (-1 semis) + {0, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2}, // C# (-0 semis) +}; + +const int saxFingerResult[17] = {-14, -13, -12, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -3, -2, -1, 0}; + +byte saxFinger[11]; + + int vibThr; // this gets auto calibrated in setup int vibThrLo; int vibZero; @@ -387,7 +419,7 @@ void setup() { #if defined(NURAD) digitalWrite(statusLedPin,HIGH); - if (!touchSensorRollers.begin(0x5D)) { + if (!touchSensorRollers.begin(0x5D)) { //should be D while (1); // Touch sensor initialization failed - stop doing stuff } if (!touchSensorLH.begin(0x5C)) { @@ -748,10 +780,16 @@ void loop() { } } if (rotatorOn) { - midiSendNoteOn(noteValueCheck(fingeredNote + parallel-24), velocitySend); // send Note On message for new note + if (parallel-24) midiSendNoteOn(noteValueCheck(fingeredNote + parallel-24), velocitySend); // send Note On message for new note if (currentRotation < 3) currentRotation++; else currentRotation = 0; - midiSendNoteOn(noteValueCheck(fingeredNote + rotations[currentRotation]-24), velocitySend); // send Note On message for new note + int allCheck=4; + while ((0 == rotations[currentRotation]-24) && allCheck){ + if (currentRotation < 3) currentRotation++; + else currentRotation = 0; + allCheck--; + } + if (rotations[currentRotation]-24) midiSendNoteOn(noteValueCheck(fingeredNote + rotations[currentRotation]-24), velocitySend); // send Note On message for new note } if (!priority) { // mono prio to base note midiSendNoteOn(fingeredNote, velocitySend); // send Note On message for new note @@ -785,8 +823,8 @@ void loop() { } } if (rotatorOn) { - midiSendNoteOff(noteValueCheck(activeNote + parallel-24 )); // send Note Off message for old note - midiSendNoteOff(noteValueCheck(activeNote + rotations[currentRotation]-24)); // send Note Off message for old note + if (parallel - 24) midiSendNoteOff(noteValueCheck(activeNote + parallel-24 )); // send Note Off message for old note + if (rotations[currentRotation]-24) midiSendNoteOff(noteValueCheck(activeNote + rotations[currentRotation]-24)); // send Note Off message for old note } if (!priority) { midiSendNoteOff(activeNote); // send Note Off message @@ -826,8 +864,8 @@ void loop() { } } if (rotatorOn) { - midiSendNoteOff(noteValueCheck(activeNote + parallel-24)); // send Note Off message for old note - midiSendNoteOff(noteValueCheck(activeNote + rotations[currentRotation]-24)); // send Note Off message for old note + if (parallel-24) midiSendNoteOff(noteValueCheck(activeNote + parallel-24)); // send Note Off message for old note + if (rotations[currentRotation]-24) midiSendNoteOff(noteValueCheck(activeNote + rotations[currentRotation]-24)); // send Note Off message for old note } if ((parallelChord || subOctaveDouble || rotatorOn) && !priority) { // poly playing, send old note off before new note on midiSendNoteOff(activeNote); // send Note Off message for old note @@ -851,10 +889,16 @@ void loop() { } } if (rotatorOn) { - midiSendNoteOn(noteValueCheck(fingeredNote + parallel-24), velocitySend); // send Note On message for new note + if (parallel-24) midiSendNoteOn(noteValueCheck(fingeredNote + parallel-24), velocitySend); // send Note On message for new note if (currentRotation < 3) currentRotation++; else currentRotation = 0; - midiSendNoteOn(noteValueCheck(fingeredNote + rotations[currentRotation]-24), velocitySend); // send Note On message for new note + int allCheck=4; + while ((0 == rotations[currentRotation]-24) && allCheck){ + if (currentRotation < 3) currentRotation++; + else currentRotation = 0; + allCheck--; + } + if (rotations[currentRotation]-24) midiSendNoteOn(noteValueCheck(fingeredNote + rotations[currentRotation]-24), velocitySend); // send Note On message for new note } if (!priority) { @@ -1445,16 +1489,61 @@ void readSwitches() { K6=RHp2; K7=RHp3; - pinkyKey = LHs; + pinkyKey = LHs || ((lpinky3==MOD) && LHp3); - int qTransp = (pinkyKey && (pinkySetting < 25)) ? pinkySetting-12 : 0; + int qTransp = ((pinkyKey && (pinkySetting < 25)) ? pinkySetting-12 : 0) + ((LHp3 && lpinky3) ? lpinky3-13 : 0); // Calculate midi note number from pressed keys - - //fingeredNote=startNote+1-2*LH1-(LHb && !(LH1 && LH2))-LH2-(LH2 && LH1)-2*LH3+LHp1-LHp2+(RHs && !LHp1)-RH1-(RH1 && LH3)-RH2-2*RH3+RHp1-RHp2-2*RHp3+octaveR*12+(octave-3)*12+transpose-12+qTransp; - fingeredNoteUntransposed=startNote+1-2*LH1-(LHb && !(LH1 && LH2))-LH2-(LH2 && LH1)-2*LH3+LHp1-LHp2+(RHs && !LHp1)-RH1-(RH1 && LH3)-RH2-2*RH3+RHp1-RHp2-2*RHp3+octaveR*12; + if (0==fingering){ //EWI standard fingering + //fingeredNote=startNote+1-2*LH1-(LHb && !(LH1 && LH2))-LH2-(LH2 && LH1)-2*LH3+LHp1-LHp2+(RHs && !LHp1)-RH1-(RH1 && LH3)-RH2-2*RH3+RHp1-RHp2-2*RHp3+octaveR*12+(octave-3)*12+transpose-12+qTransp; + + fingeredNoteUntransposed=startNote+1-2*LH1-(LHb && !(LH1 && LH2))-LH2-(LH2 && LH1)-2*LH3+LHp1-LHp2+(RHs && !LHp1)-RH1-(RH1 && LH3)-RH2-2*RH3+RHp1-RHp2-2*RHp3+octaveR*12; + } else if (1==fingering) { //EWX extended EWI fingering - lift LH1 for extended range up, touch RHp3 for extended range down + fingeredNoteUntransposed=startNote+1-2*LH1-(LHb && !(LH1 && LH2))-LH2-(LH2 && LH1)-2*LH3+LHp1-LHp2+(RHs && !LHp1)-RH1-(RH1 && LH3)-RH2-2*RH3+RHp1-RHp2-2*RHp3+9*(!LH1 && LH2 && LH3)-10*(!RH3 && RHp3)+octaveR*12; + } else if (2==fingering) { //Sax fingering + saxFinger[0] = LH1; + saxFinger[1] = LHb; + saxFinger[2] = LH2; + saxFinger[3] = LH3; + saxFinger[4] = LHp1; + saxFinger[5] = RH1; + saxFinger[6] = RH2; + saxFinger[7] = RH3; + saxFinger[8] = RHp1; + saxFinger[9] = RHp2; + saxFinger[10] = RHp3; + + byte matched = 0; + byte combo = 0; + + while (matched<11 && combo<17) + { + combo++; + matched = 0; + for (byte finger=0; finger < 11; finger++) + { + if ((saxFinger[finger] == saxFingerMatch[combo-1][finger]) || (saxFingerMatch[combo-1][finger] == 2)) matched++; + } + } + if (matched<11 && combo==17) fingeredNoteUntransposed=lastFingering; else fingeredNoteUntransposed = startNote+1+saxFingerResult[combo-1]-LHp2+RHs+octaveR*12; + } else if (3==fingering) { // EVI fingering + fingeredNoteUntransposed = startNote + - 2*RH1 - RH2 - 3*RH3 //"Trumpet valves" + - 5*LH1 //Fifth key + + 2*RHs + 4*RHp3 //Trill keys +2 and +4 + + (!LH2 || !LH3 || LHp2) // Trill +1 achieved by lifting finger from LH2 or LH3, or touching LHp2 + + octaveR*12; //Octave rollers + } else { // EVI fingering with reversed octave rollers + fingeredNoteUntransposed = startNote + - 2*RH1 - RH2 - 3*RH3 //"Trumpet valves" + - 5*LH1 //Fifth key + + 2*RHs + 4*RHp3 //Trill keys +2 and +4 + + (!LH2 || !LH3 || LHp2) // Trill +1 achieved by lifting finger from LH2 or LH3, or touching LHp2 + + (6-octaveR)*12; //Octave rollers, reversed + } + int fingeredNoteRead = fingeredNoteUntransposed + transpose - 12 + qTransp; if (pinkyKey) pitchlatch = fingeredNoteUntransposed; //use pitchlatch to make settings based on note fingered diff --git a/NuEVI/config.h b/NuEVI/config.h index a84f894..7446711 100644 --- a/NuEVI/config.h +++ b/NuEVI/config.h @@ -5,7 +5,7 @@ // Compile options, comment/uncomment to change -#define FIRMWARE_VERSION "1.4.4" // FIRMWARE VERSION NUMBER HERE <<<<<<<<<<<<<<<<<<<<<<< +#define FIRMWARE_VERSION "1.4.5" // FIRMWARE VERSION NUMBER HERE <<<<<<<<<<<<<<<<<<<<<<< #define ON_Delay 20 // Set Delay after ON threshold before velocity is checked (wait for tounging peak) #define CCN_Port 5 // Controller number for portamento level diff --git a/NuEVI/globals.h b/NuEVI/globals.h index 617c4b3..4500802 100644 --- a/NuEVI/globals.h +++ b/NuEVI/globals.h @@ -26,6 +26,9 @@ #define LVLP 28 #define GLD 29 +#define MOD 13 + + //Vibrato direction #define UPWD 1 #define DNWD 0 @@ -80,6 +83,8 @@ extern unsigned short fastPatch[7]; extern unsigned short extraCT2; // OFF:1-127 extern unsigned short levelCC; // 0-127 extern unsigned short levelVal; // 0-127 +extern unsigned short fingering; // 0-4 EWI,EWX,SAX,EVI,EVR +extern unsigned short lpinky3; // 0-25 (OFF, -12 - MOD - +12) extern uint16_t gateOpenEnable; extern uint16_t specialKeyEnable; extern byte rotatorOn; @@ -133,6 +138,28 @@ extern int breathLevel; extern byte portIsOn; extern int oldport; +#if defined(NURAD) + // Key variables, TRUE (1) for pressed, FALSE (0) for not pressed +extern byte LHs; +extern byte LH1; // Left Hand key 1 (pitch change -2) +extern byte LHb; // Left Hand bis key (pitch change -1 unless both LH1 and LH2 are pressed) +extern byte LH2; // Left Hand key 2 (with LH1 also pressed pitch change is -2, otherwise -1) +extern byte LH3; // Left Hand key 3 (pitch change -2) +extern byte LHp1; // Left Hand pinky key 1 (pitch change +1) +extern byte LHp2; // Left Hand pinky key 2 (pitch change -1) +extern byte LHp3; +extern byte RHs; // Right Hand side key (pitch change -2 unless LHp1 is pressed) +extern byte RH1; // Right Hand key 1 (with LH3 also pressed pitch change is -2, otherwise -1) +extern byte RH2; // Right Hand key 2 (pitch change -1) +extern byte RH3; // Right Hand key 3 (pitch change -2) +extern byte RHp1; // Right Hand pinky key 1 (pitch change +1) +extern byte RHp2; // Right Hand pinky key 2 (pitch change -1) +extern byte RHp3; // Right Hand pinky key 3 (pitch change -2) +extern byte Tr1; // Trill key 1 (pitch change +2) (EVI fingering) +extern byte Tr2; // Trill key 2 (pitch change +1) +extern byte Tr3; // Trill key 3 (pitch change +4) +#endif + // Key variables, TRUE (1) for pressed, FALSE (0) for not pressed extern byte K1; // Valve 1 (pitch change -2) extern byte K2; // Valve 2 (pitch change -1) diff --git a/NuEVI/hardware.h b/NuEVI/hardware.h index e777da1..a704660 100644 --- a/NuEVI/hardware.h +++ b/NuEVI/hardware.h @@ -2,7 +2,7 @@ #define __HARDWARE_H #define REVB -//#define NURAD +#define NURAD #if defined(NURAD) //NuRAD <<<<<<<<<<<<<<<<<<<<<<< diff --git a/NuEVI/menu.cpp b/NuEVI/menu.cpp index 4535af7..f9f237e 100644 --- a/NuEVI/menu.cpp +++ b/NuEVI/menu.cpp @@ -387,11 +387,19 @@ static void mainTitleGetStr(char* out) { strncpy(out, menuTitle, 22); } +#if defined(NURAD) +static void drawTrills(){ + if (LH1) display.fillRect(0,0,5,5,WHITE); else display.drawRect(0,0,5,5,WHITE); + if (LH2) display.fillRect(10,0,5,5,WHITE); else display.drawRect(10,0,5,5,WHITE); + if (LH3) display.fillRect(20,0,5,5,WHITE); else display.drawRect(20,0,5,5,WHITE); +} +#else static void drawTrills(){ if (K5) display.fillRect(0,0,5,5,WHITE); else display.drawRect(0,0,5,5,WHITE); if (K6) display.fillRect(10,0,5,5,WHITE); else display.drawRect(10,0,5,5,WHITE); if (K7) display.fillRect(20,0,5,5,WHITE); else display.drawRect(20,0,5,5,WHITE); } +#endif static void drawPatchView(){ display.clearDisplay(); @@ -437,11 +445,17 @@ void drawMenuCursor(byte itemNo, byte color){ //*********************************************************** +#if defined(NURAD) static int readTrills() { readSwitches(); - return K5+2*K6+trill3_interval*K7; + return LH1+2*LH2+4*LH3; } - +#else +static int readTrills() { + readSwitches(); + return K5+2*K6+4*K7; +} +#endif //*********************************************************** static void setFPS(int trills, uint16_t patchNum) { @@ -458,7 +472,97 @@ static void clearFPS(int trills) { FPD = 3; } + //*********************************************************** +// Rotator menu + +static void rotatorSave(const MenuEntrySub& __unused sub) { + int16_t stored; + for(int i = 0; i < 4; ++i) { + stored = readSetting(ROTN1_ADDR+2*i); + if(stored != rotations[i]) + writeSetting(ROTN1_ADDR+2*i,(rotations[i])); + } +} + +static void rotatorOptionGet(SubMenuRef sub, char *out, const char** __unused unit) { + numToString((*sub.valuePtr) - 24, out, true); +} + +static void parallelOptionGet(SubMenuRef __unused, char *out, const char** __unused unit) { + numToString(parallel-24, out, true); +} + +static void parallelSave(SubMenuRef __unused) { + writeSetting(PARAL_ADDR, parallel); +} + +const MenuEntrySub rotatorParaMenu = { + MenuType::ESub, "PARALLEL", "SEMITONES", ¶llel, 0, 48, MenuEntryFlags::ENone, + parallelOptionGet, parallelSave, nullptr +}; + +const MenuEntrySub rotator1Menu = { + MenuType::ESub, "ROTATE 1", "SEMITONES", &rotations[0], 0, 48, MenuEntryFlags::ENone, + rotatorOptionGet, rotatorSave, nullptr +}; + +const MenuEntrySub rotator2Menu = { + MenuType::ESub, "ROTATE 2", "SEMITONES", &rotations[1], 0, 48, MenuEntryFlags::ENone, + rotatorOptionGet, rotatorSave, nullptr +}; + +const MenuEntrySub rotator3Menu = { + MenuType::ESub, "ROTATE 3", "SEMITONES", &rotations[2], 0, 48, MenuEntryFlags::ENone, + rotatorOptionGet, rotatorSave, nullptr +}; + +const MenuEntrySub rotator4Menu = { + MenuType::ESub, "ROTATE 4", "SEMITONES", &rotations[3], 0, 48, MenuEntryFlags::ENone, + rotatorOptionGet, rotatorSave, nullptr +}; + +static void rotatorPrioOptionGet(SubMenuRef __unused, char* out, const char** __unused) { + if (priority) strncpy(out, "ROT", 4); + else strncpy(out, "MEL", 4); +} + +static void rotatorPrioSave(SubMenuRef __unused) { + writeSetting(PRIO_ADDR,priority); +} + +const MenuEntrySub rotatorPrioMenu = { + MenuType::ESub, "PRIORITY", "MONO PRIO", &priority, 0,1, MenuEntryFlags::EMenuEntryWrap, + rotatorPrioOptionGet, rotatorPrioSave, nullptr, +}; + +const MenuEntry* rotatorMenuEntries[] = { + (MenuEntry*)&rotatorParaMenu, + (MenuEntry*)&rotator1Menu, + (MenuEntry*)&rotator2Menu, + (MenuEntry*)&rotator3Menu, + (MenuEntry*)&rotator4Menu, + (MenuEntry*)&rotatorPrioMenu +}; +/* +const MenuPage rotatorMenuPage = { + "ROTATOR SETUP", + EMenuPageRoot, + CursorIdx::ERotator, + DISPLAYOFF_IDL, + ARR_LEN(rotatorMenuEntries), rotatorMenuEntries +}; +*/ +const MenuPage rotatorMenuPage = { + "ROTATOR SETUP", + 0, + CursorIdx::ERotator, + MAIN_MENU, + ARR_LEN(rotatorMenuEntries), rotatorMenuEntries +}; + +//*********************************************************** + // Main menu const MenuEntrySub transposeMenu = { MenuType::ESub, "TRANSPOSE", "TRANSPOSE", &transpose, 0, 24, MenuEntryFlags::ENone, @@ -655,6 +759,7 @@ const MenuEntrySub midiMenu = { const MenuEntryStateCh adjustMenu = { MenuType::EStateChange, "ADJUST", ADJUST_MENU }; const MenuEntryStateCh breathMenu = { MenuType::EStateChange, "SETUP BR", SETUP_BR_MENU }; const MenuEntryStateCh controlMenu = { MenuType::EStateChange, "SETUP CTL", SETUP_CT_MENU }; +const MenuEntryStateCh rotatorMenu = { MenuType::EStateChange, "ROTATOR", ROTATOR_MENU }; const MenuEntryStateCh extrasMenu = { MenuType::EStateChange, "EXTRAS", EXTRAS_MENU }; const MenuEntryStateCh aboutMenu = { MenuType::EStateChange, "ABOUT", ABOUT_MENU }; @@ -665,6 +770,7 @@ const MenuEntry* mainMenuEntries[] = { (MenuEntry*)&adjustMenu, (MenuEntry*)&breathMenu, (MenuEntry*)&controlMenu, + (MenuEntry*)&rotatorMenu, (MenuEntry*)&extrasMenu, (MenuEntry*)&aboutMenu, }; @@ -677,87 +783,7 @@ const MenuPage mainMenuPage = { ARR_LEN(mainMenuEntries), mainMenuEntries }; -//*********************************************************** -// Rotator menu -static void rotatorSave(const MenuEntrySub& __unused sub) { - int16_t stored; - for(int i = 0; i < 4; ++i) { - stored = readSetting(ROTN1_ADDR+2*i); - if(stored != rotations[i]) - writeSetting(ROTN1_ADDR+2*i,(rotations[i])); - } -} - -static void rotatorOptionGet(SubMenuRef sub, char *out, const char** __unused unit) { - numToString((*sub.valuePtr) - 24, out, true); -} - -static void parallelOptionGet(SubMenuRef __unused, char *out, const char** __unused unit) { - numToString(parallel-24, out, true); -} - -static void parallelSave(SubMenuRef __unused) { - writeSetting(PARAL_ADDR, parallel); -} - -const MenuEntrySub rotatorParaMenu = { - MenuType::ESub, "PARALLEL", "SEMITONES", ¶llel, 0, 48, MenuEntryFlags::ENone, - parallelOptionGet, parallelSave, nullptr -}; - -const MenuEntrySub rotator1Menu = { - MenuType::ESub, "ROTATE 1", "SEMITONES", &rotations[0], 0, 48, MenuEntryFlags::ENone, - rotatorOptionGet, rotatorSave, nullptr -}; - -const MenuEntrySub rotator2Menu = { - MenuType::ESub, "ROTATE 2", "SEMITONES", &rotations[1], 0, 48, MenuEntryFlags::ENone, - rotatorOptionGet, rotatorSave, nullptr -}; - -const MenuEntrySub rotator3Menu = { - MenuType::ESub, "ROTATE 3", "SEMITONES", &rotations[2], 0, 48, MenuEntryFlags::ENone, - rotatorOptionGet, rotatorSave, nullptr -}; - -const MenuEntrySub rotator4Menu = { - MenuType::ESub, "ROTATE 4", "SEMITONES", &rotations[3], 0, 48, MenuEntryFlags::ENone, - rotatorOptionGet, rotatorSave, nullptr -}; - -static void rotatorPrioOptionGet(SubMenuRef __unused, char* out, const char** __unused) { - if (priority) strncpy(out, "ROT", 4); - else strncpy(out, "MEL", 4); -} - -static void rotatorPrioSave(SubMenuRef __unused) { - writeSetting(PRIO_ADDR,priority); -} - -const MenuEntrySub rotatorPrioMenu = { - MenuType::ESub, "PRIORITY", "MONO PRIO", &priority, 0,1, MenuEntryFlags::EMenuEntryWrap, - rotatorPrioOptionGet, rotatorPrioSave, nullptr, -}; - -const MenuEntry* rotatorMenuEntries[] = { - (MenuEntry*)&rotatorParaMenu, - (MenuEntry*)&rotator1Menu, - (MenuEntry*)&rotator2Menu, - (MenuEntry*)&rotator3Menu, - (MenuEntry*)&rotator4Menu, - (MenuEntry*)&rotatorPrioMenu -}; - -const MenuPage rotatorMenuPage = { - "ROTATOR SETUP", - EMenuPageRoot, - CursorIdx::ERotator, - DISPLAYOFF_IDL, - ARR_LEN(rotatorMenuEntries), rotatorMenuEntries -}; - -//*********************************************************** // Breath menu const MenuEntrySub breathCCMenu = { MenuType::ESub, "BRTH CC1", "BRTH CC1", &breathCC, 0, 10, MenuEntryFlags::EMenuEntryWrap, @@ -986,16 +1012,55 @@ const MenuEntrySub lvlCtrlCCMenu = { , nullptr }; +const MenuEntrySub fingeringMenu = { + MenuType::ESub, "FINGERING", "FINGERING", &fingering, 0, 4, MenuEntryFlags::EMenuEntryWrap, + [](SubMenuRef __unused,char* out, const char ** __unused unit) { + const char* labs[] = { "EWI", "EWX", "SAX", "EVI", "EVR" }; + strncpy(out, labs[fingering], 4); + }, + [](SubMenuRef __unused sub) { writeSetting(FINGER_ADDR,fingering); } +}; + +const MenuEntrySub lpinky3Menu = { + MenuType::ESub, "EXTRA PKEY", "EXTRA PKEY", &lpinky3, 0, 25, MenuEntryFlags::ENone, + [](SubMenuRef __unused,char* textBuffer, const char** __unused unit) { + if (lpinky3 == 0) + strncpy(textBuffer, "OFF", 4); + else if (lpinky3 == MOD) + strncpy(textBuffer, "MOD", 4); + else + numToString(lpinky3-13, textBuffer, true); + }, + [](const MenuEntrySub & __unused sub) { writeSetting(LPINKY3_ADDR,lpinky3); } + , nullptr +}; + +#if defined(NURAD) const MenuEntry* controlMenuEntries[] = { (MenuEntry*)&portMenu, - (MenuEntry*)&pitchBendMenu, (MenuEntry*)&extraMenu, (MenuEntry*)&extraCC2Menu, (MenuEntry*)&vibratoSubMenu, (MenuEntry*)°litchMenu, (MenuEntry*)&pinkyMenu, - (MenuEntry*)&lvlCtrlCCMenu + (MenuEntry*)&lvlCtrlCCMenu, + (MenuEntry*)&lpinky3Menu, + (MenuEntry*)&fingeringMenu, + (MenuEntry*)&pitchBendMenu }; +#else +const MenuEntry* controlMenuEntries[] = { + (MenuEntry*)&portMenu, + (MenuEntry*)&extraMenu, + (MenuEntry*)&extraCC2Menu, + (MenuEntry*)&vibratoSubMenu, + (MenuEntry*)°litchMenu, + (MenuEntry*)&pinkyMenu, + (MenuEntry*)&lvlCtrlCCMenu, + (MenuEntry*)&pitchBendMenu +}; +#endif + const MenuPage controlMenuPage = { "SETUP CTRLS", @@ -1503,6 +1568,7 @@ static bool idlePageUpdate(KeyState& __unused input, uint32_t __unused timeNow) break; case BTN_MENU: + /* REMOVE ALL MODIFIER ENTRIES if (pinkyKey && (exSensor >= ((extracThrVal+extracMaxVal)/2)) && !specialKey) { // switch breath activated legacy settings on/off legacyBrAct = !legacyBrAct; dipSwBits = dipSwBits ^ (1<<2); @@ -1516,12 +1582,15 @@ static bool idlePageUpdate(KeyState& __unused input, uint32_t __unused timeNow) } else if (pinkyKey && !specialKey){ //hold pinky key for rotator menu, and if too high touch sensing blocks regular menu, touching special key helps display.ssd1306_command(SSD1306_DISPLAYON); menuState= ROTATOR_MENU; - stateFirstRun = 1; + stateFirstRun = 1; } else { display.ssd1306_command(SSD1306_DISPLAYON); menuState = MAIN_MENU; stateFirstRun = 1; - } + }*/ + display.ssd1306_command(SSD1306_DISPLAYON); + menuState = MAIN_MENU; + stateFirstRun = 1; break; case BTN_UP | BTN_DOWN | BTN_ENTER | BTN_MENU: diff --git a/NuEVI/settings.cpp b/NuEVI/settings.cpp index 8f2fb4c..ca0184b 100644 --- a/NuEVI/settings.cpp +++ b/NuEVI/settings.cpp @@ -109,6 +109,11 @@ void readEEPROM(const bool factoryReset) { writeSetting(LEVEL_CC_ADDR, LEVEL_CC_FACTORY); writeSetting(LEVEL_VAL_ADDR, LEVEL_VAL_FACTORY); } + + if(settingsVersion < 34) { + writeSetting(FINGER_ADDR, FINGER_FACTORY); + writeSetting(LPINKY3_ADDR, LPINKY3_FACTORY); + } writeSetting(VERSION_ADDR, EEPROM_VERSION); } @@ -167,6 +172,8 @@ void readEEPROM(const bool factoryReset) { extraCT2 = readSettingBounded(EXTRA2_ADDR, 0, 127, EXTRA2_FACTORY); levelCC = readSettingBounded(LEVEL_CC_ADDR, 0, 127, LEVEL_CC_FACTORY); levelVal = readSettingBounded(LEVEL_VAL_ADDR, 0, 127, LEVEL_VAL_FACTORY); + fingering = readSettingBounded(FINGER_ADDR, 0, 4, FINGER_FACTORY); + lpinky3 = readSettingBounded(LPINKY3_ADDR, 0, 25, LPINKY3_FACTORY); //Flags stored in bit field fastBoot = (dipSwBits & (1<