Added possibility to use bite sensor for vibrato.

This commit is contained in:
Johan Berglund 2019-07-18 13:58:28 +02:00
parent e251b86100
commit 597991c968
4 changed files with 138 additions and 40 deletions

View file

@ -72,8 +72,11 @@ unsigned short priority; // mono priority for rotator chords
unsigned short vibSens = 2; // vibrato sensitivity unsigned short vibSens = 2; // vibrato sensitivity
unsigned short vibRetn = 2; // vibrato return speed unsigned short vibRetn = 2; // vibrato return speed
unsigned short vibSquelch = 15; //vibrato signal squelch unsigned short vibSquelch = 12; //vibrato signal squelch
unsigned short vibDirection = DNWD; //direction of first vibrato wave UPWD or DNWD unsigned short vibDirection = DNWD; //direction of first vibrato wave UPWD or DNWD
unsigned short vibSensBite = 2; // vibrato sensitivity (bite)
unsigned short vibSquelchBite = 12; //vibrato signal squelch (bite)
unsigned short vibControl = 0;
unsigned short fastPatch[7] = {0,0,0,0,0,0,0}; unsigned short fastPatch[7] = {0,0,0,0,0,0,0};
@ -184,6 +187,9 @@ const unsigned short* const curves[] = {
int vibThr; // this gets auto calibrated in setup int vibThr; // this gets auto calibrated in setup
int vibThrLo; int vibThrLo;
int vibZero; int vibZero;
int vibZeroBite;
int vibThrBite;
int vibThrBiteLo;
int fingeredNote; // note calculated from fingering (switches), transpose and octave settings int fingeredNote; // note calculated from fingering (switches), transpose and octave settings
@ -309,6 +315,9 @@ void setup() {
writeSetting(VIB_DIRECTION_ADDR,VIB_DIRECTION_FACTORY); writeSetting(VIB_DIRECTION_ADDR,VIB_DIRECTION_FACTORY);
writeSetting(BREATH_CC2_ADDR,BREATH_CC2_FACTORY); writeSetting(BREATH_CC2_ADDR,BREATH_CC2_FACTORY);
writeSetting(BREATH_CC2_RISE_ADDR,BREATH_CC2_RISE_FACTORY); writeSetting(BREATH_CC2_RISE_ADDR,BREATH_CC2_RISE_FACTORY);
writeSetting(VIB_SENS_BITE_ADDR,VIB_SENS_BITE_FACTORY);
writeSetting(VIB_SQUELCH_BITE_ADDR,VIB_SQUELCH_BITE_FACTORY);
writeSetting(VIB_CONTROL_ADDR,VIB_CONTROL_FACTORY);
} }
// read settings from EEPROM // read settings from EEPROM
breathThrVal = readSetting(BREATH_THR_ADDR); breathThrVal = readSetting(BREATH_THR_ADDR);
@ -355,7 +364,10 @@ void setup() {
vibSquelch = readSetting(VIB_SQUELCH_ADDR); vibSquelch = readSetting(VIB_SQUELCH_ADDR);
vibDirection = readSetting(VIB_DIRECTION_ADDR); vibDirection = readSetting(VIB_DIRECTION_ADDR);
breathCC2 = readSetting(BREATH_CC2_ADDR); breathCC2 = readSetting(BREATH_CC2_ADDR);
breathCC2Rise = readSetting(BREATH_CC2_RISE_ADDR); breathCC2Rise = readSetting(BREATH_CC2_RISE_ADDR);
vibSensBite = readSetting(VIB_SENS_BITE_ADDR);
vibSquelchBite = readSetting(VIB_SQUELCH_BITE_ADDR);
vibControl = readSetting(VIB_CONTROL_ADDR);
legacy = dipSwBits & (1<<1); legacy = dipSwBits & (1<<1);
legacyBrAct = dipSwBits & (1<<2); legacyBrAct = dipSwBits & (1<<2);
@ -380,19 +392,23 @@ void setup() {
} }
//auto-calibrate the vibrato threshold while showing splash screen //auto-calibrate the vibrato threshold while showing splash screen
vibZero = breathCalZero = 0; vibZero = vibZeroBite = breathCalZero = 0;
const int sampleCount = 4; const int sampleCount = 4;
for(int i = 1 ; i <= sampleCount; ++i) { for(int i = 1 ; i <= sampleCount; ++i) {
vibZero += touchRead(vibratoPin); vibZero += touchRead(vibratoPin);
breathCalZero += analogRead(breathSensorPin); breathCalZero += analogRead(breathSensorPin);
if (biteJumper) vibZeroBite += analogRead(A7); else vibZeroBite += touchRead(bitePin);
digitalWrite( statusLedPin, i&1 ); digitalWrite( statusLedPin, i&1 );
delay(250); delay(250);
} }
vibZero /= sampleCount; vibZero /= sampleCount;
breathCalZero /= sampleCount; breathCalZero /= sampleCount;
vibZeroBite /= sampleCount;
vibThr = vibZero - vibSquelch; vibThr = vibZero - vibSquelch;
vibThrLo = vibZero + vibSquelch; vibThrLo = vibZero + vibSquelch;
vibThrBite = vibZeroBite - vibSquelchBite;
vibThrBiteLo = vibZeroBite + vibSquelchBite;
digitalWrite(statusLedPin, LOW); digitalWrite(statusLedPin, LOW);
delay(250); delay(250);
@ -948,49 +964,84 @@ void pitch_bend() {
int vibMax; int vibMax;
int calculatedPBdepth; int calculatedPBdepth;
byte pbTouched = 0; byte pbTouched = 0;
int vibRead;
int vibReadBite;
pbUp = touchRead(pbUpPin); // SENSOR PIN 23 - PCB PIN "Pu" pbUp = touchRead(pbUpPin); // SENSOR PIN 23 - PCB PIN "Pu"
pbDn = touchRead(pbDnPin); // SENSOR PIN 22 - PCB PIN "Pd" pbDn = touchRead(pbDnPin); // SENSOR PIN 22 - PCB PIN "Pd"
halfPitchBendKey = (pinkySetting == PBD) && (touchRead(halfPitchBendKeyPin) > touch_Thr); // SENSOR PIN 1 - PCB PIN "S1" - hold for 1/2 pitchbend value halfPitchBendKey = (pinkySetting == PBD) && (touchRead(halfPitchBendKeyPin) > touch_Thr); // SENSOR PIN 1 - PCB PIN "S1" - hold for 1/2 pitchbend value
int vibRead = touchRead(vibratoPin); // SENSOR PIN 15 - built in var cap
calculatedPBdepth = pbDepthList[PBdepth]; calculatedPBdepth = pbDepthList[PBdepth];
if (halfPitchBendKey) calculatedPBdepth = calculatedPBdepth * 0.5; if (halfPitchBendKey) calculatedPBdepth = calculatedPBdepth * 0.5;
vibMax = vibMaxList[vibSens - 1]; vibMax = vibMaxList[vibSens - 1];
if (vibRead < vibThr) { if (vibControl){ //bite vibrato
if (UPWD == vibDirection) { if (biteJumper){ //PBITE (if pulled low with jumper, use pressure sensor instead of capacitive bite sensor)
vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibRead, (vibZero - vibMax), vibThr), vibThr, (vibZero - vibMax), 0, calculatedPBdepth * vibDepth[vibrato]); vibReadBite = analogRead(bitePressurePin); // alternative kind bite sensor (air pressure tube and sensor) PBITE
} else { } else {
vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibRead, (vibZero - vibMax), vibThr), vibThr, (vibZero - vibMax), 0, (0 - calculatedPBdepth * vibDepth[vibrato])); vibReadBite = touchRead(bitePin); // get sensor data, do some smoothing - SENSOR PIN 17 - PCB PINS LABELED "BITE" (GND left, sensor pin right)
} }
} else if (vibRead > vibThrLo) { if (vibReadBite < vibThrBite) {
if (UPWD == vibDirection) { if (UPWD == vibDirection) {
vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibRead, vibThrLo, (vibZero + vibMax)), vibThrLo, (vibZero + vibMax), 0, (0 - calculatedPBdepth * vibDepth[vibrato])); vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibReadBite, (vibZeroBite - vibMax), vibThrBite), vibThrBite, (vibZeroBite - vibMax), 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]));
}
} 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]));
} else {
vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibReadBite, vibThrBiteLo, (vibZeroBite + vibMax)), vibThrBiteLo, (vibZeroBite + vibMax), 0, calculatedPBdepth * vibDepth[vibrato]);
}
} else { } else {
vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibRead, vibThrLo, (vibZero + vibMax)), vibThrLo, (vibZero + vibMax), 0, calculatedPBdepth * vibDepth[vibrato]); vibSignal = vibSignal * 0.5;
}
} else { //lever vibrato
vibRead = touchRead(vibratoPin); // SENSOR PIN 15 - built in var cap
if (vibRead < vibThr) {
if (UPWD == vibDirection) {
vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibRead, (vibZero - vibMax), vibThr), vibThr, (vibZero - vibMax), 0, calculatedPBdepth * vibDepth[vibrato]);
} else {
vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibRead, (vibZero - vibMax), vibThr), vibThr, (vibZero - vibMax), 0, (0 - calculatedPBdepth * vibDepth[vibrato]));
}
} else if (vibRead > vibThrLo) {
if (UPWD == vibDirection) {
vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibRead, vibThrLo, (vibZero + vibMax)), vibThrLo, (vibZero + vibMax), 0, (0 - calculatedPBdepth * vibDepth[vibrato]));
} else {
vibSignal = vibSignal * 0.5 + 0.5 * map(constrain(vibRead, vibThrLo, (vibZero + vibMax)), vibThrLo, (vibZero + vibMax), 0, calculatedPBdepth * vibDepth[vibrato]);
}
} else {
vibSignal = vibSignal * 0.5;
} }
} else {
vibSignal = vibSignal * 0.5;
} }
switch (vibRetn) { // moving baseline switch (vibRetn) { // moving baseline
case 0: case 0:
//keep vibZero value //keep vibZero value
break; break;
case 1: case 1:
vibZero = vibZero * 0.95 + vibRead * 0.05; vibZero = vibZero * 0.95 + vibRead * 0.05;
vibZeroBite = vibZeroBite * 0.95 + vibReadBite * 0.05;
break; break;
case 2: case 2:
vibZero = vibZero * 0.9 + vibRead * 0.1; vibZero = vibZero * 0.9 + vibRead * 0.1;
vibZeroBite = vibZeroBite * 0.9 + vibReadBite * 0.1;
break; break;
case 3: case 3:
vibZero = vibZero * 0.8 + vibRead * 0.2; vibZero = vibZero * 0.8 + vibRead * 0.2;
vibZeroBite = vibZeroBite * 0.8 + vibReadBite * 0.2;
break; break;
case 4: case 4:
vibZero = vibZero * 0.6 + vibRead * 0.4; vibZero = vibZero * 0.6 + vibRead * 0.4;
vibZeroBite = vibZeroBite * 0.6 + vibReadBite * 0.4;
} }
vibThr = vibZero - vibSquelch; vibThr = vibZero - vibSquelch;
vibThrLo = vibZero + vibSquelch; vibThrLo = vibZero + vibSquelch;
vibThrBite = vibZeroBite - vibSquelchBite;
vibThrBiteLo = vibZeroBite + vibSquelchBite;
int pbPos = map(constrain(pbUp, pitchbThrVal, pitchbMaxVal), pitchbThrVal, pitchbMaxVal, 0, calculatedPBdepth); int pbPos = map(constrain(pbUp, pitchbThrVal, pitchbMaxVal), pitchbThrVal, pitchbMaxVal, 0, calculatedPBdepth);
int pbNeg = map(constrain(pbDn, pitchbThrVal, pitchbMaxVal), pitchbThrVal, pitchbMaxVal, 0, calculatedPBdepth); int pbNeg = map(constrain(pbDn, pitchbThrVal, pitchbMaxVal), pitchbThrVal, pitchbMaxVal, 0, calculatedPBdepth);
int pbSum = 8193 + pbPos - pbNeg; int pbSum = 8193 + pbPos - pbNeg;
@ -1132,19 +1183,21 @@ void extraController() {
//*********************************************************** //***********************************************************
void portamento_() { void portamento_() {
// Portamento is controlled with the bite sensor (variable capacitor) in the mouthpiece if (!vibControl){
if (biteJumper){ //PBITE (if pulled low with jumper, use pressure sensor instead of capacitive bite sensor) // Portamento is controlled with the bite sensor (variable capacitor) in the mouthpiece
biteSensor=analogRead(bitePressurePin); // alternative kind bite sensor (air pressure tube and sensor) PBITE if (biteJumper){ //PBITE (if pulled low with jumper, use pressure sensor instead of capacitive bite sensor)
} else { biteSensor=analogRead(bitePressurePin); // alternative kind bite sensor (air pressure tube and sensor) PBITE
biteSensor = touchRead(bitePin); // get sensor data, do some smoothing - SENSOR PIN 17 - PCB PINS LABELED "BITE" (GND left, sensor pin right) } else {
} biteSensor = touchRead(bitePin); // get sensor data, do some smoothing - SENSOR PIN 17 - PCB PINS LABELED "BITE" (GND left, sensor pin right)
if (portamento && (biteSensor >= portamThrVal)) { // if we are enabled and over the threshold, send portamento }
if (!portIsOn) { if (portamento && (biteSensor >= portamThrVal)) { // if we are enabled and over the threshold, send portamento
portOn(); if (!portIsOn) {
portOn();
}
port();
} else if (portIsOn) { // we have just gone below threshold, so send zero value
portOff();
} }
port();
} else if (portIsOn) { // we have just gone below threshold, so send zero value
portOff();
} }
} }

