diff --git a/NuEVI/NuEVI.ino b/NuEVI/NuEVI.ino index e500075..c2ce486 100644 --- a/NuEVI/NuEVI.ino +++ b/NuEVI/NuEVI.ino @@ -95,7 +95,9 @@ unsigned short fingering; // 0-4 EWI,EWX,SAX,EVI,EVR unsigned short lpinky3; // 0-25 (OFF, -12 - MOD - +12) unsigned short batteryType; // 0-2 ALK,NIM,LIP unsigned short harmSetting; // 0-7 -unsigned short harmSelect; // 0-4 +unsigned short harmSelect; // 0-5 +unsigned short brHarmSetting; // 0-7 +unsigned short brHarmSelect; // 0-3 unsigned short polySelect; // OFF, MGR, MGD, MND, MNH, FWC, RTA, RTB or RTC unsigned short fwcType; // 6, m6, 7, m7 unsigned short fwcLockH; // OFF:ON @@ -221,6 +223,7 @@ int oldextrac=0; int oldextrac2=0; int harmonics = 0; +int brHarmonics = 0; int pitchBend=8192; int oldpb=8192; @@ -428,11 +431,18 @@ const int minHipHmz[12][3] = {{ -5, -9, -10 }, // C or key base { -4, -6, -9 }}; // B or base +11 -const int harmonicResult[5][7] = {{ 0, 7, 12, 16, 19, 24, 28 }, //HRM +const int harmonicResult[6][7] = {{ 0, 7, 12, 16, 19, 24, 28 }, //HM1 + { 0, 7, 12, 16, 19, 22, 24 }, //HM2 (7th harmonic not excluded) { 0, 7, 12, 19, 24, 31, 36 }, //5TH { 0, 12, 24, 36, 48, 60, 72 }, //OCT { 0, -5, -12, -17, -24, -29, -36 }, //5DN { 0, -12, -24, -36, -48, -60, -72 }}; //ODN + + +const int brHarmonicResult[4][7] = {{ 0, 7, 12, 16, 19, 24, 28 }, //HM1 + { 0, 7, 12, 16, 19, 22, 24 }, //HM2 (7th harmonic not excluded) + { 0, 7, 12, 19, 24, 31, 36 }, //5TH + { 0, 12, 24, 36, 48, 60, 72 }}; //OCT const int rollerHarmonic[2][7] = {{ 0, 7, 12, 16, 19, 24, 26 }, //F horn 2,3,4,5,6,8,9 hrm { 7, 12, 16, 19, 24, 26, 31 }}; //Bb horn 3,4,5,6,8,9,12 hrm @@ -1448,11 +1458,11 @@ void breath() { breathCCval = (breathCCvalHires >> 7) & 0x007F; breathCCvalFine = breathCCvalHires & 0x007F; breathCC2val = constrain(breathCCval*breathCC2Rise,0,127); - + if (brHarmSetting) brHarmonics = map(constrain(breathLevel, breathThrVal, breathMaxVal), breathThrVal, breathMaxVal, 0, brHarmSetting); else brHarmonics = 0; if (breathCCval != oldbreath) { // only send midi data if breath has changed from previous value if (breathCC) { // send midi cc - midiSendControlChange(ccList[breathCC], breathCCval); + midiSendControlChange(ccList[breathCC], breathCCval); } if (breathAT) { // send aftertouch @@ -1895,12 +1905,12 @@ void autoCal() { writeSetting(PITCHB_MAX_ADDR, pitchbMaxVal); // Lever calRead = 3000-touchRead(vibratoPin); - leverThrVal = constrain(calRead+70, leverLoLimit, leverHiLimit); - leverMaxVal = constrain(calRead+150, leverLoLimit, leverHiLimit); + leverThrVal = constrain(calRead+60, leverLoLimit, leverHiLimit); + leverMaxVal = constrain(calRead+120, leverLoLimit, leverHiLimit); writeSetting(LEVER_THR_ADDR, leverThrVal); writeSetting(LEVER_MAX_ADDR, leverMaxVal); #if defined(NURAD) // NuRAD sensor calibration - // Pressure sensor + // Bite Pressure sensor calRead = analogRead(bitePressurePin); portamThrVal = constrain(calRead+300, portamLoLimit, portamHiLimit); portamMaxVal = constrain(portamThrVal+600, portamLoLimit, portamHiLimit); @@ -2093,7 +2103,7 @@ void readSwitches() { + (6-octaveR)*12; //Octave rollers, reversed } - int fingeredNoteRead = fingeredNoteUntransposed + (octave - 3) * 12 + transpose - 12 + qTransp + harmonicResult[harmSelect][harmonics]; //lip sensor harmonics + int fingeredNoteRead = fingeredNoteUntransposed + (octave - 3) * 12 + transpose - 12 + qTransp + harmonicResult[harmSelect][harmonics] + brHarmonicResult[brHarmSelect][brHarmonics]; //lip sensor and breath harmonics if (pinkyKey) pitchlatch = fingeredNoteUntransposed; //use pitchlatch to make settings based on note fingered @@ -2171,7 +2181,7 @@ void readSwitches() { if (4 == trill3_interval) fingeredNoteUntransposed+=2; else fingeredNoteUntransposed+=4; } - int fingeredNoteRead = fingeredNoteUntransposed + (octave - 3) * 12 + transpose - 12 + qTransp + harmonicResult[harmSelect][harmonics]; //lip sensor harmonics + int fingeredNoteRead = fingeredNoteUntransposed + (octave - 3) * 12 + transpose - 12 + qTransp + harmonicResult[harmSelect][harmonics] + brHarmonicResult[brHarmSelect][brHarmonics]; //lip sensor harmonics pcCombo1 = (K1 && K5 && !K2 && !K3); pcCombo2 = (K2 && K6 && !K1 && !K3); diff --git a/NuEVI/adjustmenu.cpp b/NuEVI/adjustmenu.cpp index c4bd7e7..dc1a938 100644 --- a/NuEVI/adjustmenu.cpp +++ b/NuEVI/adjustmenu.cpp @@ -142,6 +142,114 @@ static const int numAdjustEntries = ARR_LEN(adjustMenuEntries); //*********************************************************** + + +void autoCalSelected() { + int calRead; + int calReadNext; +// NuRAD/NuEVI sensor calibration + // Extra Controller + if(adjustOption == 3) { + calRead = touchRead(extraPin); + extracThrVal = constrain(calRead+200, extracLoLimit, extracHiLimit); + extracMaxVal = constrain(extracThrVal+600, extracLoLimit, extracHiLimit); + writeSetting(EXTRAC_THR_ADDR, extracThrVal); + writeSetting(EXTRAC_MAX_ADDR, extracMaxVal); + } + // Breath sensor + if(adjustOption == 0) { + calRead = analogRead(breathSensorPin); + breathThrVal = constrain(calRead+200, breathLoLimit, breathHiLimit); + breathMaxVal = constrain(breathThrVal+2000, breathLoLimit, breathHiLimit); + writeSetting(BREATH_THR_ADDR, breathThrVal); + writeSetting(BREATH_MAX_ADDR, breathMaxVal); + } + // Pitch Bend + if(adjustOption == 2) { + calRead = touchRead(pbUpPin); + calReadNext = touchRead(pbDnPin); + if (calReadNext > calRead) calRead = calReadNext; //use highest value + pitchbThrVal = constrain(calRead+200, pitchbLoLimit, pitchbHiLimit); + pitchbMaxVal = constrain(pitchbThrVal+800, pitchbLoLimit, pitchbHiLimit); + writeSetting(PITCHB_THR_ADDR, pitchbThrVal); + writeSetting(PITCHB_MAX_ADDR, pitchbMaxVal); + } + // Lever + if(adjustOption == 5) { + calRead = 3000-touchRead(vibratoPin); + leverThrVal = constrain(calRead+60, leverLoLimit, leverHiLimit); + leverMaxVal = constrain(calRead+120, leverLoLimit, leverHiLimit); + writeSetting(LEVER_THR_ADDR, leverThrVal); + writeSetting(LEVER_MAX_ADDR, leverMaxVal); + } +#if defined(NURAD) // NuRAD sensor calibration + // Bite Pressure sensor + if(adjustOption == 1) { + calRead = analogRead(bitePressurePin); + portamThrVal = constrain(calRead+300, portamLoLimit, portamHiLimit); + portamMaxVal = constrain(portamThrVal+600, portamLoLimit, portamHiLimit); + writeSetting(PORTAM_THR_ADDR, portamThrVal); + writeSetting(PORTAM_MAX_ADDR, portamMaxVal); + } + // Touch sensors + if(adjustOption == 4) { + calRead = ctouchHiLimit; + for (byte i = 0; i < 6; i++) { + calReadNext = touchSensorRollers.filteredData(i) * (300-calOffsetRollers[i])/300; + if (calReadNext < calRead) calRead = calReadNext; //use lowest value + } + for (byte i = 0; i < 12; i++) { + calReadNext = touchSensorRH.filteredData(i) * (300-calOffsetRH[i])/300; + if (calReadNext < calRead) calRead = calReadNext; //use lowest value + } + for (byte i = 0; i < 12; i++) { + calReadNext = touchSensorLH.filteredData(i) * (300-calOffsetLH[i])/300; + if (calReadNext < calRead) calRead = calReadNext; //use lowest value + } + ctouchThrVal = constrain(calRead-20, ctouchLoLimit, ctouchHiLimit); + touch_Thr = map(ctouchThrVal,ctouchHiLimit,ctouchLoLimit,ttouchLoLimit,ttouchHiLimit); + writeSetting(CTOUCH_THR_ADDR, ctouchThrVal); + } +#else // NuEVI sensor calibration + // Bite sensor + if(adjustOption == 1) { + if (digitalRead(biteJumperPin)){ //PBITE (if pulled low with jumper, pressure sensor is used instead of capacitive bite sensing) + // Capacitive sensor + calRead = touchRead(bitePin); + portamThrVal = constrain(calRead+200, portamLoLimit, portamHiLimit); + portamMaxVal = constrain(portamThrVal+600, portamLoLimit, portamHiLimit); + writeSetting(PORTAM_THR_ADDR, portamThrVal); + writeSetting(PORTAM_MAX_ADDR, portamMaxVal); + } else { + // Pressure sensor + calRead = analogRead(bitePressurePin); + portamThrVal = constrain(calRead+300, portamLoLimit, portamHiLimit); + portamMaxVal = constrain(portamThrVal+600, portamLoLimit, portamHiLimit); + writeSetting(PORTAM_THR_ADDR, portamThrVal); + writeSetting(PORTAM_MAX_ADDR, portamMaxVal); + } + } + // Touch sensors + if(adjustOption == 4) { + calRead = ctouchHiLimit; + for (byte i = 0; i < 12; i++) { + calReadNext = touchSensor.filteredData(i); + if (calReadNext < calRead) calRead = calReadNext; //use lowest value + } + calReadNext=map(touchRead(halfPitchBendKeyPin),ttouchLoLimit,ttouchHiLimit,ctouchHiLimit,ctouchLoLimit); + if (calReadNext < calRead) calRead = calReadNext; //use lowest value + calReadNext=map(touchRead(specialKeyPin),ttouchLoLimit,ttouchHiLimit,ctouchHiLimit,ctouchLoLimit); + if (calReadNext < calRead) calRead = calReadNext; //use lowest value + ctouchThrVal = constrain(calRead-20, ctouchLoLimit, ctouchHiLimit); + touch_Thr = map(ctouchThrVal,ctouchHiLimit,ctouchLoLimit,ttouchLoLimit,ttouchHiLimit); + writeSetting(CTOUCH_THR_ADDR, ctouchThrVal); + } +#endif +} + + +//*********************************************************** + static void drawAdjCursor(byte color) { display.drawTriangle(16,4,20,4,18,1,color); display.drawTriangle(16,6,20,6,18,9,color); @@ -322,6 +430,7 @@ static bool drawAdjustBar(uint16_t buttons, int row, const AdjustValue* entry, u val -= step; updated = true; break; + } if(updated) { *entry->value = constrain(val, entry->limitLow, entry->limitHigh); @@ -346,7 +455,23 @@ static bool updateAdjustCursor(uint32_t timeNow) { static bool handleInput(const AdjustMenuEntry *currentMenu, uint32_t timeNow, uint8_t buttons, uint16_t *xpos, int ypos, int index) { if (buttons) { + if (buttons == BTN_DOWN+BTN_UP){ + display.fillRect(26,35,90,7,BLACK); + display.setTextSize(1); + display.setTextColor(WHITE); + display.setCursor(53,35); + display.println("AUTOCAL"); + display.display(); + delay(2000); + autoCalSelected(); + display.fillRect(26,35,90,7,BLACK); + display.display(); + drawAdjustMenu(currentMenu); + forcePix = 1; + plotSensorPixels(); + } else drawAdjustBar( buttons, ypos, ¤tMenu->entries[index], xpos ); + int last = adjustCurrent; if(buttons == BTN_ENTER) adjustCurrent += 1; else if( buttons == BTN_MENU) adjustCurrent = 0; diff --git a/NuEVI/config.h b/NuEVI/config.h index d390f45..7b70176 100644 --- a/NuEVI/config.h +++ b/NuEVI/config.h @@ -5,7 +5,7 @@ // Compile options, comment/uncomment to change -#define FIRMWARE_VERSION "1.5b2" // FIRMWARE VERSION NUMBER HERE <<<<<<<<<<<<<<<<<<<<<<< +#define FIRMWARE_VERSION "1.5b3" // 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 e77bb24..ee7f5a5 100644 --- a/NuEVI/globals.h +++ b/NuEVI/globals.h @@ -103,7 +103,9 @@ extern unsigned short fingering; // 0-4 EWI,EWX,SAX,EVI,EVR extern unsigned short lpinky3; // 0-25 (OFF, -12 - MOD - +12) extern unsigned short batteryType; // 0-2 ALK,NIM,LIP extern unsigned short harmSetting; // 0-7 -extern unsigned short harmSelect; // 0-4 +extern unsigned short harmSelect; // 0-5 +extern unsigned short brHarmSetting; // 0-7 +extern unsigned short brHarmSelect; // 0-3 extern unsigned short polySelect; // OFF, MGR, MGD, MND, MNH, FWC, RTA, RTB or RTC extern unsigned short fwcType; // 6, m6, 7, m7 extern unsigned short fwcLockH; // OFF:ON diff --git a/NuEVI/hardware.h b/NuEVI/hardware.h index a704660..e777da1 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 c90a432..cea21d1 100644 --- a/NuEVI/menu.cpp +++ b/NuEVI/menu.cpp @@ -1182,6 +1182,30 @@ const MenuEntrySub breathATMenu = { , nullptr }; +const MenuEntrySub brHarmonicsMenu = { + MenuType::ESub, "BRTH HARM", "HARM RANGE", &brHarmSetting, 0, 6, MenuEntryFlags::EMenuEntryWrap, + [](SubMenuRef __unused, char* out, const char** __unused unit) { + if(brHarmSetting) numToString(brHarmSetting, out); + else strncpy(out, "OFF", 4); + }, +[](const MenuEntrySub & __unused sub) { writeSetting(BRHARMSET_ADDR,brHarmSetting); } + , nullptr +}; + +const MenuEntrySub brHarmSelectMenu = { + MenuType::ESub, "BR HM SEL", "SERIES", &brHarmSelect, 0, 3, MenuEntryFlags::EMenuEntryWrap, + [](SubMenuRef __unused, char* out, const char** __unused unit) { + const char* brHarmSelectMenuLabels[] = { "HM1", "HM2", "5TH", "OCT" }; + strncpy(out, brHarmSelectMenuLabels[brHarmSelect], 4); + }, + [](const MenuEntrySub & __unused sub){ + if (readSetting(BRHARMSEL_ADDR) != brHarmSelect) { + writeSetting(BRHARMSEL_ADDR,brHarmSelect); + } + } + , nullptr +}; + const MenuEntrySub velocityMenu = { MenuType::ESub, "VELOCITY", "VELOCITY", &velocity, 0, 127, MenuEntryFlags::EMenuEntryWrap, [](SubMenuRef __unused, char* out, const char** __unused unit) { @@ -1254,7 +1278,9 @@ const MenuEntry* breathMenuEntries[] = { (MenuEntry*)&velocityMenu, (MenuEntry*)&curveMenu, (MenuEntry*)&velSmpDlMenu, - (MenuEntry*)&velBiasMenu, + (MenuEntry*)&velBiasMenu, + //(MenuEntry*)&brHarmonicsMenu, + //(MenuEntry*)&brHarmSelectMenu, (MenuEntry*)&breathIntervalMenu }; @@ -1334,9 +1360,9 @@ const MenuEntrySub harmonicsMenu = { }; const MenuEntrySub harmSelectMenu = { - MenuType::ESub, "HARM SEL", "SERIES", &harmSelect, 0, 4, MenuEntryFlags::EMenuEntryWrap, + MenuType::ESub, "HARM SEL", "SERIES", &harmSelect, 0, 5, MenuEntryFlags::EMenuEntryWrap, [](SubMenuRef __unused, char* out, const char** __unused unit) { - const char* harmSelectMenuLabels[] = { "HRM", "5TH", "OCT", "5DN", "ODN" }; + const char* harmSelectMenuLabels[] = { "HM1", "HM2", "5TH", "OCT", "5DN", "ODN" }; strncpy(out, harmSelectMenuLabels[harmSelect], 4); }, [](const MenuEntrySub & __unused sub){ diff --git a/NuEVI/settings.cpp b/NuEVI/settings.cpp index 2acad39..06453f0 100644 --- a/NuEVI/settings.cpp +++ b/NuEVI/settings.cpp @@ -157,6 +157,11 @@ void readEEPROM(const bool factoryReset) { writeSetting(LEVER_THR_ADDR, LEVER_THR_FACTORY); writeSetting(LEVER_MAX_ADDR, LEVER_MAX_FACTORY); } + + if(settingsVersion < 41) { + writeSetting(BRHARMSET_ADDR, BRHARMSET_FACTORY); + writeSetting(BRHARMSEL_ADDR, BRHARMSEL_FACTORY); + } writeSetting(VERSION_ADDR, EEPROM_VERSION); @@ -224,7 +229,7 @@ void readEEPROM(const bool factoryReset) { lpinky3 = readSettingBounded(LPINKY3_ADDR, 0, 25, LPINKY3_FACTORY); batteryType = readSettingBounded(BATTYPE_ADDR, 0, 2, BATTYPE_FACTORY); harmSetting = readSettingBounded(HARMSET_ADDR, 0, 6, HARMSET_FACTORY); - harmSelect = readSettingBounded(HARMSEL_ADDR, 0, 4, HARMSEL_FACTORY); + harmSelect = readSettingBounded(HARMSEL_ADDR, 0, 5, HARMSEL_FACTORY); polySelect = readSettingBounded(POLYSEL_ADDR, 0, 10, POLYSEL_FACTORY); fwcType = readSettingBounded(FWCTYPE_ADDR, 0, 4, FWCTYPE_FACTORY); fwcLockH = readSettingBounded(FWCLCH_ADDR, 0, 1, FWCLCH_FACTORY); @@ -246,7 +251,9 @@ void readEEPROM(const bool factoryReset) { portLimit = readSettingBounded(PORTLIMIT_ADDR, 1, 127, PORTLIMIT_FACTORY); leverThrVal = readSettingBounded(LEVER_THR_ADDR, leverLoLimit, leverHiLimit, LEVER_THR_FACTORY); leverMaxVal = readSettingBounded(LEVER_MAX_ADDR, leverLoLimit, leverHiLimit, LEVER_MAX_FACTORY); - + brHarmSetting = readSettingBounded(BRHARMSET_ADDR, 0, 6, BRHARMSET_FACTORY); + brHarmSelect = readSettingBounded(BRHARMSEL_ADDR, 0, 3, BRHARMSEL_FACTORY); + //Flags stored in bit field fastBoot = (dipSwBits & (1<