* New quarter tone setting for Pinky Key (NuEVI) and Mod Key (NuRAD) – QTN. This makes the Pinky/Mod key a key for playing one quarter tone down using pitchbend (MIDI) or directly affecting the built in note CV output (using CV module or NuEVI CV/Plus). Pitch bend range for MIDI synth needs to be two semitones up/dn (or compensated for in pitch bend divider setting in the controller to make the resulting range two semitones up/dn). On NuRAD, it is recommended to set the 3rd LH Pinky key (EXTRA PKEY setting) to mirror MOD key for playablility.

* Changes to extra controller harmonics settings (experimental). Reverse direction options (ending with an ‘R’) available following the ones going up. This can be used with experimental mouthpieces where increased lip tension creates less touched sensor area.
This commit is contained in:
Johan Berglund 2021-07-09 14:38:32 +02:00
parent 35a5943998
commit c8bd07799a
8 changed files with 11525 additions and 19 deletions

View file

@ -239,6 +239,7 @@ int harmonics = 0;
int brHarmonics = 0;
int pitchBend=8192;
int pbSend=8192;
int oldpb=8192;
int vibSignal=0;
int pbUp=0;
@ -461,12 +462,21 @@ const int minHipHmz[12][3] = {{ -5, -9, -10 }, // C or key base
{ -4, -6, -9 }}; // B or base +11
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 harmonicResult[8][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, 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
/*
{ 28, 24, 19, 16, 12, 7, 0 }, //H1R
{ 24, 22, 19, 16, 12, 7, 0 }, //H2R (7th harmonic not excluded)
{ 36, 31, 24, 19, 12, 7, 0 }, //5TR
{ 72, 60, 48, 36, 24, 12, 0 }}; //OCR
*/
const int brHarmonicResult[4][7] = {{ 0, 7, 12, 16, 19, 24, 28 }, //HM1
@ -545,6 +555,7 @@ byte octaveR = 0;
byte lastOctaveR = 0;
byte halfPitchBendKey;
byte quarterToneTrigger;
byte specialKey;
byte pinkyKey;
byte lastSpecialKey = 0;
@ -1429,6 +1440,7 @@ void loop() {
if(dacMode == DAC_MODE_PITCH) { // pitch CV from DAC and breath CV from PWM on pin 6, for filtering and scaling on separate board
targetPitch = (fingeredNote-24)*42;
targetPitch += map(pitchBend,0,16383,-84,84);
targetPitch -=quarterToneTrigger*21;
if (portIsOn){
if (targetPitch > cvPitch){
if (!cvPortaTuneCount) {
@ -1571,6 +1583,7 @@ void pitch_bend() {
pbUp = touchRead(pbUpPin); // PCB PIN "Pu"
pbDn = touchRead(pbDnPin); // PCB PIN "Pd"
halfPitchBendKey = (pinkySetting == PBD) && pinkyKey; // hold pinky key for 1/2 pitchbend value
quarterToneTrigger = (pinkySetting == QTN) && pinkyKey; // pinky key for a quarter tone down using pitch bend (assuming PB range on synth is set to 2 semitones)
calculatedPBdepth = pbDepthList[PBdepth];
if (halfPitchBendKey) calculatedPBdepth = calculatedPBdepth * 0.5;
@ -1668,6 +1681,10 @@ void pitch_bend() {
pitchBend = constrain(pitchBend, 0, 16383);
pbSend = pitchBend - quarterToneTrigger*calculatedPBdepth*0.25;
pbSend = constrain(pbSend, 0, 16383);
if (subVibSquelch && (8192 != pitchBend)) {
statusLedOff();
vibLedOff = 1;
@ -1680,9 +1697,9 @@ void pitch_bend() {
//Serial.print(" - ");
//Serial.println(oldpb);
if (pitchBend != oldpb) { // only send midi data if pitch bend has changed from previous value
midiSendPitchBend(pitchBend);
oldpb = pitchBend;
if (pbSend != oldpb) { // only send midi data if pitch bend has changed from previous value
midiSendPitchBend(pbSend);
oldpb = pbSend;
}
}
@ -1787,7 +1804,11 @@ void extraController() {
}
if ((harmSetting && (pinkySetting != ECH)) || ((pinkySetting == ECH) && pinkyKey)){
harmonics = map(constrain(exSensor, extracThrVal, extracMaxVal), extracThrVal, extracMaxVal, 0, harmSetting);
if (harmSelect < 4){
harmonics = map(constrain(exSensor, extracThrVal, extracMaxVal), extracThrVal, extracMaxVal, 0, harmSetting);
} else {
harmonics = map(constrain(exSensor, extracThrVal, extracMaxVal), extracMaxVal, extracThrVal, 0, harmSetting);
}
} else if ((pinkySetting == ECH) && !pinkyKey) {
harmonics = 0;
}

View file

@ -5,7 +5,7 @@
// Compile options, comment/uncomment to change
#define FIRMWARE_VERSION "1.5b7" // FIRMWARE VERSION NUMBER HERE <<<<<<<<<<<<<<<<<<<<<<<
#define FIRMWARE_VERSION "1.5b8" // 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,7 @@
#define LVLP 28
#define GLD 29
#define ECH 30
#define QTN 31
#define HOF 0
#define MGR 1
@ -162,6 +163,7 @@ extern int exSensor;
extern int exSensorIndicator;
extern int pitchBend;
extern int pbSend;
extern int pbUp;
extern int pbDn;
@ -214,6 +216,7 @@ extern byte K6; // Trill key 2 (pitch change +1)
extern byte K7; // Trill key 3 (pitch change +4)
extern byte halfPitchBendKey;
extern byte quarterToneTrigger;
extern byte specialKey;
extern byte pinkyKey;

View file

@ -1471,9 +1471,9 @@ const MenuEntrySub harmonicsMenu = {
};
const MenuEntrySub harmSelectMenu = {
MenuType::ESub, "HARM SEL", "SERIES", &harmSelect, 0, 5, MenuEntryFlags::EMenuEntryWrap,
MenuType::ESub, "HARM SEL", "SERIES", &harmSelect, 0, 7, MenuEntryFlags::EMenuEntryWrap,
[](SubMenuRef __unused, char* out, const char** __unused unit) {
const char* harmSelectMenuLabels[] = { "HM1", "HM2", "5TH", "OCT", "5DN", "ODN" };
const char* harmSelectMenuLabels[] = { "HM1", "HM2", "5TH", "OCT", "H1R", "H2R", "5TR", "OCR" };
strncpy(out, harmSelectMenuLabels[harmSelect], 4);
},
[](const MenuEntrySub & __unused sub){
@ -1501,11 +1501,11 @@ const MenuEntrySub deglitchMenu = {
#if defined(NURAD)
const MenuEntrySub pinkyMenu = {
MenuType::ESub, "MOD KEY", "MOD KEY", &pinkySetting, 0, 30, MenuEntryFlags::ENone,
MenuType::ESub, "MOD KEY", "MOD KEY", &pinkySetting, 0, 31, MenuEntryFlags::ENone,
[](SubMenuRef __unused,char* textBuffer, const char** __unused unit) {
#else
const MenuEntrySub pinkyMenu = {
MenuType::ESub, "PINKY KEY", "PINKY KEY", &pinkySetting, 0, 30, MenuEntryFlags::ENone,
MenuType::ESub, "PINKY KEY", "PINKY KEY", &pinkySetting, 0, 31, MenuEntryFlags::ENone,
[](SubMenuRef __unused,char* textBuffer, const char** __unused unit) {
#endif
if (pinkySetting == PBD)
@ -1522,6 +1522,8 @@ const MenuEntrySub pinkyMenu = {
strncpy(textBuffer, "GLD", 4);
else if (pinkySetting == ECH)
strncpy(textBuffer, "ECH", 4);
else if (pinkySetting == QTN)
strncpy(textBuffer, "QTN", 4);
else
numToString(pinkySetting-12, textBuffer, true);
},

View file

@ -207,7 +207,7 @@ void readEEPROM(const bool factoryReset) {
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, 30, PINKY_KEY_FACTORY);
pinkySetting = readSettingBounded(PINKY_KEY_ADDR, 0, 31, 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);
@ -244,7 +244,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, 5, HARMSEL_FACTORY);
harmSelect = readSettingBounded(HARMSEL_ADDR, 0, 7, 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);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,4 @@
NuEVI and NuRAD Firmware 1.5b7 Notes
NuEVI and NuRAD Firmware 1.5b8 Notes
1.5b1:
@ -62,7 +62,12 @@ Settings in GLIDE CC and LEVER CC are only used when corresponding control is se
* Support for a CME WIDI Master Bluetooth MIDI board connected to Teensy underside pads. With this mod, if present it will be powered up by touching pinky/mod key and pressing enter in MIDI meny (what previously controlled the "slow midi" function that now is replaced by the CC interval menu item). "WIDI" will be indicated in the display below the MIDI channel number and the WIDI board will be powered up. Teensy pad connections: GND to GND (blue) of WIDI, 31 (TX2) via 47 ohm resistor to signal (green) of WIDI, 33 via 47 ohm resistor to power (red) of WIDI. 27 and 28 jumpered to indicate that the WIDI is connected.
1.5b7:
* Added three new settings in EXTRAS MENU CV TUNE, CV SCALE and CV EC LFO. The first two allow for software tuning of the CV output for 1V/Oct when using NuEVI CV, NuEVI Plus or NuEVI/NuRAD with external CV box or module. Also makes more simple versions of the CV boards possible (no potentiometers for adjustment). The CV EC LFO setting controls a new CV LFO vibrato function for the extra controller (lip sensor). It can be set to OFF (no extra controller LFO vibrato) or values 1 through 8, which represent vibrato freq from 4.5Hz to 8Hz. Default value is 3 (5.5Hz).
1.5b8:
* New quarter tone setting for Pinky Key (NuEVI) and Mod Key (NuRAD) QTN. This makes the Pinky/Mod key a key for playing one quarter tone down using pitchbend (MIDI) or directly affecting the built in note CV output (using CV module or NuEVI CV/Plus). Pitch bend range for MIDI synth needs to be two semitones up/dn (or compensated for in pitch bend divider setting in the controller to make the resulting range two semitones up/dn). On NuRAD, it is recommended to set the 3rd LH Pinky key (EXTRA PKEY setting) to mirror MOD key for playablility.
* Changes to extra controller harmonics settings (experimental). Reverse direction options (ending with an R) available following the ones going up. This can be used with experimental mouthpieces where increased lip tension creates less touched sensor area.