Fix for SAX fingering and updated fingering chart (NuRAD). Experimental fingerings using rollers for harmonic series (NuEVI). LED indication for extra controller sensor and startup LED check and also fail check for MPR121 sensor boards (NuRAD).

This commit is contained in:
Johan Berglund 2020-06-04 11:43:46 +02:00
parent e68a66db84
commit c7c1825b62
9 changed files with 9334 additions and 39 deletions

View file

@ -197,6 +197,7 @@ int cvPitch;
int targetPitch; int targetPitch;
int exSensor=0; int exSensor=0;
int exSensorIndicator=0;
byte extracIsOn=0; byte extracIsOn=0;
int oldextrac=0; int oldextrac=0;
int oldextrac2=0; int oldextrac2=0;
@ -243,36 +244,42 @@ const unsigned short* const curves[] = {
// LH1, LHb, LH2, LH3, LHp1, -LHp2-, -RHsx-, RH1, RH2, RH3, RHp1, RHp2, RHp3 -excluded- LHp2 always -1, RHs always +1 // 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 // 0 = not touched, 1 = touched, 2 = whatever
const byte saxFingerMatch[17][11] = const byte saxFingerMatch[15][10] =
{ {
{1, 2, 1, 1, 2, 1, 1, 1, 2, 1, 1}, // B (-14 semis) {1, 2, 1, 1, 0, 1, 1, 1, 2, 1}, // C (-13 semis)
{1, 2, 1, 1, 0, 1, 1, 1, 2, 0, 1}, // C (-13 semis) {1, 2, 1, 1, 1, 1, 1, 1, 2, 1}, // C# (-12 semis)
{1, 2, 1, 1, 1, 1, 1, 1, 2, 0, 1}, // C# (-12 semis) {1, 2, 1, 1, 2, 1, 1, 1, 0, 0}, // D (-11 semis)
{1, 2, 1, 1, 2, 1, 1, 1, 2, 1, 0}, // C# (-12 semis) {1, 2, 1, 1, 2, 1, 1, 1, 1, 0}, // D# (-10 semis)
{1, 2, 1, 1, 2, 1, 1, 1, 0, 0, 0}, // D (-11 semis) {1, 2, 1, 1, 2, 1, 1, 0, 2, 2}, // E (-9 semis)
{1, 2, 1, 1, 2, 1, 1, 1, 1, 0, 0}, // D# (-10 semis) {1, 2, 1, 1, 2, 1, 0, 2, 2, 2}, // F (-8 semis)
{1, 2, 1, 1, 2, 1, 1, 0, 2, 2, 2}, // E (-9 semis) {1, 2, 1, 1, 2, 0, 1, 2, 2, 2}, // F# (-7 semis)
{1, 2, 1, 1, 2, 1, 0, 2, 2, 2, 2}, // F (-8 semis) {1, 2, 1, 1, 0, 0, 0, 2, 2, 2}, // G (-6 semis)
{1, 2, 1, 1, 2, 0, 1, 2, 2, 2, 2}, // F# (-7 semis) {1, 2, 1, 1, 1, 0, 0, 2, 2, 2}, // G# (-5 semis)
{1, 2, 1, 1, 0, 0, 0, 2, 2, 2, 2}, // G (-6 semis) {1, 2, 1, 0, 2, 2, 2, 2, 2, 2}, // A (-4 semis)
{1, 2, 1, 1, 1, 0, 0, 2, 2, 2, 2}, // G# (-5 semis) {1, 2, 0, 2, 2, 1, 2, 2, 2, 2}, // A# (-3 semis)
{1, 2, 1, 0, 2, 2, 2, 2, 2, 2, 2}, // A (-4 semis) {1, 1, 0, 2, 2, 2, 2, 2, 2, 2}, // A# (-3 semis)
{1, 2, 0, 2, 2, 1, 2, 2, 2, 2, 2}, // A# (-3 semis) {1, 0, 0, 2, 2, 0, 2, 2, 2, 2}, // B (-2 semis)
{1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2}, // A# (-3 semis) {0, 2, 1, 2, 2, 2, 2, 2, 2, 2}, // C (-1 semis)
{1, 0, 0, 2, 2, 0, 2, 2, 2, 2, 2}, // B (-2 semis) {0, 2, 0, 2, 2, 2, 2, 2, 2, 2}, // C# (-0 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 harmonicResult[5][7] = {{ 0, 7, 12, 16, 19, 22, 24 }, //HRM
const int harmonicResult[5][7] = {{ 0, 7, 12, 16, 19, 24, 28 }, //HRM
{ 0, 7, 12, 19, 24, 31, 36 }, //5TH { 0, 7, 12, 19, 24, 31, 36 }, //5TH
{ 0, 12, 24, 36, 48, 60, 72 }, //OCT { 0, 12, 24, 36, 48, 60, 72 }, //OCT
{ 0, -5, -12, -17, -24, -29, -36 }, //5DN { 0, -5, -12, -17, -24, -29, -36 }, //5DN
{ 0, -12, -24, -36, -48, -60, -72 }}; //ODN { 0, -12, -24, -36, -48, -60, -72 }}; //ODN
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
const int saxFingerResult[17] = {-14, -13, -12, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -3, -2, -1, 0}; const int trumpetHarmonic[2][7] = {{ 0, 7, 12, 16, 19, 26, 31 }, //!K4: hrm 8->9, 10->12
{ 0, 7, 12, 16, 19, 24, 28 }}; //trumpet 2,3,4,5,6,8,10 hrm
byte saxFinger[11]; int saxFingerResult[15] =
{-13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -3, -2, -1, 0};
byte saxFinger[10];
int vibThr; // this gets auto calibrated in setup int vibThr; // this gets auto calibrated in setup
@ -433,16 +440,30 @@ void setup() {
activePatch = patch; activePatch = patch;
#if defined(NURAD) #if defined(NURAD)
digitalWrite(statusLedPin,HIGH); digitalWrite(statusLedPin,HIGH);
delay(100);
analogWrite(bLedPin, BREATH_LED_BRIGHTNESS);
if (!touchSensorRollers.begin(0x5D)) { //should be D if (!touchSensorRollers.begin(0x5D)) { //should be D
while (1); // Touch sensor initialization failed - stop doing stuff while (1); // Touch sensor initialization failed - stop doing stuff
} }
delay(100);
analogWrite(bLedPin, 0);
analogWrite(pLedPin, PORTAM_LED_BRIGHTNESS);
if (!touchSensorLH.begin(0x5C)) { if (!touchSensorLH.begin(0x5C)) {
while (1); // Touch sensor initialization failed - stop doing stuff while (1); // Touch sensor initialization failed - stop doing stuff
} }
delay(100);
analogWrite(pLedPin, 0);
analogWrite(eLedPin, PORTAM_LED_BRIGHTNESS);
if (!touchSensorRH.begin(0x5B)) { if (!touchSensorRH.begin(0x5B)) {
while (1); // Touch sensor initialization failed - stop doing stuff while (1); // Touch sensor initialization failed - stop doing stuff
} }
delay(100);
analogWrite(eLedPin, 0);
analogWrite(sLedPin, PORTAM_LED_BRIGHTNESS);
delay(100);
analogWrite(sLedPin, 0);
delay(100);
digitalWrite(statusLedPin,LOW); digitalWrite(statusLedPin,LOW);
#else #else
if (!touchSensor.begin(0x5A)) { if (!touchSensor.begin(0x5A)) {
@ -469,7 +490,7 @@ void setup() {
breathCalZero += analogRead(breathSensorPin); breathCalZero += analogRead(breathSensorPin);
if (biteJumper) vibZeroBite += analogRead(bitePressurePin); else vibZeroBite += touchRead(bitePin); if (biteJumper) vibZeroBite += analogRead(bitePressurePin); else vibZeroBite += touchRead(bitePin);
statusLed(i&1); statusLed(i&1);
delay(fastBoot?75:250); //Shorter delay for fastboot delay(fastBoot?75:220); //Shorter delay for fastboot
} }
vibZero /= sampleCount; vibZero /= sampleCount;
@ -1262,6 +1283,7 @@ void extraController() {
int extracCC; int extracCC;
// Extra Controller is the lip touch sensor (proportional) in front of the mouthpiece // 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) 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)
exSensorIndicator = map(constrain(exSensor, extracThrVal, extracMaxVal), extracThrVal, extracMaxVal, 0, 127);
if (pinkySetting == EC2){ if (pinkySetting == EC2){
//send 0 or 127 on extra controller CC2 depending on pinky key touch //send 0 or 127 on extra controller CC2 depending on pinky key touch
if (pinkyKey && extraCT2) { if (pinkyKey && extraCT2) {
@ -1560,22 +1582,21 @@ void readSwitches() {
saxFinger[6] = RH2; saxFinger[6] = RH2;
saxFinger[7] = RH3; saxFinger[7] = RH3;
saxFinger[8] = RHp1; saxFinger[8] = RHp1;
saxFinger[9] = RHp2; saxFinger[9] = RHp3;
saxFinger[10] = RHp3;
byte matched = 0; byte matched = 0;
byte combo = 0; byte combo = 0;
while (matched<11 && combo<17) while (matched<10 && combo<15)
{ {
combo++; combo++;
matched = 0; matched = 0;
for (byte finger=0; finger < 11; finger++) for (byte finger=0; finger < 10; finger++)
{ {
if ((saxFinger[finger] == saxFingerMatch[combo-1][finger]) || (saxFingerMatch[combo-1][finger] == 2)) matched++; 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; if (matched<11 && combo==17) fingeredNoteUntransposed=lastFingering; else fingeredNoteUntransposed = startNote+1+saxFingerResult[combo-1]-LHp2+RHs-(RHp2 && (1 == combo) && LHp2)+octaveR*12;
} else if (3==fingering) { // EVI fingering } else if (3==fingering) { // EVI fingering
fingeredNoteUntransposed = startNote fingeredNoteUntransposed = startNote
- 2*RH1 - RH2 - 3*RH3 //"Trumpet valves" - 2*RH1 - RH2 - 3*RH3 //"Trumpet valves"
@ -1640,12 +1661,28 @@ void readSwitches() {
int qTransp = (pinkyKey && (pinkySetting < 25)) ? pinkySetting-12 : 0; int qTransp = (pinkyKey && (pinkySetting < 25)) ? pinkySetting-12 : 0;
// Calculate midi note number from pressed keys // Calculate midi note number from pressed keys
if (0 == fingering){ //EVI fingering
fingeredNoteUntransposed = startNote
- 2*K1 - K2 - 3*K3 //"Trumpet valves"
- 5*K4 //Fifth key
+ 2*K5 + K6 + trill3_interval*K7 //Trill keys. 3rd trill key interval controlled by setting
+ octaveR*12; //Octave rollers
} else if (1 == fingering){ //TPT fingering
fingeredNoteUntransposed = startNote
- 2*K1 - K2 - 3*K3 //"Trumpet valves"
- 2 //Trumpet in B flat
+ 2*K5 + K6 + trill3_interval*K7 //Trill keys. 3rd trill key interval controlled by setting
+ 24 + trumpetHarmonic[K4][octaveR]; // roller harmonics
} else if (2 == fingering){ //HRN fingering
fingeredNoteUntransposed = startNote
- 2*K1 - K2 - 3*K3 //"Trumpet valves"
+ 5*K4 //Switch to Bb horn
+ 5 //Horn in F
+ 2*K5 + K6 + trill3_interval*K7 //Trill keys. 3rd trill key interval controlled by setting
+ 12 + rollerHarmonic[K4][octaveR]; // roller harmonics
}
fingeredNoteUntransposed = startNote
- 2*K1 - K2 - 3*K3 //"Trumpet valves"
- 5*K4 //Fifth key
+ 2*K5 + K6 + trill3_interval*K7 //Trill keys. 3rd trill key interval controlled by setting
+ octaveR*12; //Octave rollers
if (K3 && K7){ if (K3 && K7){
if (4 == trill3_interval) fingeredNoteUntransposed+=2; else fingeredNoteUntransposed+=4; if (4 == trill3_interval) fingeredNoteUntransposed+=2; else fingeredNoteUntransposed+=4;

View file

@ -5,7 +5,7 @@
// Compile options, comment/uncomment to change // Compile options, comment/uncomment to change
#define FIRMWARE_VERSION "1.4.6" // FIRMWARE VERSION NUMBER HERE <<<<<<<<<<<<<<<<<<<<<<< #define FIRMWARE_VERSION "1.4.7" // FIRMWARE VERSION NUMBER HERE <<<<<<<<<<<<<<<<<<<<<<<
#define ON_Delay 20 // Set Delay after ON threshold before velocity is checked (wait for tounging peak) #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 #define CCN_Port 5 // Controller number for portamento level
@ -36,10 +36,10 @@
#define MIN_LED_BRIGHTNESS 5 // lowest PWM value that still is visible #define MIN_LED_BRIGHTNESS 5 // lowest PWM value that still is visible
#define BREATH_LED_BRIGHTNESS 500 // up to 4095, PWM #define BREATH_LED_BRIGHTNESS 600 // up to 4095, PWM
#define PORTAM_LED_BRIGHTNESS 500 // up to 4095, PWM #define PORTAM_LED_BRIGHTNESS 300 // up to 4095, PWM
#define EXTCON_LED_BRIGHTNESS 500 // up to 4095, PWM #define EXTCON_LED_BRIGHTNESS 300 // up to 4095, PWM
#define SPCKEY_LED_BRIGHTNESS 500 // up to 4095, PWM #define SPCKEY_LED_BRIGHTNESS 700 // up to 4095, PWM
#define ALK_BAT_FULL 2800 // about 4.6V #define ALK_BAT_FULL 2800 // about 4.6V
#define NMH_BAT_FULL 2350 // about 3.8V #define NMH_BAT_FULL 2350 // about 3.8V

View file

@ -122,6 +122,7 @@ extern int lastBite;
extern byte biteJumper; extern byte biteJumper;
extern int exSensor; extern int exSensor;
extern int exSensorIndicator;
extern int pitchBend; extern int pitchBend;

7
NuEVI/led.cpp Executable file → Normal file
View file

@ -45,6 +45,13 @@ void updateSensorLEDs() {
} else { } else {
analogWrite(pLedPin, 0); analogWrite(pLedPin, 0);
} }
#if defined(NURAD)
if (exSensorIndicator){
analogWrite(eLedPin, map(constrain(exSensorIndicator, 0, 127), 0, 127, MIN_LED_BRIGHTNESS, EXTCON_LED_BRIGHTNESS));
} else {
analogWrite(eLedPin, 0);
}
#endif
} }
void ledMeter(byte indicatedValue){ void ledMeter(byte indicatedValue){

View file

@ -1025,7 +1025,7 @@ const MenuEntrySub harmonicsMenu = {
const MenuEntrySub harmSelectMenu = { const MenuEntrySub harmSelectMenu = {
MenuType::ESub, "HARM SEL", "SERIES", &harmSelect, 0, 4, MenuEntryFlags::EMenuEntryWrap, MenuType::ESub, "HARM SEL", "SERIES", &harmSelect, 0, 4, MenuEntryFlags::EMenuEntryWrap,
[](SubMenuRef __unused, char* out, const char** __unused unit) { [](SubMenuRef __unused, char* out, const char** __unused unit) {
const char* harmSelectMenuLabels[] = { "HMS", "5TH", "OCT", "5DN", "ODN" }; const char* harmSelectMenuLabels[] = { "HRM", "5TH", "OCT", "5DN", "ODN" };
strncpy(out, harmSelectMenuLabels[harmSelect], 4); strncpy(out, harmSelectMenuLabels[harmSelect], 4);
}, },
[](const MenuEntrySub & __unused sub){ [](const MenuEntrySub & __unused sub){
@ -1091,6 +1091,7 @@ const MenuEntrySub lvlCtrlCCMenu = {
, nullptr , nullptr
}; };
#if defined(NURAD)
const MenuEntrySub fingeringMenu = { const MenuEntrySub fingeringMenu = {
MenuType::ESub, "FINGERING", "FINGERING", &fingering, 0, 4, MenuEntryFlags::EMenuEntryWrap, MenuType::ESub, "FINGERING", "FINGERING", &fingering, 0, 4, MenuEntryFlags::EMenuEntryWrap,
[](SubMenuRef __unused,char* out, const char ** __unused unit) { [](SubMenuRef __unused,char* out, const char ** __unused unit) {
@ -1099,6 +1100,18 @@ const MenuEntrySub fingeringMenu = {
}, },
[](SubMenuRef __unused sub) { writeSetting(FINGER_ADDR,fingering); } [](SubMenuRef __unused sub) { writeSetting(FINGER_ADDR,fingering); }
}; };
#else
const MenuEntrySub fingeringMenu = {
MenuType::ESub, "FINGERING", "FINGERING", &fingering, 0, 2, MenuEntryFlags::EMenuEntryWrap,
[](SubMenuRef __unused,char* out, const char ** __unused unit) {
const char* labs[] = { "EVI", "TPT", "HRN" };
strncpy(out, labs[fingering], 4);
},
[](SubMenuRef __unused sub) { writeSetting(FINGER_ADDR,fingering); }
};
#endif
const MenuEntrySub lpinky3Menu = { const MenuEntrySub lpinky3Menu = {
MenuType::ESub, "EXTRA PKEY", "EXTRA PKEY", &lpinky3, 0, 25, MenuEntryFlags::ENone, MenuType::ESub, "EXTRA PKEY", "EXTRA PKEY", &lpinky3, 0, 25, MenuEntryFlags::ENone,
@ -1140,6 +1153,7 @@ const MenuEntry* controlMenuEntries[] = {
(MenuEntry*)&deglitchMenu, (MenuEntry*)&deglitchMenu,
(MenuEntry*)&pinkyMenu, (MenuEntry*)&pinkyMenu,
(MenuEntry*)&lvlCtrlCCMenu, (MenuEntry*)&lvlCtrlCCMenu,
(MenuEntry*)&fingeringMenu,
(MenuEntry*)&pitchBendMenu (MenuEntry*)&pitchBendMenu
}; };
#endif #endif

View file

@ -178,7 +178,11 @@ void readEEPROM(const bool factoryReset) {
extraCT2 = readSettingBounded(EXTRA2_ADDR, 0, 127, EXTRA2_FACTORY); extraCT2 = readSettingBounded(EXTRA2_ADDR, 0, 127, EXTRA2_FACTORY);
levelCC = readSettingBounded(LEVEL_CC_ADDR, 0, 127, LEVEL_CC_FACTORY); levelCC = readSettingBounded(LEVEL_CC_ADDR, 0, 127, LEVEL_CC_FACTORY);
levelVal = readSettingBounded(LEVEL_VAL_ADDR, 0, 127, LEVEL_VAL_FACTORY); levelVal = readSettingBounded(LEVEL_VAL_ADDR, 0, 127, LEVEL_VAL_FACTORY);
#if defined(NURAD)
fingering = readSettingBounded(FINGER_ADDR, 0, 4, FINGER_FACTORY); fingering = readSettingBounded(FINGER_ADDR, 0, 4, FINGER_FACTORY);
#else
fingering = readSettingBounded(FINGER_ADDR, 0, 2, FINGER_FACTORY);
#endif
lpinky3 = readSettingBounded(LPINKY3_ADDR, 0, 25, LPINKY3_FACTORY); lpinky3 = readSettingBounded(LPINKY3_ADDR, 0, 25, LPINKY3_FACTORY);
batteryType = readSettingBounded(BATTYPE_ADDR, 0, 2, BATTYPE_FACTORY); batteryType = readSettingBounded(BATTYPE_ADDR, 0, 2, BATTYPE_FACTORY);
harmSetting = readSettingBounded(HARMSET_ADDR, 0, 6, HARMSET_FACTORY); harmSetting = readSettingBounded(HARMSET_ADDR, 0, 6, HARMSET_FACTORY);

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff