Merge pull request #37 from Trasselfrisyr/johans-senaste

Changes up to 1.6.0
This commit is contained in:
John Stäck 2023-02-27 13:15:23 +01:00 committed by GitHub
commit 5e52f700af
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 505 additions and 194 deletions

3
.gitignore vendored
View file

@ -1,2 +1,3 @@
.vscode/ipch .vscode/ipch
*.o *.o
.DS_STORE

View file

@ -35,7 +35,7 @@ FOR: PJRC Teensy 3.2 and three MPR121 capactive touch sensor bo
Uses an SSD1306 controlled OLED display communicating over I2C. Uses an SSD1306 controlled OLED display communicating over I2C.
PROGRAMME FUNCTION: EWI Wind Controller using the Freescale MP3V5004GP breath sensor PROGRAMME FUNCTION: EWI Wind Controller using the Freescale MP3V5004GP breath sensor
and capacitive touch keys. Output to both USB MIDI and DIN MIDI. and capacitive touch keys. Output to both USB MIDI and DIN MIDI.
...if you just uncomment the #define NURAD in hardware.h ...if you just uncomment the #define NURAD in hardware.h
*/ */
@ -92,6 +92,7 @@ unsigned short extraCT2; // OFF:1-127
unsigned short levelCC; // 0-127 unsigned short levelCC; // 0-127
unsigned short levelVal; // 0-127 unsigned short levelVal; // 0-127
unsigned short fingering; // 0-4 EWI,EWX,SAX,EVI,EVR unsigned short fingering; // 0-4 EWI,EWX,SAX,EVI,EVR
unsigned short rollerMode; //0-2
unsigned short lpinky3; // 0-25 (OFF, -12 - MOD - +12) unsigned short lpinky3; // 0-25 (OFF, -12 - MOD - +12)
unsigned short batteryType; // 0-2 ALK,NIM,LIP unsigned short batteryType; // 0-2 ALK,NIM,LIP
unsigned short harmSetting; // 0-7 unsigned short harmSetting; // 0-7
@ -102,7 +103,7 @@ PolySelect polySelect; // OFF, MGR, MGD, MND, MNH, FWC, RTA, RTB or RTC
unsigned short fwcType; // 6, m6, 7, m7 unsigned short fwcType; // 6, m6, 7, m7
unsigned short fwcLockH; // OFF:ON unsigned short fwcLockH; // OFF:ON
unsigned short fwcDrop2; // OFF:ON unsigned short fwcDrop2; // OFF:ON
unsigned short hmzKey; // 0-11 (0 is C) unsigned short hmzKey; // 0-11 (0 is C)
unsigned short hmzLimit; // 2-5 unsigned short hmzLimit; // 2-5
unsigned short otfKey; //OFF:ON unsigned short otfKey; //OFF:ON
unsigned short breathInterval = 6; // 3-15 unsigned short breathInterval = 6; // 3-15
@ -149,10 +150,16 @@ byte ccList[11] = {0,1,2,7,11,1,2,7,11,74,20}; // OFF, Modulation, Breath, Volu
int pbDepthList[13] = {8192,8192,4096,2731,2048,1638,1365,1170,1024,910,819,744,683}; int pbDepthList[13] = {8192,8192,4096,2731,2048,1638,1365,1170,1024,910,819,744,683};
#if defined(NURAD) #if defined(NURAD)
#if defined(SEAMUS)
int calOffsetRollers[6] = {-70,20,20,20,20,120};
int calOffsetRH[12] = {0,0,0,0,0,-50,121,0,0,50,0,120};
int calOffsetLH[12] = {120,0,120,0,50,115,118,0,50,0,0,0};
#else
int calOffsetRollers[6] = {16,10,8,21,24,41}; int calOffsetRollers[6] = {16,10,8,21,24,41};
int calOffsetRH[12] = {-88,-68,-31,13,4,120,121,-68,-85,-34,23,87}; int calOffsetRH[12] = {-88,-68,-31,13,4,120,121,-68,-85,-34,23,87};
int calOffsetLH[12] = {90,-13,-33,-93,-82,115,118,2,4,-40,-75,-94}; int calOffsetLH[12] = {90,-13,-33,-93,-82,115,118,2,4,-40,-75,-94};
#endif #endif
#endif
int battMeasured[50]; int battMeasured[50];
int battAvg = 0; int battAvg = 0;
@ -189,6 +196,7 @@ uint16_t legacy = 0;
uint16_t legacyBrAct = 0; uint16_t legacyBrAct = 0;
byte halfTime = 0; byte halfTime = 0;
boolean programonce = false; boolean programonce = false;
boolean oneroll;
byte widiOn = 0; byte widiOn = 0;
int breathLevel=0; // breath level (smoothed) not mapped to CC value int breathLevel=0; // breath level (smoothed) not mapped to CC value
@ -246,6 +254,7 @@ byte vibLedOff = 0;
byte oldpkey = 0; byte oldpkey = 0;
byte lap = 0; byte lap = 0;
byte rSum = 0;
static const float vibDepth[10] = {0,0.05,0.1,0.15,0.2,0.25,0.3,0.35,0.40,0.45}; // max pitch bend values (+/-) for the vibrato settings static const float vibDepth[10] = {0,0.05,0.1,0.15,0.2,0.25,0.3,0.35,0.40,0.45}; // max pitch bend values (+/-) for the vibrato settings
static const short vibMaxBiteList[17] = {1600,1400,1200,1000,900,800,700,600,500,400,300,250,200,150,100,50,25}; static const short vibMaxBiteList[17] = {1600,1400,1200,1000,900,800,700,600,500,400,300,250,200,150,100,50,25};
@ -328,7 +337,7 @@ const int blockFWC[4][12][3] = {{{ -3, -5, -8 }, // C or key base
{ -3, -6, -9 }, // D or base +2 { -3, -6, -9 }, // D or base +2
{ -3, -5, -9 }, // D# or base +3 { -3, -5, -9 }, // D# or base +3
{ -4, -5, -9 }, // E or base +4 { -4, -5, -9 }, // E or base +4
{ -3, -6, -9 }, // F or base +5 { -3, -6, -9 }, // F or base +5
{ -3, -5, -8 }, // F# or base +6 { -3, -5, -8 }, // F# or base +6
{ -3, -5, -8 }, // G or base +7 { -3, -5, -8 }, // G or base +7
{ -3, -6, -9 }, // G# or base +8 { -3, -6, -9 }, // G# or base +8
@ -341,7 +350,7 @@ const int blockFWC[4][12][3] = {{{ -3, -5, -8 }, // C or key base
{ -3, -6, -9 }, // D or base +2 { -3, -6, -9 }, // D or base +2
{ -3, -6, -8 }, // D# or base +3 { -3, -6, -8 }, // D# or base +3
{ -3, -6, -9 }, // E or base +4 { -3, -6, -9 }, // E or base +4
{ -3, -6, -9 }, // F or base +5 { -3, -6, -9 }, // F or base +5
{ -3, -6, -8 }, // F# or base +6 { -3, -6, -8 }, // F# or base +6
{ -3, -6, -8 }, // G or base +7 { -3, -6, -8 }, // G or base +7
{ -3, -6, -9 }, // G# or base +8 { -3, -6, -9 }, // G# or base +8
@ -354,26 +363,26 @@ const int blockFWC[4][12][3] = {{{ -3, -5, -8 }, // C or key base
{ -3, -6, -9 }, // D or base +2 { -3, -6, -9 }, // D or base +2
{ -4, -6, -9 }, // D# or base +3 { -4, -6, -9 }, // D# or base +3
{ -4, -6, -9 }, // E or base +4 { -4, -6, -9 }, // E or base +4
{ -3, -6, -9 }, // F or base +5 { -3, -6, -9 }, // F or base +5
{ -3, -7, -9 }, // F# or base +6 { -3, -7, -9 }, // F# or base +6
{ -3, -7, -9 }, // G or base +7 { -3, -7, -9 }, // G or base +7
{ -3, -6, -9 }, // G# or base +8 { -3, -6, -9 }, // G# or base +8
{ -3, -6, -9 }, // A or base +9 { -3, -6, -9 }, // A or base +9
{ -3, -6, -10 }, // Bb or base +10 { -3, -6, -10 }, // Bb or base +10
{ -3, -6, -9 }}, // B or base +11 { -3, -6, -9 }}, // B or base +11
// m7 // m7
{{ -2, -5, -9 }, // C or key base {{ -2, -5, -9 }, // C or key base
{ -2, -5, -9 }, // C# or base +1 { -2, -5, -9 }, // C# or base +1
{ -3, -6, -9 }, // D or base +2 { -3, -6, -9 }, // D or base +2
{ -3, -5, -8 }, // D# or base +3 { -3, -5, -8 }, // D# or base +3
{ -3, -5, -8 }, // E or base +4 3 6 9 { -3, -5, -8 }, // E or base +4 3 6 9
{ -3, -6, -9 }, // F or base +5 { -3, -6, -9 }, // F or base +5
{ -4, -7, -9 }, // F# or base +6 { -4, -7, -9 }, // F# or base +6
{ -4, -7, -9 }, // G or base +7 { -4, -7, -9 }, // G or base +7
{ -3, -6, -9 }, // G# or base +8 { -3, -6, -9 }, // G# or base +8
{ -3, -6, -9 }, // A or base +9 { -3, -6, -9 }, // A or base +9
{ -3, -7, -10 }, // Bb or base +10 { -3, -7, -10 }, // Bb or base +10
{ -3, -6, -9 }}}; // B or base +11 { -3, -6, -9 }}}; // B or base +11
// Major Gospel Root (MGR), Bert Lochs // Major Gospel Root (MGR), Bert Lochs
const int majGosRootHmz[12][3] = {{ -5, -8, -12 }, // C or key base const int majGosRootHmz[12][3] = {{ -5, -8, -12 }, // C or key base
@ -381,7 +390,7 @@ const int majGosRootHmz[12][3] = {{ -5, -8, -12 }, // C or key base
{ -3, -7, -12 }, // D or base +2 { -3, -7, -12 }, // D or base +2
{ -6, -9, -12 }, // D# or base +3 { -6, -9, -12 }, // D# or base +3
{ -4, -9, -12 }, // E or base +4 { -4, -9, -12 }, // E or base +4
{ -5, -8, -12 }, // F or base +5 { -5, -8, -12 }, // F or base +5
{ -3, -6, -12 }, // F# or base +6 { -3, -6, -12 }, // F# or base +6
{ -3, -7, -12 }, // G or base +7 { -3, -7, -12 }, // G or base +7
{ -3, -8, -12 }, // G# or base +8 { -3, -8, -12 }, // G# or base +8
@ -395,7 +404,7 @@ const int majGosDomHmz[12][3] = {{ -5, -8, -12 }, // C or key base
{ -3, -7, -12 }, // D or base +2 { -3, -7, -12 }, // D or base +2
{ -6, -9, -12 }, // D# or base +3 { -6, -9, -12 }, // D# or base +3
{ -4, -9, -12 }, // E or base +4 { -4, -9, -12 }, // E or base +4
{ -5, -8, -12 }, // F or base +5 { -5, -8, -12 }, // F or base +5
{ -3, -6, -12 }, // F# or base +6 { -3, -6, -12 }, // F# or base +6
{ -5, -8, -12 }, // G or base +7 { -5, -8, -12 }, // G or base +7
{ -3, -8, -12 }, // G# or base +8 { -3, -8, -12 }, // G# or base +8
@ -409,13 +418,13 @@ const int majAdd9Hmz[12][3] = {{ -5, -8, -10 }, // C or key base
{ -3, -5, -7 }, // D or base +2 { -3, -5, -7 }, // D or base +2
{ -3, -7, -9 }, // D# or base +3 { -3, -7, -9 }, // D# or base +3
{ -2, -4, -9 }, // E or base +4 { -2, -4, -9 }, // E or base +4
{ -5, -8, -10 }, // F or base +5 { -5, -8, -10 }, // F or base +5
{ -4, -6, -10 }, // F# or base +6 { -4, -6, -10 }, // F# or base +6
{ -3, -5, -7 }, // G or base +7 { -3, -5, -7 }, // G or base +7
{ -4, -6, -10 }, // G# or base +8 { -4, -6, -10 }, // G# or base +8
{ -2, -4, -9 }, // A or base +9 { -2, -4, -9 }, // A or base +9
{ -5, -8, -10 }, // Bb or base +10 { -5, -8, -10 }, // Bb or base +10
{ -2, -4, -9 }}; // B or base +11 { -2, -4, -9 }}; // B or base +11
// Minor Dorian (MND), Bert Lochs // Minor Dorian (MND), Bert Lochs
const int minDorHmz[12][3] = {{ -5, -9, -12 }, // C or key base const int minDorHmz[12][3] = {{ -5, -9, -12 }, // C or key base
@ -423,7 +432,7 @@ const int minDorHmz[12][3] = {{ -5, -9, -12 }, // C or key base
{ -5, -9, -12 }, // D or base +2 { -5, -9, -12 }, // D or base +2
{ -3, -8, -12 }, // D# or base +3 { -3, -8, -12 }, // D# or base +3
{ -3, -8, -12 }, // E or base +4 { -3, -8, -12 }, // E or base +4
{ -3, -8, -12 }, // F or base +5 { -3, -8, -12 }, // F or base +5
{ -5, -9, -12 }, // F# or base +6 { -5, -9, -12 }, // F# or base +6
{ -5, -9, -12 }, // G or base +7 { -5, -9, -12 }, // G or base +7
{ -5, -8, -12 }, // G# or base +8 { -5, -8, -12 }, // G# or base +8
@ -437,7 +446,7 @@ const int minAeoHmz[12][3] = {{ -5, -9, -12 }, // C or key base
{ -3, -9, -12 }, // D or base +2 { -3, -9, -12 }, // D or base +2
{ -3, -8, -12 }, // D# or base +3 { -3, -8, -12 }, // D# or base +3
{ -6, -9, -12 }, // E or base +4 { -6, -9, -12 }, // E or base +4
{ -5, -9, -12 }, // F or base +5 { -5, -9, -12 }, // F or base +5
{ -5, -9, -12 }, // F# or base +6 { -5, -9, -12 }, // F# or base +6
{ -5, -9, -12 }, // G or base +7 { -5, -9, -12 }, // G or base +7
{ -3, -8, -12 }, // G# or base +8 { -3, -8, -12 }, // G# or base +8
@ -445,13 +454,13 @@ const int minAeoHmz[12][3] = {{ -5, -9, -12 }, // C or key base
{ -3, -8, -12 }, // Bb or base +10 { -3, -8, -12 }, // Bb or base +10
{ -6, -8, -12 }}; // B or base +11 { -6, -8, -12 }}; // B or base +11
// Minor 4-voice Hip (MNH), Bert Lochs // Minor 4-voice Hip (MNH), Bert Lochs
const int minHipHmz[12][3] = {{ -5, -9, -10 }, // C or key base const int minHipHmz[12][3] = {{ -5, -9, -10 }, // C or key base
{ -5, -9, -10 }, // C# or base +1 { -5, -9, -10 }, // C# or base +1
{ -5, -9, -10 }, // D or base +2 { -5, -9, -10 }, // D or base +2
{ -3, -4, -8 }, // D# or base +3 { -3, -4, -8 }, // D# or base +3
{ -3, -4, -8 }, // E or base +4 { -3, -4, -8 }, // E or base +4
{ -3, -4, -8 }, // F or base +5 { -3, -4, -8 }, // F or base +5
{ -5, -9, -10 }, // F# or base +6 { -5, -9, -10 }, // F# or base +6
{ -5, -9, -10 }, // G or base +7 { -5, -9, -10 }, // G or base +7
{ -5, -6, -8 }, // G# or base +8 { -5, -6, -8 }, // G# or base +8
@ -480,13 +489,13 @@ const int harmonicResult[8][7] = {{ 0, 7, 12, 16, 19, 24, 28 }, //HM1
const int brHarmonicResult[4][7] = {{ 0, 7, 12, 16, 19, 24, 28 }, //HM1 const int brHarmonicResult[4][7] = {{ 0, 7, 12, 16, 19, 24, 28 }, //HM1
{ 0, 7, 12, 16, 19, 22, 24 }, //HM2 (7th harmonic not excluded) { 0, 7, 12, 16, 19, 22, 24 }, //HM2 (7th harmonic not excluded)
{ 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
const int rollerHarmonic[2][7] = {{ 0, 7, 12, 16, 19, 24, 26 }, //F horn 2,3,4,5,6,8,9 hrm 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 { 7, 12, 16, 19, 24, 26, 31 }}; //Bb horn 3,4,5,6,8,9,12 hrm
const int trumpetHarmonic[2][7] = {{ 0, 7, 12, 16, 19, 26, 31 }, //!K4: hrm 8->9, 10->12 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 { 0, 7, 12, 16, 19, 24, 28 }}; //trumpet 2,3,4,5,6,8,10 hrm
int vibThr; // this gets auto calibrated in setup int vibThr; // this gets auto calibrated in setup
@ -508,7 +517,7 @@ byte addedIntervals = 1;
#if defined(NURAD) #if defined(NURAD)
// Key variables, TRUE (1) for pressed, FALSE (0) for not pressed // Key variables, TRUE (1) for pressed, FALSE (0) for not pressed
byte LHs; byte LHs;
byte LH1; // Left Hand key 1 (pitch change -2) byte LH1; // Left Hand key 1 (pitch change -2)
byte LHb; // Left Hand bis key (pitch change -1 unless both LH1 and LH2 are pressed) byte LHb; // Left Hand bis key (pitch change -1 unless both LH1 and LH2 are pressed)
byte LH2; // Left Hand key 2 (with LH1 also pressed pitch change is -2, otherwise -1) byte LH2; // Left Hand key 2 (with LH1 also pressed pitch change is -2, otherwise -1)
@ -548,6 +557,7 @@ byte R2;
byte R3; byte R3;
byte R4; byte R4;
byte R5; byte R5;
byte R6;
byte octaveR = 0; byte octaveR = 0;
byte lastOctaveR = 0; byte lastOctaveR = 0;
@ -555,7 +565,8 @@ byte lastOctaveR = 0;
byte halfPitchBendKey; byte halfPitchBendKey;
byte quarterToneTrigger; byte quarterToneTrigger;
byte specialKey; byte specialKey;
byte pinkyKey; byte patchKey = 0;
byte pinkyKey = 0;
byte lastSpecialKey = 0; byte lastSpecialKey = 0;
byte lastPinkyKey = 0; byte lastPinkyKey = 0;
int pitchlatch; int pitchlatch;
@ -569,6 +580,7 @@ byte lastpcc2 = 0;
byte slurSustain = 0; byte slurSustain = 0;
byte parallelChord = 0; byte parallelChord = 0;
byte subOctaveDouble = 0; byte subOctaveDouble = 0;
byte slurSostenuto = 0;
#if defined(NURAD) #if defined(NURAD)
Adafruit_MPR121 touchSensorRollers = Adafruit_MPR121(); Adafruit_MPR121 touchSensorRollers = Adafruit_MPR121();
@ -638,14 +650,14 @@ void setup() {
digitalWrite(widiJumperGndPin, LOW); //WIDI digitalWrite(widiJumperGndPin, LOW); //WIDI
widiJumper = !digitalRead(widiJumperPin); //WIDI widiJumper = !digitalRead(widiJumperPin); //WIDI
Serial2.setRX (26); //WIDI Serial2.setRX (26); //WIDI
Serial2.setTX (31); //WIDI Serial2.setTX (31); //WIDI
bool factoryReset = !digitalRead(ePin) && !digitalRead(mPin); bool factoryReset = !digitalRead(ePin) && !digitalRead(mPin);
configManagementMode = !factoryReset && !digitalRead(uPin) && !digitalRead(dPin); configManagementMode = !factoryReset && !digitalRead(uPin) && !digitalRead(dPin);
i2cScan = !factoryReset && !digitalRead(mPin); i2cScan = !factoryReset && !digitalRead(mPin);
initDisplay(); //Start up display and show logo initDisplay(); //Start up display and show logo
//If going into config management mode, stop here before we even touch the EEPROM. //If going into config management mode, stop here before we even touch the EEPROM.
@ -660,15 +672,15 @@ void setup() {
i2cScanDisplay(); i2cScanDisplay();
} }
#endif #endif
//Read eeprom data into global vars //Read eeprom data into global vars
readEEPROM(factoryReset); readEEPROM(factoryReset);
touch_Thr = map(ctouchThrVal,ctouchHiLimit,ctouchLoLimit,ttouchLoLimit,ttouchHiLimit); touch_Thr = map(ctouchThrVal,ctouchHiLimit,ctouchLoLimit,ttouchLoLimit,ttouchHiLimit);
activePatch = patch; activePatch = patch;
#if defined(NURAD) #if defined(NURAD)
digitalWrite(statusLedPin,HIGH); digitalWrite(statusLedPin,HIGH);
delay(100); delay(100);
@ -768,7 +780,7 @@ void setup() {
} }
if (widiJumper && widiOn) digitalWrite(widiPowerPin, HIGH); else digitalWrite(widiPowerPin, LOW); if (widiJumper && widiOn) digitalWrite(widiPowerPin, HIGH); else digitalWrite(widiPowerPin, LOW);
activeMIDIchannel = MIDIchannel; activeMIDIchannel = MIDIchannel;
midiInitialize(MIDIchannel); midiInitialize(MIDIchannel);
@ -842,6 +854,7 @@ void loop() {
lastpcc1=pcCombo1; lastpcc1=pcCombo1;
lastpcc2=pcCombo2; lastpcc2=pcCombo2;
if ( if (
patchKey ||
(bothPB && legacy) || (bothPB && legacy) ||
(brSuck && legacyBrAct && justPbUp) || (brSuck && legacyBrAct && justPbUp) ||
(brSuck && legacyBrAct && bcasMode && noPb) (brSuck && legacyBrAct && bcasMode && noPb)
@ -954,6 +967,7 @@ void loop() {
if (K4) { if (K4) {
if (!slurSustain) { if (!slurSustain) {
slurSustain = 1; slurSustain = 1;
slurSostenuto = 0;
parallelChord = 0; parallelChord = 0;
rotatorOn = 0; rotatorOn = 0;
} else slurSustain = 0; } else slurSustain = 0;
@ -971,11 +985,19 @@ void loop() {
rotatorOn = 0; rotatorOn = 0;
} else subOctaveDouble = 0; } else subOctaveDouble = 0;
} }
if (!K1 && !K4 && !K5) { if (K2) {
if (!slurSostenuto) {
slurSostenuto = 1;
slurSustain = 0;
//rotatorOn = 0;
} else slurSostenuto = 0;
}
if (!K1 && !K4 && !K5 && !K2 && !pinkyKey) {
slurSustain = 0; slurSustain = 0;
parallelChord = 0; parallelChord = 0;
subOctaveDouble = 0; subOctaveDouble = 0;
rotatorOn = 0; rotatorOn = 0;
slurSostenuto = 0;
} }
if (pinkyKey) { if (pinkyKey) {
if (!rotatorOn) { if (!rotatorOn) {
@ -994,6 +1016,7 @@ void loop() {
slurSustain = 0; slurSustain = 0;
parallelChord = 0; parallelChord = 0;
subOctaveDouble = 0; subOctaveDouble = 0;
slurSostenuto = 0;
} }
if ((pinkySetting == LVL) || (pinkySetting == LVLP)){ if ((pinkySetting == LVL) || (pinkySetting == LVLP)){
if (pinkyKey && K7){ if (pinkyKey && K7){
@ -1081,6 +1104,9 @@ void loop() {
if (!priority) { // mono prio to base note if (!priority) { // mono prio to base note
midiSendNoteOn(fingeredNote, velocitySend); // send Note On message for new note midiSendNoteOn(fingeredNote, velocitySend); // send Note On message for new note
} }
if (slurSostenuto) {
midiSendControlChange(66, 127);
}
activeNote = fingeredNote; activeNote = fingeredNote;
mainState = NOTE_ON; mainState = NOTE_ON;
} }
@ -1118,6 +1144,9 @@ void loop() {
if (slurSustain) { if (slurSustain) {
midiSendControlChange(64, 0); midiSendControlChange(64, 0);
} }
if (slurSostenuto) {
midiSendControlChange(66, 0);
}
breathLevel = 0; breathLevel = 0;
mainState = NOTE_OFF; mainState = NOTE_OFF;
} else { } else {
@ -1228,7 +1257,7 @@ void loop() {
// even if we just alter a pixel, the whole display is redrawn (35ms of MPU lockup) and we can't do that all the time // even if we just alter a pixel, the whole display is redrawn (35ms of MPU lockup) and we can't do that all the time
// this is one of the big reasons the display is for setup use only // this is one of the big reasons the display is for setup use only
drawSensorPixels(); // live sensor monitoring for the setup screens drawSensorPixels(); // live sensor monitoring for the setup screens
if (rotatorOn || slurSustain || parallelChord || subOctaveDouble || gateOpen) { if (rotatorOn || slurSustain || parallelChord || subOctaveDouble || slurSostenuto || gateOpen) {
statusLedFlip(); statusLedFlip();
} else { } else {
statusLedOn(); statusLedOn();
@ -1265,7 +1294,7 @@ void loop() {
} else { } else {
cvPitch = targetPitch; cvPitch = targetPitch;
} }
if (cvVibRate){ if (cvVibRate){
int timeDivider = timeDividerList[cvVibRate]; int timeDivider = timeDividerList[cvVibRate];
int cvVib = map(((waveformsTable[map(currentTime%timeDivider, 0, timeDivider, 0, maxSamplesNum-1)] - 2047) * exSensorIndicator), -259968,259969,-11,11); int cvVib = map(((waveformsTable[map(currentTime%timeDivider, 0, timeDivider, 0, maxSamplesNum-1)] - 2047) * exSensorIndicator), -259968,259969,-11,11);
@ -1441,7 +1470,7 @@ void breath() {
if (breathCCval != oldbreath) { // only send midi data if breath has changed from previous value if (breathCCval != oldbreath) { // only send midi data if breath has changed from previous value
if (breathCC) { if (breathCC) {
// send midi cc // send midi cc
midiSendControlChange(ccList[breathCC], breathCCval); midiSendControlChange(ccList[breathCC], breathCCval);
} }
if (breathAT) { if (breathAT) {
// send aftertouch // send aftertouch
@ -1492,7 +1521,7 @@ void pitch_bend() {
vibReadBite = analogRead(bitePressurePin); // alternative kind bite sensor (air pressure tube and sensor) PBITE vibReadBite = analogRead(bitePressurePin); // alternative kind bite sensor (air pressure tube and sensor) PBITE
} else { } else {
vibReadBite = touchRead(bitePin); // get sensor data, do some smoothing - SENSOR PIN 17 - PCB PINS LABELED "BITE" (GND left, sensor pin right) vibReadBite = touchRead(bitePin); // get sensor data, do some smoothing - SENSOR PIN 17 - PCB PINS LABELED "BITE" (GND left, sensor pin right)
} }
if (vibReadBite < vibThrBite) { if (vibReadBite < vibThrBite) {
if (UPWD == vibDirection) { if (UPWD == vibDirection) {
vibSignal = (vibSignal + map(constrain(vibReadBite, (vibZeroBite - vibMaxBite), vibThrBite), vibThrBite, (vibZeroBite - vibMaxBite), 0, calculatedPBdepth * vibDepth[vibrato]))/2; vibSignal = (vibSignal + map(constrain(vibReadBite, (vibZeroBite - vibMaxBite), vibThrBite), vibThrBite, (vibZeroBite - vibMaxBite), 0, calculatedPBdepth * vibDepth[vibrato]))/2;
@ -1648,7 +1677,7 @@ void battCheck(){
} }
battAvg /= 50; battAvg /= 50;
battCheckPos++; battCheckPos++;
if (battCheckPos == 50) battCheckPos = 0; if (battCheckPos == 50) battCheckPos = 0;
} }
void extraController() { void extraController() {
@ -1707,7 +1736,7 @@ void extraController() {
} else if ((pinkySetting == ECH) && !pinkyKey) { } else if ((pinkySetting == ECH) && !pinkyKey) {
harmonics = 0; harmonics = 0;
} }
if ((extraCT || extraCT2) && (exSensor >= extracThrVal)) { // if we are enabled and over the threshold, send data if ((extraCT || extraCT2) && (exSensor >= extracThrVal)) { // if we are enabled and over the threshold, send data
if (!extracIsOn) { if (!extracIsOn) {
extracIsOn = 1; extracIsOn = 1;
@ -1776,7 +1805,7 @@ void extraController() {
} }
//*********************************************************** //***********************************************************
void portamento_() { void portamento_() {
int portSumCC = 0; int portSumCC = 0;
if (pinkySetting == GLD){ if (pinkySetting == GLD){
@ -1798,11 +1827,17 @@ void portamento_() {
if (2 == leverControl) { if (2 == leverControl) {
// Portamento is controlled with thumb lever // Portamento is controlled with thumb lever
leverPortRead = touchRead(vibratoPin); leverPortRead = touchRead(vibratoPin);
#if defined(SEAMUS)
if (portamento && ((leverPortRead) >= leverThrVal)) { // if we are enabled and over the threshold, send portamento
portSumCC += map(constrain((leverPortRead), leverThrVal, leverMaxVal), leverThrVal, leverMaxVal, 0, portLimit);
}
#else
if (portamento && ((3000-leverPortRead) >= leverThrVal)) { // if we are enabled and over the threshold, send portamento if (portamento && ((3000-leverPortRead) >= leverThrVal)) { // if we are enabled and over the threshold, send portamento
portSumCC += map(constrain((3000-leverPortRead), leverThrVal, leverMaxVal), leverThrVal, leverMaxVal, 0, portLimit); portSumCC += map(constrain((3000-leverPortRead), leverThrVal, leverMaxVal), leverThrVal, leverMaxVal, 0, portLimit);
} }
#endif
} }
portSumCC = constrain(portSumCC, 0, portLimit); // Total output glide rate limited to glide max setting portSumCC = constrain(portSumCC, 0, portLimit); // Total output glide rate limited to glide max setting
if (portSumCC) { // there is a portamento level, so go for it if (portSumCC) { // there is a portamento level, so go for it
if (!portIsOn) { if (!portIsOn) {
portOn(); portOn();
@ -1869,7 +1904,7 @@ void biteCC_() {
if (!biteIsOn) { if (!biteIsOn) {
biteIsOn = 1; biteIsOn = 1;
} }
if (biteCClevel != oldbitecc) { if (biteCClevel != oldbitecc) {
midiSendControlChange(biteCC, biteCClevel); midiSendControlChange(biteCC, biteCClevel);
} }
oldbitecc = biteCClevel; oldbitecc = biteCClevel;
@ -1892,7 +1927,7 @@ void leverCC_() {
if (!leverIsOn) { if (!leverIsOn) {
leverIsOn = 1; leverIsOn = 1;
} }
if (leverCClevel != oldlevercc) { if (leverCClevel != oldlevercc) {
midiSendControlChange(leverCC, leverCClevel); midiSendControlChange(leverCC, leverCClevel);
} }
oldlevercc = leverCClevel; oldlevercc = leverCClevel;
@ -1942,7 +1977,7 @@ void autoCal() {
writeSetting(PORTAM_THR_ADDR, portamThrVal); writeSetting(PORTAM_THR_ADDR, portamThrVal);
writeSetting(PORTAM_MAX_ADDR, portamMaxVal); writeSetting(PORTAM_MAX_ADDR, portamMaxVal);
// Touch sensors // Touch sensors
calRead = ctouchHiLimit; calRead = ctouchHiLimit;
for (byte i = 0; i < 6; i++) { for (byte i = 0; i < 6; i++) {
calReadNext = touchSensorRollers.filteredData(i) * (300-calOffsetRollers[i])/300; calReadNext = touchSensorRollers.filteredData(i) * (300-calOffsetRollers[i])/300;
if (calReadNext < calRead) calRead = calReadNext; //use lowest value if (calReadNext < calRead) calRead = calReadNext; //use lowest value
@ -1976,7 +2011,7 @@ void autoCal() {
writeSetting(PORTAM_MAX_ADDR, portamMaxVal); writeSetting(PORTAM_MAX_ADDR, portamMaxVal);
} }
// Touch sensors // Touch sensors
calRead = ctouchHiLimit; calRead = ctouchHiLimit;
for (byte i = 0; i < 12; i++) { for (byte i = 0; i < 12; i++) {
calReadNext = touchSensor.filteredData(i); calReadNext = touchSensor.filteredData(i);
if (calReadNext < calRead) calRead = calReadNext; //use lowest value if (calReadNext < calRead) calRead = calReadNext; //use lowest value
@ -2001,41 +2036,95 @@ void readSwitches() {
switch (lap){ switch (lap){
case 0: case 0:
// Octave rollers // Octave rollers
int touchValueRollers[12]; int touchValueRollers[12];
for (byte i=0; i<6; i++){ for (byte i=0; i<6; i++){
//touchValueRollers[i]=touchSensorRollers.filteredData(i) - calOffsetRollers[i]; //touchValueRollers[i]=touchSensorRollers.filteredData(i) - calOffsetRollers[i];
touchValueRollers[i]=touchSensorRollers.filteredData(i) * (300-calOffsetRollers[i])/300; touchValueRollers[i]=touchSensorRollers.filteredData(i) * (300-calOffsetRollers[i])/300;
} }
// 6-pin version #if defined(SEAMUS)
octaveR = 0; /*
if (touchValueRollers[rPin6] < ctouchThrVal) octaveR = 6; //R6 // 5-pin version
else if (R5=(touchValueRollers[rPin5] < ctouchThrVal)) octaveR = 5; //R5 (store for combo check) octaveR = 0;
else if (R4=(touchValueRollers[rPin4] < ctouchThrVal)) octaveR = 4; //R4 (store for combo check) if ((R5=(touchValueRollers[rPin5] < ctouchThrVal)) && ((touchValueRollers[rPin1] < ctouchThrVal))) octaveR = 6; //R6 = R5 && R1
else if (R3=(touchValueRollers[rPin3] < ctouchThrVal)) octaveR = 3; //R3 (store for combo check) else if (R5=(touchValueRollers[rPin5] < ctouchThrVal)) octaveR = 5; //R5
else if (R2=(touchValueRollers[rPin2] < ctouchThrVal)) octaveR = 2; //R2 (store for combo check) else if (R4=(touchValueRollers[rPin4] < ctouchThrVal)) octaveR = 4; //R4
else if (touchValueRollers[rPin1] < ctouchThrVal) octaveR = 1; //R1 else if ((R3=(touchValueRollers[rPin3] < ctouchThrVal)) && lastOctaveR) octaveR = 3; //R3
else if (lastOctaveR > 1) { else if (R2=(touchValueRollers[rPin2] < ctouchThrVal)) octaveR = 2; //R2
octaveR = lastOctaveR; else if (touchValueRollers[rPin1] < ctouchThrVal) octaveR = 1; //R1
if (otfKey && polySelect && (polySelect<PolySelect::ERotatorA) && rotatorOn && (mainState == NOTE_OFF)) hmzKey = fingeredNote%12; else if (lastOctaveR > 1) {
if (mainState == NOTE_OFF) currentRotation = 3; //rotator reset by releasing rollers octaveR = lastOctaveR;
} if (otfKey && polySelect && (polySelect<RT1) && rotatorOn && (mainState == NOTE_OFF)) hmzKey = fingeredNote%12;
//if rollers are released and we are not coming down from roller 1, stay at the higher octave if (mainState == NOTE_OFF) currentRotation = 3; //rotator reset by releasing rollers
}
lastOctaveR = octaveR; //if rollers are released and we are not coming down from roller 1, stay at the higher octave
/* //CV filter leak prevention when putting NuEVI aside
//5-pin version
octaveR = 0;
if ((touchValueRollers[rPin5] < ctouchThrVal) && (touchValueRollers[rPin3] < ctouchThrVal)) octaveR = 6; //R6
else if (touchValueRollers[rPin5] < ctouchThrVal) octaveR = 5; //R5
else if (touchValueRollers[rPin4] < ctouchThrVal) octaveR = 4; //R4
else if (touchValueRollers[rPin3] < ctouchThrVal) octaveR = 3; //R3
else if (touchValueRollers[rPin2] < ctouchThrVal) octaveR = 2; //R2
else if (touchValueRollers[rPin1] < ctouchThrVal) octaveR = 1; //R1
*/ */
// 5-pin version, 1 & 6 common
R1=(touchValueRollers[rPin1] < ctouchThrVal);
R2=(touchValueRollers[rPin2] < ctouchThrVal);
R3=(touchValueRollers[rPin3] < ctouchThrVal);
R4=(touchValueRollers[rPin4] < ctouchThrVal);
R5=(touchValueRollers[rPin5] < ctouchThrVal);
rSum = R1+R2+R3+R4+R5;
octaveR = 0;
oneroll = (rollerMode < 2);
if (R5 && R1) octaveR = 6; //R6 = R5 && R1
else if (R5 && (R4 || oneroll)) octaveR = 5; //R5
else if (R4 && (R3 || oneroll)) octaveR = 4; //R4
else if (R3 && (R2 || oneroll)) octaveR = 3; //R3
else if (R2 && (R1 || oneroll)) octaveR = 2; //R2
else if (R1) octaveR = 1; //R1
else if (lastOctaveR > 1) {
if (rollerMode) octaveR = lastOctaveR; //if rollers are released and we are not coming down from roller 1, stay at the higher octave
if (otfKey && !rSum && polySelect && (polySelect<PolySelect::ERotatorA) && rotatorOn && (mainState == NOTE_OFF)) hmzKey = fingeredNote%12;
if (mainState == NOTE_OFF) currentRotation = 3; //rotator reset by releasing rollers
}
if ((3 == rollerMode) && R1 && !R5 && (6 == lastOctaveR)) octaveR = 7; // Bonus octave on top
// Roller modes
// 0: Highest touched roller, no release memory (legacy style), 1 in menu
// 1: Highest touched roller, release memory, 2 in menu
// 2: Touched roller pair, release memory, 3 in menu
// 3: Touched roller pair, release memory, bonus octave on top, 4 in menu
#else
// 6-pin version, NuRAD
R1=(touchValueRollers[rPin1] < ctouchThrVal);
R2=(touchValueRollers[rPin2] < ctouchThrVal);
R3=(touchValueRollers[rPin3] < ctouchThrVal);
R4=(touchValueRollers[rPin4] < ctouchThrVal);
R5=(touchValueRollers[rPin5] < ctouchThrVal);
R6=(touchValueRollers[rPin6] < ctouchThrVal);
rSum = R1+R2+R3+R4+R5+R6;
octaveR = 0;
oneroll = (rollerMode < 2);
if (R6 && (R5 || oneroll)) octaveR = 6; //R6
else if (R5 && (R4 || oneroll)) octaveR = 5; //R5
else if (R4 && (R3 || oneroll)) octaveR = 4; //R4
else if (R3 && (R2 || oneroll)) octaveR = 3; //R3
else if (R2 && (R1 || oneroll)) octaveR = 2; //R2
else if (R1) octaveR = 1; //R1
else if (lastOctaveR > 1) {
if (rollerMode) octaveR = lastOctaveR; //if rollers are released and we are not coming down from roller 1, stay at the higher octave
if (otfKey && !rSum && polySelect && (polySelect<RT1) && rotatorOn && (mainState == NOTE_OFF)) hmzKey = fingeredNote%12;
if (mainState == NOTE_OFF) currentRotation = 3; //rotator reset by releasing rollers
}
if ((3 == rollerMode) && R6 && !R5 && (6 == lastOctaveR)) octaveR = 7; // Bonus octave on top
// Roller modes
// 0: Highest touched roller, no release memory (legacy style), 1 in menu
// 1: Highest touched roller, release memory, 2 in menu
// 2: Touched roller pair, release memory, 3 in menu
// 3: Touched roller pair, release memory, bonus octave on top, 4 in menu
#endif
lastOctaveR = octaveR;
break; break;
case 1: case 1:
// RH keys // RH keys
int touchValueRH[12]; int touchValueRH[12];
for (byte i=0; i<12; i++){ for (byte i=0; i<12; i++){
//touchValueRH[i]=touchSensorRH.filteredData(i) - calOffsetRH[i]; //touchValueRH[i]=touchSensorRH.filteredData(i) - calOffsetRH[i];
touchValueRH[i]=touchSensorRH.filteredData(i) * (300-calOffsetRH[i])/300; touchValueRH[i]=touchSensorRH.filteredData(i) * (300-calOffsetRH[i])/300;
@ -2047,11 +2136,16 @@ void readSwitches() {
RHp1=(touchValueRH[RHp1Pin] < ctouchThrVal); RHp1=(touchValueRH[RHp1Pin] < ctouchThrVal);
RHp2=(touchValueRH[RHp2Pin] < ctouchThrVal); RHp2=(touchValueRH[RHp2Pin] < ctouchThrVal);
RHp3=(touchValueRH[RHp3Pin] < ctouchThrVal); RHp3=(touchValueRH[RHp3Pin] < ctouchThrVal);
specialKey=(touchValueRH[spec1Pin] < ctouchThrVal) && (touchValueRH[spec2Pin] < ctouchThrVal); #if defined(SEAMUS)
specialKey=(touchValueRH[spec1Pin] < ctouchThrVal);
#else
specialKey=(touchValueRH[spec1Pin] < ctouchThrVal) && (touchValueRH[spec2Pin] < ctouchThrVal);
#endif
patchKey=(touchValueRH[patchPin] < ctouchThrVal);
break; break;
case 2: case 2:
// LH keys // LH keys
int touchValueLH[12]; int touchValueLH[12];
for (byte i=0; i<12; i++){ for (byte i=0; i<12; i++){
//touchValueLH[i]=touchSensorLH.filteredData(i) - calOffsetLH[i]; //touchValueLH[i]=touchSensorLH.filteredData(i) - calOffsetLH[i];
touchValueLH[i]=touchSensorLH.filteredData(i) * (300-calOffsetLH[i])/300; touchValueLH[i]=touchSensorLH.filteredData(i) * (300-calOffsetLH[i])/300;
@ -2065,8 +2159,17 @@ void readSwitches() {
LHp2=(touchValueLH[LHp2Pin] < ctouchThrVal); LHp2=(touchValueLH[LHp2Pin] < ctouchThrVal);
LHp3=(touchValueLH[LHp3Pin] < ctouchThrVal); LHp3=(touchValueLH[LHp3Pin] < ctouchThrVal);
} }
if (lap<2) lap++; else lap=0; if (lap<2) lap++; else lap=0;
#if defined(SEAMUS)
K1=RH1;
K2=RH2;
K3=RH3;
K4=LHp1;
K5=RHs;
K6=LHp2;
K7=RHp3;
#else
K1=RHp2; K1=RHp2;
K2=LHp2; K2=LHp2;
K3=LHp3; K3=LHp3;
@ -2074,17 +2177,17 @@ void readSwitches() {
K5=RHp1; K5=RHp1;
K6=RHp2; K6=RHp2;
K7=RHp3; K7=RHp3;
#endif
pinkyKey = LHs || ((lpinky3==MOD) && LHp3); pinkyKey = LHs || ((lpinky3==MOD) && LHp3);
int qTransp = ((pinkyKey && (pinkySetting < 25)) ? pinkySetting-12 : 0) + ((LHp3 && lpinky3) ? lpinky3-13 : 0); int qTransp = ((pinkyKey && (pinkySetting < 25)) ? pinkySetting-12 : 0) + ((LHp3 && lpinky3) ? lpinky3-13 : 0);
// Calculate midi note number from pressed keys // Calculate midi note number from pressed keys
if (0==fingering){ //EWI standard fingering if (0==fingering){ //EWI standard fingering
//fingeredNote=startNote+1-2*LH1-(LHb && !(LH1 && LH2))-LH2-(LH2 && LH1)-2*LH3+LHp1-LHp2+(RHs && !LHp1)-RH1-(RH1 && LH3)-RH2-2*RH3+RHp1-RHp2-2*RHp3+octaveR*12+(octave-3)*12+transpose-12+qTransp; //fingeredNote=startNote+1-2*LH1-(LHb && !(LH1 && LH2))-LH2-(LH2 && LH1)-2*LH3+LHp1-LHp2+(RHs && !LHp1)-RH1-(RH1 && LH3)-RH2-2*RH3+RHp1-RHp2-2*RHp3+octaveR*12+(octave-3)*12+transpose-12+qTransp;
fingeredNoteUntransposed=startNote+1-2*LH1-(LHb && !(LH1 && LH2))-LH2-(LH2 && LH1)-2*LH3+LHp1-LHp2+(RHs && !LHp1)-RH1-(RH1 && LH3)-RH2-2*RH3+RHp1-RHp2-2*RHp3+octaveR*12; fingeredNoteUntransposed=startNote+1-2*LH1-(LHb && !(LH1 && LH2))-LH2-(LH2 && LH1)-2*LH3+LHp1-LHp2+(RHs && !LHp1)-RH1-(RH1 && LH3)-RH2-2*RH3+RHp1-RHp2-2*RHp3+octaveR*12;
} else if (1==fingering) { //EWX extended EWI fingering - lift LH1 for extended range up, touch RHp3 for extended range down } else if (1==fingering) { //EWX extended EWI fingering - lift LH1 for extended range up, touch RHp3 for extended range down
fingeredNoteUntransposed=startNote+1-2*LH1-(LHb && !(LH1 && LH2))-LH2-(LH2 && LH1)-2*LH3+LHp1-LHp2+(RHs && !LHp1)-RH1-(RH1 && LH3)-RH2-2*RH3+RHp1-RHp2-2*RHp3+9*(!LH1 && LH2 && LH3)-10*(!RH3 && RHp3)+octaveR*12; fingeredNoteUntransposed=startNote+1-2*LH1-(LHb && !(LH1 && LH2))-LH2-(LH2 && LH1)-2*LH3+LHp1-LHp2+(RHs && !LHp1)-RH1-(RH1 && LH3)-RH2-2*RH3+RHp1-RHp2-2*RHp3+9*(!LH1 && LH2 && LH3)-10*(!RH3 && RHp3)+octaveR*12;
@ -2099,10 +2202,10 @@ void readSwitches() {
saxFinger[7] = RH3; saxFinger[7] = RH3;
saxFinger[8] = RHp1; saxFinger[8] = RHp1;
saxFinger[9] = RHp3; saxFinger[9] = RHp3;
byte matched = 0; byte matched = 0;
byte combo = 0; byte combo = 0;
while (matched<10 && combo<16) while (matched<10 && combo<16)
{ {
combo++; combo++;
@ -2110,31 +2213,41 @@ void readSwitches() {
for (byte finger=0; finger < 10; 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-(RHp2 && (1 == combo) && LHp2)+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"
- 5*LH1 //Fifth key - 5*LH1 //Fifth key
+ 2*RHs + 4*RHp3 //Trill keys +2 and +4 + 2*RHs + 4*RHp3 //Trill keys +2 and +4
+ (!LH2 || !LH3 || LHp2) // Trill +1 achieved by lifting finger from LH2 or LH3, or touching LHp2 + (!LH2 || !LH3 || LHp2) // Trill +1 achieved by lifting finger from LH2 or LH3, or touching LHp2
+ octaveR*12; //Octave rollers + octaveR*12; //Octave rollers
/*
//Evan special fingering test
fingeredNoteUntransposed = startNote
- 2*RH1 - RH2 - 3*RH3 //"Trumpet valves"
- 5*LH1 //Fifth key
- 12*LH3 - 24*LH2 //Octaves on LH2 and LH3
+ octaveR*12; //Octave rollers
*/
} else { // EVI fingering with reversed octave rollers } else { // EVI fingering with reversed octave rollers
fingeredNoteUntransposed = startNote fingeredNoteUntransposed = startNote
- 2*RH1 - RH2 - 3*RH3 //"Trumpet valves" - 2*RH1 - RH2 - 3*RH3 //"Trumpet valves"
- 5*LH1 //Fifth key - 5*LH1 //Fifth key
+ 2*RHs + 4*RHp3 //Trill keys +2 and +4 + 2*RHs + 4*RHp3 //Trill keys +2 and +4
+ (!LH2 || !LH3 || LHp2) // Trill +1 achieved by lifting finger from LH2 or LH3, or touching LHp2 + (!LH2 || !LH3 || LHp2) // Trill +1 achieved by lifting finger from LH2 or LH3, or touching LHp2
+ (6-octaveR)*12; //Octave rollers, reversed + (6-octaveR)*12; //Octave rollers, reversed
} }
int fingeredNoteRead = fingeredNoteUntransposed + (octave - 3) * 12 + transpose - 12 + qTransp + harmonicResult[harmSelect][harmonics] + brHarmonicResult[brHarmSelect][brHarmonics]; //lip sensor and breath harmonics int fingeredNoteRead = fingeredNoteUntransposed + (octave - 3) * 12 + transpose - 12 + qTransp + harmonicResult[harmSelect][harmonics] + brHarmonicResult[brHarmSelect][brHarmonics]; //lip sensor and breath harmonics
if (pinkyKey) pitchlatch = fingeredNoteUntransposed; //use pitchlatch to make settings based on note fingered if (pinkyKey) pitchlatch = fingeredNoteUntransposed; //use pitchlatch to make settings based on note fingered
#else //NuEVI #else //NuEVI
// Read touch pads (MPR121), compare against threshold value // Read touch pads (MPR121), compare against threshold value
bool touchKeys[12]; bool touchKeys[12];
for (byte i = 0; i < 12; i++) { for (byte i = 0; i < 12; i++) {
@ -2148,21 +2261,27 @@ void readSwitches() {
R3 = touchKeys[R3Pin]; R3 = touchKeys[R3Pin];
R4 = touchKeys[R4Pin]; R4 = touchKeys[R4Pin];
R5 = touchKeys[R5Pin]; R5 = touchKeys[R5Pin];
rSum = R1+R2+R3+R4+R5;
octaveR = 0; octaveR = 0;
oneroll = (rollerMode < 2);
if (R5 && R3) octaveR = 6; //R6 = R5 && R3 if (R5 && R3) octaveR = 6; //R6 = R5 && R3
else if (R5) octaveR = 5; //R5 else if (R5 && (R4 || oneroll)) octaveR = 5; //R5
else if (R4) octaveR = 4; //R4 else if (R4 && (R3 || oneroll)) octaveR = 4; //R4
else if (R3 && lastOctaveR) octaveR = 3; //R3 else if (R3 && (R2 || (oneroll && lastOctaveR))) octaveR = 3; //R3
else if (R2) octaveR = 2; //R2 else if (R2 && (R1 || oneroll)) octaveR = 2; //R2
else if (R1) octaveR = 1; //R1 else if (R1) octaveR = 1; //R1
else if (lastOctaveR > 1) { else if (lastOctaveR > 1) {
octaveR = lastOctaveR; if (rollerMode) octaveR = lastOctaveR; //if rollers are released and we are not coming down from roller 1, stay at the higher octave (CV filter leak prevention when putting NuEVI aside)
if (otfKey && polySelect && (polySelect<PolySelect::ERotatorA) && rotatorOn && (mainState == NOTE_OFF)) hmzKey = fingeredNote%12; if (otfKey && !rSum && polySelect && (polySelect<PolySelect::ERotatorA) && rotatorOn && (mainState == NOTE_OFF)) hmzKey = fingeredNote%12;
if (mainState == NOTE_OFF) currentRotation = 3; //rotator reset by releasing rollers if (mainState == NOTE_OFF) currentRotation = 3; //rotator reset by releasing rollers
} }
//if rollers are released and we are not coming down from roller 1, stay at the higher octave if ((3 == rollerMode) && R3 && !R5 && (6 == lastOctaveR)) octaveR = 7; // Bonus octave on top
//CV filter leak prevention when putting NuEVI aside // Roller modes
// 0: Highest touched roller, no release memory (legacy style), 1 in menu
// 1: Highest touched roller, release memory, 2 in menu
// 2: Touched roller pair, release memory, 3 in menu
// 3: Touched roller pair, release memory, bonus octave on top, 4 in menu
lastOctaveR = octaveR; lastOctaveR = octaveR;
@ -2210,11 +2329,11 @@ void readSwitches() {
} }
if (K3 && K7){ if (K3 && K7){
if (4 == trill3_interval) fingeredNoteUntransposed+=2; else fingeredNoteUntransposed+=4; if (4 == trill3_interval) fingeredNoteUntransposed+=2; else fingeredNoteUntransposed+=4;
} }
int fingeredNoteRead = fingeredNoteUntransposed + (octave - 3) * 12 + transpose - 12 + qTransp + harmonicResult[harmSelect][harmonics] + brHarmonicResult[brHarmSelect][brHarmonics]; //lip sensor harmonics int fingeredNoteRead = fingeredNoteUntransposed + (octave - 3) * 12 + transpose - 12 + qTransp + harmonicResult[harmSelect][harmonics] + brHarmonicResult[brHarmSelect][brHarmonics]; //lip sensor harmonics
pcCombo1 = (K1 && K5 && !K2 && !K3); pcCombo1 = (K1 && K5 && !K2 && !K3);

View file

@ -176,7 +176,11 @@ void autoCalSelected() {
} }
// Lever // Lever
if(adjustOption == 5) { if(adjustOption == 5) {
#if defined(SEAMUS)
calRead = touchRead(vibratoPin);
#else
calRead = 3000-touchRead(vibratoPin); calRead = 3000-touchRead(vibratoPin);
#endif
leverThrVal = constrain(calRead+60, leverLoLimit, leverHiLimit); leverThrVal = constrain(calRead+60, leverLoLimit, leverHiLimit);
leverMaxVal = constrain(calRead+120, leverLoLimit, leverHiLimit); leverMaxVal = constrain(calRead+120, leverLoLimit, leverHiLimit);
writeSetting(LEVER_THR_ADDR, leverThrVal); writeSetting(LEVER_THR_ADDR, leverThrVal);
@ -419,7 +423,11 @@ void plotSensorPixels(){
} }
#endif #endif
else if(adjustOption == 5) { else if(adjustOption == 5) {
int pos = map(constrain(3000-touchRead(vibratoPin), leverLoLimit, leverHiLimit), leverLoLimit, leverHiLimit, 28, 118); #if defined(SEAMUS)
int pos = map(constrain(touchRead(vibratoPin), leverLoLimit, leverHiLimit), leverLoLimit, leverHiLimit, 28, 118);
#else
int pos = map(constrain(3000-touchRead(vibratoPin), leverLoLimit, leverHiLimit), leverLoLimit, leverHiLimit, 28, 118);
#endif
redraw = updateSensorPixel(pos, -1); redraw = updateSensorPixel(pos, -1);
} }

View file

@ -5,7 +5,7 @@
// Compile options, comment/uncomment to change // Compile options, comment/uncomment to change
#define FIRMWARE_VERSION "1.5b8" // FIRMWARE VERSION NUMBER HERE <<<<<<<<<<<<<<<<<<<<<<< #define FIRMWARE_VERSION "1.6.0" // 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

View file

@ -109,6 +109,7 @@ extern unsigned short extraCT2; // OFF:1-127
extern unsigned short levelCC; // 0-127 extern unsigned short levelCC; // 0-127
extern unsigned short levelVal; // 0-127 extern unsigned short levelVal; // 0-127
extern unsigned short fingering; // 0-4 EWI,EWX,SAX,EVI,EVR extern unsigned short fingering; // 0-4 EWI,EWX,SAX,EVI,EVR
extern unsigned short rollerMode; //0-2
extern unsigned short lpinky3; // 0-25 (OFF, -12 - MOD - +12) extern unsigned short lpinky3; // 0-25 (OFF, -12 - MOD - +12)
extern unsigned short batteryType; // 0-2 ALK,NIM,LIP extern unsigned short batteryType; // 0-2 ALK,NIM,LIP
extern unsigned short harmSetting; // 0-7 extern unsigned short harmSetting; // 0-7
@ -226,6 +227,7 @@ extern byte halfPitchBendKey;
extern byte quarterToneTrigger; extern byte quarterToneTrigger;
extern byte specialKey; extern byte specialKey;
extern byte pinkyKey; extern byte pinkyKey;
extern byte patchKey;
extern unsigned int multiMap(unsigned short val, const unsigned short * _in, const unsigned short * _out, uint8_t size); extern unsigned int multiMap(unsigned short val, const unsigned short * _in, const unsigned short * _out, uint8_t size);

View file

@ -3,6 +3,7 @@
#define REVB #define REVB
//#define NURAD //#define NURAD
//#define SEAMUS
//#define I2CSCANNER //#define I2CSCANNER
@ -72,6 +73,7 @@
#define RHp3Pin 7 #define RHp3Pin 7
#define spec1Pin 10 #define spec1Pin 10
#define spec2Pin 9 #define spec2Pin 9
#define patchPin 5
// MPR121 LH 0x5B // MPR121 LH 0x5B

View file

@ -6,18 +6,30 @@
// Do things with status LED. // Do things with status LED.
void statusLedOn() { void statusLedOn() {
digitalWrite(statusLedPin, HIGH); digitalWrite(statusLedPin, HIGH);
#if defined(SEAMUS)
analogWrite(sLedPin, SPCKEY_LED_BRIGHTNESS);
#endif
} }
void statusLedOff() { void statusLedOff() {
digitalWrite(statusLedPin, LOW); digitalWrite(statusLedPin, LOW);
#if defined(SEAMUS)
analogWrite(sLedPin, 0);
#endif
} }
void statusLed(bool state) { void statusLed(bool state) {
digitalWrite(statusLedPin, state); digitalWrite(statusLedPin, state);
#if defined(SEAMUS)
analogWrite(sLedPin, state*SPCKEY_LED_BRIGHTNESS);
#endif
} }
void statusLedFlip() { void statusLedFlip() {
digitalWrite(statusLedPin, !digitalRead(statusLedPin)); digitalWrite(statusLedPin, !digitalRead(statusLedPin));
#if defined(SEAMUS)
if (digitalRead(statusLedPin)) analogWrite(sLedPin, SPCKEY_LED_BRIGHTNESS); else analogWrite(sLedPin, 0);
#endif
} }
void statusLedFlash(uint16_t delayTime) { void statusLedFlash(uint16_t delayTime) {

View file

@ -19,6 +19,9 @@ enum CursorIdx {
ERotator, ERotator,
EVibrato, EVibrato,
EExtras, EExtras,
ERotSubA,
ERotSubB,
ERotSubC,
// NEVER ADD ANYTHING AFTER THIS, ONLY ABOVE // NEVER ADD ANYTHING AFTER THIS, ONLY ABOVE
NUM_CURSORS NUM_CURSORS
}; };
@ -59,69 +62,69 @@ byte subVibSquelch = 0; //extern
#define LOGO16_GLCD_HEIGHT 64 #define LOGO16_GLCD_HEIGHT 64
#if defined(NURAD) #if defined(NURAD)
static const unsigned char PROGMEM nurad_logo_bmp[] = { static const unsigned char PROGMEM nurad_logo_bmp[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, 0x00, 0x03, 0xf9, 0xff, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x00, 0x00, 0x03, 0xf9, 0xff, 0xff, 0xfc, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x80, 0x00, 0x07, 0xf9, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xff, 0xff, 0x80, 0x00, 0x07, 0xf9, 0xff, 0xff, 0xfe, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x01, 0xc0, 0x00, 0x0e, 0x19, 0x80, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x01, 0xc0, 0x00, 0x0e, 0x19, 0x80, 0x00, 0x07, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xff, 0xfc, 0xc0, 0x00, 0x1d, 0xd9, 0xbf, 0xff, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xff, 0xfc, 0xc0, 0x00, 0x1d, 0xd9, 0xbf, 0xff, 0xf3, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xff, 0xfe, 0xc0, 0x00, 0x3b, 0xd9, 0xbf, 0xff, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, 0xff, 0xfe, 0xc0, 0x00, 0x3b, 0xd9, 0xbf, 0xff, 0xfb, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x06, 0xc0, 0x00, 0x77, 0xd9, 0xb0, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x06, 0xc0, 0x00, 0x77, 0xd9, 0xb0, 0x00, 0x1b, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x06, 0xc0, 0x00, 0xee, 0xd9, 0xb0, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x06, 0xc0, 0x00, 0xee, 0xd9, 0xb0, 0x00, 0x1b, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x06, 0xc0, 0x01, 0xdc, 0xd9, 0xb0, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x00, 0x06, 0xc0, 0x01, 0xdc, 0xd9, 0xb0, 0x00, 0x1b, 0x00,
0x00, 0x00, 0x08, 0x00, 0x00, 0x6c, 0x00, 0x06, 0xc0, 0x03, 0xb8, 0xd9, 0xb0, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x6c, 0x00, 0x06, 0xc0, 0x03, 0xb8, 0xd9, 0xb0, 0x00, 0x1b, 0x00,
0x00, 0x00, 0x18, 0x00, 0x00, 0x6f, 0xff, 0xfe, 0xc0, 0x07, 0x7f, 0xd9, 0xb0, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x6f, 0xff, 0xfe, 0xc0, 0x07, 0x7f, 0xd9, 0xb0, 0x00, 0x1b, 0x00,
0x00, 0x00, 0x18, 0x00, 0x00, 0x6f, 0xff, 0xfc, 0xc0, 0x0e, 0xff, 0xd9, 0xb0, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x6f, 0xff, 0xfc, 0xc0, 0x0e, 0xff, 0xd9, 0xb0, 0x00, 0x1b, 0x00,
0x00, 0xc0, 0x18, 0x00, 0x00, 0x60, 0x00, 0x01, 0xc0, 0x1c, 0x00, 0x19, 0xb0, 0x00, 0x1b, 0x00, 0x00, 0xc0, 0x18, 0x00, 0x00, 0x60, 0x00, 0x01, 0xc0, 0x1c, 0x00, 0x19, 0xb0, 0x00, 0x1b, 0x00,
0x00, 0xc0, 0x38, 0x00, 0x00, 0x6f, 0xfb, 0xff, 0x80, 0x3b, 0xff, 0xd9, 0xb0, 0x00, 0x1b, 0x00, 0x00, 0xc0, 0x38, 0x00, 0x00, 0x6f, 0xfb, 0xff, 0x80, 0x3b, 0xff, 0xd9, 0xb0, 0x00, 0x1b, 0x00,
0x00, 0xc0, 0x30, 0x00, 0x00, 0x6f, 0xfd, 0xff, 0x00, 0x77, 0xff, 0xd9, 0xb0, 0x00, 0x1b, 0x00, 0x00, 0xc0, 0x30, 0x00, 0x00, 0x6f, 0xfd, 0xff, 0x00, 0x77, 0xff, 0xd9, 0xb0, 0x00, 0x1b, 0x00,
0x01, 0xe0, 0x30, 0x00, 0x00, 0x6c, 0x0e, 0xe0, 0x00, 0xee, 0x00, 0xd9, 0xb0, 0x00, 0x1b, 0x00, 0x01, 0xe0, 0x30, 0x00, 0x00, 0x6c, 0x0e, 0xe0, 0x00, 0xee, 0x00, 0xd9, 0xb0, 0x00, 0x1b, 0x00,
0x01, 0xe0, 0x30, 0x00, 0x00, 0x6c, 0x07, 0x70, 0x01, 0xdc, 0x00, 0xd9, 0xb0, 0x00, 0x1b, 0x00, 0x01, 0xe0, 0x30, 0x00, 0x00, 0x6c, 0x07, 0x70, 0x01, 0xdc, 0x00, 0xd9, 0xb0, 0x00, 0x1b, 0x00,
0x01, 0xb0, 0x30, 0x00, 0x00, 0x6c, 0x03, 0xb8, 0x03, 0xb8, 0x00, 0xd9, 0xb0, 0x00, 0x1b, 0x00, 0x01, 0xb0, 0x30, 0x00, 0x00, 0x6c, 0x03, 0xb8, 0x03, 0xb8, 0x00, 0xd9, 0xb0, 0x00, 0x1b, 0x00,
0x01, 0xb0, 0x30, 0x00, 0x00, 0x6c, 0x01, 0xdc, 0x07, 0x70, 0x00, 0xd9, 0xb0, 0x00, 0x1b, 0x00, 0x01, 0xb0, 0x30, 0x00, 0x00, 0x6c, 0x01, 0xdc, 0x07, 0x70, 0x00, 0xd9, 0xb0, 0x00, 0x1b, 0x00,
0x01, 0x98, 0x20, 0xc0, 0x40, 0x6c, 0x00, 0xee, 0x0e, 0xe0, 0x00, 0xd9, 0xb0, 0x00, 0x1b, 0x00, 0x01, 0x98, 0x20, 0xc0, 0x40, 0x6c, 0x00, 0xee, 0x0e, 0xe0, 0x00, 0xd9, 0xb0, 0x00, 0x1b, 0x00,
0x03, 0x0c, 0x20, 0xc0, 0xc0, 0x6c, 0x00, 0x77, 0x1d, 0xc0, 0x00, 0xd9, 0xbf, 0xff, 0xfb, 0x00, 0x03, 0x0c, 0x20, 0xc0, 0xc0, 0x6c, 0x00, 0x77, 0x1d, 0xc0, 0x00, 0xd9, 0xbf, 0xff, 0xfb, 0x00,
0x03, 0x0c, 0x20, 0xc0, 0xc0, 0x6c, 0x00, 0x3b, 0xbb, 0x80, 0x00, 0xd9, 0xbf, 0xff, 0xf3, 0x00, 0x03, 0x0c, 0x20, 0xc0, 0xc0, 0x6c, 0x00, 0x3b, 0xbb, 0x80, 0x00, 0xd9, 0xbf, 0xff, 0xf3, 0x00,
0x03, 0x06, 0x20, 0xc1, 0xc0, 0x6c, 0x00, 0x1d, 0xf7, 0x00, 0x00, 0xd9, 0x80, 0x00, 0x07, 0x00, 0x03, 0x06, 0x20, 0xc1, 0xc0, 0x6c, 0x00, 0x1d, 0xf7, 0x00, 0x00, 0xd9, 0x80, 0x00, 0x07, 0x00,
0x03, 0x03, 0x20, 0x83, 0x80, 0x6c, 0x00, 0x0e, 0xee, 0x00, 0x00, 0xd9, 0xff, 0xff, 0xfe, 0x00, 0x03, 0x03, 0x20, 0x83, 0x80, 0x6c, 0x00, 0x0e, 0xee, 0x00, 0x00, 0xd9, 0xff, 0xff, 0xfe, 0x00,
0x03, 0x03, 0xb1, 0x83, 0x80, 0x6c, 0x00, 0x07, 0x5c, 0x00, 0x00, 0xd9, 0xff, 0xff, 0xfc, 0x00, 0x03, 0x03, 0xb1, 0x83, 0x80, 0x6c, 0x00, 0x07, 0x5c, 0x00, 0x00, 0xd9, 0xff, 0xff, 0xfc, 0x00,
0x03, 0x01, 0xf1, 0x87, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0xf1, 0x87, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0xf1, 0x8d, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0xf1, 0x8d, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0x71, 0xb9, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x71, 0xb9, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0x31, 0xf1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x31, 0xf1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0xc1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xc1, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}; };
#else #else
@ -272,7 +275,7 @@ void i2cScanDisplay(){
{ {
Wire.beginTransmission(target); // slave addr Wire.beginTransmission(target); // slave addr
error = Wire.endTransmission(); error = Wire.endTransmission();
delay(500); delay(500);
display.print("Addr 0x"); display.print("Addr 0x");
display.print(target,HEX); display.print(target,HEX);
if (error) if (error)
@ -347,7 +350,7 @@ static bool drawSubMenu(const MenuPage *page) {
const MenuEntrySub* sub = (const MenuEntrySub*)subEntry; const MenuEntrySub* sub = (const MenuEntrySub*)subEntry;
sub->getSubTextFunc(*sub, buffer, &labelPtr); sub->getSubTextFunc(*sub, buffer, &labelPtr);
// If EMenuEntryCustom flag is set, we assume that the getSubTextFunc // If EMenuEntryCustom flag is set, we assume that the getSubTextFunc
// rendered by it self. // rendered by it self.
if( !(sub->flags & EMenuEntryCustom)) { if( !(sub->flags & EMenuEntryCustom)) {
plotSubOption(buffer, labelPtr); plotSubOption(buffer, labelPtr);
@ -398,7 +401,7 @@ static void plotMenuEntries(const MenuPage *page, bool clear = false) {
display.setCursor(0,rowPixel); display.setCursor(0,rowPixel);
display.println(lineText); display.println(lineText);
} }
if(offset) if(offset)
display.drawTriangle(58, MENU_HEADER_OFFSET, 57, MENU_HEADER_OFFSET+3, 59, MENU_HEADER_OFFSET+3, WHITE); display.drawTriangle(58, MENU_HEADER_OFFSET, 57, MENU_HEADER_OFFSET+3, 59, MENU_HEADER_OFFSET+3, WHITE);
@ -447,7 +450,7 @@ static void mainTitleGetStr(char* out) {
case 2: case 2:
vLowLimit = LIP_BAT_LOW; vLowLimit = LIP_BAT_LOW;
} }
if (vMeterReading <= vLowLimit) { //2300 alkaline, 2250 lipo, 2200 nimh if (vMeterReading <= vLowLimit) { //2300 alkaline, 2250 lipo, 2200 nimh
memcpy(splice2, "LOW ", 4); memcpy(splice2, "LOW ", 4);
} else { } else {
int voltage = map(vMeterReading,2200,3060,36,50); int voltage = map(vMeterReading,2200,3060,36,50);
@ -546,6 +549,10 @@ static void clearFPS(int trills) {
//*********************************************************** //***********************************************************
// Poly Play menu // Poly Play menu
const MenuEntryStateCh rotSubAMenu = { MenuType::EStateChange, "ROTATOR A", ROTA_MENU };
const MenuEntryStateCh rotSubBMenu = { MenuType::EStateChange, "ROTATOR B", ROTB_MENU };
const MenuEntryStateCh rotSubCMenu = { MenuType::EStateChange, "ROTATOR C", ROTC_MENU };
static void saveRotatorSetting(const Rotator * rotator, uint16_t settingAddr) static void saveRotatorSetting(const Rotator * rotator, uint16_t settingAddr)
{ {
int16_t stored; int16_t stored;
@ -682,7 +689,7 @@ static void rotatorPrioSave(SubMenuRef __unused) {
} }
const MenuEntrySub rotatorPrioMenu = { const MenuEntrySub rotatorPrioMenu = {
MenuType::ESub, "PRIORITY", "MONO PRIO", &priority, 0,1, MenuEntryFlags::EMenuEntryWrap, MenuType::ESub, "PRIORITY", "MONO PRIO", &priority, 0,1, MenuEntryFlags::EMenuEntryWrap,
rotatorPrioOptionGet, rotatorPrioSave, nullptr, rotatorPrioOptionGet, rotatorPrioSave, nullptr,
}; };
@ -708,7 +715,7 @@ static void fwcTypeSave(SubMenuRef __unused) {
} }
const MenuEntrySub fwcTypeMenu = { const MenuEntrySub fwcTypeMenu = {
MenuType::ESub, "FWC TYPE", "CHORD", &fwcType, 0,3, MenuEntryFlags::EMenuEntryWrap, MenuType::ESub, "FWC TYPE", "CHORD", &fwcType, 0,3, MenuEntryFlags::EMenuEntryWrap,
fwcTypeOptionGet, fwcTypeSave, nullptr, fwcTypeOptionGet, fwcTypeSave, nullptr,
}; };
@ -722,7 +729,7 @@ static void fwcLockHSave(SubMenuRef __unused) {
} }
const MenuEntrySub fwcLockHMenu = { const MenuEntrySub fwcLockHMenu = {
MenuType::ESub, "FWC LOCKH", "LH MELODY", &fwcLockH, 0,1, MenuEntryFlags::EMenuEntryWrap, MenuType::ESub, "FWC LOCKH", "LH MELODY", &fwcLockH, 0,1, MenuEntryFlags::EMenuEntryWrap,
fwcLockHOptionGet, fwcLockHSave, nullptr, fwcLockHOptionGet, fwcLockHSave, nullptr,
}; };
@ -736,7 +743,7 @@ static void fwcDrop2Save(SubMenuRef __unused) {
} }
const MenuEntrySub fwcDrop2Menu = { const MenuEntrySub fwcDrop2Menu = {
MenuType::ESub, "FWC DROP2", "DROP 2", &fwcDrop2, 0,1, MenuEntryFlags::EMenuEntryWrap, MenuType::ESub, "FWC DROP2", "DROP 2", &fwcDrop2, 0,1, MenuEntryFlags::EMenuEntryWrap,
fwcDrop2OptionGet, fwcDrop2Save, nullptr, fwcDrop2OptionGet, fwcDrop2Save, nullptr,
}; };
@ -786,7 +793,7 @@ static void hmzKeySave(SubMenuRef __unused) {
} }
const MenuEntrySub hmzKeyMenu = { const MenuEntrySub hmzKeyMenu = {
MenuType::ESub, "HMZ KEY", "KEY PLAYED", &hmzKey, 0,11, MenuEntryFlags::EMenuEntryWrap, MenuType::ESub, "HMZ KEY", "KEY PLAYED", &hmzKey, 0,11, MenuEntryFlags::EMenuEntryWrap,
hmzKeyOptionGet, hmzKeySave, nullptr, hmzKeyOptionGet, hmzKeySave, nullptr,
}; };
@ -847,7 +854,7 @@ static void hmzLimitSave(SubMenuRef __unused) {
} }
const MenuEntrySub hmzLimitMenu = { const MenuEntrySub hmzLimitMenu = {
MenuType::ESub, "HMZ LIMIT", "VOICES", &hmzLimit, 2,5, MenuEntryFlags::EMenuEntryWrap, MenuType::ESub, "HMZ LIMIT", "VOICES", &hmzLimit, 2,5, MenuEntryFlags::EMenuEntryWrap,
hmzLimitOptionGet, hmzLimitSave, nullptr, hmzLimitOptionGet, hmzLimitSave, nullptr,
}; };
@ -861,11 +868,48 @@ static void otfKeySave(SubMenuRef __unused) {
} }
const MenuEntrySub otfKeyMenu = { const MenuEntrySub otfKeyMenu = {
MenuType::ESub, "OTF KEY", "OTF KEYSW", &otfKey, 0,1, MenuEntryFlags::EMenuEntryWrap, MenuType::ESub, "OTF KEY", "OTF KEYSW", &otfKey, 0,1, MenuEntryFlags::EMenuEntryWrap,
otfKeyOptionGet, otfKeySave, nullptr, otfKeyOptionGet, otfKeySave, nullptr,
}; };
const MenuEntry* rotSubAMenuEntries[] = {
(MenuEntry*)&rotatorParaMenu,
(MenuEntry*)&rotator1Menu,
(MenuEntry*)&rotator2Menu,
(MenuEntry*)&rotator3Menu,
(MenuEntry*)&rotator4Menu
};
const MenuPage rotSubAMenuPage = {
"ROTATOR A", 0, CursorIdx::ERotSubA, ROTATOR_MENU, ARR_LEN(rotSubAMenuEntries), rotSubAMenuEntries
};
const MenuEntry* rotSubBMenuEntries[] = {
(MenuEntry*)&rotatorParaBMenu,
(MenuEntry*)&rotatorB1Menu,
(MenuEntry*)&rotatorB2Menu,
(MenuEntry*)&rotatorB3Menu,
(MenuEntry*)&rotatorB4Menu
};
const MenuPage rotSubBMenuPage = {
"ROTATOR B", 0, CursorIdx::ERotSubB, ROTATOR_MENU, ARR_LEN(rotSubBMenuEntries), rotSubBMenuEntries
};
const MenuEntry* rotSubCMenuEntries[] = {
(MenuEntry*)&rotatorParaCMenu,
(MenuEntry*)&rotatorC1Menu,
(MenuEntry*)&rotatorC2Menu,
(MenuEntry*)&rotatorC3Menu,
(MenuEntry*)&rotatorC4Menu
};
const MenuPage rotSubCMenuPage = {
"ROTATOR C", 0, CursorIdx::ERotSubC, ROTATOR_MENU, ARR_LEN(rotSubCMenuEntries), rotSubCMenuEntries
};
const MenuEntry* rotatorMenuEntries[] = { const MenuEntry* rotatorMenuEntries[] = {
(MenuEntry*)&polySelectMenu, (MenuEntry*)&polySelectMenu,
@ -876,7 +920,7 @@ const MenuEntry* rotatorMenuEntries[] = {
(MenuEntry*)&fwcLockHMenu, (MenuEntry*)&fwcLockHMenu,
(MenuEntry*)&fwcDrop2Menu, (MenuEntry*)&fwcDrop2Menu,
(MenuEntry*)&rotatorPrioMenu, (MenuEntry*)&rotatorPrioMenu,
(MenuEntry*)&rotatorParaMenu, /*(MenuEntry*)&rotatorParaMenu,
(MenuEntry*)&rotator1Menu, (MenuEntry*)&rotator1Menu,
(MenuEntry*)&rotator2Menu, (MenuEntry*)&rotator2Menu,
(MenuEntry*)&rotator3Menu, (MenuEntry*)&rotator3Menu,
@ -890,7 +934,10 @@ const MenuEntry* rotatorMenuEntries[] = {
(MenuEntry*)&rotatorC1Menu, (MenuEntry*)&rotatorC1Menu,
(MenuEntry*)&rotatorC2Menu, (MenuEntry*)&rotatorC2Menu,
(MenuEntry*)&rotatorC3Menu, (MenuEntry*)&rotatorC3Menu,
(MenuEntry*)&rotatorC4Menu (MenuEntry*)&rotatorC4Menu */
(MenuEntry*)&rotSubAMenu,
(MenuEntry*)&rotSubBMenu,
(MenuEntry*)&rotSubCMenu
}; };
/* /*
const MenuPage rotatorMenuPage = { const MenuPage rotatorMenuPage = {
@ -907,22 +954,116 @@ const MenuPage rotatorMenuPage = {
CursorIdx::ERotator, CursorIdx::ERotator,
MAIN_MENU, MAIN_MENU,
ARR_LEN(rotatorMenuEntries), rotatorMenuEntries ARR_LEN(rotatorMenuEntries), rotatorMenuEntries
}; };
//*********************************************************** //***********************************************************
// Main menu // Main menu
/*
const MenuEntrySub transposeMenu = { const MenuEntrySub transposeMenu = {
MenuType::ESub, "TRANSPOSE", "TRANSPOSE", &transpose, 0, 24, MenuEntryFlags::ENone, MenuType::ESub, "TRANSPOSE", "TRANSPOSE", &transpose, 0, 24, MenuEntryFlags::ENone,
[](SubMenuRef __unused, char* out, const char** __unused unit) { [](SubMenuRef __unused, char* out, const char** __unused unit) {
numToString(transpose - 12, out, true); numToString(transpose - 12, out, true);
}, },
[](const MenuEntrySub &sub) { writeSetting(TRANSP_ADDR,*sub.valuePtr); } [](const MenuEntrySub &sub) { writeSetting(TRANSP_ADDR,*sub.valuePtr); }
, nullptr , nullptr
}; };
*/
static void transposeOptionGet(SubMenuRef __unused, char* out, const char** __unused) {
switch (transpose){
case 0:
strncpy(out, "C>", 4);
break;
case 1:
strncpy(out, "C#>", 4);
break;
case 2:
strncpy(out, "D>", 4);
break;
case 3:
strncpy(out, "D#>", 4);
break;
case 4:
strncpy(out, "E>", 4);
break;
case 5:
strncpy(out, "F>", 4);
break;
case 6:
strncpy(out, "F#>", 4);
break;
case 7:
strncpy(out, "G>", 4);
break;
case 8:
strncpy(out, "G#>", 4);
break;
case 9:
strncpy(out, "A>", 4);
break;
case 10:
strncpy(out, "Bb>", 4);
break;
case 11:
strncpy(out, "B>", 4);
break;
case 12:
strncpy(out, ">C<", 4);
break;
case 13:
strncpy(out, "<C#", 4);
break;
case 14:
strncpy(out, "<D", 4);
break;
case 15:
strncpy(out, "<D#", 4);
break;
case 16:
strncpy(out, "<E", 4);
break;
case 17:
strncpy(out, "<F", 4);
break;
case 18:
strncpy(out, "<F#", 4);
break;
case 19:
strncpy(out, "<G", 4);
break;
case 20:
strncpy(out, "<G#", 4);
break;
case 21:
strncpy(out, "<A", 4);
break;
case 22:
strncpy(out, "<Bb", 4);
break;
case 23:
strncpy(out, "<B", 4);
break;
case 24:
strncpy(out, "<C", 4);
break;
}
}
static void transposeSave(SubMenuRef __unused) {
writeSetting(TRANSP_ADDR,transpose);
}
const MenuEntrySub transposeMenu = {
MenuType::ESub, "TRANSPOSE", "TRANSPOSE", &transpose, 0,24, MenuEntryFlags::ENone,
transposeOptionGet, transposeSave, nullptr,
};
const MenuEntrySub octaveMenu = { const MenuEntrySub octaveMenu = {
MenuType::ESub, "OCTAVE", "OCTAVE", &octave, 0, 6, MenuEntryFlags::ENone, MenuType::ESub, "OCTAVE", "OCTAVE", &octave, 0, 6, MenuEntryFlags::ENone,
[](SubMenuRef __unused, char* out, const char** __unused unit) { [](SubMenuRef __unused, char* out, const char** __unused unit) {
numToString(octave-3, out, true); numToString(octave-3, out, true);
}, },
@ -1034,7 +1175,7 @@ const MenuEntrySub fastBootMenu = {
}; };
const MenuEntrySub cvTuneMenu = { const MenuEntrySub cvTuneMenu = {
MenuType::ESub, "CV TUNE", "TUNING", &cvTune, 1, 199, MenuEntryFlags::ENone, MenuType::ESub, "CV TUNE", "TUNING", &cvTune, 1, 199, MenuEntryFlags::ENone,
[](SubMenuRef __unused, char* out, const char** __unused unit) { [](SubMenuRef __unused, char* out, const char** __unused unit) {
numToString(cvTune-100, out, true); numToString(cvTune-100, out, true);
}, },
@ -1043,7 +1184,7 @@ const MenuEntrySub cvTuneMenu = {
}; };
const MenuEntrySub cvScaleMenu = { const MenuEntrySub cvScaleMenu = {
MenuType::ESub, "CV SCALE", "SCALING", &cvScale, 1, 199, MenuEntryFlags::ENone, MenuType::ESub, "CV SCALE", "SCALING", &cvScale, 1, 199, MenuEntryFlags::ENone,
[](SubMenuRef __unused, char* out, const char** __unused unit) { [](SubMenuRef __unused, char* out, const char** __unused unit) {
numToString(cvScale-100, out, true); numToString(cvScale-100, out, true);
}, },
@ -1139,10 +1280,10 @@ const MenuPage extrasMenuPage = {
CursorIdx::EExtras, CursorIdx::EExtras,
MAIN_MENU, MAIN_MENU,
ARR_LEN(extrasMenuEntries), extrasMenuEntries ARR_LEN(extrasMenuEntries), extrasMenuEntries
}; };
static bool midiEnterHandlerFunc() { static bool midiEnterHandlerFunc() {
//this switching is removed due to new breathInterval setting //this switching is removed due to new breathInterval setting
readSwitches(); readSwitches();
if (pinkyKey && widiJumper){ if (pinkyKey && widiJumper){
@ -1155,13 +1296,13 @@ static bool midiEnterHandlerFunc() {
writeSetting(MIDI_ADDR, MIDIchannel); writeSetting(MIDI_ADDR, MIDIchannel);
return true; return true;
} }
//writeSetting(MIDI_ADDR, MIDIchannel); //writeSetting(MIDI_ADDR, MIDIchannel);
//return true; //return true;
} }
const MenuEntrySub midiMenu = { const MenuEntrySub midiMenu = {
MenuType::ESub, "MIDI CH", "MIDI CHNL", &MIDIchannel, 1, 16, EMenuEntryCustom | EMenuEntryEnterHandler, MenuType::ESub, "MIDI CH", "MIDI CHNL", &MIDIchannel, 1, 16, EMenuEntryCustom | EMenuEntryEnterHandler,
midiCustomDrawFunc, midiSaveFunc, midiEnterHandlerFunc midiCustomDrawFunc, midiSaveFunc, midiEnterHandlerFunc
}; };
@ -1345,7 +1486,7 @@ const MenuEntry* breathMenuEntries[] = {
(MenuEntry*)&velocityMenu, (MenuEntry*)&velocityMenu,
(MenuEntry*)&curveMenu, (MenuEntry*)&curveMenu,
(MenuEntry*)&velSmpDlMenu, (MenuEntry*)&velSmpDlMenu,
(MenuEntry*)&velBiasMenu, (MenuEntry*)&velBiasMenu,
//(MenuEntry*)&brHarmonicsMenu, //(MenuEntry*)&brHarmonicsMenu,
//(MenuEntry*)&brHarmSelectMenu, //(MenuEntry*)&brHarmSelectMenu,
(MenuEntry*)&breathIntervalMenu (MenuEntry*)&breathIntervalMenu
@ -1558,6 +1699,14 @@ const MenuEntrySub fingeringMenu = {
}; };
#endif #endif
const MenuEntrySub rollerMenu = {
MenuType::ESub, "ROLLRMODE", "ROLLRMODE", &rollerMode, 0, 3, MenuEntryFlags::EMenuEntryWrap,
[](SubMenuRef __unused, char* out, const char** __unused unit) {
numToString(rollerMode+1, out);
},
[](const MenuEntrySub & __unused sub) { writeSetting(ROLLER_ADDR,rollerMode); }
, nullptr
};
const MenuEntrySub lpinky3Menu = { const MenuEntrySub lpinky3Menu = {
@ -1592,6 +1741,7 @@ const MenuEntry* controlMenuEntries[] = {
(MenuEntry*)&lvlCtrlCCMenu, (MenuEntry*)&lvlCtrlCCMenu,
(MenuEntry*)&lpinky3Menu, (MenuEntry*)&lpinky3Menu,
(MenuEntry*)&fingeringMenu, (MenuEntry*)&fingeringMenu,
(MenuEntry*)&rollerMenu,
(MenuEntry*)&pitchBendMenu (MenuEntry*)&pitchBendMenu
}; };
#else #else
@ -1611,6 +1761,7 @@ const MenuEntry* controlMenuEntries[] = {
(MenuEntry*)&pinkyMenu, (MenuEntry*)&pinkyMenu,
(MenuEntry*)&lvlCtrlCCMenu, (MenuEntry*)&lvlCtrlCCMenu,
(MenuEntry*)&fingeringMenu, (MenuEntry*)&fingeringMenu,
(MenuEntry*)&rollerMenu,
(MenuEntry*)&pitchBendMenu (MenuEntry*)&pitchBendMenu
}; };
#endif #endif
@ -1641,7 +1792,7 @@ static void vibStore(const MenuEntrySub & __unused sub) {
const MenuEntrySub vibDepthMenu = { const MenuEntrySub vibDepthMenu = {
MenuType::ESub, "DEPTH", "LEVEL", &vibrato, 0, 9, MenuEntryFlags::ENone, MenuType::ESub, "DEPTH", "LEVEL", &vibrato, 0, 9, MenuEntryFlags::ENone,
vibGetStr, vibGetStr,
vibStore, vibStore,
nullptr nullptr
}; };
@ -1802,7 +1953,7 @@ const MenuPageCustom aboutMenuPage = { nullptr, EMenuPageCustom,
display.print("v"); display.print("v");
} }
} }
return true; return true;
} else { } else {
@ -2151,7 +2302,7 @@ static bool idlePageUpdate(KeyState& __unused input, uint32_t __unused timeNow)
case BTN_DOWN: case BTN_DOWN:
if (!trills) { if (!trills) {
patch = (((patch-1u) + ((input.current == BTN_UP)?1u:-1u))&127u) + 1u; patch = (((patch-1u) + ((input.current == BTN_UP)?1u:-1u))&127u) + 1u;
} }
// fallthrough // fallthrough
case BTN_ENTER: case BTN_ENTER:
if (trills && (fastPatch[trills-1] > 0)){ if (trills && (fastPatch[trills-1] > 0)){
@ -2179,7 +2330,7 @@ static bool idlePageUpdate(KeyState& __unused input, uint32_t __unused timeNow)
} else if (pinkyKey && !specialKey){ //hold pinky key for rotator menu, and if too high touch sensing blocks regular menu, touching special key helps } else if (pinkyKey && !specialKey){ //hold pinky key for rotator menu, and if too high touch sensing blocks regular menu, touching special key helps
display.ssd1306_command(SSD1306_DISPLAYON); display.ssd1306_command(SSD1306_DISPLAYON);
menuState= ROTATOR_MENU; menuState= ROTATOR_MENU;
stateFirstRun = 1; stateFirstRun = 1;
} else { } else {
display.ssd1306_command(SSD1306_DISPLAYON); display.ssd1306_command(SSD1306_DISPLAYON);
menuState = MAIN_MENU; menuState = MAIN_MENU;
@ -2288,6 +2439,12 @@ void menu() {
redraw |= updatePage((const MenuPage*)&aboutMenuPage, input, timeNow); redraw |= updatePage((const MenuPage*)&aboutMenuPage, input, timeNow);
} else if (menuState == EXTRAS_MENU) { } else if (menuState == EXTRAS_MENU) {
redraw |= updatePage((const MenuPage*)&extrasMenuPage, input, timeNow); redraw |= updatePage((const MenuPage*)&extrasMenuPage, input, timeNow);
} else if (menuState == ROTA_MENU) {
redraw |= updatePage((const MenuPage*)&rotSubAMenuPage, input, timeNow);
} else if (menuState == ROTB_MENU) {
redraw |= updatePage((const MenuPage*)&rotSubBMenuPage, input, timeNow);
} else if (menuState == ROTC_MENU) {
redraw |= updatePage((const MenuPage*)&rotSubCMenuPage, input, timeNow);
} }
if(redraw) { if(redraw) {

View file

@ -19,6 +19,9 @@
#define VIBRATO_MENU 7 #define VIBRATO_MENU 7
#define ABOUT_MENU 8 #define ABOUT_MENU 8
#define EXTRAS_MENU 9 #define EXTRAS_MENU 9
#define ROTA_MENU 10
#define ROTB_MENU 11
#define ROTC_MENU 12
#define ARR_LEN(a) (sizeof (a) / sizeof (a[0])) #define ARR_LEN(a) (sizeof (a) / sizeof (a[0]))

View file

@ -179,6 +179,10 @@ void readEEPROM(const bool factoryReset) {
writeSetting(CVRATE_ADDR, CVRATE_FACTORY); writeSetting(CVRATE_ADDR, CVRATE_FACTORY);
} }
if(settingsVersion < 45) {
writeSetting(ROLLER_ADDR, ROLLER_FACTORY);
}
writeSetting(VERSION_ADDR, EEPROM_VERSION); writeSetting(VERSION_ADDR, EEPROM_VERSION);
} }
@ -275,6 +279,7 @@ void readEEPROM(const bool factoryReset) {
cvTune = readSettingBounded(CVTUNE_ADDR, 1, 199, CVTUNE_FACTORY); cvTune = readSettingBounded(CVTUNE_ADDR, 1, 199, CVTUNE_FACTORY);
cvScale = readSettingBounded(CVSCALE_ADDR, 1, 199, CVSCALE_FACTORY); cvScale = readSettingBounded(CVSCALE_ADDR, 1, 199, CVSCALE_FACTORY);
cvVibRate = readSettingBounded(CVRATE_ADDR, 0, 8, CVRATE_FACTORY); cvVibRate = readSettingBounded(CVRATE_ADDR, 0, 8, CVRATE_FACTORY);
rollerMode = readSettingBounded(ROLLER_ADDR, 0, 3, ROLLER_FACTORY);
//Flags stored in bit field //Flags stored in bit field
fastBoot = (dipSwBits & (1<<DIPSW_FASTBOOT))?1:0; fastBoot = (dipSwBits & (1<<DIPSW_FASTBOOT))?1:0;

View file

@ -93,8 +93,9 @@
#define CVTUNE_ADDR 180 #define CVTUNE_ADDR 180
#define CVSCALE_ADDR 182 #define CVSCALE_ADDR 182
#define CVRATE_ADDR 184 #define CVRATE_ADDR 184
#define ROLLER_ADDR 186
#define EEPROM_SIZE 186 //Last address +2 #define EEPROM_SIZE 188 //Last address +2
//DAC output modes //DAC output modes
@ -111,7 +112,7 @@
//"factory" values for settings //"factory" values for settings
#define EEPROM_VERSION 44 #define EEPROM_VERSION 45
#define BREATH_THR_FACTORY 1400 #define BREATH_THR_FACTORY 1400
#define BREATH_MAX_FACTORY 4000 #define BREATH_MAX_FACTORY 4000
@ -156,7 +157,7 @@
#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 8 #define VIB_SENS_BITE_FACTORY 8
#define VIB_SQUELCH_BITE_FACTORY 10 #define VIB_SQUELCH_BITE_FACTORY 15
#define VIB_CONTROL_FACTORY 0 #define VIB_CONTROL_FACTORY 0
#define TRILL3_INTERVAL_FACTORY 4 #define TRILL3_INTERVAL_FACTORY 4
#define DAC_MODE_FACTORY DAC_MODE_PITCH #define DAC_MODE_FACTORY DAC_MODE_PITCH
@ -196,6 +197,7 @@
#define CVTUNE_FACTORY 100 // 100 is zero tuning #define CVTUNE_FACTORY 100 // 100 is zero tuning
#define CVSCALE_FACTORY 100 // 100 is zero scaling #define CVSCALE_FACTORY 100 // 100 is zero scaling
#define CVRATE_FACTORY 3 // 3 is 5.5Hz #define CVRATE_FACTORY 3 // 3 is 5.5Hz
#define ROLLER_FACTORY 1
#define NO_CHECKSUM 0x7F007F00 #define NO_CHECKSUM 0x7F007F00