From fcf3bf2e17375bea4cac0ffd7dffc7dcf01f59a4 Mon Sep 17 00:00:00 2001 From: Johan Berglund Date: Tue, 20 Aug 2019 09:19:52 +0200 Subject: [PATCH 1/4] Adjust bite vibrato sensitivity range. --- NuEVI/NuEVI.ino | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/NuEVI/NuEVI.ino b/NuEVI/NuEVI.ino index 2f22029..50bfb81 100644 --- a/NuEVI/NuEVI.ino +++ b/NuEVI/NuEVI.ino @@ -818,6 +818,7 @@ void pitch_bend() { // handle input from pitchbend touchpads and // on-pcb variable capacitor for vibrato. int vibMax; + int vibMaxBite; int calculatedPBdepth; byte pbTouched = 0; int vibRead = 0; @@ -831,6 +832,7 @@ void pitch_bend() { vibMax = vibMaxList[vibSens - 1]; + vibMaxBite = vibMax*4; if (vibControl){ //bite vibrato if (biteJumper){ //PBITE (if pulled low with jumper, use pressure sensor instead of capacitive bite sensor) @@ -840,15 +842,15 @@ void pitch_bend() { } if (vibReadBite < vibThrBite) { if (UPWD == vibDirection) { - vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibReadBite, (vibZeroBite - vibMax), vibThrBite), vibThrBite, (vibZeroBite - vibMax), 0, calculatedPBdepth * vibDepth[vibrato]); + vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibReadBite, (vibZeroBite - vibMaxBite), vibThrBite), vibThrBite, (vibZeroBite - vibMaxBite), 0, calculatedPBdepth * vibDepth[vibrato]); } else { - vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibReadBite, (vibZeroBite - vibMax), vibThrBite), vibThrBite, (vibZeroBite - vibMax), 0, (0 - calculatedPBdepth * vibDepth[vibrato])); + vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibReadBite, (vibZeroBite - vibMaxBite), vibThrBite), vibThrBite, (vibZeroBite - vibMaxBite), 0, (0 - calculatedPBdepth * vibDepth[vibrato])); } } else if (vibReadBite > vibThrBiteLo) { if (UPWD == vibDirection) { - vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibReadBite, vibThrBiteLo, (vibZeroBite + vibMax)), vibThrBiteLo, (vibZeroBite + vibMax), 0, (0 - calculatedPBdepth * vibDepth[vibrato])); + vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibReadBite, vibThrBiteLo, (vibZeroBite + vibMaxBite)), vibThrBiteLo, (vibZeroBite + vibMaxBite), 0, (0 - calculatedPBdepth * vibDepth[vibrato])); } else { - vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibReadBite, vibThrBiteLo, (vibZeroBite + vibMax)), vibThrBiteLo, (vibZeroBite + vibMax), 0, calculatedPBdepth * vibDepth[vibrato]); + vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibReadBite, vibThrBiteLo, (vibZeroBite + vibMaxBite)), vibThrBiteLo, (vibZeroBite + vibMaxBite), 0, calculatedPBdepth * vibDepth[vibrato]); } } else { vibSignal = vibSignal * 0.5; From d5506ff2b9367162d0365d15f76d1ddc4c6cb20d Mon Sep 17 00:00:00 2001 From: Johan Berglund Date: Wed, 21 Aug 2019 08:44:22 +0200 Subject: [PATCH 2/4] Added secondary CC for extra controller and a Level CC control (stored), both with new settings for pinky key. New pinky settings: "EC2" sends on/off (127/0) for extra ctr CC2. "ECS" uses pinky key as switch between sending primary and secondary CC with extra controller. "LVL" lights up breath and portamento LEDs to indicate level (breath LED on full is max level, portamento LED full is min level), and level can be adjusted with K5 (up) and K1 (down). "LVP" is the same as "LVL", but with stored level transmitted at power up. --- NuEVI/NuEVI.ino | 99 +++++++++++++++++++++++++++++++++++++++------- NuEVI/globals.h | 10 ++++- NuEVI/led.cpp | 5 +++ NuEVI/led.h | 1 + NuEVI/menu.cpp | 34 +++++++++++++++- NuEVI/settings.cpp | 11 +++++- NuEVI/settings.h | 9 ++++- 7 files changed, 147 insertions(+), 22 deletions(-) diff --git a/NuEVI/NuEVI.ino b/NuEVI/NuEVI.ino index 50bfb81..21ff30c 100644 --- a/NuEVI/NuEVI.ino +++ b/NuEVI/NuEVI.ino @@ -66,10 +66,14 @@ unsigned short octave; unsigned short curve; unsigned short velSmpDl; // 0-30 ms unsigned short velBias; // 0-9 -unsigned short pinkySetting; // 0 - 11 (QuickTranspose -12 to -1), 12 (pb/2), 13 - 24 (QuickTranspose +1 to +12) +unsigned short pinkySetting; // 0 - 11 (QuickTranspose -12 to -1), 12 (pb/2), 13 - 24 (QuickTranspose +1 to +12), 25 (EC2), 26 (ECSW), 27 (LVL), 28 (LVLP) unsigned short dipSwBits; // virtual dip switch settings for special modes (work in progress) 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 vibSens = 2; // vibrato sensitivity unsigned short vibRetn = 2; // vibrato return speed unsigned short vibSquelch = 12; //vibrato signal squelch @@ -158,7 +162,7 @@ int targetPitch; int exSensor=0; byte extracIsOn=0; int oldextrac=0; -int lastEx=0; +int oldextrac2=0; int pitchBend=8192; int oldpb=8192; @@ -226,6 +230,7 @@ byte halfPitchBendKey; byte specialKey; byte pinkyKey; byte lastSpecialKey = 0; +byte lastPinkyKey = 0; byte pitchlatch; int reverb; @@ -317,6 +322,10 @@ void setup() { doPatchUpdate=1; } + if ((pinkySetting == LVLP) && levelCC){ + midiSendControlChange(levelCC, levelVal); + } + activeMIDIchannel = MIDIchannel; midiInitialize(MIDIchannel); @@ -507,6 +516,21 @@ void loop() { parallelChord = 0; subOctaveDouble = 0; } + if ((pinkySetting == LVL) || (pinkySetting == LVLP)){ + if (pinkyKey){ + ledMeter(levelVal); + if (K5 && (levelVal < 127)){ + levelVal++; + if (levelCC) midiSendControlChange(levelCC, levelVal); + } else if (K1 && (levelVal > 0)){ + levelVal--; + if (levelCC) midiSendControlChange(levelCC, levelVal); + } + } else if (lastPinkyKey){ + writeSetting(LEVEL_VAL_ADDR,levelVal); + } + lastPinkyKey = pinkyKey; + } } else if (mainState == RISE_WAIT) { if ((pressureSensor > breathThrVal) || gateOpen) { // Has enough time passed for us to collect our second @@ -684,7 +708,9 @@ void loop() { } else { if (slowMidi) breath(); extraController(); - updateSensorLEDs(); + if (((pinkySetting == LVL) || (pinkySetting == LVLP)) && pinkyKey){ + // show LVL indication + } else updateSensorLEDs(); doorKnobCheck(); } ccSendTime = millis(); @@ -970,60 +996,103 @@ void doorKnobCheck() { //*********************************************************** void extraController() { + bool CC2sw; + bool CC1sw; + int extracCC; // Extra Controller is the lip touch sensor (proportional) in front of the mouthpiece exSensor = exSensor * 0.6 + 0.4 * touchRead(extraPin); // get sensor data, do some smoothing - SENSOR PIN 16 - PCB PIN "EC" (marked K4 on some prototype boards) + if (pinkySetting == EC2){ + //send 0 or 127 on extra controller CC2 depending on pinky key touch + if (pinkyKey && extraCT2) { + if (lastPinkyKey != pinkyKey){ + midiSendControlChange(extraCT2, 127); + lastPinkyKey = pinkyKey; + } + } else { + if (lastPinkyKey != pinkyKey){ + midiSendControlChange(extraCT2, 0); + lastPinkyKey = pinkyKey; + } + } + } else if (pinkySetting == ECSW){ + if (pinkyKey){ + //send extra controller CC2 only + CC2sw = 1; + CC1sw = 0; + } else { + //send extra controller primary CC only + CC2sw = 0; + CC1sw = 1; + } + } else { + //send both primary CC and CC2 + CC2sw = 1; + CC1sw = 1; + } if (extraCT && (exSensor >= extracThrVal)) { // if we are enabled and over the threshold, send data if (!extracIsOn) { extracIsOn = 1; - if (extraCT == 4) { //Sustain ON + if ((extraCT == 4) && CC1sw) { //Sustain ON midiSendControlChange(64, 127); } } - if (extraCT == 1) { //Send modulation - int extracCC = map(constrain(exSensor, extracThrVal, extracMaxVal), extracThrVal, extracMaxVal, 1, 127); + if ((extraCT == 1) && CC1sw) { //Send modulation + extracCC = map(constrain(exSensor, extracThrVal, extracMaxVal), extracThrVal, extracMaxVal, 1, 127); if (extracCC != oldextrac) { midiSendControlChange(1, extracCC); } oldextrac = extracCC; } - if (extraCT == 2) { //Send foot pedal (CC#4) - int extracCC = map(constrain(exSensor, extracThrVal, extracMaxVal), extracThrVal, extracMaxVal, 1, 127); + if ((extraCT == 2) && CC1sw) { //Send foot pedal (CC#4) + extracCC = map(constrain(exSensor, extracThrVal, extracMaxVal), extracThrVal, extracMaxVal, 1, 127); if (extracCC != oldextrac) { midiSendControlChange(4, extracCC); } oldextrac = extracCC; } - if ((extraCT == 3) && (breathCC != 9)) { //Send filter cutoff (CC#74) - int extracCC = map(constrain(exSensor, extracThrVal, extracMaxVal), extracThrVal, extracMaxVal, 1, 127); + if ((extraCT == 3) && (breathCC != 9) && CC1sw) { //Send filter cutoff (CC#74) + extracCC = map(constrain(exSensor, extracThrVal, extracMaxVal), extracThrVal, extracMaxVal, 1, 127); if (extracCC != oldextrac) { midiSendControlChange(74, extracCC); } oldextrac = extracCC; } + if ((extraCT2 ) && CC2sw){ //Send extra controller CC2 + extracCC = map(constrain(exSensor, extracThrVal, extracMaxVal), extracThrVal, extracMaxVal, 1, 127); + if (extracCC != oldextrac2) { + midiSendControlChange(extraCT2, extracCC); + } + oldextrac2 = extracCC; + } } else if (extracIsOn) { // we have just gone below threshold, so send zero value extracIsOn = 0; - if (extraCT == 1) { //MW + if ((extraCT == 1) && CC1sw) { //MW if (oldextrac != 0) { //send modulation 0 midiSendControlChange(1, 0); oldextrac = 0; } - } else if (extraCT == 2) { //FP + } else if ((extraCT == 2) && CC1sw) { //FP if (oldextrac != 0) { //send foot pedal 0 midiSendControlChange(4, 0); oldextrac = 0; } - } else if ((extraCT == 3) && (breathCC != 9)) { //CF + } else if ((extraCT == 3) && (breathCC != 9) && CC1sw) { //CF if (oldextrac != 0) { //send filter cutoff 0 midiSendControlChange(74, 0); oldextrac = 0; } - } else if (extraCT == 4) { //SP + } else if ((extraCT == 4) && CC1sw) { //SP //send sustain off midiSendControlChange(64, 0); } + if ((extraCT2 ) && CC2sw){ //CC2 + //send 0 for extra ctr CC2 + midiSendControlChange(extraCT2, 0); + oldextrac2 = 0; + } } } @@ -1127,7 +1196,7 @@ void readSwitches() { pinkyKey = (touchRead(halfPitchBendKeyPin) > touch_Thr); // SENSOR PIN 1 - PCB PIN "S1" - int qTransp = pinkyKey ? pinkySetting-12 : 0; + int qTransp = (pinkyKey && (pinkySetting < 25)) ? pinkySetting-12 : 0; // Calculate midi note number from pressed keys diff --git a/NuEVI/globals.h b/NuEVI/globals.h index 03fabd6..bccf687 100644 --- a/NuEVI/globals.h +++ b/NuEVI/globals.h @@ -20,6 +20,10 @@ //Magic value where pinky button means "pitch bend" #define PBD 12 +#define EC2 25 +#define ECSW 26 +#define LVL 27 +#define LVLP 28 //Vibrato direction #define UPWD 1 @@ -55,7 +59,7 @@ extern unsigned short octave; extern unsigned short curve; extern unsigned short velSmpDl; // 0-30 ms extern unsigned short velBias; // 0-9 -extern unsigned short pinkySetting; // 0 - 11 (QuickTranspose -12 to -1), 12 (pb/2), 13 - 24 (QuickTranspose +1 to +12) +extern unsigned short pinkySetting; // 0 - 11 (QuickTranspose -12 to -1), 12 (pb/2), 13 - 24 (QuickTranspose +1 to +12), 25 (EC2), 26 (ECSW), 27 (LVL), 28 (LVLP) extern unsigned short dipSwBits; // virtual dip switch settings for special modes (work in progress) extern unsigned short priority; // mono priority for rotator chords extern unsigned short vibSens; // vibrato sensitivity @@ -66,6 +70,9 @@ extern unsigned short vibSensBite; // vibrato sensitivity (bite) extern unsigned short vibSquelchBite; //vibrato signal squelch (bite) extern unsigned short vibControl; 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 uint16_t gateOpenEnable; extern uint16_t specialKeyEnable; extern byte rotatorOn; @@ -99,7 +106,6 @@ extern int lastBite; extern byte biteJumper; extern int exSensor; -extern int lastEx; extern int pitchBend; diff --git a/NuEVI/led.cpp b/NuEVI/led.cpp index 2412388..092af37 100644 --- a/NuEVI/led.cpp +++ b/NuEVI/led.cpp @@ -46,3 +46,8 @@ void updateSensorLEDs() { analogWrite(pLedPin, 0); } } + +void ledMeter(byte indicatedValue){ + analogWrite(bLedPin, map(constrain(indicatedValue, 0, 127), 0, 127, 0, BREATH_LED_BRIGHTNESS)); // full glow at maximum value + analogWrite(pLedPin, map(constrain(indicatedValue, 0, 127), 127, 0, 0, PORTAM_LED_BRIGHTNESS)); // full glow at minimum value +} diff --git a/NuEVI/led.h b/NuEVI/led.h index 4b43241..a5ccaa8 100644 --- a/NuEVI/led.h +++ b/NuEVI/led.h @@ -8,5 +8,6 @@ void statusLed(bool state); void statusLedFlash(uint16_t delayTime); void statusLedBlink(); void updateSensorLEDs(); +void ledMeter(byte indicatedValue); #endif diff --git a/NuEVI/menu.cpp b/NuEVI/menu.cpp index 5788e68..328ce2c 100644 --- a/NuEVI/menu.cpp +++ b/NuEVI/menu.cpp @@ -840,6 +840,16 @@ const MenuEntrySub extraMenu = { , nullptr }; +const MenuEntrySub extraCC2Menu = { + MenuType::ESub, "EXCTR CC2", "EXCTR CC2", &extraCT2, 0, 127, MenuEntryFlags::EMenuEntryWrap, + [](SubMenuRef __unused, char* out, const char** __unused unit) { + if(extraCT2) numToString(extraCT2, out); + else strncpy(out, "OFF", 4); + }, +[](const MenuEntrySub & __unused sub) { writeSetting(EXTRA2_ADDR,extraCT2); } + , nullptr +}; + const MenuEntryStateCh vibratoSubMenu = { MenuType::EStateChange, "VIBRATO", VIBRATO_MENU }; const MenuEntrySub deglitchMenu = { @@ -856,10 +866,18 @@ const MenuEntrySub deglitchMenu = { }; const MenuEntrySub pinkyMenu = { - MenuType::ESub, "PINKY KEY", "PINKY KEY", &pinkySetting, 0, 24, MenuEntryFlags::ENone, + MenuType::ESub, "PINKY KEY", "PINKY KEY", &pinkySetting, 0, 28, MenuEntryFlags::ENone, [](SubMenuRef __unused,char* textBuffer, const char** __unused unit) { if (pinkySetting == PBD) strncpy(textBuffer, "PBD", 4); + else if (pinkySetting == EC2) + strncpy(textBuffer, "EC2", 4); + else if (pinkySetting == ECSW) + strncpy(textBuffer, "ECS", 4); + else if (pinkySetting == LVL) + strncpy(textBuffer, "LVL", 4); + else if (pinkySetting == LVLP) + strncpy(textBuffer, "LVP", 4); else numToString(pinkySetting-12, textBuffer, true); }, @@ -867,13 +885,25 @@ const MenuEntrySub pinkyMenu = { , nullptr }; +const MenuEntrySub lvlCtrlCCMenu = { + MenuType::ESub, "LEVEL CC", "LEVEL CC", &levelCC, 0, 127, MenuEntryFlags::EMenuEntryWrap, + [](SubMenuRef __unused, char* out, const char** __unused unit) { + if(levelCC) numToString(levelCC, out); + else strncpy(out, "OFF", 4); + }, +[](const MenuEntrySub & __unused sub) { writeSetting(LEVEL_CC_ADDR,levelCC); } + , nullptr +}; + const MenuEntry* controlMenuEntries[] = { (MenuEntry*)&portMenu, (MenuEntry*)&pitchBendMenu, (MenuEntry*)&extraMenu, + (MenuEntry*)&extraCC2Menu, (MenuEntry*)&vibratoSubMenu, (MenuEntry*)°litchMenu, - (MenuEntry*)&pinkyMenu + (MenuEntry*)&pinkyMenu, + (MenuEntry*)&lvlCtrlCCMenu }; const MenuPage controlMenuPage = { diff --git a/NuEVI/settings.cpp b/NuEVI/settings.cpp index 913e06f..d8b3195 100644 --- a/NuEVI/settings.cpp +++ b/NuEVI/settings.cpp @@ -96,6 +96,12 @@ void readEEPROM() { writeSetting(DAC_MODE_ADDR, DAC_MODE_FACTORY); } + if(settingsVersion < 33) { + writeSetting(EXTRA2_ADDR, EXTRA2_FACTORY); + writeSetting(LEVEL_CC_ADDR, LEVEL_CC_FACTORY); + writeSetting(LEVEL_VAL_ADDR, LEVEL_VAL_FACTORY); + } + writeSetting(VERSION_ADDR, EEPROM_VERSION); } @@ -124,7 +130,7 @@ void readEEPROM() { curve = readSettingBounded(BREATHCURVE_ADDR, 0, 12, BREATHCURVE_FACTORY); velSmpDl = readSettingBounded(VEL_SMP_DL_ADDR, 0, 30, VEL_SMP_DL_FACTORY); velBias = readSettingBounded(VEL_BIAS_ADDR, 0, 9, VEL_BIAS_FACTORY); - pinkySetting = readSettingBounded(PINKY_KEY_ADDR, 0, 24, PINKY_KEY_FACTORY); + pinkySetting = readSettingBounded(PINKY_KEY_ADDR, 0, 28, PINKY_KEY_FACTORY); fastPatch[0] = readSettingBounded(FP1_ADDR, 0, 127, 0); fastPatch[1] = readSettingBounded(FP2_ADDR, 0, 127, 0); fastPatch[2] = readSettingBounded(FP3_ADDR, 0, 127, 0); @@ -150,6 +156,9 @@ void readEEPROM() { vibControl = readSettingBounded(VIB_CONTROL_ADDR, 0, 1, VIB_CONTROL_FACTORY); dacMode = readSettingBounded(DAC_MODE_ADDR, DAC_MODE_BREATH, DAC_MODE_PITCH, DAC_MODE_FACTORY); trill3_interval = readSettingBounded(TRILL3_INTERVAL_ADDR, 3, 4, TRILL3_INTERVAL_FACTORY); + 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); //Flags stored in bit field fastBoot = (dipSwBits & (1< Date: Wed, 21 Aug 2019 18:33:09 +0200 Subject: [PATCH 3/4] Added AT (aftertouch) instead of OFF for Level control. --- NuEVI/NuEVI.ino | 2 ++ NuEVI/menu.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/NuEVI/NuEVI.ino b/NuEVI/NuEVI.ino index 21ff30c..720452e 100644 --- a/NuEVI/NuEVI.ino +++ b/NuEVI/NuEVI.ino @@ -522,9 +522,11 @@ void loop() { if (K5 && (levelVal < 127)){ levelVal++; if (levelCC) midiSendControlChange(levelCC, levelVal); + else midiSendAfterTouch(levelVal); } else if (K1 && (levelVal > 0)){ levelVal--; if (levelCC) midiSendControlChange(levelCC, levelVal); + else midiSendAfterTouch(levelVal); } } else if (lastPinkyKey){ writeSetting(LEVEL_VAL_ADDR,levelVal); diff --git a/NuEVI/menu.cpp b/NuEVI/menu.cpp index 328ce2c..3f65e41 100644 --- a/NuEVI/menu.cpp +++ b/NuEVI/menu.cpp @@ -889,7 +889,7 @@ const MenuEntrySub lvlCtrlCCMenu = { MenuType::ESub, "LEVEL CC", "LEVEL CC", &levelCC, 0, 127, MenuEntryFlags::EMenuEntryWrap, [](SubMenuRef __unused, char* out, const char** __unused unit) { if(levelCC) numToString(levelCC, out); - else strncpy(out, "OFF", 4); + else strncpy(out, "AT", 4); }, [](const MenuEntrySub & __unused sub) { writeSetting(LEVEL_CC_ADDR,levelCC); } , nullptr From bab51190e15d4a985cd993ef14fabe6ea574b6b0 Mon Sep 17 00:00:00 2001 From: Johan Berglund Date: Sun, 25 Aug 2019 12:38:02 +0200 Subject: [PATCH 4/4] Fix for bite vibrato sensitivity. Added increased range of sensitivity settings. Added possibility to use both bite and lever for vibrato at the same time. Separate timing interval for breath (trying to get speed up again). Moved Teensy touch sense calls for pinky key and special key to function less often called (every standard CC interval). Changed menu name VEL BIAS to VEL BOOST which is a more accurate description. --- NuEVI/NuEVI.ino | 59 +++++++++++++++++++++++++++------------------- NuEVI/config.h | 5 ++-- NuEVI/menu.cpp | 10 ++++---- NuEVI/settings.cpp | 4 ++-- NuEVI/settings.h | 2 +- 5 files changed, 47 insertions(+), 33 deletions(-) diff --git a/NuEVI/NuEVI.ino b/NuEVI/NuEVI.ino index 720452e..5e86363 100644 --- a/NuEVI/NuEVI.ino +++ b/NuEVI/NuEVI.ino @@ -114,6 +114,7 @@ static const unsigned long pixelUpdateInterval = 80; unsigned long lastDeglitchTime = 0; // The last time the fingering was changed unsigned long ccSendTime = 0L; // The last time we sent CC values +unsigned long ccBreathSendTime = 0L; // The last time we sent breath CC values unsigned long breath_on_time = 0L; // Time when breath sensor value went over the ON threshold int lastFingering = 0; // Keep the last fingering value for debouncing @@ -173,6 +174,7 @@ byte vibLedOff = 0; byte oldpkey = 0; static const float vibDepth[10] = {0,0.05,0.1,0.15,0.2,0.25,0.3,0.35,0.40,0.45}; // max pitch bend values (+/-) for the vibrato settings +static const short vibMaxBiteList[17] = {1600,1400,1200,1000,900,800,700,600,500,400,300,250,200,150,100,50,25}; static const short vibMaxList[12] = {300,275,250,225,200,175,150,125,100,75,50,25}; static const unsigned short curveM4[] = {0,4300,7000,8700,9900,10950,11900,12600,13300,13900,14500,15000,15450,15700,16000,16250,16383}; @@ -467,9 +469,7 @@ void loop() { } if (analogRead(breathSensorPin) > (breathCalZero - 800)) programonce = false; - - if (specialKeyEnable) { - specialKey = (touchRead(specialKeyPin) > touch_Thr); //S2 on pcb + if (specialKeyEnable) { if (lastSpecialKey != specialKey) { if (specialKey) { // special key just pressed, check other keys @@ -700,21 +700,20 @@ void loop() { if (pressureSensor > breathThrVal) cursorBlinkTime = millis(); // keep display from updating with cursor blinking if breath is over thr } // Is it time to send more CC data? + if (millis() - ccBreathSendTime > (CC_BREATH_INTERVAL*(slowMidi+1))){ + breath(); + ccBreathSendTime = millis(); + } if (millis() - ccSendTime > CC_INTERVAL) { - // deal with Breath, Pitch Bend, Modulation, etc. - if (!slowMidi) breath(); - halfTime = !halfTime; - if (halfTime) { - pitch_bend(); - portamento_(); - } else { - if (slowMidi) breath(); - extraController(); - if (((pinkySetting == LVL) || (pinkySetting == LVLP)) && pinkyKey){ - // show LVL indication - } else updateSensorLEDs(); - doorKnobCheck(); - } + // deal with Pitch Bend, Modulation, etc. + pitch_bend(); + portamento_(); + extraController(); + readTeensySwitches(); + if (((pinkySetting == LVL) || (pinkySetting == LVLP)) && pinkyKey){ + // show LVL indication + } else updateSensorLEDs(); + doorKnobCheck(); ccSendTime = millis(); } if (millis() - pixelUpdateTime > pixelUpdateInterval) { @@ -860,7 +859,7 @@ void pitch_bend() { vibMax = vibMaxList[vibSens - 1]; - vibMaxBite = vibMax*4; + vibMaxBite = vibMaxBiteList[vibSensBite - 1]; if (vibControl){ //bite vibrato if (biteJumper){ //PBITE (if pulled low with jumper, use pressure sensor instead of capacitive bite sensor) @@ -883,7 +882,8 @@ void pitch_bend() { } else { vibSignal = vibSignal * 0.5; } - } else { //lever vibrato + } + if (vibControl != 1) { //lever vibrato vibRead = touchRead(vibratoPin); // SENSOR PIN 15 - built in var cap if (vibRead < vibThr) { if (UPWD == vibDirection) { @@ -1102,12 +1102,12 @@ void extraController() { void portamento_() { - if (biteJumper){ //PBITE (if pulled low with jumper, use pressure sensor instead of capacitive bite sensor) + if (biteJumper) { //PBITE (if pulled low with jumper, use pressure sensor instead of capacitive bite sensor) biteSensor=analogRead(bitePressurePin); // alternative kind bite sensor (air pressure tube and sensor) PBITE } else { biteSensor = touchRead(bitePin); // get sensor data, do some smoothing - SENSOR PIN 17 - PCB PINS LABELED "BITE" (GND left, sensor pin right) } - if (!vibControl){ + if (0 == vibControl) { // Portamento is controlled with the bite sensor (variable capacitor) in the mouthpiece if (portamento && (biteSensor >= portamThrVal)) { // if we are enabled and over the threshold, send portamento if (!portIsOn) { @@ -1117,7 +1117,8 @@ void portamento_() { } else if (portIsOn) { // we have just gone below threshold, so send zero value portOff(); } - } else { + } else if (1 == vibControl) { + // Portamento is switched to lever control leverPortRead = touchRead(vibratoPin); if (portamento && (leverPortRead <= (leverPortZero-leverPortThr))) { // if we are enabled and over the threshold, send portamento if (!portIsOn) { @@ -1127,6 +1128,10 @@ void portamento_() { } else if (portIsOn) { // we have just gone below threshold, so send zero value portOff(); } + } else { + // no control for portamento + if (portIsOn) + portOff(); } } @@ -1143,7 +1148,7 @@ void portOn() { void port() { int portCC; - if (!vibControl) + if (1 != vibControl) portCC = map(constrain(biteSensor, portamThrVal, portamMaxVal), portamThrVal, portamMaxVal, 0, 127); else portCC = constrain((leverPortZero-leverPortThr-leverPortRead),0,127); @@ -1168,6 +1173,12 @@ void portOff() { //*********************************************************** + +void readTeensySwitches() { //these seem to slow things down, so do it less often + pinkyKey = (touchRead(halfPitchBendKeyPin) > touch_Thr); // SENSOR PIN 1 - PCB PIN "S1" + specialKey = (touchRead(specialKeyPin) > touch_Thr); //S2 on pcb +} + void readSwitches() { // Read touch pads (MPR121), compare against threshold value @@ -1196,7 +1207,7 @@ void readSwitches() { K6 = touchKeys[K6Pin]; K7 = touchKeys[K7Pin]; - pinkyKey = (touchRead(halfPitchBendKeyPin) > touch_Thr); // SENSOR PIN 1 - PCB PIN "S1" + int qTransp = (pinkyKey && (pinkySetting < 25)) ? pinkySetting-12 : 0; diff --git a/NuEVI/config.h b/NuEVI/config.h index 84520ea..059dd93 100644 --- a/NuEVI/config.h +++ b/NuEVI/config.h @@ -11,9 +11,10 @@ #define CCN_Port 5 // Controller number for portamento level #define CCN_PortOnOff 65// Controller number for portamento on/off -// Send breath CC data no more than every CC_INTERVAL (other CC is sent with double interval) +// Send breath CC data no more than every CC_BREATH_INTERVAL // milliseconds (due to timing errors, the value should be about half the actual wanted value) -#define CC_INTERVAL 2 +#define CC_BREATH_INTERVAL 1 +#define CC_INTERVAL 10 #define breathLoLimit 0 diff --git a/NuEVI/menu.cpp b/NuEVI/menu.cpp index 3f65e41..d285352 100644 --- a/NuEVI/menu.cpp +++ b/NuEVI/menu.cpp @@ -777,7 +777,7 @@ const MenuEntrySub velSmpDlMenu = { }; const MenuEntrySub velBiasMenu = { - MenuType::ESub, "VEL BIAS", "VEL BIAS", &velBias, 0, 9, MenuEntryFlags::EMenuEntryWrap, + MenuType::ESub, "VEL BOOST", "VEL BOOST", &velBias, 0, 9, MenuEntryFlags::EMenuEntryWrap, [](SubMenuRef __unused, char* out, const char** __unused unit) { if (velBias) numToString(velBias, out); else strncpy(out, "OFF", 4); @@ -964,7 +964,7 @@ const MenuEntrySub vibSquelchMenu = { }; const MenuEntrySub vibSenseBiteMenu = { - MenuType::ESub, "SENSE BTE", "LEVEL", &vibSensBite, 1, 12, MenuEntryFlags::ENone, + MenuType::ESub, "SENSE BTE", "LEVEL", &vibSensBite, 1, 17, MenuEntryFlags::ENone, [](SubMenuRef __unused,char* textBuffer, const char** __unused unit) { numToString(vibSensBite, textBuffer); }, @@ -982,9 +982,11 @@ const MenuEntrySub vibSquelchBiteMenu = { }; const MenuEntrySub vibControlMenu = { - MenuType::ESub, "CONTROL", "CONTROL", &vibControl , 0, 1, MenuEntryFlags::EMenuEntryWrap, + MenuType::ESub, "CONTROL", "CONTROL", &vibControl , 0, 2, MenuEntryFlags::EMenuEntryWrap, [](SubMenuRef __unused, char* out, const char** __unused unit) { - if (vibControl) + if (2 == vibControl) + strncpy(out, "BTH", 4); + else if (1 == vibControl) strncpy(out, "BIT", 4); else strncpy(out, "LVR", 4); diff --git a/NuEVI/settings.cpp b/NuEVI/settings.cpp index d8b3195..e83eeac 100644 --- a/NuEVI/settings.cpp +++ b/NuEVI/settings.cpp @@ -151,9 +151,9 @@ void readEEPROM() { vibDirection = readSettingBounded(VIB_DIRECTION_ADDR, 0, 1, VIB_DIRECTION_FACTORY); breathCC2 = readSettingBounded(BREATH_CC2_ADDR, 0, 127, BREATH_CC2_FACTORY); breathCC2Rise = readSettingBounded(BREATH_CC2_RISE_ADDR, 1, 10, BREATH_CC2_RISE_FACTORY); - vibSensBite = readSettingBounded(VIB_SENS_BITE_ADDR, 1, 12, VIB_SENS_BITE_FACTORY); + vibSensBite = readSettingBounded(VIB_SENS_BITE_ADDR, 1, 17, VIB_SENS_BITE_FACTORY); vibSquelchBite = readSettingBounded(VIB_SQUELCH_BITE_ADDR, 1, 30, VIB_SQUELCH_BITE_FACTORY); - vibControl = readSettingBounded(VIB_CONTROL_ADDR, 0, 1, VIB_CONTROL_FACTORY); + vibControl = readSettingBounded(VIB_CONTROL_ADDR, 0, 2, VIB_CONTROL_FACTORY); dacMode = readSettingBounded(DAC_MODE_ADDR, DAC_MODE_BREATH, DAC_MODE_PITCH, DAC_MODE_FACTORY); trill3_interval = readSettingBounded(TRILL3_INTERVAL_ADDR, 3, 4, TRILL3_INTERVAL_FACTORY); extraCT2 = readSettingBounded(EXTRA2_ADDR, 0, 127, EXTRA2_FACTORY); diff --git a/NuEVI/settings.h b/NuEVI/settings.h index 36f0141..2aed720 100644 --- a/NuEVI/settings.h +++ b/NuEVI/settings.h @@ -120,7 +120,7 @@ #define VIB_SQUELCH_BITE_FACTORY 10 #define VIB_CONTROL_FACTORY 0 #define TRILL3_INTERVAL_FACTORY 4 -#define DAC_MODE_FACTORY DAC_MODE_BREATH +#define DAC_MODE_FACTORY DAC_MODE_PITCH #define EXTRA2_FACTORY 0 #define LEVEL_CC_FACTORY 11 #define LEVEL_VAL_FACTORY 127