Added fingerings for NuRAD - SAX, EVI, EVR and EWX. Added setting for extra pinky key (NuRAD). Fix for quickpatch function (NuEVI/NuRAD). Rotator menu moved to main menu (NuEVI/NuRAD). Activation of legacy patch selection and settings now only done in extras menu. Changed zero setting in rotator to set rotators off and move on to next one (you can now rotate between 2-4 notes or set to static chord or interval). Changed order of some menu items.

This commit is contained in:
Johan Berglund 2020-03-17 13:31:34 +01:00
parent 7eccf7eeec
commit 0f65c0d3d8
7 changed files with 301 additions and 104 deletions

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -2,7 +2,7 @@
#define __HARDWARE_H
#define REVB
//#define NURAD
#define NURAD
#if defined(NURAD) //NuRAD <<<<<<<<<<<<<<<<<<<<<<<

View file

@ -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", &parallel, 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", &parallel, 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*)&deglitchMenu,
(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*)&deglitchMenu,
(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:

View file

@ -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<<DIPSW_FASTBOOT))?1:0;

View file

@ -58,8 +58,11 @@
#define EXTRA2_ADDR 102
#define LEVEL_CC_ADDR 104
#define LEVEL_VAL_ADDR 106
#define FINGER_ADDR 108
#define LPINKY3_ADDR 110
#define EEPROM_SIZE 102
#define EEPROM_SIZE 112
//DAC output modes
@ -76,7 +79,7 @@
//"factory" values for settings
#define EEPROM_VERSION 33
#define EEPROM_VERSION 34
#define BREATH_THR_FACTORY 1400
#define BREATH_MAX_FACTORY 4000
#define PORTAM_THR_FACTORY 2600
@ -125,6 +128,8 @@
#define EXTRA2_FACTORY 0
#define LEVEL_CC_FACTORY 11
#define LEVEL_VAL_FACTORY 127
#define FINGER_FACTORY 0
#define LPINKY3_FACTORY 0
#define NO_CHECKSUM 0x7F007F00