View file

@ -62,6 +62,9 @@ extern unsigned short vibSens; // vibrato sensitivity
extern unsigned short vibRetn; // vibrato return speed extern unsigned short vibRetn; // vibrato return speed
extern unsigned short vibSquelch; //vibrato signal squelch extern unsigned short vibSquelch; //vibrato signal squelch
extern unsigned short vibDirection; //direction of first vibrato wave UPWD or DNWD extern unsigned short vibDirection; //direction of first vibrato wave UPWD or DNWD
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 fastPatch[7];
extern uint16_t gateOpenEnable; extern uint16_t gateOpenEnable;
extern uint16_t specialKeyEnable; extern uint16_t specialKeyEnable;
@ -103,6 +106,9 @@ extern byte oldpkey;
extern int vibThr; // this gets auto calibrated in setup extern int vibThr; // this gets auto calibrated in setup
extern int vibThrLo; extern int vibThrLo;
extern int vibZero; extern int vibZero;
extern int vibZeroBite;
extern int vibThrBite;
extern int vibThrBiteLo;
// Key variables, TRUE (1) for pressed, FALSE (0) for not pressed // Key variables, TRUE (1) for pressed, FALSE (0) for not pressed
extern byte K1; // Valve 1 (pitch change -2) extern byte K1; // Valve 1 (pitch change -2)

