Added Teensy touch sensors to touch adjustment settings (they had a fixed thr value before). Fix for newer teensyduino versions where pitchbend over USB is changed (compile option in start of code, #define NEWTEENSYDUINO). Added Filter Cutoff (CF) as an option for breath control. Added legacy controls for patch selection and midi channel selection (default off). Changed names for some menu items.

This commit is contained in:
Johan Berglund 2018-07-31 11:54:29 +02:00
parent 564031447a
commit 69e582cd47
2 changed files with 105 additions and 18 deletions

123
NuEVI.ino
View file

@ -23,6 +23,7 @@ PROGRAMME FUNCTION: EVI Wind Controller using the Freescale MP3V5004GP breath
// Compile options, comment/uncomment to change // Compile options, comment/uncomment to change
#define REVB #define REVB
//#define NEWTEENSYDUINO
// Pin definitions // Pin definitions
@ -107,7 +108,7 @@ PROGRAMME FUNCTION: EVI Wind Controller using the Freescale MP3V5004GP breath
#endif #endif
#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 touch_Thr 1200 // sensitivity for Teensy touch sensors //#define touch_Thr 1200 // sensitivity for Teensy touch sensors
#define CCN_Port 5 // Controller number for portamento level #define CCN_Port 5 // Controller number for portamento level
#define CCN_PortOnOff 65// Controller number for portamento on/off #define CCN_PortOnOff 65// Controller number for portamento on/off
@ -325,12 +326,12 @@ unsigned short extracMaxVal;// = 2400;
unsigned short ctouchThrVal;// = 120; unsigned short ctouchThrVal;// = 120;
unsigned short transpose; unsigned short transpose;
unsigned short MIDIchannel; unsigned short MIDIchannel;
unsigned short breathCC; // OFF:MW:BR:VL:EX:MW+:BR+:VL+:EX+ unsigned short breathCC; // OFF:MW:BR:VL:EX:MW+:BR+:VL+:EX+:CF
unsigned short breathAT; unsigned short breathAT;
unsigned short velocity; unsigned short velocity;
unsigned short portamento;// switching on cc65? just cc5 enabled? SW:ON:OFF unsigned short portamento;// switching on cc65? just cc5 enabled? SW:ON:OFF
unsigned short PBdepth; // OFF:1-12 divider unsigned short PBdepth; // OFF:1-12 divider
unsigned short extraCT; // OFF:MW:FP:FC:SP unsigned short extraCT; // OFF:MW:FP:CF:SP
unsigned short vibrato; // OFF:1-9 unsigned short vibrato; // OFF:1-9
unsigned short deglitch; // 0-70 ms in steps of 5 unsigned short deglitch; // 0-70 ms in steps of 5
unsigned short patch; // 1-128 unsigned short patch; // 1-128
@ -359,6 +360,11 @@ int extracLoLimit = 500;
int extracHiLimit = 4000; int extracHiLimit = 4000;
int ctouchLoLimit = 50; int ctouchLoLimit = 50;
int ctouchHiLimit = 350; int ctouchHiLimit = 350;
int ttouchLoLimit = 50;
int ttouchHiLimit = 1900;
int touch_Thr = 1300;
int breathStep; int breathStep;
int portamStep; int portamStep;
@ -400,7 +406,7 @@ byte subParallel = 0;
byte subRotator = 0; byte subRotator = 0;
byte subPriority = 0; byte subPriority = 0;
byte ccList[9] = {0,1,2,7,11,1,2,7,11}; // OFF, Modulation, Breath, Volume, Expression (then same sent in hires) byte ccList[10] = {0,1,2,7,11,1,2,7,11,74}; // OFF, Modulation, Breath, Volume, Expression (then same sent in hires)
int pbDepthList[13] = {0,8192,4096,2731,2048,1638,1365,1170,1024,910,819,744,683}; int pbDepthList[13] = {0,8192,4096,2731,2048,1638,1365,1170,1024,910,819,744,683};
@ -441,6 +447,8 @@ byte activeMIDIchannel=1; // MIDI channel
byte activePatch=0; byte activePatch=0;
byte doPatchUpdate=0; byte doPatchUpdate=0;
byte legacy = 0;
byte FPD = 0; byte FPD = 0;
int breathLevel=0; // breath level (smoothed) not mapped to CC value int breathLevel=0; // breath level (smoothed) not mapped to CC value
@ -498,6 +506,7 @@ int oldvibRead=0;
byte dirUp=0; // direction of first vibrato wave byte dirUp=0; // direction of first vibrato wave
int fingeredNote; // note calculated from fingering (switches), transpose and octave settings int fingeredNote; // note calculated from fingering (switches), transpose and octave settings
int fingeredNoteUntransposed; // note calculated from fingering (switches), for on the fly settings
byte activeNote; // note playing byte activeNote; // note playing
byte startNote=36; // set startNote to C (change this value in steps of 12 to start in other octaves) 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 slurBase; // first note in slur sustain chord
@ -637,6 +646,7 @@ void setup() {
rotations[3] = readSetting(ROTN4_ADDR)-24; rotations[3] = readSetting(ROTN4_ADDR)-24;
priority = readSetting(PRIO_ADDR); priority = readSetting(PRIO_ADDR);
legacy = dipSwBits & (1<<1);
activePatch = patch; activePatch = patch;
breathStep = (breathHiLimit - breathLoLimit)/92; // 92 is the number of pixels in the settings bar breathStep = (breathHiLimit - breathLoLimit)/92; // 92 is the number of pixels in the settings bar
@ -645,6 +655,7 @@ void setup() {
extracStep = (extracHiLimit - extracLoLimit)/92; extracStep = (extracHiLimit - extracLoLimit)/92;
ctouchStep = (ctouchHiLimit - ctouchLoLimit)/92; ctouchStep = (ctouchHiLimit - ctouchLoLimit)/92;
touch_Thr = map(ctouchThrVal,ctouchHiLimit,ctouchLoLimit,ttouchLoLimit,ttouchHiLimit);
if (!touchSensor.begin(0x5A)) { if (!touchSensor.begin(0x5A)) {
while (1); // Touch sensor initialization failed - stop doing stuff while (1); // Touch sensor initialization failed - stop doing stuff
@ -684,7 +695,7 @@ void setup() {
display.setTextColor(WHITE); display.setTextColor(WHITE);
display.setTextSize(1); display.setTextSize(1);
display.setCursor(85,52); display.setCursor(85,52);
display.println("v.1.1.5"); // FIRMWARE VERSION NUMBER HERE <<<<<<<<<<<<<<<<<<<<<<< display.println("v.1.1.7"); // FIRMWARE VERSION NUMBER HERE <<<<<<<<<<<<<<<<<<<<<<<
display.display(); display.display();
delay(2000); delay(2000);
@ -738,6 +749,48 @@ void mainLoop() {
initial_breath_value = pressureSensor; initial_breath_value = pressureSensor;
mainState = RISE_WAIT; // Go to next state mainState = RISE_WAIT; // Go to next state
} }
if (legacy){
if ((pbUp > ((pitchbMaxVal + pitchbThrVal)/2)) && (pbDn > ((pitchbMaxVal + pitchbThrVal)/2))){ // both pb pads touched
readSwitches();
fingeredNoteUntransposed=patchLimit(fingeredNoteUntransposed+1);
if (exSensor >= ((extracThrVal+extracMaxVal)/2)){ // instant midi setting
if ((fingeredNoteUntransposed >= 72) && (fingeredNoteUntransposed <= 88)) {
MIDIchannel = fingeredNoteUntransposed - 72; // Mid C and up
digitalWrite(13,LOW);
delay(150);
digitalWrite(13,HIGH);
}
} else {
if (!pinkyKey){ // note number to patch number
if (patch != fingeredNoteUntransposed){
patch = fingeredNoteUntransposed;
doPatchUpdate = 1;
digitalWrite(13,LOW);
delay(150);
digitalWrite(13,HIGH);
}
} else { // hi and lo patch numbers
if (fingeredNoteUntransposed > 75){
if (patch != patchLimit(fingeredNoteUntransposed + 24)){
patch = patchLimit(fingeredNoteUntransposed + 24); // add 24 to get high numbers 108 to 127
doPatchUpdate = 1;
digitalWrite(13,LOW);
delay(150);
digitalWrite(13,HIGH);
}
} else {
if (patch != patchLimit(fingeredNoteUntransposed - 36)){
patch = patchLimit(fingeredNoteUntransposed - 36); // subtract 36 to get low numbers 0 to 36
doPatchUpdate = 1;
digitalWrite(13,LOW);
delay(150);
digitalWrite(13,HIGH);
}
}
}
}
}
}
specialKey=(touchRead(specialKeyPin) > touch_Thr); //S2 on pcb specialKey=(touchRead(specialKeyPin) > touch_Thr); //S2 on pcb
if (lastSpecialKey != specialKey){ if (lastSpecialKey != specialKey){
if (specialKey){ if (specialKey){
@ -1121,6 +1174,10 @@ int noteValueCheck(int note){
//************************************************************** //**************************************************************
int patchLimit(int value){
if (value < 1) return 1; else if (value > 128) return 128; else return value;
}
void midiPanic(){ // all notes off void midiPanic(){ // all notes off
usbMIDI.sendControlChange(123, 0, activeMIDIchannel); usbMIDI.sendControlChange(123, 0, activeMIDIchannel);
dinMIDIsendControlChange(123, 0, activeMIDIchannel - 1); dinMIDIsendControlChange(123, 0, activeMIDIchannel - 1);
@ -1242,7 +1299,7 @@ void breath(){
} }
if (breathCCvalHires != oldbreathhires){ if (breathCCvalHires != oldbreathhires){
if (breathCC > 4){ // send high resolution midi if ((breathCC > 4) && (breathCC < 9)){ // send high resolution midi
usbMIDI.sendControlChange(ccList[breathCC]+32, breathCCvalFine, activeMIDIchannel); usbMIDI.sendControlChange(ccList[breathCC]+32, breathCCvalFine, activeMIDIchannel);
dinMIDIsendControlChange(ccList[breathCC]+32, breathCCvalFine, activeMIDIchannel - 1); dinMIDIsendControlChange(ccList[breathCC]+32, breathCCvalFine, activeMIDIchannel - 1);
} }
@ -1303,7 +1360,11 @@ void pitch_bend(){
} }
pitchBend=constrain(pitchBend, 0, 16383); pitchBend=constrain(pitchBend, 0, 16383);
if (pitchBend != oldpb){// only send midi data if pitch bend has changed from previous value if (pitchBend != oldpb){// only send midi data if pitch bend has changed from previous value
#if defined(NEWTEENSYDUINO)
usbMIDI.sendPitchBend(pitchBend-8192, activeMIDIchannel); // newer teensyduino "pitchBend-8192" older just "pitchBend"... strange thing to change
#else
usbMIDI.sendPitchBend(pitchBend, activeMIDIchannel); usbMIDI.sendPitchBend(pitchBend, activeMIDIchannel);
#endif
dinMIDIsendPitchBend(pitchBend, activeMIDIchannel - 1); dinMIDIsendPitchBend(pitchBend, activeMIDIchannel - 1);
oldpb=pitchBend; oldpb=pitchBend;
} }
@ -1338,7 +1399,7 @@ void extraController(){
} }
oldextrac = extracCC; oldextrac = extracCC;
} }
if (extraCT == 3){ //Send filter cutoff (CC#74) if ((extraCT == 3) && (breathCC != 9)){ //Send filter cutoff (CC#74)
int extracCC = map(constrain(exSensor,extracThrVal,extracMaxVal),extracThrVal,extracMaxVal,1,127); int extracCC = map(constrain(exSensor,extracThrVal,extracMaxVal),extracThrVal,extracMaxVal,1,127);
if (extracCC != oldextrac){ if (extracCC != oldextrac){
usbMIDI.sendControlChange(74,extracCC, activeMIDIchannel); usbMIDI.sendControlChange(74,extracCC, activeMIDIchannel);
@ -1358,8 +1419,8 @@ void extraController(){
usbMIDI.sendControlChange(4,0, activeMIDIchannel); usbMIDI.sendControlChange(4,0, activeMIDIchannel);
dinMIDIsendControlChange(4,0, activeMIDIchannel - 1); dinMIDIsendControlChange(4,0, activeMIDIchannel - 1);
oldextrac = 0; oldextrac = 0;
} else if (extraCT == 3){ //FC } else if ((extraCT == 3) && (breathCC != 9)){ //CF
//send foot pedal 0 //send filter cutoff 0
usbMIDI.sendControlChange(74,0, activeMIDIchannel); usbMIDI.sendControlChange(74,0, activeMIDIchannel);
dinMIDIsendControlChange(74,0, activeMIDIchannel - 1); dinMIDIsendControlChange(74,0, activeMIDIchannel - 1);
oldextrac = 0; oldextrac = 0;
@ -1462,6 +1523,7 @@ void readSwitches(){
// Calculate midi note number from pressed keys // 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+qTransp; fingeredNote=startNote-2*K1-K2-3*K3-5*K4+2*K5+K6+4*K7+octaveR*12+(octave-3)*12+transpose-12+qTransp;
fingeredNoteUntransposed=startNote-2*K1-K2-3*K3-5*K4+2*K5+K6+4*K7+octaveR*12;
} }
//*********************************************************** //***********************************************************
@ -1606,14 +1668,27 @@ void menu() {
stateFirstRun = 1; stateFirstRun = 1;
break; break;
case 8: case 8:
// menu // menu
display.ssd1306_command(SSD1306_DISPLAYON); if (exSensor >= ((extracThrVal+extracMaxVal)/2)){ // switch legacy settings control on/off
if (pinkyKey){ legacy = !legacy;
dipSwBits = dipSwBits ^ (1<<1);
writeSetting(DIPSW_BITS_ADDR,dipSwBits);
digitalWrite(13,LOW);
delay(150);
digitalWrite(13,HIGH);
delay(150);
digitalWrite(13,LOW);
delay(150);
digitalWrite(13,HIGH);
} else if (pinkyKey){
display.ssd1306_command(SSD1306_DISPLAYON);
state = ROTATOR_MENU; state = ROTATOR_MENU;
stateFirstRun = 1;
} else { } else {
display.ssd1306_command(SSD1306_DISPLAYON);
state = MAIN_MENU; state = MAIN_MENU;
stateFirstRun = 1;
} }
stateFirstRun = 1;
break; break;
case 15: case 15:
//all keys depressed, reboot to programming mode //all keys depressed, reboot to programming mode
@ -2761,6 +2836,7 @@ void menu() {
// down // down
if (ctouchThrVal - ctouchStep > ctouchLoLimit){ if (ctouchThrVal - ctouchStep > ctouchLoLimit){
ctouchThrVal -= ctouchStep; ctouchThrVal -= ctouchStep;
touch_Thr = map(ctouchThrVal,ctouchHiLimit,ctouchLoLimit,ttouchLoLimit,ttouchHiLimit);
display.drawLine(pos1,20,pos1,26,BLACK); display.drawLine(pos1,20,pos1,26,BLACK);
pos1 = map(ctouchThrVal, ctouchLoLimit, ctouchHiLimit, 27, 119); pos1 = map(ctouchThrVal, ctouchLoLimit, ctouchHiLimit, 27, 119);
display.drawLine(pos1,20,pos1,26,WHITE); display.drawLine(pos1,20,pos1,26,WHITE);
@ -2779,6 +2855,7 @@ void menu() {
// up // up
if (ctouchThrVal + ctouchStep < ctouchHiLimit){ if (ctouchThrVal + ctouchStep < ctouchHiLimit){
ctouchThrVal += ctouchStep; ctouchThrVal += ctouchStep;
touch_Thr = map(ctouchThrVal,ctouchHiLimit,ctouchLoLimit,ttouchLoLimit,ttouchHiLimit);
display.drawLine(pos1,20,pos1,26,BLACK); display.drawLine(pos1,20,pos1,26,BLACK);
pos1 = map(ctouchThrVal, ctouchLoLimit, ctouchHiLimit, 27, 119); pos1 = map(ctouchThrVal, ctouchLoLimit, ctouchHiLimit, 27, 119);
display.drawLine(pos1,20,pos1,26,WHITE); display.drawLine(pos1,20,pos1,26,WHITE);
@ -2823,7 +2900,7 @@ void menu() {
cursorBlinkTime = millis(); cursorBlinkTime = millis();
} else { } else {
plotBreathCC(BLACK); plotBreathCC(BLACK);
breathCC = 8; breathCC = 9;
plotBreathCC(WHITE); plotBreathCC(WHITE);
cursorNow = BLACK; cursorNow = BLACK;
display.display(); display.display();
@ -2843,7 +2920,7 @@ void menu() {
break; break;
case 4: case 4:
// up // up
if (breathCC < 8){ if (breathCC < 9){
plotBreathCC(BLACK); plotBreathCC(BLACK);
breathCC++; breathCC++;
plotBreathCC(WHITE); plotBreathCC(WHITE);
@ -3962,7 +4039,7 @@ void drawRotatorMenuScreen(){
display.print("ROTATOR SETUP"); display.print("ROTATOR SETUP");
display.drawLine(0,9,127,9,WHITE); display.drawLine(0,9,127,9,WHITE);
display.setCursor(0,12); display.setCursor(0,12);
display.println("INTERVAL"); display.println("PARALLEL");
display.setCursor(0,21); display.setCursor(0,21);
display.println("ROTATE 1"); display.println("ROTATE 1");
display.setCursor(0,30); display.setCursor(0,30);
@ -4089,7 +4166,7 @@ void plotPriority(int color){
if (priority){ if (priority){
display.println("ROT"); display.println("ROT");
} else { } else {
display.println("BAS"); display.println("MEL");
} }
} }
@ -4186,6 +4263,10 @@ void plotBreathCC(int color){
display.setCursor(79,33); display.setCursor(79,33);
display.println("EX+"); display.println("EX+");
break; break;
case 9:
display.setCursor(83,33);
display.println("CF");
break;
} }
} else { } else {
display.setCursor(79,33); display.setCursor(79,33);
@ -4387,7 +4468,7 @@ void plotExtra(int color){
break; break;
case 3: case 3:
display.setCursor(83,33); display.setCursor(83,33);
display.println("FC"); display.println("CF");
break; break;
case 4: case 4:
display.setCursor(83,33); display.setCursor(83,33);
@ -4641,6 +4722,12 @@ void drawSensorPixels(){
pos = map(constrain(touchSensor.filteredData(i), ctouchLoLimit, ctouchHiLimit), ctouchLoLimit, ctouchHiLimit, 28, 118); pos = map(constrain(touchSensor.filteredData(i), ctouchLoLimit, ctouchHiLimit), ctouchLoLimit, ctouchHiLimit, 28, 118);
display.drawPixel(pos, 38, WHITE); display.drawPixel(pos, 38, WHITE);
} }
int posRead = map(touchRead(halfPitchBendKeyPin),ttouchLoLimit,ttouchHiLimit,ctouchHiLimit,ctouchLoLimit);
pos = map(constrain(posRead, ctouchLoLimit, ctouchHiLimit), ctouchLoLimit, ctouchHiLimit, 28, 118);
display.drawPixel(pos, 38, WHITE);
posRead = map(touchRead(specialKeyPin),ttouchLoLimit,ttouchHiLimit,ctouchHiLimit,ctouchLoLimit);
pos = map(constrain(posRead, ctouchLoLimit, ctouchHiLimit), ctouchLoLimit, ctouchHiLimit, 28, 118);
display.drawPixel(pos, 38, WHITE);
display.display(); display.display();
} }
forcePix = 0; forcePix = 0;