From 27071c44bd231a4507476fad1cbe970984515a43 Mon Sep 17 00:00:00 2001 From: Johan Berglund Date: Sat, 20 Feb 2021 15:35:01 +0100 Subject: [PATCH] =?UTF-8?q?*=20Added=20three=20new=20settings=20in=20EXTRA?= =?UTF-8?q?S=20MENU=20=E2=80=93=20CV=20TUNE,=20CV=20SCALE=20and=20CV=20EC?= =?UTF-8?q?=20LFO.=20The=20first=20two=20allow=20for=20software=20tuning?= =?UTF-8?q?=20of=20the=20CV=20output=20for=201V/Oct=20when=20using=20NuEVI?= =?UTF-8?q?=20CV,=20NuEVI=20Plus=20or=20NuEVI/NuRAD=20with=20external=20CV?= =?UTF-8?q?=20box=20or=20module.=20Also=20makes=20more=20simple=20versions?= =?UTF-8?q?=20of=20the=20CV=20boards=20possible=20(no=20potentiometers=20f?= =?UTF-8?q?or=20adjustment).=20The=20CV=20EC=20LFO=20setting=20controls=20?= =?UTF-8?q?a=20new=20CV=20LFO=20vibrato=20function=20for=20the=20extra=20c?= =?UTF-8?q?ontroller=20(lip=20sensor).=20It=20can=20be=20set=20to=20OFF=20?= =?UTF-8?q?(no=20extra=20controller=20LFO=20vibrato)=20or=20values=201=20t?= =?UTF-8?q?hrough=208,=20which=20represent=20vibrato=20freq=20from=204.5Hz?= =?UTF-8?q?=20to=208Hz.=20Default=20value=20is=203=20(5.5Hz).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- NuEVI/NuEVI.ino | 126 +- NuEVI/config.h | 3 +- NuEVI/globals.h | 3 + NuEVI/menu.cpp | 37 + NuEVI/settings.cpp | 11 + NuEVI/settings.h | 10 +- uploadable hex files/NuEVI-v15b7.ino.hex | 5656 ++++++++++++++++ uploadable hex files/NuRAD-v15b7.ino.hex | 5769 +++++++++++++++++ .../{notes 1.5b6.txt => notes 1.5b7.txt} | 6 +- 9 files changed, 11520 insertions(+), 101 deletions(-) create mode 100644 uploadable hex files/NuEVI-v15b7.ino.hex create mode 100644 uploadable hex files/NuRAD-v15b7.ino.hex rename user guides/{notes 1.5b6.txt => notes 1.5b7.txt} (87%) diff --git a/NuEVI/NuEVI.ino b/NuEVI/NuEVI.ino index ce52779..c0899e6 100644 --- a/NuEVI/NuEVI.ino +++ b/NuEVI/NuEVI.ino @@ -119,6 +119,10 @@ unsigned short leverControl = 0; // OFF, VIB, GLD, CC unsigned short biteCC = 0; // 0 - 127 unsigned short leverCC = 0; // 0 -127 +unsigned short cvTune; // 1 - 199 representing -99 to +99 in menu (offset of 100 to keep postitive) +unsigned short cvScale; // 1 - 199 representing -99 to +99 in menu (offset of 100 to keep postitive) +unsigned short cvVibRate; // OFF, 1 - 8 CV extra controller LFO vibrato rate 4.5Hz to 8Hz + unsigned short fastPatch[7] = {0,0,0,0,0,0,0}; uint16_t bcasMode; //Legacy CASSIDY compile flag @@ -247,6 +251,7 @@ byte lap = 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 int timeDividerList[9] = {0, 222, 200, 181, 167, 152, 143, 130, 125}; // For CV vibrato - 222 is 4.5Hz, 200 is 5Hz, 181 is 5.5Hz 167 is 6Hz, 152 is 6.5Hz, 143 is 7Hz, 130 is 7.5Hz, 125 is 8Hz static const unsigned short curveM4[] = {0,4300,7000,8700,9900,10950,11900,12600,13300,13900,14500,15000,15450,15700,16000,16250,16383}; static const unsigned short curveM3[] = {0,2900,5100,6650,8200,9500,10550,11500,12300,13100,13800,14450,14950,15350,15750,16150,16383}; @@ -294,6 +299,22 @@ const byte saxFingerMatch[16][10] = {0, 2, 0, 2, 2, 2, 2, 2, 2, 2}, // C# (-0 semis) }; +static int waveformsTable[maxSamplesNum] = { + // Sine wave + 0x7ff, 0x86a, 0x8d5, 0x93f, 0x9a9, 0xa11, 0xa78, 0xadd, 0xb40, 0xba1, + 0xbff, 0xc5a, 0xcb2, 0xd08, 0xd59, 0xda7, 0xdf1, 0xe36, 0xe77, 0xeb4, + 0xeec, 0xf1f, 0xf4d, 0xf77, 0xf9a, 0xfb9, 0xfd2, 0xfe5, 0xff3, 0xffc, + 0xfff, 0xffc, 0xff3, 0xfe5, 0xfd2, 0xfb9, 0xf9a, 0xf77, 0xf4d, 0xf1f, + 0xeec, 0xeb4, 0xe77, 0xe36, 0xdf1, 0xda7, 0xd59, 0xd08, 0xcb2, 0xc5a, + 0xbff, 0xba1, 0xb40, 0xadd, 0xa78, 0xa11, 0x9a9, 0x93f, 0x8d5, 0x86a, + 0x7ff, 0x794, 0x729, 0x6bf, 0x655, 0x5ed, 0x586, 0x521, 0x4be, 0x45d, + 0x3ff, 0x3a4, 0x34c, 0x2f6, 0x2a5, 0x257, 0x20d, 0x1c8, 0x187, 0x14a, + 0x112, 0xdf, 0xb1, 0x87, 0x64, 0x45, 0x2c, 0x19, 0xb, 0x2, + 0x0, 0x2, 0xb, 0x19, 0x2c, 0x45, 0x64, 0x87, 0xb1, 0xdf, + 0x112, 0x14a, 0x187, 0x1c8, 0x20d, 0x257, 0x2a5, 0x2f6, 0x34c, 0x3a4, + 0x3ff, 0x45d, 0x4be, 0x521, 0x586, 0x5ed, 0x655, 0x6bf, 0x729, 0x794 +}; + int saxFingerResult[16] = {-13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -3, -3, -2, -1, 0}; @@ -1432,8 +1453,14 @@ void loop() { } else { cvPitch = targetPitch; } - analogWrite(dacPin,constrain(cvPitch+map(pitchBend,0,16383,-84,84),0,4095)); - //analogWrite(pwmDacPin,breathCurve(map(constrain(pressureSensor,breathThrVal,breathMaxVal),breathThrVal,breathMaxVal,500,4095))); //starting at 0.6V to match use of cv from sensor, so recalibration of cv offset/scaler is not needed + cvPitch += map(pitchBend,0,16383,-84,84); + if (cvVibRate){ + int timeDivider = timeDividerList[cvVibRate]; + int cvVib = map(((waveformsTable[map(currentTime%timeDivider, 0, timeDivider, 0, maxSamplesNum)] - 2047) * exSensorIndicator), -259968,259969,-11,11); + cvPitch += cvVib; + } + int cvPitchTuned = cvTune-100+map(cvPitch,0,4032,0,4032+cvScale-100); + analogWrite(dacPin,constrain(cvPitchTuned,0,4095)); } else if(dacMode == DAC_MODE_BREATH) { // else breath CV on DAC pin, directly to unused pin of MIDI DIN jack //analogWrite(dacPin,breathCurve(map(constrain(pressureSensor,breathThrVal,breathMaxVal),breathThrVal,breathMaxVal,0,4095))); } @@ -1832,101 +1859,6 @@ void extraController() { } //*********************************************************** - -/* -void portamento_() { //old version - 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 (pinkySetting == GLD){ - if (portamento && pinkyKey){ - if (!portIsOn) { - portOn(); - } - port(); - } else if (portIsOn) { // pinky key released - portOff(); - } - } else 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) { - portOn(); - } - port(); - } else if (portIsOn) { // we have just gone below threshold, so send zero value - portOff(); - } - } else if (1 == vibControl) { - // Portamento is switched to lever control - leverPortRead = touchRead(vibratoPin); - if (portamento && ((3000-leverPortRead) >= leverThrVal)) { // if we are enabled and over the threshold, send portamento - if (!portIsOn) { - portOn(); - } - port(); - } else if (portIsOn) { // we have just gone below threshold, so send zero value - portOff(); - } - } else { - // no control for portamento - if (portIsOn) - portOff(); - } -} - - -//*********************************************************** - -void portOn() { - if ((portamento == 2) || (portamento == 5)) { // if portamento midi switching is enabled - midiSendControlChange(CCN_PortOnOff, 127); - } else if (portamento == 3) { // if portamento midi switching is enabled - SE02 OFF/LIN - midiSendControlChange(CCN_PortSE02, 64); - } else if (portamento == 4) { // if portamento midi switching is enabled - SE02 OFF/EXP - midiSendControlChange(CCN_PortSE02, 127); - } - portIsOn = 1; -} - -//*********************************************************** - -void port() { - int portCC; - if (pinkySetting == GLD){ - portCC = portLimit; - } else if (1 == vibControl) - portCC = map(constrain((3000-leverPortRead), leverThrVal, leverMaxVal), leverThrVal, leverMaxVal, 0, portLimit); - else - portCC = map(constrain(biteSensor, portamThrVal, portamMaxVal), portamThrVal, portamMaxVal, 0, portLimit); - if ((portamento != 5) && (portCC != oldport)) { // portamento setting 5 is switch only, do not transmit glide rate - midiSendControlChange(CCN_Port, portCC); - } - oldport = portCC; -} - -//*********************************************************** - -void portOff() { - if ((portamento != 5) && (oldport != 0)) { //did a zero get sent? if not, then send one (unless portamento is switch only) - midiSendControlChange(CCN_Port, 0); - } - if ((portamento == 2) || (portamento == 5)) { // if portamento midi switching is enabled - midiSendControlChange(CCN_PortOnOff, 0); - } else if (portamento == 3) { // if portamento midi switching is enabled - SE02 OFF/LIN - midiSendControlChange(CCN_PortSE02, 0); - } else if (portamento == 4) { // if portamento midi switching is enabled - SE02 OFF/EXP - midiSendControlChange(CCN_PortSE02, 0); - } - portIsOn = 0; - oldport = 0; -} - -//*********************************************************** -*/ - void portamento_() { int portSumCC = 0; diff --git a/NuEVI/config.h b/NuEVI/config.h index cc2922d..09ebd36 100644 --- a/NuEVI/config.h +++ b/NuEVI/config.h @@ -5,7 +5,7 @@ // Compile options, comment/uncomment to change -#define FIRMWARE_VERSION "1.5b6" // FIRMWARE VERSION NUMBER HERE <<<<<<<<<<<<<<<<<<<<<<< +#define FIRMWARE_VERSION "1.5b7" // 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 @@ -22,6 +22,7 @@ #define LVL_TIMER_INTERVAL 15 #define CVPORTATUNE 2 +#define maxSamplesNum 120 #define breathLoLimit 0 #define breathHiLimit 4095 diff --git a/NuEVI/globals.h b/NuEVI/globals.h index 28c4304..59bda93 100644 --- a/NuEVI/globals.h +++ b/NuEVI/globals.h @@ -117,6 +117,9 @@ extern unsigned short biteControl; // OFF, VIB, GLD, CC extern unsigned short leverControl; // OFF, VIB, GLD, CC extern unsigned short biteCC; // 0 - 127 extern unsigned short leverCC; // 0 -127 +extern unsigned short cvTune; // 1 - 199 representing -99 to +99 in menu (offset of 100 to keep postitive) +extern unsigned short cvScale; // 1 - 199 representing -99 to +99 in menu (offset of 100 to keep postitive) +extern unsigned short cvVibRate; // OFF, 1 - 8 CV extra controller LFO vibrato rate 4.5Hz to 8Hz extern uint16_t gateOpenEnable; extern uint16_t specialKeyEnable; extern byte rotatorOn; diff --git a/NuEVI/menu.cpp b/NuEVI/menu.cpp index 3bee8f3..775ba36 100644 --- a/NuEVI/menu.cpp +++ b/NuEVI/menu.cpp @@ -1038,6 +1038,37 @@ const MenuEntrySub fastBootMenu = { , nullptr }; +const MenuEntrySub cvTuneMenu = { + MenuType::ESub, "CV TUNE", "TUNING", &cvTune, 1, 199, MenuEntryFlags::ENone, + [](SubMenuRef __unused, char* out, const char** __unused unit) { + numToString(cvTune-100, out, true); + }, + [](SubMenuRef __unused) { writeSetting(CVTUNE_ADDR,cvTune); } + , nullptr +}; + +const MenuEntrySub cvScaleMenu = { + MenuType::ESub, "CV SCALE", "SCALING", &cvScale, 1, 199, MenuEntryFlags::ENone, + [](SubMenuRef __unused, char* out, const char** __unused unit) { + numToString(cvScale-100, out, true); + }, + [](SubMenuRef __unused) { writeSetting(CVSCALE_ADDR,cvScale); } + , nullptr +}; + +const MenuEntrySub cvEcVibMenu = { + MenuType::ESub, "CV EC LFO", "RATE", &cvVibRate, 0, 8, MenuEntryFlags::EMenuEntryWrap, + [](SubMenuRef __unused, char* out, const char** __unused unit) { + if(cvVibRate) numToString(cvVibRate, out); + else strncpy(out, "OFF", 4); + }, + [](const MenuEntrySub & __unused sub){ + if (readSetting(CVRATE_ADDR) != cvVibRate) { + writeSetting(CVRATE_ADDR,cvVibRate); + } + } + , nullptr +}; static uint16_t wireless_power=0; static uint16_t wireless_channel=4; @@ -1083,6 +1114,9 @@ const MenuEntry* extrasMenuEntries[] = { (MenuEntry*)&dacModeMenu, (MenuEntry*)&batteryTypeMenu, (MenuEntry*)&fastBootMenu, + (MenuEntry*)&cvTuneMenu, + (MenuEntry*)&cvScaleMenu, + (MenuEntry*)&cvEcVibMenu, (MenuEntry*)&wlPowerMenu, (MenuEntry*)&wlChannelMenu, }; @@ -1096,6 +1130,9 @@ const MenuEntry* extrasMenuEntries[] = { (MenuEntry*)&dacModeMenu, (MenuEntry*)&batteryTypeMenu, (MenuEntry*)&fastBootMenu, + (MenuEntry*)&cvTuneMenu, + (MenuEntry*)&cvScaleMenu, + (MenuEntry*)&cvEcVibMenu, (MenuEntry*)&wlPowerMenu, (MenuEntry*)&wlChannelMenu, }; diff --git a/NuEVI/settings.cpp b/NuEVI/settings.cpp index 0af59a6..e4c4129 100644 --- a/NuEVI/settings.cpp +++ b/NuEVI/settings.cpp @@ -170,6 +170,14 @@ void readEEPROM(const bool factoryReset) { writeSetting(LEVERCC_ADDR, LEVERCC_FACTORY); } + if(settingsVersion < 43) { + writeSetting(CVTUNE_ADDR, CVTUNE_FACTORY); + writeSetting(CVSCALE_ADDR, CVSCALE_FACTORY); + } + + if(settingsVersion < 44) { + writeSetting(CVRATE_ADDR, CVRATE_FACTORY); + } writeSetting(VERSION_ADDR, EEPROM_VERSION); } @@ -264,6 +272,9 @@ void readEEPROM(const bool factoryReset) { leverControl = readSettingBounded(LEVERCTL_ADDR, 0, 3, LEVERCTL_FACTORY); biteCC = readSettingBounded(BITECC_ADDR, 0, 127, BITECC_FACTORY); leverCC = readSettingBounded(LEVERCC_ADDR, 0, 127, LEVERCC_FACTORY); + cvTune = readSettingBounded(CVTUNE_ADDR, 1, 199, CVTUNE_FACTORY); + cvScale = readSettingBounded(CVSCALE_ADDR, 1, 199, CVSCALE_FACTORY); + cvVibRate = readSettingBounded(CVRATE_ADDR, 0, 8, CVRATE_FACTORY); //Flags stored in bit field fastBoot = (dipSwBits & (1<