View file

@ -871,15 +871,6 @@ const MenuEntrySub vibDepthMenu = {
nullptr nullptr
}; };
const MenuEntrySub vibSenseMenu = {
MenuType::ESub, "SENSE", "LEVEL", &vibSens, 1, 12, MenuEntryFlags::ENone,
[](SubMenuRef __unused,char* textBuffer, const char** __unused unit) {
numToString(vibSens, textBuffer);
},
[](const MenuEntrySub & __unused sub) { writeSetting(VIB_SENS_ADDR,vibSens); }
, nullptr
};
const MenuEntrySub vibRetnMenu = { const MenuEntrySub vibRetnMenu = {
MenuType::ESub, "RETURN", "LEVEL", &vibRetn, 0, 4, MenuEntryFlags::ENone, MenuType::ESub, "RETURN", "LEVEL", &vibRetn, 0, 4, MenuEntryFlags::ENone,
[](SubMenuRef __unused, char* textBuffer, const char** __unused unit) { [](SubMenuRef __unused, char* textBuffer, const char** __unused unit) {
@ -889,8 +880,17 @@ const MenuEntrySub vibRetnMenu = {
, nullptr , nullptr
}; };
const MenuEntrySub vibSenseMenu = {
MenuType::ESub, "SENSE LVR", "LEVEL", &vibSens, 1, 12, MenuEntryFlags::ENone,
[](SubMenuRef __unused,char* textBuffer, const char** __unused unit) {
numToString(vibSens, textBuffer);
},
[](const MenuEntrySub & __unused sub) { writeSetting(VIB_SENS_ADDR,vibSens); }
, nullptr
};
const MenuEntrySub vibSquelchMenu = { const MenuEntrySub vibSquelchMenu = {
MenuType::ESub, "SQUELCH", "LEVEL", &vibSquelch, 1, 30, MenuEntryFlags::ENone, MenuType::ESub, "SQUELCH L", "LEVEL", &vibSquelch, 1, 30, MenuEntryFlags::ENone,
[](SubMenuRef __unused, char* textBuffer, const char** __unused unit) { [](SubMenuRef __unused, char* textBuffer, const char** __unused unit) {
numToString(vibSquelch, textBuffer); numToString(vibSquelch, textBuffer);
}, },
@ -898,6 +898,36 @@ const MenuEntrySub vibSquelchMenu = {
, nullptr , nullptr
}; };
const MenuEntrySub vibSenseBiteMenu = {
MenuType::ESub, "SENSE BTE", "LEVEL", &vibSensBite, 1, 12, MenuEntryFlags::ENone,
[](SubMenuRef __unused,char* textBuffer, const char** __unused unit) {
numToString(vibSensBite, textBuffer);
},
[](const MenuEntrySub & __unused sub) { writeSetting(VIB_SENS_BITE_ADDR,vibSensBite); }
, nullptr
};
const MenuEntrySub vibSquelchBiteMenu = {
MenuType::ESub, "SQUELCH B", "LEVEL", &vibSquelchBite, 1, 30, MenuEntryFlags::ENone,
[](SubMenuRef __unused, char* textBuffer, const char** __unused unit) {
numToString(vibSquelchBite, textBuffer);
},
[](const MenuEntrySub & __unused sub) { writeSetting(VIB_SQUELCH_BITE_ADDR,vibSquelchBite); }
, nullptr
};
const MenuEntrySub vibControlMenu = {
MenuType::ESub, "CONTROL", "CONTROL", &vibControl , 0, 1, MenuEntryFlags::EMenuEntryWrap,
[](SubMenuRef __unused, char* out, const char** __unused unit) {
if (vibControl)
strncpy(out, "BIT", 4);
else
strncpy(out, "LVR", 4);
},
[](const MenuEntrySub & __unused sub) { writeSetting(VIB_CONTROL_ADDR,vibControl); }
, nullptr
};
const MenuEntrySub vibDirMenu = { const MenuEntrySub vibDirMenu = {
MenuType::ESub, "DIRECTION", "DIRECTION", &vibDirection , 0, 1, MenuEntryFlags::EMenuEntryWrap, MenuType::ESub, "DIRECTION", "DIRECTION", &vibDirection , 0, 1, MenuEntryFlags::EMenuEntryWrap,
[](SubMenuRef __unused, char* out, const char** __unused unit) { [](SubMenuRef __unused, char* out, const char** __unused unit) {
@ -911,11 +941,14 @@ const MenuEntrySub vibDirMenu = {
}; };
const MenuEntry* vibratorMenuEntries[] = { const MenuEntry* vibratorMenuEntries[] = {
(MenuEntry*)&vibControlMenu,
(MenuEntry*)&vibDepthMenu, (MenuEntry*)&vibDepthMenu,
(MenuEntry*)&vibSenseMenu,
(MenuEntry*)&vibRetnMenu, (MenuEntry*)&vibRetnMenu,
(MenuEntry*)&vibDirMenu,
(MenuEntry*)&vibSenseMenu,
(MenuEntry*)&vibSquelchMenu, (MenuEntry*)&vibSquelchMenu,
(MenuEntry*)&vibDirMenu (MenuEntry*)&vibSenseBiteMenu,
(MenuEntry*)&vibSquelchBiteMenu,
}; };
const MenuPage vibratoMenuPage = { const MenuPage vibratoMenuPage = {

View file

@ -51,6 +51,9 @@
#define VIB_DIRECTION_ADDR 86 #define VIB_DIRECTION_ADDR 86
#define BREATH_CC2_ADDR 88 #define BREATH_CC2_ADDR 88
#define BREATH_CC2_RISE_ADDR 90 #define BREATH_CC2_RISE_ADDR 90
#define VIB_SENS_BITE_ADDR 92
#define VIB_SQUELCH_BITE_ADDR 94
#define VIB_CONTROL_ADDR 96
//"factory" values for settings //"factory" values for settings
#define VERSION 32 #define VERSION 32
@ -90,9 +93,12 @@
#define PRIO_FACTORY 0 // Mono priority 0 - BAS(e note), 1 - ROT(ating note) #define PRIO_FACTORY 0 // Mono priority 0 - BAS(e note), 1 - ROT(ating note)
#define VIB_SENS_FACTORY 6 // 1 least sensitive, higher more sensitive #define VIB_SENS_FACTORY 6 // 1 least sensitive, higher more sensitive
#define VIB_RETN_FACTORY 2 // 0, no return, 1 slow return, higher faster return #define VIB_RETN_FACTORY 2 // 0, no return, 1 slow return, higher faster return
#define VIB_SQUELCH_FACTORY 15 // 0 to 30, vib signal squelch #define VIB_SQUELCH_FACTORY 12 // 0 to 30, vib signal squelch
#define VIB_DIRECTION_FACTORY 0 #define VIB_DIRECTION_FACTORY 0
#define BREATH_CC2_FACTORY 0 //OFF,1-127 #define BREATH_CC2_FACTORY 0 //OFF,1-127
#define BREATH_CC2_RISE_FACTORY 1 #define BREATH_CC2_RISE_FACTORY 1
#define VIB_SENS_BITE_FACTORY 6
#define VIB_SQUELCH_BITE_FACTORY 12
#define VIB_CONTROL_FACTORY 0
#endif #endif