Breath reading changed from 10 bit to 12 bit. Added hi res midi on cc#1 (mod) and an option to compile with breath CV output on DAC pin. Special key functions implemented (slur sustain, parallel chord, sub octave double). Cursor blinking disabled during note on to prevent glitching when testing changes in menus.

This commit is contained in:
Johan Berglund 2017-09-16 22:53:18 +02:00
parent 7598f62986
commit 5542a840c6

337
NuEVI.ino
View file

@ -19,6 +19,58 @@ PROGRAMME FUNCTION: EVI Wind Controller using the Freescale MP3V5004GP breath
//_______________________________________________________________________________________________ DECLARATIONS
// Compile options, comment/uncomment to change
//#define BREATHCVOUTA14 // enables breath CV out on pin A14/DAC for Teensy 3.2
//#define BREATHCVOUTA12 // enables breath CV out on pin A12/DAC for Teensy LC
// Pin definitions
// Teensy pins
#define specialKeyPin 0 // 0
#define halfPitchBendKeyPin 1 // 1
#define bitePin 17
#define extraPin 16
#define pbUpPin 23
#define pbDnPin 22
#define vibratoPin 15
#define dPin 3
#define ePin 4
#define uPin 5
#define mPin 6
#define bLedPin 10
#define pLedPin 9
// MPR121 pins
#define R1Pin 10
#define R2Pin 11
#define R3Pin 8
#define R4Pin 9
#define R5Pin 6
#define K4Pin 7
#define K1Pin 4
#define K2Pin 5
#define K3Pin 2
#define K5Pin 3
#define K6Pin 0
#define K7Pin 1
/*
* PINOUT ON PCB vs PINS ON MPR121
*
* (R2) (R4) (K4) (K2) (K5) (K7) <-> (11) (09) (07) (05) (03) (01)
*
* (R1) (R3/6) (R5) (K1) (K3) (K6) <-> (10) (08) (06) (04) (02) (00)
*
*/
#define ON_Delay 20 // Set Delay after ON threshold before velocity is checked (wait for tounging peak)
#define touch_Thr 1200 // sensitivity for Teensy touch sensors
@ -94,9 +146,9 @@ PROGRAMME FUNCTION: EVI Wind Controller using the Freescale MP3V5004GP breath
#define CTOUCH_THR_ADDR 42
//"factory" values for settings
#define VERSION 15
#define BREATH_THR_FACTORY 350
#define BREATH_MAX_FACTORY 1000
#define VERSION 16
#define BREATH_THR_FACTORY 1400
#define BREATH_MAX_FACTORY 4000
#define PORTAM_THR_FACTORY 1730
#define PORTAM_MAX_FACTORY 3300
#define PITCHB_THR_FACTORY 1300
@ -222,7 +274,7 @@ unsigned short octave; //
int breathLoLimit = 0;
int breathHiLimit = 1023;
int breathHiLimit = 4095;
int portamLoLimit = 1000;
int portamHiLimit = 5000;
int pitchbLoLimit = 500;
@ -240,11 +292,6 @@ int ctouchStep;
int minOffset = 50;
byte dPin = 3;
byte ePin = 4;
byte uPin = 5;
byte mPin = 6;
int deumButtons = 0;
int lastDeumButtons = 0;
int deumButtonState = 0;
@ -269,7 +316,8 @@ byte subExtra = 0;
byte subVibrato = 0;
byte subDeglitch = 0;
byte ccList[4] = {0,2,7,11}; // OFF, Breath, Volume, Expression
byte ccList[5] = {0,1,2,7,11}; // OFF, Modulation (Hi-res), Breath, Volume, Expression
int pbDepthList[13] = {0,8192,4096,2731,2048,1638,1365,1170,1024,910,819,744,683};
byte cursorNow;
@ -309,6 +357,7 @@ byte doPatchUpdate=1;
int breathLevel=0; // breath level (smoothed) not mapped to CC value
int oldbreath=0;
unsigned int oldbreathhires=0;
int pressureSensor; // pressure data from breath sensor, for midi breath cc and breath threshold checks
int lastPressure;
@ -340,9 +389,29 @@ byte dirUp=0; // direction of first vibrato wave
int fingeredNote; // note calculated from fingering (switches), transpose and octave settings
byte activeNote; // note playing
byte startNote=36; // set startNote to C (change this value in steps of 12 to start in other octaves)
int slurBase; // first note in slur sustain chord
int slurInterval[9] = {-5,0,0,0,0,0,0,0,0};
byte addedIntervals = 1;
// Key variables, TRUE (1) for pressed, FALSE (0) for not pressed
byte K1; // Valve 1 (pitch change -2)
byte K2; // Valve 2 (pitch change -1)
byte K3; // Valve 3 (pitch change -3)
byte K4; // Left Hand index finger (pitch change -5)
byte K5; // Trill key 1 (pitch change +2)
byte K6; // Trill key 2 (pitch change +1)
byte K7; // Trill key 3 (pitch change +4)
byte octaveR = 0;
byte halfPitchBendKey;
byte specialKey;
byte lastSpecialKey = 0;
byte slurSustain = 0;
byte parallelChord = 0;
byte subOctaveDouble = 0;
byte breathLedBrightness = 100; // up to 255, PWM
byte portamLedBrightness = 100; // up to 255, PWM
@ -406,14 +475,16 @@ void setup() {
pitchbStep = (pitchbHiLimit - pitchbLoLimit)/92;
extracStep = (extracHiLimit - extracLoLimit)/92;
ctouchStep = (ctouchHiLimit - ctouchLoLimit)/92;
analogReadResolution(12); // todo: adapt code for this first, then uncomment
pinMode(dPin, INPUT_PULLUP);
pinMode(ePin, INPUT_PULLUP);
pinMode(uPin, INPUT_PULLUP);
pinMode(mPin, INPUT_PULLUP);
pinMode(10, OUTPUT); // breath indicator LED
pinMode(9, OUTPUT); // portam indicator LED
pinMode(bLedPin, OUTPUT); // breath indicator LED
pinMode(pLedPin, OUTPUT); // portam indicator LED
if (!touchSensor.begin(0x5A)) {
while (1); // Touch sensor initialization failed - stop doing stuff
@ -463,6 +534,9 @@ void loop() {
usbMIDI.sendProgramChange(activePatch-1,activeMIDIchannel);
dinMIDIsendProgramChange(activePatch-1,activeMIDIchannel-1);
if (readSetting(PATCH_ADDR) != activePatch) writeSetting(PATCH_ADDR,activePatch);
slurSustain = 0;
parallelChord = 0;
subOctaveDouble = 0;
doPatchUpdate = 0;
}
if (pressureSensor > breathThrVal) {
@ -472,6 +546,27 @@ void loop() {
initial_breath_value = pressureSensor;
mainState = RISE_WAIT; // Go to next state
}
specialKey=(touchRead(specialKeyPin) > touch_Thr); //S2 on pcb
if (lastSpecialKey != specialKey){
if (specialKey){
// special key just pressed, check other keys
readSwitches();
if (K4) {
if (!slurSustain) {
slurSustain = 1;
parallelChord = 0;
} else slurSustain = 0;
}
if (K5) {
if (!parallelChord) {
parallelChord = 1;
slurSustain = 0;
} else parallelChord = 0;
}
if (K1) subOctaveDouble = !subOctaveDouble;
}
}
lastSpecialKey = specialKey;
} else if (mainState == RISE_WAIT) {
if (pressureSensor > breathThrVal) {
// Has enough time passed for us to collect our second
@ -479,7 +574,6 @@ void loop() {
if (millis() - breath_on_time > ON_Delay) {
// Yes, so calculate MIDI note and velocity, then send a note on event
readSwitches();
//fingeredNote = startNote + 24;
// We should be at tonguing peak, so set velocity based on current pressureSensor value unless fixed velocity is set
// If initial value is greater than value after delay, go with initial value, constrain input to keep mapped output within 1 to 127
if (!velocity) {
@ -488,9 +582,29 @@ void loop() {
breathLevel=constrain(max(pressureSensor,initial_breath_value),breathThrVal,breathMaxVal);
breath(); // send breath data
fingeredNote=noteValueCheck(fingeredNote);
if ((fingeredNote >= 0) and (fingeredNote <= 127)){ // don't send midi out of range
usbMIDI.sendNoteOn(fingeredNote, velocitySend, activeMIDIchannel); // send Note On message for new note
dinMIDIsendNoteOn(fingeredNote, velocitySend, activeMIDIchannel - 1);
usbMIDI.sendNoteOn(fingeredNote, velocitySend, activeMIDIchannel); // send Note On message for new note
dinMIDIsendNoteOn(fingeredNote, velocitySend, activeMIDIchannel - 1);
if (parallelChord){
for (int i=0; i < addedIntervals; i++){
usbMIDI.sendNoteOn(noteValueCheck(fingeredNote+slurInterval[i]), velocitySend, activeMIDIchannel); // send Note On message for new note
dinMIDIsendNoteOn(noteValueCheck(fingeredNote+slurInterval[i]), velocitySend, activeMIDIchannel - 1);
}
}
if (slurSustain){
usbMIDI.sendControlChange(64,127, activeMIDIchannel);
dinMIDIsendControlChange(64,127, activeMIDIchannel - 1);
slurBase = fingeredNote;
addedIntervals = 0;
}
if (subOctaveDouble){
usbMIDI.sendNoteOn(noteValueCheck(fingeredNote-12), velocitySend, activeMIDIchannel);
dinMIDIsendNoteOn(noteValueCheck(fingeredNote-12), velocitySend, activeMIDIchannel - 1);
if (parallelChord){
for (int i=0; i < addedIntervals; i++){
usbMIDI.sendNoteOn(noteValueCheck(fingeredNote+slurInterval[i]-12), velocitySend, activeMIDIchannel); // send Note On message for new note
dinMIDIsendNoteOn(noteValueCheck(fingeredNote+slurInterval[i]-12), velocitySend, activeMIDIchannel - 1);
}
}
}
activeNote=fingeredNote;
mainState = NOTE_ON;
@ -501,18 +615,36 @@ void loop() {
mainState = NOTE_OFF;
}
} else if (mainState == NOTE_ON) {
cursorBlinkTime = millis(); // keep display from updating with cursor blinking if note on
if (pressureSensor < breathThrVal) {
// Value has fallen below threshold - turn the note off
activeNote=noteValueCheck(activeNote);
if ((activeNote >= 0) and (activeNote <= 127)){ // don't send midi out of range
usbMIDI.sendNoteOff(activeNote, velocitySend, activeMIDIchannel); // send Note Off message
dinMIDIsendNoteOff(activeNote, velocitySend, activeMIDIchannel - 1);
usbMIDI.sendNoteOff(activeNote, velocitySend, activeMIDIchannel); // send Note Off message
dinMIDIsendNoteOff(activeNote, velocitySend, activeMIDIchannel - 1);
if (parallelChord){
for (int i=0; i < addedIntervals; i++){
usbMIDI.sendNoteOff(noteValueCheck(activeNote+slurInterval[i]), velocitySend, activeMIDIchannel); // send Note On message for new note
dinMIDIsendNoteOff(noteValueCheck(activeNote+slurInterval[i]), velocitySend, activeMIDIchannel - 1);
}
}
if (subOctaveDouble){
usbMIDI.sendNoteOff(noteValueCheck(activeNote-12), velocitySend, activeMIDIchannel);
dinMIDIsendNoteOff(noteValueCheck(activeNote-12), velocitySend, activeMIDIchannel - 1);
if (parallelChord){
for (int i=0; i < addedIntervals; i++){
usbMIDI.sendNoteOff(noteValueCheck(activeNote+slurInterval[i]-12), velocitySend, activeMIDIchannel); // send Note On message for new note
dinMIDIsendNoteOff(noteValueCheck(activeNote+slurInterval[i]-12), velocitySend, activeMIDIchannel - 1);
}
}
}
if (slurSustain){
usbMIDI.sendControlChange(64,0, activeMIDIchannel);
dinMIDIsendControlChange(64,0, activeMIDIchannel - 1);
}
breathLevel=0;
mainState = NOTE_OFF;
} else {
readSwitches();
//fingeredNote = startNote + 24;
if (fingeredNote != lastFingering){ //
// reset the debouncing timer
lastDeglitchTime = millis();
@ -525,15 +657,58 @@ void loop() {
// Send a note off for the current note and a note on for
// the new note.
velocity = map(constrain(pressureSensor,breathThrVal,breathMaxVal),breathThrVal,breathMaxVal,7,127); // set new velocity value based on current pressure sensor level
fingeredNote=noteValueCheck(fingeredNote);
if ((fingeredNote >= 0) and (fingeredNote <= 127)){ // don't send midi out of range
usbMIDI.sendNoteOn(fingeredNote, velocitySend, activeMIDIchannel); // send Note On message for new note
dinMIDIsendNoteOn(fingeredNote, velocitySend, activeMIDIchannel - 1);
}
activeNote=noteValueCheck(activeNote);
if ((activeNote >= 0) and (activeNote <= 127)){ // don't send midi out of range
usbMIDI.sendNoteOff(activeNote, 0, activeMIDIchannel); // send Note Off message for previous note (legato)
dinMIDIsendNoteOff(activeNote, 0, activeMIDIchannel - 1);
if (parallelChord || subOctaveDouble){ // poly playing, send old note off before new note on
usbMIDI.sendNoteOff(activeNote, velocitySend, activeMIDIchannel); // send Note Off message for old note
dinMIDIsendNoteOff(activeNote, velocitySend, activeMIDIchannel - 1);
}
if (parallelChord){
for (int i=0; i < addedIntervals; i++){
usbMIDI.sendNoteOff(noteValueCheck(activeNote+slurInterval[i]), velocitySend, activeMIDIchannel); // send Note Off message for old note
dinMIDIsendNoteOff(noteValueCheck(activeNote+slurInterval[i]), velocitySend, activeMIDIchannel - 1);
}
}
if (subOctaveDouble){
usbMIDI.sendNoteOff(noteValueCheck(activeNote-12), velocitySend, activeMIDIchannel); // send Note Off message for old note
dinMIDIsendNoteOff(noteValueCheck(activeNote-12), velocitySend, activeMIDIchannel - 1);
if (parallelChord){
for (int i=0; i < addedIntervals; i++){
usbMIDI.sendNoteOff(noteValueCheck(activeNote+slurInterval[i]-12), velocitySend, activeMIDIchannel); // send Note Off message for old note
dinMIDIsendNoteOff(noteValueCheck(activeNote+slurInterval[i]-12), velocitySend, activeMIDIchannel - 1);
}
}
}
fingeredNote=noteValueCheck(fingeredNote);
usbMIDI.sendNoteOn(fingeredNote, velocitySend, activeMIDIchannel); // send Note On message for new note
dinMIDIsendNoteOn(fingeredNote, velocitySend, activeMIDIchannel - 1);
if (parallelChord){
for (int i=0; i < addedIntervals; i++){
usbMIDI.sendNoteOn(noteValueCheck(fingeredNote+slurInterval[i]), velocitySend, activeMIDIchannel); // send Note On message for new note
dinMIDIsendNoteOn(noteValueCheck(fingeredNote+slurInterval[i]), velocitySend, activeMIDIchannel - 1);
}
}
if (subOctaveDouble){
usbMIDI.sendNoteOn(noteValueCheck(fingeredNote-12), velocitySend, activeMIDIchannel); // send Note On message for new note
dinMIDIsendNoteOn(noteValueCheck(fingeredNote-12), velocitySend, activeMIDIchannel - 1);
if (parallelChord){
for (int i=0; i < addedIntervals; i++){
usbMIDI.sendNoteOn(noteValueCheck(fingeredNote+slurInterval[i]-12), velocitySend, activeMIDIchannel); // send Note On message for new note
dinMIDIsendNoteOn(noteValueCheck(fingeredNote+slurInterval[i]-12), velocitySend, activeMIDIchannel - 1);
}
}
}
if (!parallelChord && !subOctaveDouble){ // mono playing, send old note off after new note on
usbMIDI.sendNoteOff(activeNote, velocitySend, activeMIDIchannel); // send Note Off message
dinMIDIsendNoteOff(activeNote, velocitySend, activeMIDIchannel - 1);
}
if (slurSustain){
addedIntervals++;
slurInterval[addedIntervals] = fingeredNote - slurBase;
}
activeNote=fingeredNote;
}
@ -542,10 +717,7 @@ void loop() {
}
// Is it time to send more CC data?
if (millis() - ccSendTime > CC_INTERVAL) {
// Read touch pads (Teensy built in) and put value in variables
specialKey=(touchRead(0) > touch_Thr); //S2 - not yet used
halfPitchBendKey=(touchRead(1) > touch_Thr); //S1 - hold for 1/2 pitchbend value
// deal with Breath, Pitch Bend and Modulation
// deal with Breath, Pitch Bend, Modulation, etc.
breath();
pitch_bend();
portamento_();
@ -563,6 +735,7 @@ void loop() {
//do menu stuff
menu();
}
//_______________________________________________________________________________________________ FUNCTIONS
// MIDI note value check with out of range octave repeat
@ -575,6 +748,9 @@ int noteValueCheck(int note){
return note;
}
//**************************************************************
// Send a three byte din midi message
void midiSend3B(byte midistatus, byte data1, byte data2) {
Serial3.write(midistatus);
@ -638,14 +814,14 @@ void dinMIDIsendProgramChange(byte value, byte ch) {
void statusLEDs() {
if (breathLevel > breathThrVal){ // breath indicator LED, labeled "B" on PCB
analogWrite(10, breathLedBrightness);
analogWrite(bLedPin, breathLedBrightness);
} else {
analogWrite(10, 0);
analogWrite(bLedPin, 0);
}
if (biteSensor > portamThrVal){ // portamento indicator LED, labeled "P" on PCB
analogWrite(9, portamLedBrightness);
analogWrite(pLedPin, portamLedBrightness);
} else {
analogWrite(9, 0);
analogWrite(pLedPin, 0);
}
}
@ -653,10 +829,12 @@ void statusLEDs() {
void breath(){
int breathCCval;
unsigned int breathCCvalHires;
breathLevel = breathLevel*0.8+pressureSensor*0.2; // smoothing of breathLevel value
breathCCval = map(constrain(breathLevel,breathThrVal,breathMaxVal),breathThrVal,breathMaxVal,0,127);
breathCCvalHires = map(constrain(breathLevel,breathThrVal,breathMaxVal),breathThrVal,breathMaxVal,0,16383);
if (breathCCval != oldbreath){ // only send midi data if breath has changed from previous value
if (breathCCval){
if (ccList[breathCC] > 1){
// send midi cc
usbMIDI.sendControlChange(ccList[breathCC], breathCCval, activeMIDIchannel);
dinMIDIsendControlChange(ccList[breathCC], breathCCval, activeMIDIchannel - 1);
@ -664,10 +842,27 @@ void breath(){
if (breathAT){
// send aftertouch
usbMIDI.sendAfterTouch(breathCCval, activeMIDIchannel);
dinMIDIsendAfterTouch(breathCCval, activeMIDIchannel);
dinMIDIsendAfterTouch(breathCCval, activeMIDIchannel - 1);
}
oldbreath = breathCCval;
}
}
if (breathCCvalHires != oldbreathhires){
#if defined(BREATHCVOUTA14)
analogWrite(A14,breathCCvalHires); // Breath CV out at A14 on Teensy 3.2
#endif
#if defined(BREATHCVOUTA12)
analogWrite(A12,breathCCvalHires); // Breath CV out at A12 on Teensy LC
#endif
if (ccList[breathCC] == 1){ // if modulation cc is used, send high resolution midi
int fine = breathCCvalHires & 0x007F;
int coarse = (breathCCvalHires >>7) & 0x007F;
usbMIDI.sendControlChange(ccList[breathCC], coarse, activeMIDIchannel);
dinMIDIsendControlChange(ccList[breathCC], coarse, activeMIDIchannel - 1);
usbMIDI.sendControlChange(ccList[breathCC]+32, fine, activeMIDIchannel);
dinMIDIsendControlChange(ccList[breathCC]+32, fine, activeMIDIchannel - 1);
}
oldbreathhires = breathCCvalHires;
}
}
//**************************************************************
@ -678,9 +873,10 @@ void pitch_bend(){
float nudge;
int calculatedPBdepth;
byte vibratoMoved = 0;
pbUp = touchRead(23); // SENSOR PIN 23 - PCB PIN "Pu"
pbDn = touchRead(22); // SENSOR PIN 22 - PCB PIN "Pd"
int vibRead = touchRead(15); // SENSOR PIN 15 - built in var cap
pbUp = touchRead(pbUpPin); // SENSOR PIN 23 - PCB PIN "Pu"
pbDn = touchRead(pbDnPin); // SENSOR PIN 22 - PCB PIN "Pd"
halfPitchBendKey=(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
if ((vibRead < vibThr)&&(vibRead > oldvibRead)){
nudge = 0.01*constrain(abs(vibRead - oldvibRead),0,100);
if (!dirUp){
@ -731,7 +927,7 @@ void pitch_bend(){
void extraController(){
// Extra Controller is the lip touch sensor (proportional) in front of the mouthpiece
exSensor=exSensor*0.6+0.4*touchRead(16); // 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)
if (extraCT && (exSensor >= extracThrVal)) { // if we are enabled and over the threshold, send data
if (!extracIsOn) {
extracIsOn=1;
@ -764,9 +960,10 @@ void extraController(){
}
//***********************************************************
void portamento_(){
// Portamento is controlled with the bite sensor (variable capacitor) in the mouthpiece
biteSensor=biteSensor*0.6+0.4*touchRead(17); // get sensor data, do some smoothing - SENSOR PIN 17 - PCB PINS LABELED "BITE" (GND left, sensor pin right)
biteSensor=biteSensor*0.6+0.4*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) {
portOn();
@ -816,17 +1013,6 @@ void portOff(){
void readSwitches(){
// Key variables, TRUE (1) for pressed, FALSE (0) for not pressed
byte K1; // Valve 1 (pitch change -2)
byte K2; // Valve 2 (pitch change -1)
byte K3; // Valve 3 (pitch change -3)
byte K4; // Left Hand index finger (pitch change -5)
byte K5; // Trill key 1 (pitch change +2)
byte K6; // Trill key 2 (pitch change +1)
byte K7; // Trill key 3 (pitch change +4)
byte octaveR = 0;
// Read touch pads (MPR121) and put value in variables
int touchValue[12];
for (byte i=0; i<12; i++){
@ -834,31 +1020,22 @@ void readSwitches(){
}
// Octave rollers
if ((touchValue[6] < ctouchThrVal) && (touchValue[8] < ctouchThrVal)) octaveR = 6; //R6 = R5 && R3
else if (touchValue[6] < ctouchThrVal) octaveR = 5; //R5
else if (touchValue[9] < ctouchThrVal) octaveR = 4; //R4
else if (touchValue[8] < ctouchThrVal) octaveR = 3; //R3
else if (touchValue[11] < ctouchThrVal) octaveR = 2; //R2
else if (touchValue[10] < ctouchThrVal) octaveR = 1; //R1
octaveR = 0;
if ((touchValue[R5Pin] < ctouchThrVal) && (touchValue[R3Pin] < ctouchThrVal)) octaveR = 6; //R6 = R5 && R3
else if (touchValue[R5Pin] < ctouchThrVal) octaveR = 5; //R5
else if (touchValue[R4Pin] < ctouchThrVal) octaveR = 4; //R4
else if (touchValue[R3Pin] < ctouchThrVal) octaveR = 3; //R3
else if (touchValue[R2Pin] < ctouchThrVal) octaveR = 2; //R2
else if (touchValue[R1Pin] < ctouchThrVal) octaveR = 1; //R1
// Valves and trill keys
K4=(touchValue[7] < ctouchThrVal);
K1=(touchValue[4] < ctouchThrVal);
K2=(touchValue[5] < ctouchThrVal);
K3=(touchValue[2] < ctouchThrVal);
K5=(touchValue[3] < ctouchThrVal);
K6=(touchValue[0] < ctouchThrVal);
K7=(touchValue[1] < ctouchThrVal);
/*
* PINOUT ON PCB vs PINS ON MPR121
*
* (R2) (R4) (K4) (K2) (K5) (K7) <-> (11) (09) (07) (05) (03) (01)
*
* (R1) (R3/6) (R5) (K1) (K3) (K6) <-> (10) (08) (06) (04) (02) (00)
*
*/
K4=(touchValue[K4Pin] < ctouchThrVal);
K1=(touchValue[K1Pin] < ctouchThrVal);
K2=(touchValue[K2Pin] < ctouchThrVal);
K3=(touchValue[K3Pin] < ctouchThrVal);
K5=(touchValue[K5Pin] < ctouchThrVal);
K6=(touchValue[K6Pin] < ctouchThrVal);
K7=(touchValue[K7Pin] < ctouchThrVal);
// Calculate midi note number from pressed keys
fingeredNote=startNote-2*K1-K2-3*K3-5*K4+2*K5+K6+4*K7+octaveR*12+(octave-3)*12+transpose-12;
@ -924,7 +1101,7 @@ void menu() {
// save the reading. Next time through the loop, it'll be the lastButtonState:
lastDeumButtons = deumButtons;
if (state && ((millis() - menuTime) > menuTimeUp)) { // shut off menu system if not used for a while
if (state && ((millis() - menuTime) > menuTimeUp)) { // shut off menu system if not used for a while (changes not stored by exiting a setting manually will not be stored in EEPROM)
state = DISPLAYOFF_IDL;
stateFirstRun = 1;
subTranspose = 0;
@ -1899,7 +2076,7 @@ void menu() {
break;
case 4:
// up
if (breathCC < 3){
if (breathCC < 4){
plotBreathCC(BLACK);
breathCC++;
plotBreathCC(WHITE);