From 40e8760de379f3e5791d2f32ae5c17d59cea8949 Mon Sep 17 00:00:00 2001 From: Johan Berglund Date: Sat, 26 Aug 2017 12:55:23 +0200 Subject: [PATCH] Added untested version with menu system and other added features. Preview. --- untested/NuEVI-merged/NuEVI-merged.ino | 2854 ++++++++++++++++++++++++ 1 file changed, 2854 insertions(+) create mode 100644 untested/NuEVI-merged/NuEVI-merged.ino diff --git a/untested/NuEVI-merged/NuEVI-merged.ino b/untested/NuEVI-merged/NuEVI-merged.ino new file mode 100644 index 0000000..2003ad8 --- /dev/null +++ b/untested/NuEVI-merged/NuEVI-merged.ino @@ -0,0 +1,2854 @@ +#include +#include +#include +#include +#include +#include + +/* +NAME: NuEVI +WRITTEN BY: JOHAN BERGLUND +DATE: 2017-08-08 +FILE SAVED AS: NuEVI.ino +FOR: PJRC Teensy LC or 3.2 and a MPR121 capactive touch sensor board. + Uses an SSD1306 controlled OLED dispaly communicating over I2C. +PROGRAMME FUNCTION: EVI Wind Controller using the Freescale MP3V5004GP breath sensor + and capacitive touch keys. Output to both USB MIDI and DIN MIDI. + +*/ + +//_______________________________________________________________________________________________ DECLARATIONS + + +#define ON_Delay 20 // Set Delay after ON threshold before velocity is checked (wait for tounging peak) +#define touch_Thr 1800 // sensitivity for Teensy touch sensors +#define CCN_Port 5 // Controller number for portamento level +#define CCN_PortOnOff 65// Controller number for portamento on/off + + +// Send CC data no more than every CC_INTERVAL +// milliseconds +#define CC_INTERVAL 5 + + +// The three states of our main state machine + +// No note is sounding +#define NOTE_OFF 1 + +// We've observed a transition from below to above the +// threshold value. We wait a while to see how fast the +// breath velocity is increasing +#define RISE_WAIT 2 + +// A note is sounding +#define NOTE_ON 3 + + +//display states +#define DISPLAYOFF_IDL 0 +#define MAIN_MENU 1 +#define PATCH_VIEW 2 +#define BREATH_ADJ_IDL 10 +#define BREATH_ADJ_THR 11 +#define BREATH_ADJ_MAX 12 +#define PORTAM_ADJ_IDL 20 +#define PORTAM_ADJ_THR 21 +#define PORTAM_ADJ_MAX 22 +#define PITCHB_ADJ_IDL 30 +#define PITCHB_ADJ_THR 31 +#define PITCHB_ADJ_MAX 32 +#define EXTRAC_ADJ_IDL 40 +#define EXTRAC_ADJ_THR 41 +#define EXTRAC_ADJ_MAX 42 +#define VIBRAT_ADJ_IDL 50 +#define VIBRAT_ADJ_THR 51 +#define VIBRAT_ADJ_DPT 52 +#define SETUP_BR_MENU 80 +#define SETUP_CT_MENU 90 + +// EEPROM addresses for settings +#define VERSION_ADDR 0 +#define BREATH_THR_ADDR 2 +#define breathMaxVal_ADDR 4 +#define PORTAM_THR_ADDR 6 +#define PORTAM_MAX_ADDR 8 +#define PITCHB_THR_ADDR 10 +#define PITCHB_MAX_ADDR 12 +#define TRANSP_ADDR 14 +#define MIDI_ADDR 16 +#define BREATH_CC_ADDR 18 +#define BREATH_AT_ADDR 20 +#define VELOCITY_ADDR 22 +#define PORTAM_ADDR 24 +#define PB_ADDR 26 +#define EXTRA_ADDR 28 +#define VIBRATO_ADDR 30 +#define DEGLITCH_ADDR 32 +#define EXTRAC_THR_ADDR 34 +#define EXTRAC_MAX_ADDR 36 +#define PATCH_ADDR 38 +#define OCTAVE_ADDR 40 + +//"factory" values for settings +#define VERSION 12 +#define BREATH_THR_FACTORY 350 +#define breathMaxVal_FACTORY 1000 +#define PORTAM_THR_FACTORY 1730 +#define PORTAM_MAX_FACTORY 3300 +#define PITCHB_THR_FACTORY 1200 +#define PITCHB_MAX_FACTORY 2400 +#define EXTRAC_THR_FACTORY 1200 +#define EXTRAC_MAX_FACTORY 2400 +#define TRANSP_FACTORY 12 // 12 is 0 transpose +#define MIDI_FACTORY 1 // 1-16 +#define BREATH_CC_FACTORY 1 //thats CC#2, see ccList +#define BREATH_AT_FACTORY 0 //aftertouch default off +#define VELOCITY_FACTORY 0 // 0 is dynamic/breath controlled velocity +#define PORTAM_FACTORY 2 // 0 - OFF, 1 - ON, 2 - SW +#define PB_FACTORY 1 // 0 - OFF, 1 - 12 +#define EXTRA_FACTORY 1 // 0 - OFF, 1 - ON->Modulation, 2 - Sustain +#define VIBRATO_FACTORY 3 // 0 - OFF, 1 - 7 depth +#define DEGLITCH_FACTORY 20 // 0 - OFF, 5 to 70 ms in steps of 5 +#define PATCH_FACTORY 1 // MIDI program change 1-128 +#define OCTAVE_FACTORY 3 // 3 is 0 octave change + +#define OLED_RESET 4 +Adafruit_SSD1306 display(OLED_RESET); + +#define LOGO16_GLCD_HEIGHT 16 +#define LOGO16_GLCD_WIDTH 16 + + // 'NuEVI' logo +static const unsigned char PROGMEM nuevi_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, 0x01, 0xff, 0xff, 0xff, 0xe3, 0x60, 0x00, 0x07, 0x73, 0x60, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xe3, 0x60, 0x00, 0x0e, 0xe3, 0x60, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x03, 0x60, 0x00, 0x1d, 0xc3, 0x60, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xbf, 0xff, 0xff, 0xe3, 0x60, 0x00, 0x3b, 0x83, 0x60, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xbf, 0xff, 0xff, 0xe3, 0x60, 0x00, 0x77, 0x03, 0x60, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xb0, 0x00, 0x00, 0x03, 0x60, 0x00, 0xee, 0x03, 0x60, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xb0, 0x00, 0x00, 0x03, 0x60, 0x01, 0xdc, 0x03, 0x60, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xb0, 0x00, 0x00, 0x03, 0x60, 0x03, 0xb8, 0x03, 0x60, 0x00, +0x00, 0x00, 0x00, 0x20, 0x00, 0x01, 0xb0, 0x00, 0x00, 0x03, 0x60, 0x07, 0x70, 0x03, 0x60, 0x00, +0x00, 0x00, 0x00, 0x60, 0x00, 0x01, 0xbf, 0xff, 0xff, 0xe3, 0x60, 0x0e, 0xe0, 0x03, 0x60, 0x00, +0x00, 0x00, 0x00, 0x60, 0x00, 0x01, 0xbf, 0xff, 0xff, 0xe3, 0x60, 0x1d, 0xc0, 0x03, 0x60, 0x00, +0x00, 0x03, 0x00, 0x60, 0x00, 0x01, 0x80, 0x00, 0x00, 0x03, 0x60, 0x3b, 0x80, 0x03, 0x60, 0x00, +0x00, 0x03, 0x00, 0xe0, 0x00, 0x01, 0xbf, 0xff, 0xff, 0xe3, 0x60, 0x77, 0x00, 0x03, 0x60, 0x00, +0x00, 0x03, 0x00, 0xc0, 0x00, 0x01, 0xbf, 0xff, 0xff, 0xe3, 0x60, 0xee, 0x00, 0x03, 0x60, 0x00, +0x00, 0x03, 0x80, 0xc0, 0x00, 0x01, 0xb0, 0x00, 0x00, 0x03, 0x61, 0xdc, 0x00, 0x03, 0x60, 0x00, +0x00, 0x07, 0x80, 0xc0, 0x00, 0x01, 0xb0, 0x00, 0x00, 0x03, 0x63, 0xb8, 0x00, 0x03, 0x60, 0x00, +0x00, 0x07, 0xc0, 0xc0, 0x00, 0x01, 0xb0, 0x00, 0x00, 0x03, 0x67, 0x70, 0x00, 0x03, 0x60, 0x00, +0x00, 0x06, 0xc0, 0xc0, 0x00, 0x01, 0xb0, 0x00, 0x00, 0x03, 0x6e, 0xe0, 0x00, 0x03, 0x60, 0x00, +0x00, 0x06, 0x60, 0xc1, 0x01, 0x01, 0xb0, 0x00, 0x00, 0x03, 0x7d, 0xc0, 0x00, 0x03, 0x60, 0x00, +0x00, 0x06, 0x30, 0xc3, 0x03, 0x01, 0xbf, 0xff, 0xff, 0xe3, 0x7b, 0x80, 0x00, 0x03, 0x60, 0x00, +0x00, 0x0c, 0x30, 0xc3, 0x07, 0x01, 0xbf, 0xff, 0xff, 0xe3, 0x77, 0x00, 0x00, 0x03, 0x60, 0x00, +0x00, 0x0c, 0x1c, 0xc3, 0x06, 0x01, 0x80, 0x00, 0x00, 0x03, 0x0e, 0x00, 0x00, 0x03, 0x60, 0x00, +0x00, 0x0c, 0x0c, 0xc2, 0x0e, 0x01, 0xff, 0xff, 0xff, 0xe3, 0xfc, 0x00, 0x00, 0x03, 0x60, 0x00, +0x00, 0x0c, 0x0e, 0xc6, 0x1e, 0x01, 0xff, 0xff, 0xff, 0xe3, 0xf8, 0x00, 0x00, 0x03, 0x60, 0x00, +0x00, 0x0c, 0x07, 0xc6, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x0c, 0x03, 0xc6, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x0c, 0x01, 0xc7, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x0c, 0x00, 0xc7, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x0c, 0x00, 0x03, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +#if (SSD1306_LCDHEIGHT != 64) +#error("Height incorrect, please fix Adafruit_SSD1306.h!"); +#endif + + +//variables setup + +unsigned short breathThrVal;// = 350; +unsigned short breathMaxVal;// = 1000; +unsigned short portamThrVal;// = 1730; +unsigned short portamMaxVal;// = 3300; +unsigned short pitchbThrVal;// = 1200; +unsigned short pitchbMaxVal;// = 2400; +unsigned short extracThrVal;// = 1200; +unsigned short extracMaxVal;// = 2400; +unsigned short transpose; +unsigned short MIDIchannel; +unsigned short breathCC; +unsigned short breathAT; +unsigned short velocity; +unsigned short portamento;// switching on cc65? just cc5 enabled? SW:ON:OFF +unsigned short PBdepth; // OFF:1-12 divider +unsigned short extraCT; // OFF:MOD +unsigned short vibrato; // OFF:1-7 +unsigned short deglitch; // 0-70 ms in steps of 5 +unsigned short patch; // 1-128 +unsigned short octave; // + +int breathLoLimit = 0; +int breathHiLimit = 1023; +int portamLoLimit = 1000; +int portamHiLimit = 5000; +int pitchbLoLimit = 500; +int pitchbHiLimit = 4000; +int extracLoLimit = 500; +int extracHiLimit = 4000; + +int breathStep; +int portamStep; +int pitchbStep; +int extracStep; + +int minOffset = 50; + +byte dPin = 3; +byte ePin = 4; +byte uPin = 5; +byte mPin = 6; + +int deumButtons = 0; +int lastDeumButtons = 0; +int deumButtonState = 0; +byte buttonPressedAndNotUsed = 0; + +byte mainMenuCursor = 1; +byte setupBrMenuCursor = 1; +byte setupCtMenuCursor = 1; + +byte state = 0; +byte stateFirstRun = 1; + +byte subTranspose = 0; +byte subOctave = 0; +byte subMIDI = 0; +byte subBreathCC = 0; +byte subBreathAT = 0; +byte subVelocity = 0; +byte subPort = 0; +byte subPB = 0; +byte subExtra = 0; +byte subVibrato = 0; +byte subDeglitch = 0; + +byte ccList[4] = {0,2,7,11}; // OFF, Breath, Volume, Expression + +byte cursorNow; + +int pos1; +int pos2; + +// the following variables are unsigned longs because the time, measured in +// milliseconds, will quickly become a bigger number than can be stored in an int. +unsigned long lastDebounceTime = 0; // the last time the output pin was toggled +unsigned long debounceDelay = 20; // the debounce time; increase if the output flickers +unsigned long buttonRepeatTime = 0; +unsigned long buttonPressedTime = 0; +unsigned long buttonRepeatInterval = 50; +unsigned long buttonRepeatDelay = 400; +unsigned long cursorBlinkTime = 0; // the last time the cursor was toggled +unsigned long cursorBlinkInterval = 300; // the cursor blink toggle interval time +unsigned long patchViewTime = 0; +unsigned long patchViewTimeUp = 2000; // ms until patch view shuts off +unsigned long menuTime = 0; +unsigned long menuTimeUp = 60000; // menu shuts off after one minute of button inactivity +unsigned long lastDeglitchTime = 0; // The last time the fingering was changed +unsigned long ccSendTime = 0L; // The last time we sent CC values +unsigned long breath_on_time = 0L; // Time when breath sensor value went over the ON threshold + + +int lastFingering = 0; // Keep the last fingering value for debouncing + +int mainState; // The state of the main state machine + +int initial_breath_value; // The breath value at the time we observed the transition + +byte activeMIDIchannel=1; // MIDI channel +byte activePatch=0; +byte doPatchUpdate=1; + +int breathLevel=0; // breath level (smoothed) not mapped to CC value +int oldbreath=0; + +int pressureSensor; // pressure data from breath sensor, for midi breath cc and breath threshold checks +byte velocitySend; // remapped midi velocity from breath sensor (or set to static value if selected) + +int biteSensor=0; // capacitance data from bite sensor, for midi cc and threshold checks +byte portIsOn=0; // keep track and make sure we send CC with 0 value when off threshold +int oldport=0; + +int exSensor=0; +byte extracIsOn=0; +int oldextrac=0; + +int pitchBend=0; +int oldpb=8192; + +int vibDepth[8] = {0,31,63,127,254,1023,2047,4095}; + +int vibThr=1800; +int oldvibRead=0; +byte dirUp=0; // direction of first vibrato wave + +int fingeredNote; // note calculated from fingering (switches), transpose and octave settings +byte activeNote; // note playing +byte startNote=36; // set startNote to C (change this value in steps of 12 to start in other octaves) + +byte halfPitchBendKey; +byte specialKey; + +Adafruit_MPR121 touchSensor = Adafruit_MPR121(); // This is the 12-input touch sensor + + +//_______________________________________________________________________________________________ SETUP + +void setup() { + // if stored settings are not for current version, they are replaced by factory settings + if (readSetting(VERSION_ADDR) != VERSION){ + writeSetting(VERSION_ADDR,VERSION); + writeSetting(BREATH_THR_ADDR,BREATH_THR_FACTORY); + writeSetting(breathMaxVal_ADDR,breathMaxVal_FACTORY); + writeSetting(PORTAM_THR_ADDR,PORTAM_THR_FACTORY); + writeSetting(PORTAM_MAX_ADDR,PORTAM_MAX_FACTORY); + writeSetting(PITCHB_THR_ADDR,PITCHB_THR_FACTORY); + writeSetting(PITCHB_MAX_ADDR,PITCHB_MAX_FACTORY); + writeSetting(TRANSP_ADDR,TRANSP_FACTORY); + writeSetting(MIDI_ADDR,MIDI_FACTORY); + writeSetting(BREATH_CC_ADDR,BREATH_CC_FACTORY); + writeSetting(BREATH_AT_ADDR,BREATH_AT_FACTORY); + writeSetting(VELOCITY_ADDR,VELOCITY_FACTORY); + writeSetting(PORTAM_ADDR,PORTAM_FACTORY); + writeSetting(PB_ADDR,PB_FACTORY); + writeSetting(EXTRA_ADDR,EXTRA_FACTORY); + writeSetting(VIBRATO_ADDR,VIBRATO_FACTORY); + writeSetting(DEGLITCH_ADDR,DEGLITCH_FACTORY); + writeSetting(EXTRAC_THR_ADDR,EXTRAC_THR_FACTORY); + writeSetting(EXTRAC_MAX_ADDR,EXTRAC_MAX_FACTORY); + writeSetting(PATCH_ADDR,PATCH_FACTORY); + writeSetting(OCTAVE_ADDR,OCTAVE_FACTORY); + } + // read settings from EEPROM + breathThrVal = readSetting(BREATH_THR_ADDR); + breathMaxVal = readSetting(breathMaxVal_ADDR); + portamThrVal = readSetting(PORTAM_THR_ADDR); + portamMaxVal = readSetting(PORTAM_MAX_ADDR); + pitchbThrVal = readSetting(PITCHB_THR_ADDR); + pitchbMaxVal = readSetting(PITCHB_MAX_ADDR); + transpose = readSetting(TRANSP_ADDR); + MIDIchannel = readSetting(MIDI_ADDR); + breathCC = readSetting(BREATH_CC_ADDR); + breathAT = readSetting(BREATH_AT_ADDR); + velocity = readSetting(VELOCITY_ADDR); + portamento = readSetting(PORTAM_ADDR); + PBdepth = readSetting(PB_ADDR); + extraCT = readSetting(EXTRA_ADDR); + vibrato = readSetting(VIBRATO_ADDR); + deglitch = readSetting(DEGLITCH_ADDR); + extracThrVal = readSetting(EXTRAC_THR_ADDR); + extracMaxVal = readSetting(EXTRAC_MAX_ADDR); + patch = readSetting(PATCH_ADDR); + octave = readSetting(OCTAVE_ADDR); + + breathStep = (breathHiLimit - breathLoLimit)/92; // 92 is the number of pixels in the settings bar + portamStep = (portamHiLimit - portamLoLimit)/92; + pitchbStep = (pitchbHiLimit - pitchbLoLimit)/92; + extracStep = (extracHiLimit - extracLoLimit)/92; + + pinMode(dPin, INPUT_PULLUP); + pinMode(ePin, INPUT_PULLUP); + pinMode(uPin, INPUT_PULLUP); + pinMode(mPin, INPUT_PULLUP); + + // by default, we'll generate the high voltage from the 3.3v line internally! (neat!) + display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3D (for the 128x64) + // init done + + // Show image buffer on the display hardware. + // Since the buffer is intialized with an Adafruit splashscreen + // internally, this will display the splashscreen. + + display.clearDisplay(); + display.drawBitmap(0,0,nuevi_logo_bmp,128,64,1); + display.display(); + delay(5000); + mainState = NOTE_OFF; // initialize main state machine + if (!touchSensor.begin(0x5A)) { + while (1); // Touch sensor initialization failed - stop doing stuff + } + Serial3.begin(31250); // start serial with midi baudrate 31250 + Serial3.flush(); + +} + +//_______________________________________________________________________________________________ MAIN LOOP + +void loop() { + pressureSensor = analogRead(A0); // Get the pressure sensor reading from analog pin A0 + + if (mainState == NOTE_OFF) { + if (activeMIDIchannel != MIDIchannel) activeMIDIchannel = MIDIchannel; // only switch channel if no active note + if ((activePatch != patch) && doPatchUpdate){ + activePatch = patch; + usbMIDI.sendProgramChange(activePatch-1,activeMIDIchannel); + dinMIDIsendProgramChange(activePatch-1,activeMIDIchannel); + doPatchUpdate = 0; + } + if (pressureSensor > breathThrVal) { + // Value has risen above threshold. Move to the ON_Delay + // state. Record time and initial breath value. + breath_on_time = millis(); + initial_breath_value = pressureSensor; + mainState = RISE_WAIT; // Go to next state + } + } else if (mainState == RISE_WAIT) { + if (pressureSensor > breathThrVal) { + // Has enough time passed for us to collect our second + // sample? + if (millis() - breath_on_time > ON_Delay) { + // Yes, so calculate MIDI note and velocity, then send a note on event + readSwitches(); + //fingeredNote = startNote + 24; + // We should be at tonguing peak, so set velocity based on current pressureSensor value unless fixed velocity is set + // If initial value is greater than value after delay, go with initial value, constrain input to keep mapped output within 1 to 127 + if (!velocity) { + velocitySend = map(constrain(max(pressureSensor,initial_breath_value),breathThrVal,breathMaxVal),breathThrVal,breathMaxVal,1,127); + } else velocitySend = velocity; + breathLevel=constrain(max(pressureSensor,initial_breath_value),breathThrVal,breathMaxVal); + breath(); // send breath data + if ((fingeredNote >= 0) and (fingeredNote <= 127)){ // don't send midi out of range + usbMIDI.sendNoteOn(fingeredNote, velocitySend, activeMIDIchannel); // send Note On message for new note + dinMIDIsendNoteOn(fingeredNote, velocitySend, activeMIDIchannel - 1); + } + activeNote=fingeredNote; + mainState = NOTE_ON; + } + } else { + // Value fell below threshold before ON_Delay passed. Return to + // NOTE_OFF state (e.g. we're ignoring a short blip of breath) + mainState = NOTE_OFF; + } + } else if (mainState == NOTE_ON) { + if (pressureSensor < breathThrVal) { + // Value has fallen below threshold - turn the note off + if ((activeNote >= 0) and (activeNote <= 127)){ // don't send midi out of range + usbMIDI.sendNoteOff(activeNote, velocitySend, activeMIDIchannel); // send Note Off message + dinMIDIsendNoteOff(activeNote, velocitySend, activeMIDIchannel - 1); + } + breathLevel=0; + mainState = NOTE_OFF; + } else { + readSwitches(); + //fingeredNote = startNote + 24; + if (fingeredNote != lastFingering){ // + // reset the debouncing timer + lastDeglitchTime = millis(); + } + if ((millis() - lastDeglitchTime) > deglitch) { + // whatever the reading is at, it's been there for longer + // than the debounce delay, so take it as the actual current state + if (fingeredNote != activeNote) { + // Player has moved to a new fingering while still blowing. + // Send a note off for the current note and a note on for + // the new note. + velocity = map(constrain(pressureSensor,breathThrVal,breathMaxVal),breathThrVal,breathMaxVal,7,127); // set new velocity value based on current pressure sensor level + if ((fingeredNote >= 0) and (fingeredNote <= 127)){ // don't send midi out of range + usbMIDI.sendNoteOn(fingeredNote, velocitySend, activeMIDIchannel); // send Note On message for new note + dinMIDIsendNoteOn(fingeredNote, velocitySend, activeMIDIchannel - 1); + } + if ((activeNote >= 0) and (activeNote <= 127)){ // don't send midi out of range + usbMIDI.sendNoteOff(activeNote, 0, activeMIDIchannel); // send Note Off message for previous note (legato) + dinMIDIsendNoteOff(activeNote, 0, activeMIDIchannel - 1); + } + activeNote=fingeredNote; + } + } + } + } + // Is it time to send more CC data? + if (millis() - ccSendTime > CC_INTERVAL) { + // deal with Breath, Pitch Bend and Modulation + breath(); + pitch_bend(); + portamento_(); + ccSendTime = millis(); + } + lastFingering=fingeredNote; +} +//_______________________________________________________________________________________________ FUNCTIONS + +// Send a three byte din midi message +void midiSend3B(byte midistatus, byte data1, byte data2) { + Serial3.write(midistatus); + Serial3.write(data1); + Serial3.write(data2); +} + +//************************************************************** + +// Send a two byte din midi message +void midiSend2B(byte midistatus, byte data) { + Serial3.write(midistatus); + Serial3.write(data); +} + +//************************************************************** + +// Send din pitchbend +void dinMIDIsendPitchBend(int pb, byte ch) { + int pitchLSB = pb & 0x007F; + int pitchMSB = (pb >>7) & 0x007F; + midiSend3B((0xE0 | ch), pitchLSB, pitchMSB); +} + +//************************************************************** + +// Send din control change +void dinMIDIsendControlChange(byte ccNumber, int cc, byte ch) { + midiSend3B((0xB0 | ch), ccNumber, cc); +} + +//************************************************************** + +// Send din note on +void dinMIDIsendNoteOn(byte note, int vel, byte ch) { + midiSend3B((0x90 | ch), note, vel); +} + +//************************************************************** + +// Send din note off +void dinMIDIsendNoteOff(byte note, int vel, byte ch) { + midiSend3B((0x80 | ch), note, vel); +} + +//************************************************************** + +// Send din aftertouch +void dinMIDIsendAfterTouch(byte value, byte ch) { + midiSend2B((0xD0 | ch), value); +} + +//************************************************************** + +// Send din program change +void dinMIDIsendProgramChange(byte value, byte ch) { + midiSend2B((0xC0 | ch), value); +} + +//************************************************************** + +void breath(){ + int breathCCval; + breathLevel = breathLevel*0.8+pressureSensor*0.2; // smoothing of breathLevel value + breathCC = map(constrain(breathLevel,breathThrVal,breathMaxVal),breathThrVal,breathMaxVal,0,127); + if (breathCC != oldbreath){ // only send midi data if breath has changed from previous value + if (breathCC){ + // send midi cc + usbMIDI.sendControlChange(breathCC, breathCCval, activeMIDIchannel); + dinMIDIsendControlChange(breathCC, breathCCval, activeMIDIchannel - 1); + } + if (breathAT){ + // send aftertouch + usbMIDI.sendAfterTouch(breathCCval, activeMIDIchannel); + dinMIDIsendAfterTouch(breathCCval, activeMIDIchannel); + } + oldbreath = breathCCval; + } +} + +//************************************************************** + +void pitch_bend(){ + int calculatedPBdepth; + int pbUp = touchRead(23); + int pbDn = touchRead(22); + int vibRead = touchRead(1); + if ((vibRead > vibThr)&&(vibRead > (oldvibRead+7))){ + if (dirUp){ + pitchBend=oldpb*0.7+0.3*(8192 + vibDepth[vibrato]); + } else { + pitchBend=oldpb*0.7+0.3*(8191 - vibDepth[vibrato]); + } + } else if ((vibRead > vibThr)&&(vibRead < (oldvibRead-7))){ + if (dirUp ){ + pitchBend=oldpb*0.7+0.3*(8191 - vibDepth[vibrato]); + } else { + pitchBend=oldpb*0.7+0.3*(8192 + vibDepth[vibrato]); + } + } else { + pitchBend = oldpb*0.7+8192*0.3; // released, so smooth your way back to zero + if ((pitchBend > 8187) && (pitchBend < 8197)) pitchBend = 8192; // 8192 is 0 pitch bend, don't miss it bc of smoothing + } + oldvibRead = vibRead; + if (PBdepth){ + calculatedPBdepth = (1/PBdepth*8192); + if (halfPitchBendKey) calculatedPBdepth = calculatedPBdepth/2; + } + if ((pbUp > pitchbThrVal) && PBdepth){ + pitchBend=pitchBend*0.8+0.2*map(constrain(pbUp,pitchbThrVal,pitchbMaxVal),pitchbThrVal,pitchbMaxVal,8192,(8192 + calculatedPBdepth)); + } else if ((pbDn > pitchbThrVal) && PBdepth){ + pitchBend=pitchBend*0.8+0.2*map(constrain(pbDn,pitchbThrVal,pitchbMaxVal),pitchbThrVal,pitchbMaxVal,8192,(8191 - calculatedPBdepth)); + } else if (oldvibRead < vibThr){ + pitchBend = pitchBend*0.8+8192*0.2; // released, so smooth your way back to zero + if ((pitchBend > 8187) && (pitchBend < 8197)) pitchBend = 8192; // 8192 is 0 pitch bend, don't miss it bc of smoothing + } + pitchBend=constrain(pitchBend, 0, 16383); + if (pitchBend != oldpb){// only send midi data if pitch bend has changed from previous value + usbMIDI.sendPitchBend(pitchBend, activeMIDIchannel); + dinMIDIsendPitchBend(pitchBend, activeMIDIchannel - 1); + oldpb=pitchBend; + } +} + +//*********************************************************** + +void extraController(){ + exSensor=exSensor*0.6+0.4*touchRead(15); // get sensor data, do some smoothing + if (extraCT && (exSensor >= extracThrVal)) { // if we are enabled and over the threshold, send portamento + if (!extracIsOn) { + extracIsOn=1; + if (extraCT == 2){ //Sustan ON + usbMIDI.sendControlChange(65,127, activeMIDIchannel); + dinMIDIsendControlChange(65,127, activeMIDIchannel - 1); + } + } + if (extraCT == 1){ //Send modulation + int extracCC = map(constrain(exSensor,extracThrVal,extracMaxVal),extracThrVal,extracMaxVal,1,127); + if (extracCC != oldextrac){ + usbMIDI.sendControlChange(1,extracCC, activeMIDIchannel); + dinMIDIsendControlChange(1,extracCC, activeMIDIchannel - 1); + } + oldextrac = extracCC; + } + } else if (extracIsOn) { // we have just gone below threshold, so send zero value + extracIsOn=0; + if (extraCT == 1){ //MOD + //send modulation 0 + usbMIDI.sendControlChange(1,0, activeMIDIchannel); + dinMIDIsendControlChange(1,0, activeMIDIchannel - 1); + oldextrac = 0; + } else if (extraCT == 2){ //SUS + //send sustain off + usbMIDI.sendControlChange(65,0, activeMIDIchannel); + dinMIDIsendControlChange(65,0, activeMIDIchannel - 1); + } + } +} + +//*********************************************************** +void portamento_(){ + biteSensor=biteSensor*0.6+0.4*touchRead(0); // get sensor data, do some smoothing + if (portamento && (biteSensor >= portamThrVal)) { // if we are enabled and over the threshold, send portamento + if (!portIsOn) { + portOn(); + } + port(); + } else if (portIsOn) { // we have just gone below threshold, so send zero value + portOff(); + } +} + +//*********************************************************** + +void portOn(){ + if (portamento == 2){ // if portamento midi switching is enabled + usbMIDI.sendControlChange(CCN_PortOnOff, 127, activeMIDIchannel); + dinMIDIsendControlChange(CCN_PortOnOff, 127, activeMIDIchannel - 1); + } + portIsOn=1; +} + +//*********************************************************** + +void port(){ + int portCC; + portCC = map(constrain(biteSensor,portamThrVal,portamMaxVal),portamThrVal,portamMaxVal,1,127); + if (portCC!=oldport){ + usbMIDI.sendControlChange(CCN_Port, portCC, activeMIDIchannel); + dinMIDIsendControlChange(CCN_Port, portCC, activeMIDIchannel - 1); + } + oldport = portCC; +} + +//*********************************************************** + +void portOff(){ + usbMIDI.sendControlChange(CCN_Port, 0, activeMIDIchannel); + dinMIDIsendControlChange(CCN_Port, 0, activeMIDIchannel - 1); + if (portamento == 2){ // if portamento midi switching is enabled + usbMIDI.sendControlChange(CCN_PortOnOff, 0, activeMIDIchannel); + dinMIDIsendControlChange(CCN_PortOnOff, 0, activeMIDIchannel - 1); + } + portIsOn=0; + oldport = 0; +} + +//*********************************************************** + +void readSwitches(){ + + // Key variables, TRUE (1) for pressed, FALSE (0) for not pressed + byte K1; // Valve 1 (pitch change -2) + byte K2; // Valve 2 (pitch change -1) + byte K3; // Valve 3 (pitch change -3) + byte K4; // Left Hand index finger (pitch change -5) + byte K5; // Trill key 1 (pitch change +2) + byte K6; // Trill key 2 (pitch change +1) + byte K7; // Trill key 3 (pitch change +4) + + byte octaveR = 0; + + // Read touch pads (MPR121) and put value in variables + uint16_t touchValue = touchSensor.touched(); + + // Octave rollers + if (((touchValue >> 2) & 0x01) && ((touchValue >> 4) & 0x01)) octaveR = 6; //R6 = R5 && R3 + else if ((touchValue >> 4) & 0x01) octaveR = 5; //R5 + else if ((touchValue >> 3) & 0x01) octaveR = 4; //R4 + else if ((touchValue >> 2) & 0x01) octaveR = 3; //R3 + else if ((touchValue >> 1) & 0x01) octaveR = 2; //R2 + else if ((touchValue >> 0) & 0x01) octaveR = 1; //R1 + + // Valves and trill keys + K4=((touchValue >> 5) & 0x01); + K1=((touchValue >> 6) & 0x01); + K2=((touchValue >> 7) & 0x01); + K3=((touchValue >> 8) & 0x01); + K5=((touchValue >> 9) & 0x01); + K6=((touchValue >> 10) & 0x01); + K7=((touchValue >> 11) & 0x01); + + // Read touch pads (Teensy built in) and put value in variables + //K4=touchRead(15) > touch_Thr; <<< this has been changed so K4 is now pin 5 on MPR121 (prev R6) + specialKey=touchRead(0) > touch_Thr; //S2 + halfPitchBendKey=touchRead(1) > touch_Thr; //S1 + + // 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; +} + + + + + + + + + + +// MENU STUFF FROM THIS POINT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< + + + + + + + + + + + +void menu() { + /* + display.drawPixel(34, 38, BLACK); + display.drawPixel(35, 38, WHITE); + display.display(); + //delay(500); + display.drawPixel(35, 38, BLACK); + display.drawPixel(36, 38, WHITE); + display.display(); + //delay(500); + display.drawPixel(36, 38, BLACK); + display.drawPixel(35, 38, WHITE); + display.display(); + //delay(500); + display.drawPixel(35, 38, BLACK); + display.drawPixel(34, 38, WHITE); + display.display(); + //delay(500); + */ + + // read the state of the switches + deumButtons = !digitalRead(dPin)+2*!digitalRead(ePin)+4*!digitalRead(uPin)+8*!digitalRead(mPin); + + // check to see if you just pressed the button + // (i.e. the input went from LOW to HIGH), and you've waited long enough + // since the last press to ignore any noise: + + // If the switch changed, due to noise or pressing: + if (deumButtons != lastDeumButtons) { + // reset the debouncing timer + lastDebounceTime = millis(); + } + + if ((millis() - lastDebounceTime) > debounceDelay) { + // whatever the reading is at, it's been there for longer than the debounce + // delay, so take it as the actual current state: + + // if the button state has changed: + if (deumButtons != deumButtonState) { + deumButtonState = deumButtons; + menuTime = millis(); + Serial.println(deumButtonState); + buttonPressedAndNotUsed = 1; + buttonPressedTime = millis(); + } + + if (((deumButtons == 1) || (deumButtons == 4)) && (millis() - buttonPressedTime > buttonRepeatDelay) && (millis() - buttonRepeatTime > buttonRepeatInterval)){ + buttonPressedAndNotUsed = 1; + buttonRepeatTime = millis(); + } + + } + + + // save the reading. Next time through the loop, it'll be the lastButtonState: + lastDeumButtons = deumButtons; + + if (state && ((millis() - menuTime) > menuTimeUp)) { // shut off menu system if not used for a while + state = DISPLAYOFF_IDL; + stateFirstRun = 1; + subTranspose = 0; + subMIDI = 0; + subBreathCC = 0; + subBreathAT = 0; + subVelocity = 0; + subPort = 0; + subPB = 0; + subExtra = 0; + subVibrato = 0; + subDeglitch = 0; + } + + + + if (state == DISPLAYOFF_IDL){ + if (stateFirstRun) { + display.ssd1306_command(SSD1306_DISPLAYOFF); + stateFirstRun = 0; + } + if (buttonPressedAndNotUsed){ + buttonPressedAndNotUsed = 0; + switch (deumButtonState){ + case 1: + // down + display.ssd1306_command(SSD1306_DISPLAYON); + state = PATCH_VIEW; + buttonPressedAndNotUsed = 1; + stateFirstRun = 1; + break; + case 2: + // enter + display.ssd1306_command(SSD1306_DISPLAYON); + state = PATCH_VIEW; + stateFirstRun = 1; + break; + case 4: + // up + display.ssd1306_command(SSD1306_DISPLAYON); + state = PATCH_VIEW; + buttonPressedAndNotUsed = 1; + stateFirstRun = 1; + break; + case 8: + // menu + display.ssd1306_command(SSD1306_DISPLAYON); + state = MAIN_MENU; + stateFirstRun = 1; + break; + } + } + } else if (state == PATCH_VIEW){ + if (stateFirstRun) { + drawPatchView(); + patchViewTime = millis(); + stateFirstRun = 0; + } + if ((millis() - patchViewTime) > patchViewTimeUp) { + state = DISPLAYOFF_IDL; + stateFirstRun = 1; + doPatchUpdate = 1; + } + if (buttonPressedAndNotUsed){ + buttonPressedAndNotUsed = 0; + switch (deumButtonState){ + case 1: + // down + if (patch > 1){ + patch--; + } else patch = 128; + drawPatchView(); + patchViewTime = millis(); + break; + case 2: + // enter + patchViewTime = millis(); + break; + case 4: + // up + if (patch < 128){ + patch++; + } else patch = 1; + drawPatchView(); + patchViewTime = millis(); + break; + case 8: + // menu + state = DISPLAYOFF_IDL; + stateFirstRun = 1; + doPatchUpdate = 1; + break; + } + } + } else if (state == MAIN_MENU){ // MAIN MENU HERE <<<<<<<<<<<<<<< + if (stateFirstRun) { + drawMenuScreen(); + stateFirstRun = 0; + } + if (subTranspose){ + if ((millis() - cursorBlinkTime) > cursorBlinkInterval) { + if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE; + plotTranspose(cursorNow); + display.display(); + cursorBlinkTime = millis(); + } + if (buttonPressedAndNotUsed){ + buttonPressedAndNotUsed = 0; + switch (deumButtonState){ + case 1: + // down + if (transpose > 0){ + plotTranspose(BLACK); + transpose--; + plotTranspose(WHITE); + cursorNow = BLACK; + display.display(); + cursorBlinkTime = millis(); + } + break; + case 2: + // enter + plotTranspose(WHITE); + cursorNow = BLACK; + display.display(); + subTranspose = 0; + writeSetting(TRANSP_ADDR,transpose); + break; + case 4: + // up + if (transpose < 24){ + plotTranspose(BLACK); + transpose++; + plotTranspose(WHITE); + cursorNow = BLACK; + display.display(); + cursorBlinkTime = millis(); + } + break; + case 8: + // menu + plotTranspose(WHITE); + cursorNow = BLACK; + display.display(); + subTranspose = 0; + writeSetting(TRANSP_ADDR,transpose); + break; + } + } + } else if (subOctave){ + if ((millis() - cursorBlinkTime) > cursorBlinkInterval) { + if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE; + plotOctave(cursorNow); + display.display(); + cursorBlinkTime = millis(); + } + if (buttonPressedAndNotUsed){ + buttonPressedAndNotUsed = 0; + switch (deumButtonState){ + case 1: + // down + if (octave > 0){ + plotOctave(BLACK); + octave--; + plotOctave(WHITE); + cursorNow = BLACK; + display.display(); + cursorBlinkTime = millis(); + } + break; + case 2: + // enter + plotOctave(WHITE); + cursorNow = BLACK; + display.display(); + subOctave = 0; + writeSetting(OCTAVE_ADDR,octave); + break; + case 4: + // up + if (octave < 6){ + plotOctave(BLACK); + octave++; + plotOctave(WHITE); + cursorNow = BLACK; + display.display(); + cursorBlinkTime = millis(); + } + break; + case 8: + // menu + plotOctave(WHITE); + cursorNow = BLACK; + display.display(); + subOctave = 0; + writeSetting(OCTAVE_ADDR,octave); + break; + } + } + } else if (subMIDI) { + if ((millis() - cursorBlinkTime) > cursorBlinkInterval) { + if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE; + plotMIDI(cursorNow); + display.display(); + cursorBlinkTime = millis(); + } + if (buttonPressedAndNotUsed){ + buttonPressedAndNotUsed = 0; + switch (deumButtonState){ + case 1: + // down + if (MIDIchannel > 1){ + plotMIDI(BLACK); + MIDIchannel--; + plotMIDI(WHITE); + cursorNow = BLACK; + display.display(); + cursorBlinkTime = millis(); + } + break; + case 2: + // enter + plotMIDI(WHITE); + cursorNow = BLACK; + display.display(); + subMIDI = 0; + writeSetting(MIDI_ADDR,MIDIchannel); + break; + case 4: + // up + if (MIDIchannel < 16){ + plotMIDI(BLACK); + MIDIchannel++; + plotMIDI(WHITE); + cursorNow = BLACK; + display.display(); + cursorBlinkTime = millis(); + } + break; + case 8: + // menu + plotMIDI(WHITE); + cursorNow = BLACK; + display.display(); + subMIDI = 0; + writeSetting(MIDI_ADDR,MIDIchannel); + break; + } + } + } else { + if ((millis() - cursorBlinkTime) > cursorBlinkInterval) { + if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE; + drawMenuCursor(mainMenuCursor, cursorNow); + display.display(); + cursorBlinkTime = millis(); + } + if (buttonPressedAndNotUsed){ + buttonPressedAndNotUsed = 0; + switch (deumButtonState){ + case 1: + // down + if (mainMenuCursor < 6){ + drawMenuCursor(mainMenuCursor, BLACK); + mainMenuCursor++; + drawMenuCursor(mainMenuCursor, WHITE); + cursorNow = BLACK; + clearSub(); + display.display(); + } + break; + case 2: + // enter + selectMainMenu(); + break; + case 4: + // up + if (mainMenuCursor > 1){ + drawMenuCursor(mainMenuCursor, BLACK); + mainMenuCursor--; + drawMenuCursor(mainMenuCursor, WHITE); + cursorNow = BLACK; + clearSub(); + display.display(); + } + break; + case 8: + // menu + state = DISPLAYOFF_IDL; + stateFirstRun = 1; + break; + } + } + } + } else if (state == BREATH_ADJ_IDL){ + if (stateFirstRun) { + drawBreathScreen(); + stateFirstRun = 0; + } + if ((millis() - cursorBlinkTime) > cursorBlinkInterval) { + if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE; + drawAdjCursor(cursorNow); + display.display(); + cursorBlinkTime = millis(); + } + if (buttonPressedAndNotUsed){ + buttonPressedAndNotUsed = 0; + switch (deumButtonState){ + case 1: + // down + state = PORTAM_ADJ_IDL; + stateFirstRun = 1; + writeSetting(BREATH_THR_ADDR,breathThrVal); + writeSetting(breathMaxVal_ADDR,breathMaxVal); + break; + case 2: + // enter + state = BREATH_ADJ_THR; + break; + case 4: + // up + state = EXTRAC_ADJ_IDL; + stateFirstRun = 1; + writeSetting(BREATH_THR_ADDR,breathThrVal); + writeSetting(breathMaxVal_ADDR,breathMaxVal); + break; + case 8: + // menu + state = MAIN_MENU; + stateFirstRun = 1; + writeSetting(BREATH_THR_ADDR,breathThrVal); + writeSetting(breathMaxVal_ADDR,breathMaxVal); + break; + } + } + } else if (state == BREATH_ADJ_THR){ + if ((millis() - cursorBlinkTime) > cursorBlinkInterval) { + if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE; + display.drawLine(pos1,20,pos1,26,cursorNow); + display.display(); + cursorBlinkTime = millis(); + } + if (buttonPressedAndNotUsed){ + buttonPressedAndNotUsed = 0; + switch (deumButtonState){ + case 1: + // down + if (breathThrVal - breathStep > breathLoLimit){ + breathThrVal -= breathStep; + display.drawLine(pos1,20,pos1,26,BLACK); + pos1 = map(breathThrVal, breathLoLimit, breathHiLimit, 27, 119); + display.drawLine(pos1,20,pos1,26,WHITE); + display.display(); + cursorBlinkTime = millis(); + cursorNow = BLACK; + } + break; + case 2: + // enter + state = BREATH_ADJ_MAX; + display.drawLine(pos1,20,pos1,26,WHITE); + display.display(); + break; + case 4: + // up + if (breathThrVal + breathStep < breathHiLimit){ + breathThrVal += breathStep; + display.drawLine(pos1,20,pos1,26,BLACK); + pos1 = map(breathThrVal, breathLoLimit, breathHiLimit, 27, 119); + display.drawLine(pos1,20,pos1,26,WHITE); + display.display(); + cursorBlinkTime = millis(); + cursorNow = BLACK; + } + break; + case 8: + // menu + state = BREATH_ADJ_IDL; + display.drawLine(pos1,20,pos1,26,WHITE); + display.display(); + break; + } + } + } else if (state == BREATH_ADJ_MAX){ + if ((millis() - cursorBlinkTime) > cursorBlinkInterval) { + if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE; + display.drawLine(pos2,50,pos2,57,cursorNow);; + display.display(); + cursorBlinkTime = millis(); + } + if (buttonPressedAndNotUsed){ + buttonPressedAndNotUsed = 0; + switch (deumButtonState){ + case 1: + // down + if ((breathMaxVal - breathStep) > (breathThrVal + minOffset)){ + breathMaxVal -= breathStep; + display.drawLine(pos2,50,pos2,57,BLACK); + pos2 = map(breathMaxVal, breathLoLimit, breathHiLimit, 27, 119); + display.drawLine(pos2,50,pos2,57,WHITE); + display.display(); + cursorBlinkTime = millis(); + cursorNow = BLACK; + } + break; + case 2: + // enter + state = BREATH_ADJ_IDL; + display.drawLine(pos2,50,pos2,57,WHITE); + display.display(); + break; + case 4: + // up + if (breathMaxVal + breathStep < breathHiLimit){ + breathMaxVal += breathStep; + display.drawLine(pos2,50,pos2,57,BLACK); + pos2 = map(breathMaxVal, breathLoLimit, breathHiLimit, 27, 119); + display.drawLine(pos2,50,pos2,57,WHITE); + display.display(); + cursorBlinkTime = millis(); + cursorNow = BLACK; + } + break; + case 8: + // menu + state = BREATH_ADJ_IDL; + display.drawLine(pos2,50,pos2,57,WHITE); + display.display(); + break; + } + } + } else if (state == PORTAM_ADJ_IDL){ + if (stateFirstRun) { + drawPortamScreen(); + stateFirstRun = 0; + } + if ((millis() - cursorBlinkTime) > cursorBlinkInterval) { + if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE; + drawAdjCursor(cursorNow); + display.display(); + cursorBlinkTime = millis(); + } + if (buttonPressedAndNotUsed){ + buttonPressedAndNotUsed = 0; + switch (deumButtonState){ + case 1: + // down + state = PITCHB_ADJ_IDL; + stateFirstRun = 1; + writeSetting(PORTAM_THR_ADDR,portamThrVal); + writeSetting(PORTAM_MAX_ADDR,portamMaxVal); + break; + case 2: + // enter + state = PORTAM_ADJ_THR; + break; + case 4: + // up + state = BREATH_ADJ_IDL; + stateFirstRun = 1; + writeSetting(PORTAM_THR_ADDR,portamThrVal); + writeSetting(PORTAM_MAX_ADDR,portamMaxVal); + break; + case 8: + // menu + state = MAIN_MENU; + stateFirstRun = 1; + writeSetting(PORTAM_THR_ADDR,portamThrVal); + writeSetting(PORTAM_MAX_ADDR,portamMaxVal); + break; + } + } + } else if (state == PORTAM_ADJ_THR){ + if ((millis() - cursorBlinkTime) > cursorBlinkInterval) { + if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE; + display.drawLine(pos1,20,pos1,26,cursorNow); + display.display(); + cursorBlinkTime = millis(); + } + if (buttonPressedAndNotUsed){ + buttonPressedAndNotUsed = 0; + switch (deumButtonState){ + case 1: + // down + if (portamThrVal - portamStep > portamLoLimit){ + portamThrVal -= portamStep; + display.drawLine(pos1,20,pos1,26,BLACK); + pos1 = map(portamThrVal, portamLoLimit, portamHiLimit, 27, 119); + display.drawLine(pos1,20,pos1,26,WHITE); + display.display(); + cursorBlinkTime = millis(); + cursorNow = BLACK; + } + break; + case 2: + // enter + state = PORTAM_ADJ_MAX; + display.drawLine(pos1,20,pos1,26,WHITE); + display.display(); + break; + case 4: + // up + if (portamThrVal + portamStep < portamHiLimit){ + portamThrVal += portamStep; + display.drawLine(pos1,20,pos1,26,BLACK); + pos1 = map(portamThrVal, portamLoLimit, portamHiLimit, 27, 119); + display.drawLine(pos1,20,pos1,26,WHITE); + display.display(); + cursorBlinkTime = millis(); + cursorNow = BLACK; + } + break; + case 8: + // menu + state = PORTAM_ADJ_IDL; + display.drawLine(pos1,20,pos1,26,WHITE); + display.display(); + break; + } + } + } else if (state == PORTAM_ADJ_MAX){ + if ((millis() - cursorBlinkTime) > cursorBlinkInterval) { + if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE; + display.drawLine(pos2,50,pos2,57,cursorNow);; + display.display(); + cursorBlinkTime = millis(); + } + if (buttonPressedAndNotUsed){ + buttonPressedAndNotUsed = 0; + switch (deumButtonState){ + case 1: + // down + if ((portamMaxVal - portamStep) > (portamThrVal + minOffset)){ + portamMaxVal -= portamStep; + display.drawLine(pos2,50,pos2,57,BLACK); + pos2 = map(portamMaxVal, portamLoLimit, portamHiLimit, 27, 119); + display.drawLine(pos2,50,pos2,57,WHITE); + display.display(); + cursorBlinkTime = millis(); + cursorNow = BLACK; + } + break; + case 2: + // enter + state = PORTAM_ADJ_IDL; + display.drawLine(pos2,50,pos2,57,WHITE); + display.display(); + break; + case 4: + // up + if (portamMaxVal + portamStep < portamHiLimit){ + portamMaxVal += portamStep; + display.drawLine(pos2,50,pos2,57,BLACK); + pos2 = map(portamMaxVal, portamLoLimit, portamHiLimit, 27, 119); + display.drawLine(pos2,50,pos2,57,WHITE); + display.display(); + cursorBlinkTime = millis(); + cursorNow = BLACK; + } + break; + case 8: + // menu + state = PORTAM_ADJ_IDL; + display.drawLine(pos2,50,pos2,57,WHITE); + display.display(); + break; + } + } + } else if (state == PITCHB_ADJ_IDL){ + if (stateFirstRun) { + drawPitchbScreen(); + stateFirstRun = 0; + } + if ((millis() - cursorBlinkTime) > cursorBlinkInterval) { + if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE; + drawAdjCursor(cursorNow); + display.display(); + cursorBlinkTime = millis(); + } + if (buttonPressedAndNotUsed){ + buttonPressedAndNotUsed = 0; + switch (deumButtonState){ + case 1: + // down + state = EXTRAC_ADJ_IDL; + stateFirstRun = 1; + writeSetting(PITCHB_THR_ADDR,pitchbThrVal); + writeSetting(PITCHB_MAX_ADDR,pitchbMaxVal); + break; + case 2: + // enter + state = PITCHB_ADJ_THR; + break; + case 4: + // up + state = PORTAM_ADJ_IDL; + stateFirstRun = 1; + writeSetting(PITCHB_THR_ADDR,pitchbThrVal); + writeSetting(PITCHB_MAX_ADDR,pitchbMaxVal); + break; + case 8: + // menu + state = MAIN_MENU; + stateFirstRun = 1; + writeSetting(PITCHB_THR_ADDR,pitchbThrVal); + writeSetting(PITCHB_MAX_ADDR,pitchbMaxVal); + break; + } + } + } else if (state == PITCHB_ADJ_THR){ + if ((millis() - cursorBlinkTime) > cursorBlinkInterval) { + if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE; + display.drawLine(pos1,20,pos1,26,cursorNow); + display.display(); + cursorBlinkTime = millis(); + } + if (buttonPressedAndNotUsed){ + buttonPressedAndNotUsed = 0; + switch (deumButtonState){ + case 1: + // down + if (pitchbThrVal - pitchbStep > pitchbLoLimit){ + pitchbThrVal -= pitchbStep; + display.drawLine(pos1,20,pos1,26,BLACK); + pos1 = map(pitchbThrVal, pitchbLoLimit, pitchbHiLimit, 27, 119); + display.drawLine(pos1,20,pos1,26,WHITE); + display.display(); + cursorBlinkTime = millis(); + cursorNow = BLACK; + } + break; + case 2: + // enter + state = PITCHB_ADJ_MAX; + display.drawLine(pos1,20,pos1,26,WHITE); + display.display(); + break; + case 4: + // up + if (pitchbThrVal + pitchbStep < pitchbHiLimit){ + pitchbThrVal += pitchbStep; + display.drawLine(pos1,20,pos1,26,BLACK); + pos1 = map(pitchbThrVal, pitchbLoLimit, pitchbHiLimit, 27, 119); + display.drawLine(pos1,20,pos1,26,WHITE); + display.display(); + cursorBlinkTime = millis(); + cursorNow = BLACK; + } + break; + case 8: + // menu + state = PITCHB_ADJ_IDL; + display.drawLine(pos1,20,pos1,26,WHITE); + display.display(); + break; + } + } + } else if (state == PITCHB_ADJ_MAX){ + if ((millis() - cursorBlinkTime) > cursorBlinkInterval) { + if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE; + display.drawLine(pos2,50,pos2,57,cursorNow);; + display.display(); + cursorBlinkTime = millis(); + } + if (buttonPressedAndNotUsed){ + buttonPressedAndNotUsed = 0; + switch (deumButtonState){ + case 1: + // down + if ((pitchbMaxVal - pitchbStep) > (pitchbThrVal + minOffset)){ + pitchbMaxVal -= pitchbStep; + display.drawLine(pos2,50,pos2,57,BLACK); + pos2 = map(pitchbMaxVal, pitchbLoLimit, pitchbHiLimit, 27, 119); + display.drawLine(pos2,50,pos2,57,WHITE); + display.display(); + cursorBlinkTime = millis(); + cursorNow = BLACK; + } + break; + case 2: + // enter + state = PITCHB_ADJ_IDL; + display.drawLine(pos2,50,pos2,57,WHITE); + display.display(); + break; + case 4: + // up + if (pitchbMaxVal + pitchbStep < pitchbHiLimit){ + pitchbMaxVal += pitchbStep; + display.drawLine(pos2,50,pos2,57,BLACK); + pos2 = map(pitchbMaxVal, pitchbLoLimit, pitchbHiLimit, 27, 119); + display.drawLine(pos2,50,pos2,57,WHITE); + display.display(); + cursorBlinkTime = millis(); + cursorNow = BLACK; + } + break; + case 8: + // menu + state = PITCHB_ADJ_IDL; + display.drawLine(pos2,50,pos2,57,WHITE); + display.display(); + break; + } + } + + } else if (state == EXTRAC_ADJ_IDL){ + if (stateFirstRun) { + drawExtracScreen(); + stateFirstRun = 0; + } + if ((millis() - cursorBlinkTime) > cursorBlinkInterval) { + if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE; + drawAdjCursor(cursorNow); + display.display(); + cursorBlinkTime = millis(); + } + if (buttonPressedAndNotUsed){ + buttonPressedAndNotUsed = 0; + switch (deumButtonState){ + case 1: + // down + state = BREATH_ADJ_IDL; + stateFirstRun = 1; + writeSetting(EXTRAC_THR_ADDR,pitchbThrVal); + writeSetting(EXTRAC_MAX_ADDR,pitchbMaxVal); + break; + case 2: + // enter + state = EXTRAC_ADJ_THR; + break; + case 4: + // up + state = PITCHB_ADJ_IDL; + stateFirstRun = 1; + writeSetting(EXTRAC_THR_ADDR,pitchbThrVal); + writeSetting(EXTRAC_MAX_ADDR,pitchbMaxVal); + break; + case 8: + // menu + state = MAIN_MENU; + stateFirstRun = 1; + writeSetting(EXTRAC_THR_ADDR,pitchbThrVal); + writeSetting(EXTRAC_MAX_ADDR,pitchbMaxVal); + break; + } + } + } else if (state == EXTRAC_ADJ_THR){ + if ((millis() - cursorBlinkTime) > cursorBlinkInterval) { + if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE; + display.drawLine(pos1,20,pos1,26,cursorNow); + display.display(); + cursorBlinkTime = millis(); + } + if (buttonPressedAndNotUsed){ + buttonPressedAndNotUsed = 0; + switch (deumButtonState){ + case 1: + // down + if (extracThrVal - extracStep > extracLoLimit){ + extracThrVal -= extracStep; + display.drawLine(pos1,20,pos1,26,BLACK); + pos1 = map(extracThrVal, extracLoLimit, extracHiLimit, 27, 119); + display.drawLine(pos1,20,pos1,26,WHITE); + display.display(); + cursorBlinkTime = millis(); + cursorNow = BLACK; + } + break; + case 2: + // enter + state = EXTRAC_ADJ_MAX; + display.drawLine(pos1,20,pos1,26,WHITE); + display.display(); + break; + case 4: + // up + if (extracThrVal + extracStep < extracHiLimit){ + extracThrVal += extracStep; + display.drawLine(pos1,20,pos1,26,BLACK); + pos1 = map(extracThrVal, extracLoLimit, extracHiLimit, 27, 119); + display.drawLine(pos1,20,pos1,26,WHITE); + display.display(); + cursorBlinkTime = millis(); + cursorNow = BLACK; + } + break; + case 8: + // menu + state = EXTRAC_ADJ_IDL; + display.drawLine(pos1,20,pos1,26,WHITE); + display.display(); + break; + } + } + } else if (state == EXTRAC_ADJ_MAX){ + if ((millis() - cursorBlinkTime) > cursorBlinkInterval) { + if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE; + display.drawLine(pos2,50,pos2,57,cursorNow);; + display.display(); + cursorBlinkTime = millis(); + } + if (buttonPressedAndNotUsed){ + buttonPressedAndNotUsed = 0; + switch (deumButtonState){ + case 1: + // down + if ((extracMaxVal - extracStep) > (extracThrVal + minOffset)){ + extracMaxVal -= extracStep; + display.drawLine(pos2,50,pos2,57,BLACK); + pos2 = map(extracMaxVal, extracLoLimit, extracHiLimit, 27, 119); + display.drawLine(pos2,50,pos2,57,WHITE); + display.display(); + cursorBlinkTime = millis(); + cursorNow = BLACK; + } + break; + case 2: + // enter + state = EXTRAC_ADJ_IDL; + display.drawLine(pos2,50,pos2,57,WHITE); + display.display(); + break; + case 4: + // up + if (extracMaxVal + extracStep < extracHiLimit){ + extracMaxVal += extracStep; + display.drawLine(pos2,50,pos2,57,BLACK); + pos2 = map(extracMaxVal, extracLoLimit, extracHiLimit, 27, 119); + display.drawLine(pos2,50,pos2,57,WHITE); + display.display(); + cursorBlinkTime = millis(); + cursorNow = BLACK; + } + break; + case 8: + // menu + state = EXTRAC_ADJ_IDL; + display.drawLine(pos2,50,pos2,57,WHITE); + display.display(); + break; + } + } + + + + } else if (state == SETUP_BR_MENU) { // SETUP BREATH MENU HERE <<<<<<<<<<<<<< + if (stateFirstRun) { + drawSetupBrMenuScreen(); + stateFirstRun = 0; + } + if (subBreathCC){ + if ((millis() - cursorBlinkTime) > cursorBlinkInterval) { + if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE; + plotBreathCC(cursorNow); + display.display(); + cursorBlinkTime = millis(); + } + if (buttonPressedAndNotUsed){ + buttonPressedAndNotUsed = 0; + switch (deumButtonState){ + case 1: + // down + if (breathCC > 0){ + plotBreathCC(BLACK); + breathCC--; + plotBreathCC(WHITE); + cursorNow = BLACK; + display.display(); + cursorBlinkTime = millis(); + } else { + plotBreathCC(BLACK); + breathCC = 3; + plotBreathCC(WHITE); + cursorNow = BLACK; + display.display(); + cursorBlinkTime = millis(); + } + break; + case 2: + // enter + plotBreathCC(WHITE); + cursorNow = BLACK; + display.display(); + subBreathCC = 0; + writeSetting(BREATH_CC_ADDR,breathCC); + break; + case 4: + // up + if (breathCC < 3){ + plotBreathCC(BLACK); + breathCC++; + plotBreathCC(WHITE); + cursorNow = BLACK; + display.display(); + cursorBlinkTime = millis(); + } else { + plotBreathCC(BLACK); + breathCC = 0; + plotBreathCC(WHITE); + cursorNow = BLACK; + display.display(); + cursorBlinkTime = millis(); + } + break; + case 8: + // menu + plotBreathCC(WHITE); + cursorNow = BLACK; + display.display(); + subBreathCC = 0; + writeSetting(BREATH_CC_ADDR,breathCC); + break; + } + } + } else if (subBreathAT) { + if ((millis() - cursorBlinkTime) > cursorBlinkInterval) { + if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE; + plotBreathAT(cursorNow); + display.display(); + cursorBlinkTime = millis(); + } + if (buttonPressedAndNotUsed){ + buttonPressedAndNotUsed = 0; + switch (deumButtonState){ + case 1: + // down + plotBreathAT(BLACK); + breathAT=!breathAT; + plotBreathAT(WHITE); + cursorNow = BLACK; + display.display(); + cursorBlinkTime = millis(); + break; + case 2: + // enter + plotBreathAT(WHITE); + cursorNow = BLACK; + display.display(); + subBreathAT = 0; + writeSetting(MIDI_ADDR,MIDIchannel); + break; + case 4: + // up + plotBreathAT(BLACK); + breathAT=!breathAT; + plotBreathAT(WHITE); + cursorNow = BLACK; + display.display(); + cursorBlinkTime = millis(); + break; + case 8: + // menu + plotBreathAT(WHITE); + cursorNow = BLACK; + display.display(); + subBreathAT = 0; + writeSetting(MIDI_ADDR,MIDIchannel); + break; + } + } + } else if (subVelocity) { + if ((millis() - cursorBlinkTime) > cursorBlinkInterval) { + if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE; + plotVelocity(cursorNow); + display.display(); + cursorBlinkTime = millis(); + } + if (buttonPressedAndNotUsed){ + buttonPressedAndNotUsed = 0; + switch (deumButtonState){ + case 1: + // down + plotVelocity(BLACK); + if (velocity > 0){ + velocity--; + } else velocity = 127; + plotVelocity(WHITE); + cursorNow = BLACK; + display.display(); + cursorBlinkTime = millis(); + break; + case 2: + // enter + plotVelocity(WHITE); + cursorNow = BLACK; + display.display(); + subVelocity = 0; + writeSetting(VELOCITY_ADDR,velocity); + break; + case 4: + // up + plotVelocity(BLACK); + if (velocity < 127){ + velocity++; + } else velocity = 0; + plotVelocity(WHITE); + cursorNow = BLACK; + display.display(); + cursorBlinkTime = millis(); + break; + case 8: + // menu + plotVelocity(WHITE); + cursorNow = BLACK; + display.display(); + subVelocity = 0; + writeSetting(VELOCITY_ADDR,velocity); + break; + } + } + } else { + if ((millis() - cursorBlinkTime) > cursorBlinkInterval) { + if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE; + drawMenuCursor(setupBrMenuCursor, cursorNow); + display.display(); + cursorBlinkTime = millis(); + } + if (buttonPressedAndNotUsed){ + buttonPressedAndNotUsed = 0; + switch (deumButtonState){ + case 1: + // down + if (setupBrMenuCursor < 3){ + drawMenuCursor(setupBrMenuCursor, BLACK); + setupBrMenuCursor++; + drawMenuCursor(setupBrMenuCursor, WHITE); + cursorNow = BLACK; + clearSub(); + display.display(); + } + break; + case 2: + // enter + selectSetupBrMenu(); + break; + case 4: + // up + if (setupBrMenuCursor > 1){ + drawMenuCursor(setupBrMenuCursor, BLACK); + setupBrMenuCursor--; + drawMenuCursor(setupBrMenuCursor, WHITE); + cursorNow = BLACK; + clearSub(); + display.display(); + } + break; + case 8: + // menu + state = MAIN_MENU; + stateFirstRun = 1; + break; + } + } + } + + + } else if (state == SETUP_CT_MENU) { // SETUP CONTROLLERS MENU HERE <<<<<<<<<<<<< + if (stateFirstRun) { + drawSetupCtMenuScreen(); + stateFirstRun = 0; + } + if (subPort){ + if ((millis() - cursorBlinkTime) > cursorBlinkInterval) { + if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE; + plotPort(cursorNow); + display.display(); + cursorBlinkTime = millis(); + } + if (buttonPressedAndNotUsed){ + buttonPressedAndNotUsed = 0; + switch (deumButtonState){ + case 1: + // down + plotPort(BLACK); + if (portamento > 0){ + portamento--; + } else portamento = 2; + plotPort(WHITE); + cursorNow = BLACK; + display.display(); + cursorBlinkTime = millis(); + break; + case 2: + // enter + plotPort(WHITE); + cursorNow = BLACK; + display.display(); + subPort = 0; + writeSetting(PORTAM_ADDR,portamento); + break; + case 4: + // up + plotPort(BLACK); + if (portamento < 2){ + portamento++; + } else portamento = 0; + plotPort(WHITE); + cursorNow = BLACK; + display.display(); + cursorBlinkTime = millis(); + break; + case 8: + // menu + plotPort(WHITE); + cursorNow = BLACK; + display.display(); + subPort = 0; + writeSetting(PORTAM_ADDR,portamento); + break; + } + } + } else if (subPB) { + if ((millis() - cursorBlinkTime) > cursorBlinkInterval) { + if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE; + plotPB(cursorNow); + display.display(); + cursorBlinkTime = millis(); + } + if (buttonPressedAndNotUsed){ + buttonPressedAndNotUsed = 0; + switch (deumButtonState){ + case 1: + // down + if (PBdepth > 0){ + plotPB(BLACK); + PBdepth--; + plotPB(WHITE); + cursorNow = BLACK; + display.display(); + cursorBlinkTime = millis(); + } + break; + case 2: + // enter + plotPB(WHITE); + cursorNow = BLACK; + display.display(); + subPB = 0; + writeSetting(PB_ADDR,PBdepth); + break; + case 4: + // up + if (PBdepth < 12){ + plotPB(BLACK); + PBdepth++; + plotPB(WHITE); + cursorNow = BLACK; + display.display(); + cursorBlinkTime = millis(); + } + break; + case 8: + // menu + plotPB(WHITE); + cursorNow = BLACK; + display.display(); + subPB = 0; + writeSetting(PB_ADDR,PBdepth); + break; + } + } + } else if (subExtra) { + if ((millis() - cursorBlinkTime) > cursorBlinkInterval) { + if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE; + plotExtra(cursorNow); + display.display(); + cursorBlinkTime = millis(); + } + if (buttonPressedAndNotUsed){ + buttonPressedAndNotUsed = 0; + switch (deumButtonState){ + case 1: + // down + plotExtra(BLACK); + if (extraCT > 0){ + extraCT--; + } else extraCT = 2; + plotExtra(WHITE); + cursorNow = BLACK; + display.display(); + cursorBlinkTime = millis(); + break; + case 2: + // enter + plotExtra(WHITE); + cursorNow = BLACK; + display.display(); + subExtra = 0; + writeSetting(EXTRA_ADDR,extraCT); + break; + case 4: + // up + plotExtra(BLACK); + if (extraCT < 2){ + extraCT++; + } else extraCT = 0; + plotExtra(WHITE); + cursorNow = BLACK; + display.display(); + cursorBlinkTime = millis(); + break; + case 8: + // menu + plotExtra(WHITE); + cursorNow = BLACK; + display.display(); + subExtra = 0; + writeSetting(EXTRA_ADDR,extraCT); + break; + } + } + } else if (subVibrato) { + if ((millis() - cursorBlinkTime) > cursorBlinkInterval) { + if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE; + plotVibrato(cursorNow); + display.display(); + cursorBlinkTime = millis(); + } + if (buttonPressedAndNotUsed){ + buttonPressedAndNotUsed = 0; + switch (deumButtonState){ + case 1: + // down + if (vibrato > 0){ + plotVibrato(BLACK); + vibrato--; + plotVibrato(WHITE); + cursorNow = BLACK; + display.display(); + cursorBlinkTime = millis(); + } + break; + case 2: + // enter + plotVibrato(WHITE); + cursorNow = BLACK; + display.display(); + subVibrato = 0; + writeSetting(VIBRATO_ADDR,vibrato); + break; + case 4: + // up + if (vibrato < 7){ + plotVibrato(BLACK); + vibrato++; + plotVibrato(WHITE); + cursorNow = BLACK; + display.display(); + cursorBlinkTime = millis(); + } + break; + case 8: + // menu + plotVibrato(WHITE); + cursorNow = BLACK; + display.display(); + subVibrato = 0; + writeSetting(VIBRATO_ADDR,vibrato); + break; + } + } + } else if (subDeglitch) { + if ((millis() - cursorBlinkTime) > cursorBlinkInterval) { + if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE; + plotDeglitch(cursorNow); + display.display(); + cursorBlinkTime = millis(); + } + if (buttonPressedAndNotUsed){ + buttonPressedAndNotUsed = 0; + switch (deumButtonState){ + case 1: + // down + if (deglitch > 0){ + plotDeglitch(BLACK); + deglitch-=5; + plotDeglitch(WHITE); + cursorNow = BLACK; + display.display(); + cursorBlinkTime = millis(); + } + break; + case 2: + // enter + plotDeglitch(WHITE); + cursorNow = BLACK; + display.display(); + subDeglitch = 0; + writeSetting(DEGLITCH_ADDR,deglitch); + break; + case 4: + // up + if (deglitch < 70){ + plotDeglitch(BLACK); + deglitch+=5; + plotDeglitch(WHITE); + cursorNow = BLACK; + display.display(); + cursorBlinkTime = millis(); + } + break; + case 8: + // menu + plotDeglitch(WHITE); + cursorNow = BLACK; + display.display(); + subDeglitch = 0; + writeSetting(DEGLITCH_ADDR,deglitch); + break; + } + } + } else { + if ((millis() - cursorBlinkTime) > cursorBlinkInterval) { + if (cursorNow == WHITE) cursorNow = BLACK; else cursorNow = WHITE; + drawMenuCursor(setupCtMenuCursor, cursorNow); + display.display(); + cursorBlinkTime = millis(); + } + if (buttonPressedAndNotUsed){ + buttonPressedAndNotUsed = 0; + switch (deumButtonState){ + case 1: + // down + if (setupCtMenuCursor < 5){ + drawMenuCursor(setupCtMenuCursor, BLACK); + setupCtMenuCursor++; + drawMenuCursor(setupCtMenuCursor, WHITE); + cursorNow = BLACK; + clearSub(); + display.display(); + } + break; + case 2: + // enter + selectSetupCtMenu(); + break; + case 4: + // up + if (setupCtMenuCursor > 1){ + drawMenuCursor(setupCtMenuCursor, BLACK); + setupCtMenuCursor--; + drawMenuCursor(setupCtMenuCursor, WHITE); + cursorNow = BLACK; + clearSub(); + display.display(); + } + break; + case 8: + // menu + state = MAIN_MENU; + stateFirstRun = 1; + break; + } + } + } + } + +} + +void selectMainMenu(){ + switch (mainMenuCursor){ + case 1: + subTranspose = 1; + drawMenuCursor(mainMenuCursor, WHITE); + display.display(); + cursorBlinkTime = millis(); + drawSubTranspose(); + break; + case 2: + subOctave = 1; + drawMenuCursor(mainMenuCursor, WHITE); + display.display(); + cursorBlinkTime = millis(); + drawSubOctave(); + break; + case 3: + subMIDI = 1; + drawMenuCursor(mainMenuCursor, WHITE); + display.display(); + cursorBlinkTime = millis(); + drawSubMIDI(); + break; + case 4: + state = BREATH_ADJ_IDL; + stateFirstRun = 1; + break; + case 5: + state = SETUP_BR_MENU; + stateFirstRun = 1; + break; + case 6: + state = SETUP_CT_MENU; + stateFirstRun = 1; + break; + } +} + +void selectSetupBrMenu(){ + switch (setupBrMenuCursor){ + case 1: + subBreathCC = 1; + drawMenuCursor(setupBrMenuCursor, WHITE); + display.display(); + cursorBlinkTime = millis(); + drawSubBreathCC(); + break; + case 2: + subBreathAT = 1; + drawMenuCursor(setupBrMenuCursor, WHITE); + display.display(); + cursorBlinkTime = millis(); + drawSubBreathAT(); + break; + case 3: + subVelocity = 1; + drawMenuCursor(setupBrMenuCursor, WHITE); + display.display(); + cursorBlinkTime = millis(); + drawSubVelocity(); + } +} + +void selectSetupCtMenu(){ + switch (setupCtMenuCursor){ + case 1: + subPort = 1; + drawMenuCursor(setupCtMenuCursor, WHITE); + display.display(); + cursorBlinkTime = millis(); + drawSubPort(); + break; + case 2: + subPB = 1; + drawMenuCursor(setupCtMenuCursor, WHITE); + display.display(); + cursorBlinkTime = millis(); + drawSubPB(); + break; + case 3: + subExtra = 1; + drawMenuCursor(setupCtMenuCursor, WHITE); + display.display(); + cursorBlinkTime = millis(); + drawSubExtra(); + break; + case 4: + subVibrato = 1; + drawMenuCursor(setupCtMenuCursor, WHITE); + display.display(); + cursorBlinkTime = millis(); + drawSubVibrato(); + break; + case 5: + subDeglitch = 1; + drawMenuCursor(setupCtMenuCursor, WHITE); + display.display(); + cursorBlinkTime = millis(); + drawSubDeglitch(); + } +} +void drawBreathScreen(){ + // Clear the buffer. + display.clearDisplay(); + + display.setTextSize(1); + display.setTextColor(WHITE); + display.setCursor(25,2); + display.println("BREATH"); + //display.drawLine(0,10,127,10,WHITE); + display.setCursor(0,20); + display.println("THR"); + display.drawLine(25,17,120,17,WHITE); + display.drawLine(25,18,25,19,WHITE); + display.drawLine(120,18,120,19,WHITE); + display.drawLine(25,29,120,29,WHITE); + display.drawLine(25,27,25,28,WHITE); + display.drawLine(120,27,120,28,WHITE); + display.setCursor(0,35); + display.println("SNS"); + //display.drawLine(25,38,120,38,WHITE); + display.drawLine(25,36,25,40,WHITE); + display.drawLine(120,36,120,40,WHITE); + display.setCursor(0,50); + display.println("MAX"); + display.drawLine(25,47,120,47,WHITE); + display.drawLine(25,48,25,49,WHITE); + display.drawLine(120,48,120,49,WHITE); + display.drawLine(25,60,120,60,WHITE); + display.drawLine(25,58,25,59,WHITE); + display.drawLine(120,58,120,59,WHITE); + + //display.drawLine(38,20,38,26,WHITE); // indikation thr + pos1 = map(breathThrVal, breathLoLimit, breathHiLimit, 27, 119); + display.drawLine(pos1,20,pos1,26,WHITE); + cursorNow = WHITE; + //display.drawLine(115,50,115,57,WHITE); // indikation max + pos2 = map(breathMaxVal, breathLoLimit, breathHiLimit, 27, 119); + display.drawLine(pos2,50,pos2,57,WHITE); + //display.drawPixel(34, 38, WHITE); + drawAdjCursor(WHITE); + display.display(); +} + +void drawPortamScreen(){ + // Clear the buffer. + display.clearDisplay(); + + display.setTextSize(1); + display.setTextColor(WHITE); + display.setCursor(25,2); + display.println("PORTAMENTO"); + //display.drawLine(0,10,127,10,WHITE); + display.setCursor(0,20); + display.println("THR"); + display.drawLine(25,17,120,17,WHITE); + display.drawLine(25,18,25,19,WHITE); + display.drawLine(120,18,120,19,WHITE); + display.drawLine(25,29,120,29,WHITE); + display.drawLine(25,27,25,28,WHITE); + display.drawLine(120,27,120,28,WHITE); + display.setCursor(0,35); + display.println("SNS"); + //display.drawLine(25,38,120,38,WHITE); + display.drawLine(25,36,25,40,WHITE); + display.drawLine(120,36,120,40,WHITE); + display.setCursor(0,50); + display.println("MAX"); + display.drawLine(25,47,120,47,WHITE); + display.drawLine(25,48,25,49,WHITE); + display.drawLine(120,48,120,49,WHITE); + display.drawLine(25,60,120,60,WHITE); + display.drawLine(25,58,25,59,WHITE); + display.drawLine(120,58,120,59,WHITE); + + //display.drawLine(38,20,38,26,WHITE); // indikation thr + pos1 = map(portamThrVal, portamLoLimit, portamHiLimit, 27, 119); + display.drawLine(pos1,20,pos1,26,WHITE); + cursorNow = WHITE; + //display.drawLine(115,50,115,57,WHITE); // indikation max + pos2 = map(portamMaxVal, portamLoLimit, portamHiLimit, 27, 119); + display.drawLine(pos2,50,pos2,57,WHITE); + //display.drawPixel(34, 38, WHITE); + drawAdjCursor(WHITE); + display.display(); +} + +void drawPitchbScreen(){ + // Clear the buffer. + display.clearDisplay(); + + display.setTextSize(1); + display.setTextColor(WHITE); + display.setCursor(25,2); + display.println("PITCH BEND"); + //display.drawLine(0,10,127,10,WHITE); + display.setCursor(0,20); + display.println("THR"); + display.drawLine(25,17,120,17,WHITE); + display.drawLine(25,18,25,19,WHITE); + display.drawLine(120,18,120,19,WHITE); + display.drawLine(25,29,120,29,WHITE); + display.drawLine(25,27,25,28,WHITE); + display.drawLine(120,27,120,28,WHITE); + display.setCursor(0,35); + display.println("SNS"); + //display.drawLine(25,38,120,38,WHITE); + display.drawLine(25,36,25,40,WHITE); + display.drawLine(120,36,120,40,WHITE); + display.setCursor(0,50); + display.println("MAX"); + display.drawLine(25,47,120,47,WHITE); + display.drawLine(25,48,25,49,WHITE); + display.drawLine(120,48,120,49,WHITE); + display.drawLine(25,60,120,60,WHITE); + display.drawLine(25,58,25,59,WHITE); + display.drawLine(120,58,120,59,WHITE); + + //display.drawLine(38,20,38,26,WHITE); // indikation thr + pos1 = map(pitchbThrVal, pitchbLoLimit, pitchbHiLimit, 27, 119); + display.drawLine(pos1,20,pos1,26,WHITE); + cursorNow = WHITE; + //display.drawLine(115,50,115,57,WHITE); // indikation max + pos2 = map(pitchbMaxVal, pitchbLoLimit, pitchbHiLimit, 27, 119); + display.drawLine(pos2,50,pos2,57,WHITE); + //display.drawPixel(34, 38, WHITE); + drawAdjCursor(WHITE); + display.display(); +} + +void drawExtracScreen(){ + // Clear the buffer. + display.clearDisplay(); + + display.setTextSize(1); + display.setTextColor(WHITE); + display.setCursor(25,2); + display.println("EXTRA CONTROLLER"); + //display.drawLine(0,10,127,10,WHITE); + display.setCursor(0,20); + display.println("THR"); + display.drawLine(25,17,120,17,WHITE); + display.drawLine(25,18,25,19,WHITE); + display.drawLine(120,18,120,19,WHITE); + display.drawLine(25,29,120,29,WHITE); + display.drawLine(25,27,25,28,WHITE); + display.drawLine(120,27,120,28,WHITE); + display.setCursor(0,35); + display.println("SNS"); + //display.drawLine(25,38,120,38,WHITE); + display.drawLine(25,36,25,40,WHITE); + display.drawLine(120,36,120,40,WHITE); + display.setCursor(0,50); + display.println("MAX"); + display.drawLine(25,47,120,47,WHITE); + display.drawLine(25,48,25,49,WHITE); + display.drawLine(120,48,120,49,WHITE); + display.drawLine(25,60,120,60,WHITE); + display.drawLine(25,58,25,59,WHITE); + display.drawLine(120,58,120,59,WHITE); + + //display.drawLine(38,20,38,26,WHITE); // indikation thr + pos1 = map(extracThrVal, extracLoLimit, extracHiLimit, 27, 119); + display.drawLine(pos1,20,pos1,26,WHITE); + cursorNow = WHITE; + //display.drawLine(115,50,115,57,WHITE); // indikation max + pos2 = map(extracMaxVal, extracLoLimit, extracHiLimit, 27, 119); + display.drawLine(pos2,50,pos2,57,WHITE); + //display.drawPixel(34, 38, WHITE); + drawAdjCursor(WHITE); + display.display(); +} + +void drawMenuCursor(byte itemNo, byte color){ + byte xmid = 6 + 9 * itemNo; + display.drawTriangle(57,xmid,61,xmid+2,61,xmid-2,color); +} + +void drawAdjCursor(byte color){ + display.drawTriangle(16,4,20,4,18,1,color); + display.drawTriangle(16,6,20,6,18,9,color); +} + +void drawMenuScreen(){ + // Clear the buffer. + display.clearDisplay(); + + display.setTextSize(1); + display.setTextColor(WHITE); + display.setCursor(0,0); + display.println("MENU"); + display.drawLine(0,9,127,9,WHITE); + display.setCursor(0,12); + display.println("TRANSPOSE"); + display.setCursor(0,21); + display.println("OCTAVE"); + display.setCursor(0,30); + display.println("MIDI CH"); + display.setCursor(0,39); + display.println("ADJUST"); + display.setCursor(0,48); + display.println("SETUP BR"); + display.setCursor(0,57); + display.println("SETUP CTL"); + drawMenuCursor(mainMenuCursor, WHITE); + display.display(); +} + +void drawPatchView(){ + display.clearDisplay(); + display.setTextColor(WHITE); + display.setTextSize(6); + if (patch < 10){ + // 1-9 + display.setCursor(48,10); + } else if (patch < 100){ + // 10-99 + display.setCursor(31,10); + } else { + // 99-128 + display.setCursor(10,10); + } + display.println(patch); + display.display(); +} + +void clearSub(){ + display.fillRect(63,11,64,52,BLACK); +} + +void drawSubTranspose(){ + display.fillRect(63,11,64,52,BLACK); + display.drawRect(63,11,64,52,WHITE); + display.setTextColor(WHITE); + display.setTextSize(1); + display.setCursor(68,15); + display.println("TRANSPOSE"); + plotTranspose(WHITE); + display.display(); +} + +void plotTranspose(int color){ + display.setTextColor(color); + display.setTextSize(2); + display.setCursor(80,33); + if ((transpose-12) > -1){ + display.println("+"); + display.setCursor(93,33); + display.println(transpose-12); + } else { + display.println("-"); + display.setCursor(93,33); + display.println(abs(transpose-12)); + } +} + +void drawSubOctave(){ + display.fillRect(63,11,64,52,BLACK); + display.drawRect(63,11,64,52,WHITE); + display.setTextColor(WHITE); + display.setTextSize(1); + display.setCursor(74,15); + display.println("OCTAVE"); + plotOctave(WHITE); + display.display(); +} + +void plotOctave(int color){ + display.setTextColor(color); + display.setTextSize(2); + display.setCursor(80,33); + if ((octave-3) > -1){ + display.println("+"); + display.setCursor(93,33); + display.println(octave-3); + } else { + display.println("-"); + display.setCursor(93,33); + display.println(abs(octave-3)); + } +} + +void drawSubMIDI(){ + display.fillRect(63,11,64,52,BLACK); + display.drawRect(63,11,64,52,WHITE); + display.setTextColor(WHITE); + display.setTextSize(1); + display.setCursor(68,15); + display.println("MIDI CHNL"); + plotMIDI(WHITE); + display.display(); +} + +void plotMIDI(int color){ + display.setTextColor(color); + display.setTextSize(2); + display.setCursor(90,33); + display.println(MIDIchannel); +} + +void drawSubBreathCC(){ + display.fillRect(63,11,64,52,BLACK); + display.drawRect(63,11,64,52,WHITE); + display.setTextColor(WHITE); + display.setTextSize(1); + display.setCursor(68,15); + display.println("BREATH CC"); + plotBreathCC(WHITE); + display.display(); +} + +void plotBreathCC(int color){ + display.setTextColor(color); + display.setTextSize(2); + if (breathCC){ + display.setCursor(90,33); + display.println(ccList[breathCC]); + } else { + display.setCursor(79,33); + display.println("OFF"); + } +} + +void drawSubBreathAT(){ + display.fillRect(63,11,64,52,BLACK); + display.drawRect(63,11,64,52,WHITE); + display.setTextColor(WHITE); + display.setTextSize(1); + display.setCursor(68,15); + display.println("BREATH AT"); + plotBreathAT(WHITE); + display.display(); +} + +void plotBreathAT(int color){ + display.setTextColor(color); + display.setTextSize(2); + display.setCursor(79,33); + if (breathAT){ + display.println("ON"); + } else { + display.println("OFF"); + } +} + +void drawSubVelocity(){ + display.fillRect(63,11,64,52,BLACK); + display.drawRect(63,11,64,52,WHITE); + display.setTextColor(WHITE); + display.setTextSize(1); + display.setCursor(71,15); + display.println("VELOCITY"); + plotVelocity(WHITE); + display.display(); +} + +void plotVelocity(int color){ + display.setTextColor(color); + display.setTextSize(2); + display.setCursor(79,33); + if (velocity){ + display.println(velocity); + } else { + display.println("DYN"); + } +} + +void drawSubPort(){ + display.fillRect(63,11,64,52,BLACK); + display.drawRect(63,11,64,52,WHITE); + display.setTextColor(WHITE); + display.setTextSize(1); + display.setCursor(71,15); + display.println("PORT/GLD"); + plotPort(WHITE); + display.display(); +} + +void plotPort(int color){ + display.setTextColor(color); + display.setTextSize(2); + display.setCursor(79,33); + if (portamento == 1){ + display.println("ON"); + } else if (portamento == 2){ + display.println("SW"); + } else { + display.println("OFF"); + } +} + +void drawSubPB(){ + display.fillRect(63,11,64,52,BLACK); + display.drawRect(63,11,64,52,WHITE); + display.setTextColor(WHITE); + display.setTextSize(1); + display.setCursor(68,15); + display.println("PITCHBEND"); + plotPB(WHITE); + display.display(); +} + +void plotPB(int color){ + display.setTextColor(color); + display.setTextSize(2); + display.setCursor(76,33); + if (PBdepth){ + display.println("1/"); + display.setCursor(101,33); + display.println(PBdepth); + } else { + display.println("OFF"); + } +} + +void drawSubExtra(){ + display.fillRect(63,11,64,52,BLACK); + display.drawRect(63,11,64,52,WHITE); + display.setTextColor(WHITE); + display.setTextSize(1); + display.setCursor(68,15); + display.println("EXTRA CTR"); + plotExtra(WHITE); + display.display(); +} + +void plotExtra(int color){ + display.setTextColor(color); + display.setTextSize(2); + display.setCursor(79,33); + if (extraCT == 1){ + display.println("MOD"); + } else if (extraCT == 2){ + display.println("SUS"); + } else { + display.println("OFF"); + } +} + +void drawSubVibrato(){ + display.fillRect(63,11,64,52,BLACK); + display.drawRect(63,11,64,52,WHITE); + display.setTextColor(WHITE); + display.setTextSize(1); + display.setCursor(74,15); + display.println("VIBRATO"); + plotVibrato(WHITE); + display.display(); +} + +void plotVibrato(int color){ + display.setTextColor(color); + display.setTextSize(2); + if (vibrato){ + display.setCursor(90,33); + display.println(vibrato); + } else { + display.setCursor(79,33); + display.println("OFF"); + } +} + +void drawSubDeglitch(){ + display.fillRect(63,11,64,52,BLACK); + display.drawRect(63,11,64,52,WHITE); + display.setTextColor(WHITE); + display.setTextSize(1); + display.setCursor(71,15); + display.println("DEGLITCH"); + plotDeglitch(WHITE); + display.display(); +} + +void plotDeglitch(int color){ + display.setTextColor(color); + display.setTextSize(2); + display.setCursor(79,33); + if (deglitch){ + display.println(deglitch); + display.setCursor(105,40); + display.setTextSize(1); + display.println("ms"); + } else { + display.println("OFF"); + } +} + +void drawSetupBrMenuScreen(){ + // Clear the buffer. + display.clearDisplay(); + + display.setTextSize(1); + display.setTextColor(WHITE); + display.setCursor(0,0); + display.println("SETUP BREATH"); + display.drawLine(0,9,127,9,WHITE); + display.setCursor(0,12); + display.println("BREATH CC"); + display.setCursor(0,21); + display.println("BREATH AT"); + display.setCursor(0,30); + display.println("VELOCITY"); + display.setCursor(0,39); + display.println(""); + display.setCursor(0,48); + display.println(""); + display.setCursor(0,57); + display.println(""); + + display.display(); +} + +void drawSetupCtMenuScreen(){ + // Clear the buffer. + display.clearDisplay(); + + display.setTextSize(1); + display.setTextColor(WHITE); + display.setCursor(0,0); + display.println("SETUP CTRLS"); + display.drawLine(0,9,127,9,WHITE); + display.setCursor(0,12); + display.println("PORT/GLD"); + display.setCursor(0,21); + display.println("PITCHBEND"); + display.setCursor(0,30); + display.println("EXTRA CTR"); + display.setCursor(0,39); + display.println("VIBRATO"); + display.setCursor(0,48); + display.println("DEGLITCH"); + display.setCursor(0,57); + display.println(""); + + display.display(); +} + +void writeSetting(byte address, unsigned short value){ + union { + byte v[2]; + unsigned short val; + } data; + data.val = value; + EEPROM.write(address, data.v[0]); + EEPROM.write(address+1, data.v[1]); +} + +unsigned short readSetting(byte address){ + union { + byte v[2]; + unsigned short val; + } data; + data.v[0] = EEPROM.read(address); + data.v[1] = EEPROM.read(address+1); + return data.val; +} + +