/* MicroDexed MicroDexed is a port of the Dexed sound engine (https://github.com/asb2m10/dexed) for the Teensy-3.5/3.6 with audio shield. Dexed ist heavily based on https://github.com/google/music-synthesizer-for-android (c)2018-2020 H. Wirtz This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef ENABLE_LCD_UI #ifndef _UI_HPP_ #define _UI_HPP_ #include "config.h" #include "Disp_Plus.h" #include "effect_modulated_delay.h" #include "effect_stereo_mono.h" #include "dexed.h" #include //#include #include #define _LCDML_DISP_cols LCD_cols #define _LCDML_DISP_rows LCD_rows #ifdef I2C_DISPLAY #define _LCDML_DISP_cfg_cursor 0x7E // cursor Symbol #else #define _LCDML_DISP_cfg_cursor 0x8d // cursor Symbol #endif #define _LCDML_DISP_cfg_scrollbar 1 // enable a scrollbar extern config_t configuration; extern uint8_t dexed_setup_number; extern void set_volume(uint8_t v, uint8_t m); extern char bank_names[NUM_DEXED][MAX_BANKS][BANK_NAME_LEN]; extern char bank_name[NUM_DEXED][BANK_NAME_LEN]; extern char voice_name[NUM_DEXED][VOICE_NAME_LEN]; extern char voice_names[NUM_DEXED][MAX_VOICES][VOICE_NAME_LEN]; extern void strip_extension(char* s, char *target); //extern void eeprom_write(void); extern bool get_voice_names_from_bank(uint8_t b, uint8_t instance_id); extern bool load_sysex(uint8_t b, uint8_t v); extern void generate_version_string(char* buffer, uint8_t len); extern void initial_values_from_eeprom(bool init); extern void _softRestart(void); extern void eeprom_update_sys(void); extern void eeprom_update_performance(void); extern void eeprom_update_fx(void); extern void eeprom_update_dexed(uint8_t instance_id); #ifdef DISPLAY_LCD_SPI extern void change_disp_sd(bool d); #endif #ifdef USE_FX extern AudioEffectDelay delay_r; extern AudioEffectDelay delay_l; extern AudioEffectFreeverb freeverb_r; extern AudioEffectFreeverb freeverb_l; extern AudioMixer4 reverb_send_mixer_r; extern AudioMixer4 reverb_send_mixer_l; extern AudioEffectModulatedDelay modchorus_r; extern AudioEffectModulatedDelay modchorus_l; extern AudioSynthWaveform chorus_modulator; extern AudioMixer4 chorus_send_mixer_r; extern AudioMixer4 chorus_send_mixer_l; extern AudioMixer4 delay_send_mixer_r; extern AudioMixer4 delay_send_mixer_l; extern AudioMixer4 delay_fb_mixer_r; extern AudioMixer4 delay_fb_mixer_l; #endif extern AudioMixer4 master_mixer_r; extern AudioMixer4 master_mixer_l; extern AudioAmplifier volume_r; extern AudioAmplifier volume_l; extern AudioEffectStereoMono stereo2mono; extern AudioSourceMicroDexed* MicroDexed[NUM_DEXED]; extern AudioAmplifier* dexed_level[NUM_DEXED]; extern AudioEffectMonoStereo* mono2stereo[NUM_DEXED]; extern AudioSynthWaveformDc* pan[NUM_DEXED]; extern char sd_string[LCD_cols + 1]; /*********************************************************************** GLOBAL ************************************************************************/ elapsedMillis back_from_volume; #ifdef I2C_DISPLAY #include Disp_Plus lcd(LCD_I2C_ADDRESS, _LCDML_DISP_cols, _LCDML_DISP_rows); #endif #ifdef U8X8_DISPLAY #include #ifdef U8X8_HAVE_HW_SPI #include #endif #ifdef U8X8_HAVE_HW_I2C #include #endif Disp_Plus lcd(/* cs=*/ U8X8_CS_PIN, /* dc=*/ U8X8_DC_PIN, /* reset=*/ U8X8_RESET_PIN); //Disp_Plus lcd(U8X8_PIN_NONE); #endif const uint8_t scroll_bar[5][8] = { {B10001, B10001, B10001, B10001, B10001, B10001, B10001, B10001}, // scrollbar top {B11111, B11111, B10001, B10001, B10001, B10001, B10001, B10001}, // scroll state 1 {B10001, B10001, B11111, B11111, B10001, B10001, B10001, B10001}, // scroll state 2 {B10001, B10001, B10001, B10001, B11111, B11111, B10001, B10001}, // scroll state 3 {B10001, B10001, B10001, B10001, B10001, B10001, B11111, B11111} // scrollbar bottom }; const uint8_t block_bar[5][8] = { {B10000, B10000, B10000, B10000, B10000, B10000, B10000, B10000}, {B11000, B11000, B11000, B11000, B11000, B11000, B11000, B11000}, {B11100, B11100, B11100, B11100, B11100, B11100, B11100, B11100}, {B11110, B11110, B11110, B11110, B11110, B11110, B11110, B11110}, {B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111} }; const uint8_t meter_bar[5][8] = { {B10000, B10000, B10000, B10000, B10000, B10000, B10000, B10000}, {B01000, B01000, B01000, B01000, B01000, B01000, B01000, B01000}, {B00100, B00100, B00100, B00100, B00100, B00100, B00100, B00100}, {B00010, B00010, B00010, B00010, B00010, B00010, B00010, B00010}, {B00001, B00001, B00001, B00001, B00001, B00001, B00001, B00001} }; enum { SCROLLBAR, BLOCKBAR, METERBAR }; enum { ENC_R, ENC_L }; enum {MENU_VOICE_BANK, MENU_VOICE_SOUND}; uint8_t menu_voice_select = MENU_VOICE_SOUND; void lcdml_menu_display(void); void lcdml_voice_menu_display(void); void lcdml_menu_clear(void); void lcdml_menu_control(void); void lcdml_voice_menu_control(void); #ifdef USE_FX void UI_func_reverb_roomsize(uint8_t param); void UI_func_reverb_damping(uint8_t param); void UI_func_reverb_send(uint8_t param); void UI_func_reverb_level(uint8_t param); void UI_func_chorus_frequency(uint8_t param); void UI_func_chorus_waveform(uint8_t param); void UI_func_chorus_depth(uint8_t param); void UI_func_chorus_send(uint8_t param); void UI_func_chorus_level(uint8_t param); void UI_func_delay_time(uint8_t param); void UI_func_delay_feedback(uint8_t param); void UI_func_delay_send(uint8_t param); void UI_func_delay_level(uint8_t param); void UI_func_filter_cutoff(uint8_t param); void UI_func_filter_resonance(uint8_t param); #endif void UI_func_transpose(uint8_t param); void UI_func_tune(uint8_t param); void UI_func_midi_channel(uint8_t param); void UI_func_lowest_note(uint8_t param); void UI_func_highest_note(uint8_t param); void UI_func_sound_intensity(uint8_t param); void UI_func_panorama(uint8_t param); void UI_func_stereo_mono(uint8_t param); void UI_func_note_refresh(uint8_t param); void UI_func_polyphony(uint8_t param); void UI_func_engine(uint8_t param); void UI_func_mono_poly(uint8_t param); void UI_func_pb_range(uint8_t param); void UI_func_pb_step(uint8_t param); void UI_func_mw_range(uint8_t param); void UI_func_mw_assign(uint8_t param); void UI_func_mw_mode(uint8_t param); void UI_func_fc_range(uint8_t param); void UI_func_fc_assign(uint8_t param); void UI_func_fc_mode(uint8_t param); void UI_func_bc_range(uint8_t param); void UI_func_bc_assign(uint8_t param); void UI_func_bc_mode(uint8_t param); void UI_func_at_range(uint8_t param); void UI_func_at_assign(uint8_t param); void UI_func_at_mode(uint8_t param); void UI_func_portamento_mode(uint8_t param); void UI_func_portamento_glissando(uint8_t param); void UI_func_portamento_time(uint8_t param); void UI_func_OP1(uint8_t param); void UI_func_OP2(uint8_t param); void UI_func_OP3(uint8_t param); void UI_func_OP4(uint8_t param); void UI_func_OP5(uint8_t param); void UI_func_OP6(uint8_t param); void UI_handle_OP(uint8_t param, uint8_t op, uint8_t instance_id); void UI_func_information(uint8_t param); void UI_func_volume(uint8_t param); void UI_func_load_performance(uint8_t param); void UI_func_save_performance(uint8_t param); void UI_func_load_voiceconfig(uint8_t param); void UI_func_save_voiceconfig(uint8_t param); void UI_func_save_voice(uint8_t param); void UI_func_load_fx(uint8_t param); void UI_func_save_fx(uint8_t param); void UI_func_eeprom_reset(uint8_t param); void UI_func_midi_soft_thru(uint8_t param); void UI_func_velocity_level(uint8_t param); void UI_func_voice_select(uint8_t param); void UI_func_sysex_send_voice(uint8_t param); void UI_func_sysex_receive_voice(uint8_t param); void UI_func_save_voice(uint8_t param); void UI_func_sysex_receive_bank(uint8_t param); void UI_func_sysex_send_bank(uint8_t param); void UI_function_not_enabled(void); void UI_function_not_implemented(uint8_t param); void lcd_display_int(int16_t var, uint8_t size, bool zeros, bool brackets, bool sign); void lcd_display_float(float var, uint8_t size_number, uint8_t size_fraction, bool zeros, bool brackets, bool sign); void lcd_display_bar_int(const char* title, uint32_t value, float factor, int32_t min_value, int32_t max_value, uint8_t size, bool zeros, bool brackets, bool sign, bool init); void lcd_display_bar_float(const char* title, float value, float factor, int32_t min_value, int32_t max_value, uint8_t size_number, uint8_t size_fraction, bool zeros, bool brackets, bool sign, bool init); void lcd_display_meter_int(const char* title, uint32_t value, float factor, float offset, int32_t min_value, int32_t max_value, uint8_t size, bool zeros, bool brackets, bool sign, bool init); void lcd_display_meter_float(const char* title, float value, float factor, float offset, int32_t min_value, int32_t max_value, uint8_t size_number, uint8_t size_fraction, bool zeros, bool brackets, bool sign, bool init); void lcd_special_chars(uint8_t mode); void eeprom_update_var(uint16_t pos, uint8_t val, const char* val_string); // normal menu LCDMenuLib2_menu LCDML_0(255, 0, 0, NULL, NULL); // normal root menu element (do not change) LCDMenuLib2 LCDML(LCDML_0, _LCDML_DISP_rows, _LCDML_DISP_cols, lcdml_menu_display, lcdml_menu_clear, lcdml_menu_control); #if defined(NUM_DEXED)>1 && defined(USE_FX) #include "UI_2_FX.h" #elif defined(NUM_DEXED)==1 && defined(USE_FX) #include "UI_1_FX.h" #elif defined(NUM_DEXED)==2 && !defined(USE_FX) #include "UI_2.h" #else #include "UI_1.h" #endif // create menu LCDML_createMenu(_LCDML_DISP_cnt); /*********************************************************************** CONTROL ***********************************************************************/ class EncoderDirection { public: EncoderDirection(void) { reset(); } void reset(void) { button_short = false; button_long = false; left = false; right = false; up = false; down = false; } void ButtonShort(bool state) { button_short = state; } bool ButtonShort(void) { if (button_short == true) { button_short = false; return (true); } return (false); } void ButtonLong(bool state) { button_long = state; } bool ButtonLong(void) { if (button_long == true) { button_long = false; return (true); } return (false); } void Left(bool state) { left = state; } bool Left(void) { if (left == true) { left = false; return (true); } return (false); } void Right(bool state) { right = state; } bool Right(void) { if (right == true) { right = false; return (true); } return (false); } void Up(bool state) { up = state; } bool Up(void) { if (up == true) { up = false; return (true); } return (false); } void Down(bool state) { down = state; } bool Down(void) { if (down == true) { down = false; return (true); } return (false); } private: bool button_short; bool button_long; bool left; bool right; bool up; bool down; }; #define g_LCDML_CONTROL_button_long_press LONG_BUTTON_PRESS #define g_LCDML_CONTROL_button_short_press BUT_DEBOUNCE_MS //Encoder ENCODER[NUM_ENCODER] = {Encoder(ENC_R_PIN_B, ENC_R_PIN_A), Encoder(ENC_L_PIN_B, ENC_L_PIN_A)}; MD_REncoder ENCODER[NUM_ENCODER] = {MD_REncoder(ENC_R_PIN_B, ENC_R_PIN_A), MD_REncoder(ENC_L_PIN_B, ENC_L_PIN_A)}; EncoderDirection encoderDir[NUM_ENCODER]; long g_LCDML_CONTROL_button_press_time[NUM_ENCODER] = {0, 0}; bool g_LCDML_CONTROL_button_prev[NUM_ENCODER] = {HIGH, HIGH}; uint8_t g_LCDML_CONTROL_prev[NUM_ENCODER] = {0, 0}; bool menu_init = true; #ifdef U8X8_DISPLAY const uint8_t * flipped_scroll_bar[5]; const uint8_t * flipped_block_bar[5]; uint8_t * rotTile(const uint8_t * tile) { uint8_t * newt = new uint8_t[8]; for (int x = 0; x < 8; x++) { uint8_t newb = 0; for (int y = 0 ; y < 8; y++) { newb |= (tile[y] << x) & 0x80; newb >>= 1; } newt[x] = newb; } return newt; } #endif void setup_ui(void) { // LCD Begin #ifdef I2C_DISPLAY lcd.init(); lcd.backlight(); lcd.clear(); lcd.blink_off(); lcd.cursor_off(); lcd.backlight(); #else lcd.begin(); lcd.clear(); lcd.setFont(u8x8_font_amstrad_cpc_extended_f); #endif lcd.setCursor(3, 0); lcd.print(F("MicroDexed")); lcd.setCursor(0, 1); lcd.print(F("(c)parasiTstudio")); lcd_special_chars(SCROLLBAR); // LCDMenuLib Setup LCDML_setup(_LCDML_DISP_cnt); // Enable Menu Rollover //LCDML.MENU_enRollover(); // Enable Screensaver (screensaver menu function, time to activate in ms) LCDML.SCREEN_enable(UI_func_voice_select, VOICE_SELECTION_MS); } #ifdef DEBUG void setup_debug_message(void) { // LCD Begin lcd.clear(); lcd.setCursor(1, 0); lcd.print(F("* DEBUG MODE *")); lcd.setCursor(1, 1); lcd.print(F("ENABLE CONSOLE")); delay(300); lcd.setCursor(1, 1); lcd.print(_LCDML_VERSION); lcd.print(F(" ")); } #endif /*********************************************************************** MENU CONTROL ***********************************************************************/ uint8_t get_current_cursor_id(void) { LCDMenuLib2_menu *tmp; if ((tmp = LCDML.MENU_getCurrentObj()) != NULL) return (tmp->getChild(LCDML.MENU_getCursorPosAbs())->getID()); else return (0); } void lcdml_menu_control(void) { // If something must init, put in in the setup condition if (LCDML.BT_setup()) { pinMode(BUT_R_PIN, INPUT_PULLUP); pinMode(BUT_L_PIN, INPUT_PULLUP); ENCODER[ENC_R].begin(); ENCODER[ENC_L].begin(); } //if (back_from_volume > BACK_FROM_VOLUME_MS && LCDML.FUNC_getID() == LCDML.OTHER_getIDFromFunction(UI_func_volume)) if (back_from_volume > BACK_FROM_VOLUME_MS && LCDML.FUNC_getID() == VOLUME_MENU_ID) { Serial.print("LCDML.FUNC_getID()="); Serial.println(LCDML.FUNC_getID()); Serial.print("LCDML.OTHER_getIDFromFunction(UI_func_volume)="); Serial.println(LCDML.OTHER_getIDFromFunction(UI_func_volume)); encoderDir[ENC_L].reset(); encoderDir[ENC_R].reset(); if (LCDML.MENU_getLastActiveFunctionID() < 0xff) LCDML.OTHER_jumpToID(LCDML.MENU_getLastActiveFunctionID()); else LCDML.OTHER_setCursorToID(LCDML.MENU_getLastCursorPositionID()); //LCDML.FUNC_goBackToMenu(); } // Volatile Variables long g_LCDML_CONTROL_Encoder_position[NUM_ENCODER] = {ENCODER[ENC_R].read(), ENCODER[ENC_L].read()}; bool button[NUM_ENCODER] = {digitalRead(BUT_R_PIN), digitalRead(BUT_L_PIN)}; /************************************************************************************ Basic encoder handling (from LCDMenuLib2) ************************************************************************************/ // RIGHT if (g_LCDML_CONTROL_Encoder_position[ENC_R] <= -3) { if (!button[ENC_R]) { LCDML.BT_left(); #ifdef DEBUG Serial.println(F("ENC-R left")); #endif encoderDir[ENC_R].Left(true); g_LCDML_CONTROL_button_prev[ENC_R] = LOW; g_LCDML_CONTROL_button_press_time[ENC_R] = -1; } else { #ifdef DEBUG Serial.println(F("ENC-R down")); #endif encoderDir[ENC_R].Down(true); LCDML.BT_down(); } ENCODER[ENC_R].write(g_LCDML_CONTROL_Encoder_position[ENC_R] + 4); } else if (g_LCDML_CONTROL_Encoder_position[ENC_R] >= 3) { if (!button[ENC_R]) { #ifdef DEBUG Serial.println(F("ENC-R right")); #endif encoderDir[ENC_R].Right(true); LCDML.BT_right(); g_LCDML_CONTROL_button_prev[ENC_R] = LOW; g_LCDML_CONTROL_button_press_time[ENC_R] = -1; } else { #ifdef DEBUG Serial.println(F("ENC-R up")); #endif encoderDir[ENC_R].Up(true); LCDML.BT_up(); } ENCODER[ENC_R].write(g_LCDML_CONTROL_Encoder_position[ENC_R] - 4); } else { if (!button[ENC_R] && g_LCDML_CONTROL_button_prev[ENC_R]) //falling edge, button pressed { g_LCDML_CONTROL_button_prev[ENC_R] = LOW; g_LCDML_CONTROL_button_press_time[ENC_R] = millis(); } else if (button[ENC_R] && !g_LCDML_CONTROL_button_prev[ENC_R]) //rising edge, button not active { g_LCDML_CONTROL_button_prev[ENC_R] = HIGH; if (g_LCDML_CONTROL_button_press_time[ENC_R] < 0) { g_LCDML_CONTROL_button_press_time[ENC_R] = millis(); //Reset for left right action } else if ((millis() - g_LCDML_CONTROL_button_press_time[ENC_R]) >= g_LCDML_CONTROL_button_long_press) { #ifdef DEBUG Serial.println("ENC-R long"); #endif //LCDML.BT_quit(); encoderDir[ENC_R].ButtonLong(true); /* if (LCDML.FUNC_getID() < 0xff) LCDML.FUNC_setGBAToLastFunc(); else LCDML.FUNC_setGBAToLastCursorPos(); */ LCDML.FUNC_setGBA(); LCDML.OTHER_jumpToFunc(UI_func_voice_select); } else if ((millis() - g_LCDML_CONTROL_button_press_time[ENC_R]) >= g_LCDML_CONTROL_button_short_press) { #ifdef DEBUG Serial.println(F("ENC-R short")); #endif encoderDir[ENC_R].ButtonShort(true); LCDML.BT_enter(); } } } // LEFT if (g_LCDML_CONTROL_Encoder_position[ENC_L] <= -3) { if (!button[ENC_L]) { #ifdef DEBUG Serial.println(F("ENC-L left")); #endif encoderDir[ENC_L].Left(true); LCDML.BT_left(); g_LCDML_CONTROL_button_prev[ENC_L] = LOW; g_LCDML_CONTROL_button_press_time[ENC_L] = -1; } else { #ifdef DEBUG Serial.println(F("ENC-L down")); #endif encoderDir[ENC_L].Down(true); LCDML.BT_down(); //if (LCDML.FUNC_getID() != LCDML.OTHER_getIDFromFunction(UI_func_volume)) if (LCDML.FUNC_getID() != VOLUME_MENU_ID) { LCDML.OTHER_jumpToFunc(UI_func_volume); } } ENCODER[ENC_L].write(g_LCDML_CONTROL_Encoder_position[ENC_L] + 4); } else if (g_LCDML_CONTROL_Encoder_position[ENC_L] >= 3) { if (!button[ENC_L]) { #ifdef DEBUG Serial.println(F("ENC-L right")); #endif encoderDir[ENC_L].Right(true); LCDML.BT_right(); g_LCDML_CONTROL_button_prev[ENC_L] = LOW; g_LCDML_CONTROL_button_press_time[ENC_L] = -1; } else { #ifdef DEBUG Serial.println(F("ENC-L up")); #endif encoderDir[ENC_L].Up(true); LCDML.BT_up(); //if (LCDML.FUNC_getID() != LCDML.OTHER_getIDFromFunction(UI_func_volume)) if (LCDML.FUNC_getID() != VOLUME_MENU_ID) { LCDML.OTHER_jumpToFunc(UI_func_volume); } } ENCODER[ENC_L].write(g_LCDML_CONTROL_Encoder_position[ENC_L] - 4); } else { if (!button[ENC_L] && g_LCDML_CONTROL_button_prev[ENC_L]) //falling edge, button pressed { g_LCDML_CONTROL_button_prev[ENC_L] = LOW; g_LCDML_CONTROL_button_press_time[ENC_L] = millis(); } else if (button[ENC_L] && !g_LCDML_CONTROL_button_prev[ENC_L]) //rising edge, button not active { g_LCDML_CONTROL_button_prev[ENC_L] = HIGH; if (g_LCDML_CONTROL_button_press_time[ENC_L] < 0) { g_LCDML_CONTROL_button_press_time[ENC_L] = millis(); //Reset for left right action } else if ((millis() - g_LCDML_CONTROL_button_press_time[ENC_L]) >= g_LCDML_CONTROL_button_long_press) { #ifdef DEBUG Serial.println(F("ENC-L long")); #endif //encoderDir[ENC_L].ButtonLong(true); //LCDML.BT_quit(); for (uint8_t i = 0; i < NUM_DEXED; i++) MicroDexed[i]->panic(); } else if ((millis() - g_LCDML_CONTROL_button_press_time[ENC_L]) >= g_LCDML_CONTROL_button_short_press) { //LCDML.BT_enter(); #ifdef DEBUG Serial.println(F("ENC-L short")); #endif encoderDir[ENC_L].ButtonShort(true); if ((LCDML.MENU_getLastActiveFunctionID() == 0xff && LCDML.MENU_getLastCursorPositionID() == 0) || menu_init == true) { LCDML.MENU_goRoot(); menu_init = false; } else LCDML.BT_quit(); } } } } /*********************************************************************** MENU DISPLAY ***********************************************************************/ void lcdml_menu_clear(void) { lcd.clear(); lcd.setCursor(0, 0); } void lcdml_menu_display(void) { // update content // *************** if (LCDML.DISP_checkMenuUpdate()) { // clear menu // *************** LCDML.DISP_clear(); // declaration of some variables // *************** // content variable char content_text[_LCDML_DISP_cols]; // save the content text of every menu element // menu element object LCDMenuLib2_menu *tmp; // some limit values uint8_t i = LCDML.MENU_getScroll(); uint8_t maxi = _LCDML_DISP_rows + i; uint8_t n = 0; // check if this element has children if ((tmp = LCDML.MENU_getDisplayedObj()) != NULL) { // loop to display lines do { // check if a menu element has a condition and if the condition be true if (tmp->checkCondition()) { // check the type off a menu element if (tmp->checkType_menu() == true) { // display normal content LCDML_getContent(content_text, tmp->getID()); lcd.setCursor(1, n); lcd.print(content_text); } else { if (tmp->checkType_dynParam()) { tmp->callback(n); } } // increment some values i++; n++; } // try to go to the next sibling and check the number of displayed rows } while (((tmp = tmp->getSibling(1)) != NULL) && (i < maxi)); } } if (LCDML.DISP_checkMenuCursorUpdate()) { // init vars uint8_t n_max = (LCDML.MENU_getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.MENU_getChilds()); uint8_t scrollbar_min = 0; uint8_t scrollbar_max = LCDML.MENU_getChilds(); uint8_t scrollbar_cur_pos = LCDML.MENU_getCursorPosAbs(); uint8_t scroll_pos = ((1.*n_max * _LCDML_DISP_rows) / (scrollbar_max - 1) * scrollbar_cur_pos); // display rows for (uint8_t n = 0; n < n_max; n++) { //set cursor lcd.setCursor(0, n); //set cursor char if (n == LCDML.MENU_getCursorPos()) { lcd.write(_LCDML_DISP_cfg_cursor); } else { lcd.write(' '); } // delete or reset scrollbar if (_LCDML_DISP_cfg_scrollbar == 1) { if (scrollbar_max > n_max) { #ifdef I2C_DISPLAY lcd.setCursor((_LCDML_DISP_cols - 1), n); lcd.write((uint8_t)0); #else lcd.drawTile((_LCDML_DISP_cols - 1), n, 1, flipped_scroll_bar[0]); lcd.setCursor((_LCDML_DISP_cols), n + 1); #endif } else { lcd.setCursor((_LCDML_DISP_cols - 1), n); lcd.print(F(" ")); } } } // display scrollbar if (_LCDML_DISP_cfg_scrollbar == 1) { if (scrollbar_max > n_max) { //set scroll position if (scrollbar_cur_pos == scrollbar_min) { // min pos #ifdef I2C_DISPLAY lcd.setCursor((_LCDML_DISP_cols - 1), 0); lcd.write((uint8_t)1); #else lcd.drawTile((_LCDML_DISP_cols - 1), 0, 1, flipped_scroll_bar[1]); lcd.setCursor((_LCDML_DISP_cols), 1); #endif } else if (scrollbar_cur_pos == (scrollbar_max - 1)) { // max pos #ifdef I2C_DISPLAY lcd.setCursor((_LCDML_DISP_cols - 1), (n_max - 1)); lcd.write((uint8_t)4); #else lcd.drawTile((_LCDML_DISP_cols - 1), (n_max - 1), 1, flipped_scroll_bar[4]); lcd.setCursor((_LCDML_DISP_cols), (n_max)); #endif } else { // between #ifdef I2C_DISPLAY lcd.setCursor((_LCDML_DISP_cols - 1), scroll_pos / n_max); lcd.write((uint8_t)(scroll_pos % n_max) + 1); #else lcd.drawTile((_LCDML_DISP_cols - 1), scroll_pos / n_max, 1, flipped_scroll_bar[(scroll_pos % n_max) + 1]); lcd.setCursor((_LCDML_DISP_cols), (scroll_pos / n_max) + 1); #endif } } } } } //#################################################################################################################################################################################################### /*********************************************************************** MENU ***********************************************************************/ #ifdef USE_FX void UI_func_reverb_roomsize(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("Reverb Room", configuration.fx.reverb_roomsize, 1.0, REVERB_ROOMSIZE_MIN, REVERB_ROOMSIZE_MAX, 3, false, false, false, true); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.fx.reverb_roomsize = constrain(configuration.fx.reverb_roomsize + ENCODER[ENC_R].speed(), REVERB_ROOMSIZE_MIN, REVERB_ROOMSIZE_MAX); else if (LCDML.BT_checkUp()) configuration.fx.reverb_roomsize = constrain(configuration.fx.reverb_roomsize - ENCODER[ENC_R].speed(), REVERB_ROOMSIZE_MIN, REVERB_ROOMSIZE_MAX); lcd_display_bar_int("Reverb Room", configuration.fx.reverb_roomsize, 1.0, REVERB_ROOMSIZE_MIN, REVERB_ROOMSIZE_MAX, 3, false, false, false, false); freeverb_r.roomsize(mapfloat(configuration.fx.reverb_roomsize, REVERB_ROOMSIZE_MIN, REVERB_ROOMSIZE_MAX, 0.0, 1.0)); freeverb_l.roomsize(mapfloat(configuration.fx.reverb_roomsize, REVERB_ROOMSIZE_MIN, REVERB_ROOMSIZE_MAX, 0.0, 1.0)); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, fx.reverb_roomsize), configuration.fx.reverb_roomsize); } } void UI_func_reverb_damping(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("Reverb Damp.", configuration.fx.reverb_damping, 1.0, REVERB_DAMPING_MIN, REVERB_DAMPING_MAX, 3, false, false, false, true); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.fx.reverb_damping = constrain(configuration.fx.reverb_damping + ENCODER[ENC_R].speed(), REVERB_DAMPING_MIN, REVERB_DAMPING_MAX); else if (LCDML.BT_checkUp()) configuration.fx.reverb_damping = constrain(configuration.fx.reverb_damping - ENCODER[ENC_R].speed(), REVERB_DAMPING_MIN, REVERB_DAMPING_MAX); lcd_display_bar_int("Reverb Damp.", configuration.fx.reverb_damping, 1.0, REVERB_DAMPING_MIN, REVERB_DAMPING_MAX, 3, false, false, false, false); freeverb_r.damping(mapfloat(configuration.fx.reverb_damping, REVERB_DAMPING_MIN, REVERB_DAMPING_MAX, 0.0, 1.0)); freeverb_l.damping(mapfloat(configuration.fx.reverb_damping, REVERB_DAMPING_MIN, REVERB_DAMPING_MAX, 0.0, 1.0)); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, fx.reverb_damping), configuration.fx.reverb_damping); } } void UI_func_reverb_send(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("Reverb Send", configuration.dexed[instance_id].reverb_send, 1.0, REVERB_SEND_MIN, REVERB_SEND_MAX, 3, false, false, false, true); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].reverb_send = constrain(configuration.dexed[instance_id].reverb_send + ENCODER[ENC_R].speed(), REVERB_SEND_MIN, REVERB_SEND_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].reverb_send = constrain(configuration.dexed[instance_id].reverb_send - ENCODER[ENC_R].speed(), REVERB_SEND_MIN, REVERB_SEND_MAX); lcd_display_bar_int("Reverb Send", configuration.dexed[instance_id].reverb_send, 1.0, REVERB_SEND_MIN, REVERB_SEND_MAX, 3, false, false, false, false); reverb_send_mixer_r.gain(instance_id, configuration.dexed[instance_id].reverb_send / 100.0); reverb_send_mixer_l.gain(instance_id, configuration.dexed[instance_id].reverb_send / 100.0); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].reverb_send), configuration.dexed[0].reverb_send); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].reverb_send), configuration.dexed[1].reverb_send); #endif } } void UI_func_reverb_level(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("Reverb Level", configuration.fx.reverb_level, 1.0, REVERB_LEVEL_MIN, REVERB_LEVEL_MAX, 3, false, false, false, true); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.fx.reverb_level = constrain(configuration.fx.reverb_level + ENCODER[ENC_R].speed(), REVERB_LEVEL_MIN, REVERB_LEVEL_MAX); else if (LCDML.BT_checkUp()) configuration.fx.reverb_level = constrain(configuration.fx.reverb_level - ENCODER[ENC_R].speed(), REVERB_LEVEL_MIN, REVERB_LEVEL_MAX); lcd_display_bar_int("Reverb Level", configuration.fx.reverb_level, 1.0, REVERB_LEVEL_MIN, REVERB_LEVEL_MAX, 3, false, false, false, true); master_mixer_r.gain(REVERB, mapfloat(configuration.fx.reverb_level, REVERB_LEVEL_MIN, REVERB_LEVEL_MAX, 0.0, 1.0)); master_mixer_l.gain(REVERB, mapfloat(configuration.fx.reverb_level, REVERB_LEVEL_MIN, REVERB_LEVEL_MAX, 0.0, 1.0)); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, fx.reverb_level), configuration.fx.reverb_level); } } void UI_func_chorus_frequency(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_float("Chorus Frq.", configuration.fx.chorus_frequency, 0.1, CHORUS_FREQUENCY_MIN, CHORUS_FREQUENCY_MAX, 2, 1, false, false, false, true); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.fx.chorus_frequency = constrain(configuration.fx.chorus_frequency + ENCODER[ENC_R].speed(), CHORUS_FREQUENCY_MIN, CHORUS_FREQUENCY_MAX); else if (LCDML.BT_checkUp()) configuration.fx.chorus_frequency = constrain(configuration.fx.chorus_frequency - ENCODER[ENC_R].speed(), CHORUS_FREQUENCY_MIN, CHORUS_FREQUENCY_MAX); lcd_display_bar_float("Chorus Frq.", configuration.fx.chorus_frequency, 0.1, CHORUS_FREQUENCY_MIN, CHORUS_FREQUENCY_MAX, 2, 1, false, false, false, false); chorus_modulator.frequency(configuration.fx.chorus_frequency / 10.0); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, fx.chorus_frequency), configuration.fx.chorus_frequency); } } void UI_func_chorus_waveform(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("Chorus Waveform")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) configuration.fx.chorus_waveform = constrain(configuration.fx.chorus_waveform + 1, CHORUS_WAVEFORM_MIN, CHORUS_WAVEFORM_MAX); else if (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()) configuration.fx.chorus_waveform = constrain(configuration.fx.chorus_waveform - 1, CHORUS_WAVEFORM_MIN, CHORUS_WAVEFORM_MAX); lcd.setCursor(0, 1); switch (configuration.fx.chorus_waveform) { case 0: chorus_modulator.begin(WAVEFORM_TRIANGLE); lcd.print(F("[TRIANGLE]")); break; case 1: chorus_modulator.begin(WAVEFORM_SINE); lcd.print(F("[SINE ]")); break; default: chorus_modulator.begin(WAVEFORM_TRIANGLE); lcd.print(F("[TRIANGLE]")); break; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, fx.chorus_waveform), configuration.fx.chorus_waveform); } } void UI_func_chorus_depth(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("Chorus Dpt.", configuration.fx.chorus_depth, 1.0, CHORUS_DEPTH_MIN, CHORUS_DEPTH_MAX, 3, false, false, false, true); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.fx.chorus_depth = constrain(configuration.fx.chorus_depth + ENCODER[ENC_R].speed(), CHORUS_DEPTH_MIN, CHORUS_DEPTH_MAX); else if (LCDML.BT_checkUp()) configuration.fx.chorus_depth = constrain(configuration.fx.chorus_depth - ENCODER[ENC_R].speed(), CHORUS_DEPTH_MIN, CHORUS_DEPTH_MAX); lcd_display_bar_int("Chorus Dpt.", configuration.fx.chorus_depth, 1.0, CHORUS_DEPTH_MIN, CHORUS_DEPTH_MAX, 3, false, false, false, false); chorus_modulator.amplitude(configuration.fx.chorus_depth / 100.0); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, fx.chorus_depth), configuration.fx.chorus_depth); } } void UI_func_chorus_send(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("Chorus Send", configuration.dexed[instance_id].chorus_send, 1.0, CHORUS_SEND_MIN, CHORUS_SEND_MAX, 3, false, false, false, true); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].chorus_send = constrain(configuration.dexed[instance_id].chorus_send + ENCODER[ENC_R].speed(), CHORUS_SEND_MIN, CHORUS_SEND_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].chorus_send = constrain(configuration.dexed[instance_id].chorus_send - ENCODER[ENC_R].speed(), CHORUS_SEND_MIN, CHORUS_SEND_MAX); lcd_display_bar_int("Chorus Send", configuration.dexed[instance_id].chorus_send, 1.0, CHORUS_SEND_MIN, CHORUS_SEND_MAX, 3, false, false, false, false); chorus_send_mixer_r.gain(instance_id, configuration.dexed[instance_id].chorus_send / 100.0); chorus_send_mixer_l.gain(instance_id, configuration.dexed[instance_id].chorus_send / 100.0); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].chorus_send), configuration.dexed[0].chorus_send); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].chorus_send), configuration.dexed[1].chorus_send); #endif } } void UI_func_chorus_level(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("Chorus Lvl.", configuration.fx.chorus_level, 1.0, CHORUS_LEVEL_MIN, CHORUS_LEVEL_MAX, 3, false, false, false, true); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.fx.chorus_level = constrain(configuration.fx.chorus_level + ENCODER[ENC_R].speed(), CHORUS_LEVEL_MIN, CHORUS_LEVEL_MAX); else if (LCDML.BT_checkUp()) configuration.fx.chorus_level = constrain(configuration.fx.chorus_level - ENCODER[ENC_R].speed(), CHORUS_LEVEL_MIN, CHORUS_LEVEL_MAX); lcd_display_bar_int("Chorus Lvl.", configuration.fx.chorus_level, 1.0, CHORUS_LEVEL_MIN, CHORUS_LEVEL_MAX, 3, false, false, false, false); master_mixer_r.gain(CHORUS, mapfloat(configuration.fx.chorus_level, CHORUS_LEVEL_MIN, CHORUS_LEVEL_MAX, 0.0, 1.0)); master_mixer_l.gain(CHORUS, mapfloat(configuration.fx.chorus_level, CHORUS_LEVEL_MIN, CHORUS_LEVEL_MAX, 0.0, 1.0)); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, fx.chorus_level), configuration.fx.chorus_level); } } void UI_func_delay_time(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("Delay Time", configuration.fx.delay_time, 10.0, DELAY_TIME_MIN, DELAY_TIME_MAX, 3, false, false, false, true); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.fx.delay_time = constrain(configuration.fx.delay_time + ENCODER[ENC_R].speed(), DELAY_TIME_MIN, DELAY_TIME_MAX); else if (LCDML.BT_checkUp()) configuration.fx.delay_time = constrain(configuration.fx.delay_time - ENCODER[ENC_R].speed(), DELAY_TIME_MIN, DELAY_TIME_MAX); lcd_display_bar_int("Delay Time", configuration.fx.delay_time, 10.0, DELAY_TIME_MIN, DELAY_TIME_MAX, 3, false, false, false, true); delay_r.delay(0, configuration.fx.delay_time * 10); delay_l.delay(0, configuration.fx.delay_time * 10); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, fx.delay_time), configuration.fx.delay_time); } } void UI_func_delay_feedback(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("Delay Feedb.", configuration.fx.delay_feedback, 1.0, DELAY_FEEDBACK_MIN, DELAY_FEEDBACK_MAX, 3, false, false, false, true); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.fx.delay_feedback = constrain(configuration.fx.delay_feedback + ENCODER[ENC_R].speed(), DELAY_FEEDBACK_MIN, DELAY_FEEDBACK_MAX); else if (LCDML.BT_checkUp()) configuration.fx.delay_feedback = constrain(configuration.fx.delay_feedback - ENCODER[ENC_R].speed(), DELAY_FEEDBACK_MIN, DELAY_FEEDBACK_MAX); lcd_display_bar_int("Delay Feedb.", configuration.fx.delay_feedback, 1.0, DELAY_FEEDBACK_MIN, DELAY_FEEDBACK_MAX, 3, false, false, false, false); delay_fb_mixer_r.gain(1, configuration.fx.delay_feedback / 100.0); // amount of feedback delay_fb_mixer_l.gain(1, configuration.fx.delay_feedback / 100.0); // amount of feedback //delay_fb_mixer.gain(0, 1.0 - configuration.fx.delay_feedback / 200.0); // original signal } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, fx.delay_feedback), configuration.fx.delay_feedback); } } void UI_func_delay_send(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("Delay Send", configuration.dexed[instance_id].delay_send, 1.0, DELAY_SEND_MIN, DELAY_SEND_MAX, 3, false, false, false, true); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].delay_send = constrain(configuration.dexed[instance_id].delay_send + ENCODER[ENC_R].speed(), DELAY_SEND_MIN, DELAY_SEND_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].delay_send = constrain(configuration.dexed[instance_id].delay_send - ENCODER[ENC_R].speed(), DELAY_SEND_MIN, DELAY_SEND_MAX); lcd_display_bar_int("Delay Send", configuration.dexed[instance_id].delay_send, 1.0, DELAY_SEND_MIN, DELAY_SEND_MAX, 3, false, false, false, false); delay_send_mixer_r.gain(instance_id, configuration.dexed[instance_id].delay_send / 100.0); delay_send_mixer_l.gain(instance_id, configuration.dexed[instance_id].delay_send / 100.0); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].delay_send), configuration.dexed[0].delay_send); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].delay_send), configuration.dexed[1].delay_send); #endif } } void UI_func_delay_level(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("Delay Lvl.", configuration.fx.delay_level, 1.0, DELAY_LEVEL_MIN, DELAY_LEVEL_MAX, 3, false, false, false, true); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.fx.delay_level = constrain(configuration.fx.delay_level + ENCODER[ENC_R].speed(), DELAY_LEVEL_MIN, DELAY_LEVEL_MAX); else if (LCDML.BT_checkUp()) configuration.fx.delay_level = constrain(configuration.fx.delay_level - ENCODER[ENC_R].speed(), DELAY_LEVEL_MIN, DELAY_LEVEL_MAX); lcd_display_bar_int("Delay Lvl.", configuration.fx.delay_level, 1.0, DELAY_LEVEL_MIN, DELAY_LEVEL_MAX, 3, false, false, false, false); master_mixer_r.gain(DELAY, mapfloat(configuration.fx.delay_level, DELAY_LEVEL_MIN, DELAY_LEVEL_MAX, 0.0, 1.0)); master_mixer_l.gain(DELAY, mapfloat(configuration.fx.delay_level, DELAY_LEVEL_MIN, DELAY_LEVEL_MAX, 0.0, 1.0)); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, fx.delay_level), configuration.fx.delay_level); } } void UI_func_filter_cutoff(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("Filter Cut", configuration.dexed[instance_id].filter_cutoff, 1.0, FILTER_CUTOFF_MIN, FILTER_CUTOFF_MAX, 3, false, false, false, true); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].filter_cutoff = constrain(configuration.dexed[instance_id].filter_cutoff + ENCODER[ENC_R].speed(), FILTER_CUTOFF_MIN, FILTER_CUTOFF_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].filter_cutoff = constrain(configuration.dexed[instance_id].filter_cutoff - ENCODER[ENC_R].speed(), FILTER_CUTOFF_MIN, FILTER_CUTOFF_MAX); lcd_display_bar_int("Filter Cut", configuration.dexed[instance_id].filter_cutoff, 1.0, FILTER_CUTOFF_MIN, FILTER_CUTOFF_MAX, 3, false, false, false, false); MicroDexed[instance_id]->fx.Cutoff = mapfloat(configuration.dexed[instance_id].filter_cutoff, FILTER_CUTOFF_MIN, FILTER_CUTOFF_MAX, 1.0, 0.0); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].filter_cutoff), configuration.dexed[0].filter_cutoff); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].filter_cutoff), configuration.dexed[1].filter_cutoff); #endif } } void UI_func_filter_resonance(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("Filter Res", configuration.dexed[instance_id].filter_resonance, 1.0, FILTER_RESONANCE_MIN, FILTER_RESONANCE_MAX, 3, false, false, false, true); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].filter_resonance = constrain(configuration.dexed[instance_id].filter_resonance + ENCODER[ENC_R].speed(), FILTER_RESONANCE_MIN, FILTER_RESONANCE_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].filter_resonance = constrain(configuration.dexed[instance_id].filter_resonance - ENCODER[ENC_R].speed(), FILTER_RESONANCE_MIN, FILTER_RESONANCE_MAX); lcd_display_bar_int("Filter Res", configuration.dexed[instance_id].filter_resonance, 1.0, FILTER_RESONANCE_MIN, FILTER_RESONANCE_MAX, 3, false, false, false, false); MicroDexed[instance_id]->fx.Reso = mapfloat(configuration.dexed[instance_id].filter_resonance, FILTER_RESONANCE_MIN, FILTER_RESONANCE_MAX, 1.0, 0.0); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].filter_resonance), configuration.dexed[0].filter_resonance); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].filter_resonance), configuration.dexed[1].filter_resonance); #endif } } #endif void UI_func_transpose(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(METERBAR); lcd_display_meter_int("Transpose", configuration.dexed[instance_id].transpose, 1.0, -24.0, TRANSPOSE_MIN, TRANSPOSE_MAX, 3, false, false, true, true); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].transpose = constrain(configuration.dexed[instance_id].transpose + ENCODER[ENC_R].speed(), TRANSPOSE_MIN, TRANSPOSE_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].transpose = constrain(configuration.dexed[instance_id].transpose - ENCODER[ENC_R].speed(), TRANSPOSE_MIN, TRANSPOSE_MAX); lcd_display_meter_int("Transpose", configuration.dexed[instance_id].transpose, 1.0, -24.0, TRANSPOSE_MIN, TRANSPOSE_MAX, 3, false, false, true, true); MicroDexed[instance_id]->data[DEXED_VOICE_OFFSET + DEXED_TRANSPOSE] = configuration.dexed[instance_id].transpose; MicroDexed[instance_id]->notesOff(); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].transpose), configuration.dexed[0].transpose); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].transpose), configuration.dexed[1].transpose); #endif } } void UI_func_tune(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(METERBAR); lcd_display_meter_int("Fine Tune", configuration.dexed[instance_id].tune, 1.0, -100.0, TUNE_MIN, TUNE_MAX, 3, false, false, true, true); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].tune = constrain(configuration.dexed[instance_id].tune + ENCODER[ENC_R].speed(), TUNE_MIN, TUNE_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].tune = constrain(configuration.dexed[instance_id].tune - ENCODER[ENC_R].speed(), TUNE_MIN, TUNE_MAX); lcd_display_meter_int("Fine Tune", configuration.dexed[instance_id].tune, 1.0, -100.0, TUNE_MIN, TUNE_MAX, 3, false, false, true, false); MicroDexed[instance_id]->controllers.masterTune = (int((configuration.dexed[instance_id].tune - 100) / 100.0 * 0x4000) << 11) * (1.0 / 12); MicroDexed[instance_id]->doRefreshVoice(); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].tune), configuration.dexed[0].tune); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].tune), configuration.dexed[1].tune); #endif } } void UI_func_midi_channel(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("MIDI Channel")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].midi_channel = constrain(configuration.dexed[instance_id].midi_channel + ENCODER[ENC_R].speed(), MIDI_CHANNEL_MIN, MIDI_CHANNEL_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].midi_channel = constrain(configuration.dexed[instance_id].midi_channel - ENCODER[ENC_R].speed(), MIDI_CHANNEL_MIN, MIDI_CHANNEL_MAX); lcd.setCursor(0, 1); if (configuration.dexed[instance_id].midi_channel == 0) { lcd.print(F("[OMNI]")); } else { lcd_display_int(configuration.dexed[instance_id].midi_channel, 4, false, true, false); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { // you can here reset some global vars or do nothing encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].midi_channel), configuration.dexed[0].midi_channel); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].midi_channel), configuration.dexed[1].midi_channel); #endif } } void getNoteName(char* noteName, uint8_t noteNumber) { char notes [12][3] = {"A", "A#", "B", "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#"}; uint8_t oct_index = noteNumber - 12; noteNumber -= 21; sprintf(noteName, "%2s%1d", notes[noteNumber % 12], oct_index / 12); } void UI_func_lowest_note(uint8_t param) { uint8_t instance_id = 0; char note_name[4]; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); getNoteName(note_name, configuration.dexed[instance_id].lowest_note); lcd.setCursor(0, 0); lcd.print(F("Lowest Note")); lcd.setCursor(0, 1); lcd.print(F("[")); lcd.print(note_name); lcd.print(F("]")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].lowest_note = constrain(configuration.dexed[instance_id].lowest_note + ENCODER[ENC_R].speed(), INSTANCE_LOWEST_NOTE_MIN, INSTANCE_LOWEST_NOTE_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].lowest_note = constrain(configuration.dexed[instance_id].lowest_note - ENCODER[ENC_R].speed(), INSTANCE_LOWEST_NOTE_MIN, INSTANCE_LOWEST_NOTE_MAX); getNoteName(note_name, configuration.dexed[instance_id].lowest_note); lcd.setCursor(1, 1); lcd.print(note_name); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].lowest_note), configuration.dexed[0].lowest_note); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].lowest_note), configuration.dexed[1].lowest_note); #endif } } void UI_func_highest_note(uint8_t param) { uint8_t instance_id = 0; char note_name[4]; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); getNoteName(note_name, configuration.dexed[instance_id].highest_note); lcd.setCursor(0, 0); lcd.print(F("Highest Note")); lcd.setCursor(0, 1); lcd.print(F("[")); lcd.print(note_name); lcd.print(F("]")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].highest_note = constrain(configuration.dexed[instance_id].highest_note + ENCODER[ENC_R].speed(), INSTANCE_HIGHEST_NOTE_MIN, INSTANCE_HIGHEST_NOTE_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].highest_note = constrain(configuration.dexed[instance_id].highest_note - ENCODER[ENC_R].speed(), INSTANCE_HIGHEST_NOTE_MIN, INSTANCE_HIGHEST_NOTE_MAX); getNoteName(note_name, configuration.dexed[instance_id].highest_note); lcd.setCursor(1, 1); lcd.print(note_name); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].highest_note), configuration.dexed[0].highest_note); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].highest_note), configuration.dexed[1].highest_note); #endif } } void UI_func_sound_intensity(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_float("Voice Level", float(configuration.dexed[instance_id].sound_intensity), 1.0, SOUND_INTENSITY_MIN, SOUND_INTENSITY_MAX, 3, 0, false, false, false, true); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].sound_intensity = constrain(configuration.dexed[instance_id].sound_intensity + ENCODER[ENC_R].speed(), SOUND_INTENSITY_MIN, SOUND_INTENSITY_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].sound_intensity = constrain(configuration.dexed[instance_id].sound_intensity - ENCODER[ENC_R].speed(), SOUND_INTENSITY_MIN, SOUND_INTENSITY_MAX); lcd_display_bar_float("Voice Level", float(configuration.dexed[instance_id].sound_intensity), 1.0, SOUND_INTENSITY_MIN, SOUND_INTENSITY_MAX, 3, 0, false, false, false, false); dexed_level[instance_id]->gain(mapfloat(configuration.dexed[instance_id].sound_intensity, SOUND_INTENSITY_MIN, SOUND_INTENSITY_MAX, 0.0, SOUND_INTENSITY_AMP_MAX)); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].sound_intensity), configuration.dexed[0].sound_intensity); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].sound_intensity), configuration.dexed[1].sound_intensity); #endif } } void UI_func_panorama(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); if (configuration.sys.mono > 0) { lcd.setCursor(0, 0); lcd.print(F("Panorama")); lcd.setCursor(0, 1); lcd.print(F("MONO-disabled")); return; } lcd_special_chars(METERBAR); lcd_display_meter_float("Panorama", configuration.dexed[instance_id].pan, 0.05, -20.0, PANORAMA_MIN, PANORAMA_MAX, 3, 1, false, false, true, true); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkDown() && configuration.sys.mono == 0) configuration.dexed[instance_id].pan = constrain(configuration.dexed[instance_id].pan + ENCODER[ENC_R].speed(), PANORAMA_MIN, PANORAMA_MAX); else if (LCDML.BT_checkUp() && configuration.sys.mono == 0) configuration.dexed[instance_id].pan = constrain(configuration.dexed[instance_id].pan - ENCODER[ENC_R].speed(), PANORAMA_MIN, PANORAMA_MAX); if (configuration.sys.mono == 0) { lcd_display_meter_float("Panorama", configuration.dexed[instance_id].pan, 0.05, -20.0, PANORAMA_MIN, PANORAMA_MAX, 3, 1, false, false, true, false); mono2stereo[instance_id]->panorama(mapfloat(configuration.dexed[instance_id].pan, PANORAMA_MIN, PANORAMA_MAX, -1.0, 1.0)); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].pan), configuration.dexed[0].pan); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].pan), configuration.dexed[1].pan); #endif } } void UI_func_stereo_mono(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("Stereo/Mono")); lcd.setCursor(0, 1); switch (configuration.sys.mono) { case 0: lcd.print(F("[STEREO]")); stereo2mono.stereo(true); break; case 1: lcd.print(F("[MONO ]")); stereo2mono.stereo(false); break; case 2: lcd.print(F("[MONO-R]")); stereo2mono.stereo(false); break; case 3: lcd.print(F("[MONO-L]")); stereo2mono.stereo(false); break; } } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkDown()) configuration.sys.mono = constrain(configuration.sys.mono + 1, MONO_MIN, MONO_MAX); else if (LCDML.BT_checkUp()) configuration.sys.mono = constrain(configuration.sys.mono - 1, MONO_MIN, MONO_MAX); lcd.setCursor(0, 1); switch (configuration.sys.mono) { case 0: lcd.print(F("[STEREO]")); stereo2mono.stereo(true); break; case 1: lcd.print(F("[MONO ]")); stereo2mono.stereo(false); break; case 2: lcd.print(F("[MONO-R]")); stereo2mono.stereo(false); break; case 3: lcd.print(F("[MONO-L]")); stereo2mono.stereo(false); break; } set_volume(configuration.sys.vol, configuration.sys.mono); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, sys.mono), configuration.sys.mono); } } void UI_func_polyphony(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("Polyphony", configuration.dexed[instance_id].polyphony, 1.0, POLYPHONY_MIN, POLYPHONY_MAX, 3, false, false, false, true); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].polyphony = constrain(configuration.dexed[instance_id].polyphony + ENCODER[ENC_R].speed(), POLYPHONY_MIN, POLYPHONY_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].polyphony = constrain(configuration.dexed[instance_id].polyphony - ENCODER[ENC_R].speed(), POLYPHONY_MIN, POLYPHONY_MAX); lcd_display_bar_int("Polyphony", configuration.dexed[instance_id].polyphony, 1.0, POLYPHONY_MIN, POLYPHONY_MAX, 3, false, false, false, false); MicroDexed[instance_id]->setMaxNotes(configuration.dexed[instance_id].polyphony); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].polyphony), configuration.dexed[0].polyphony); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].polyphony), configuration.dexed[1].polyphony); #endif } } void UI_func_engine(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("Engine")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].engine = constrain(configuration.dexed[instance_id].engine + 1, ENGINE_MIN, ENGINE_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].engine = constrain(configuration.dexed[instance_id].engine - 1, ENGINE_MIN, ENGINE_MAX); MicroDexed[instance_id]->setEngineType(configuration.dexed[instance_id].engine); } lcd.setCursor(0, 1); switch (configuration.dexed[instance_id].engine) { case 0: lcd.print(F("[MODERN]")); break; case 1: lcd.print(F("[MARK 1]")); break; case 2: lcd.print(F("[OPL ]")); break; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].engine), configuration.dexed[0].engine); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].engine), configuration.dexed[1].engine); #endif } } void UI_func_mono_poly(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("Mono/Polyphonic")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].monopoly = constrain(configuration.dexed[instance_id].monopoly + 1, MONOPOLY_MIN, MONOPOLY_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].monopoly = constrain(configuration.dexed[instance_id].monopoly - 1, MONOPOLY_MIN, MONOPOLY_MAX); MicroDexed[instance_id]->setMonoMode(!configuration.dexed[instance_id].monopoly); } lcd.setCursor(0, 1); switch (configuration.dexed[instance_id].monopoly) { case 0: lcd.print(F("[MONOPHONIC]")); break; case 1: lcd.print(F("[POLYPHONIC]")); break; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].monopoly), configuration.dexed[0].monopoly); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].monopoly), configuration.dexed[1].monopoly); #endif } } void UI_func_note_refresh(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("Note Refresh")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].note_refresh = constrain(configuration.dexed[instance_id].note_refresh + 1, NOTE_REFRESH_MIN, NOTE_REFRESH_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].note_refresh = constrain(configuration.dexed[instance_id].note_refresh - 1, NOTE_REFRESH_MIN, NOTE_REFRESH_MAX); MicroDexed[instance_id]->setRefreshMode(configuration.dexed[instance_id].note_refresh); } lcd.setCursor(0, 1); switch (configuration.dexed[instance_id].note_refresh) { case 0: lcd.print(F("[NORMAL ]")); break; case 1: lcd.print(F("[RETRIGGERED]")); break; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].note_refresh), configuration.dexed[0].note_refresh); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].note_refresh), configuration.dexed[1].note_refresh); #endif } } void UI_func_pb_range(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("PB Range", configuration.dexed[instance_id].pb_range, 1.0, PB_RANGE_MIN, PB_RANGE_MAX, 2, false, false, false, true); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].pb_range = constrain(configuration.dexed[instance_id].pb_range + ENCODER[ENC_R].speed(), PB_RANGE_MIN, PB_RANGE_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].pb_range = constrain(configuration.dexed[instance_id].pb_range - ENCODER[ENC_R].speed(), PB_RANGE_MIN, PB_RANGE_MAX); lcd_display_bar_int("PB Range", configuration.dexed[instance_id].pb_range, 1.0, PB_RANGE_MIN, PB_RANGE_MAX, 2, false, false, false, false); MicroDexed[instance_id]->setPBController(configuration.dexed[instance_id].pb_range, configuration.dexed[instance_id].pb_step); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].pb_range), configuration.dexed[0].pb_range); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].pb_range), configuration.dexed[1].pb_range); #endif } } void UI_func_pb_step(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("PB Step", configuration.dexed[instance_id].pb_step, 1.0, PB_STEP_MIN, PB_STEP_MAX, 2, false, false, false, true); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].pb_step = constrain(configuration.dexed[instance_id].pb_step + ENCODER[ENC_R].speed(), PB_STEP_MIN, PB_STEP_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].pb_step = constrain(configuration.dexed[instance_id].pb_step - ENCODER[ENC_R].speed(), PB_STEP_MIN, PB_STEP_MAX); lcd_display_bar_int("PB Step", configuration.dexed[instance_id].pb_step, 1.0, PB_STEP_MIN, PB_STEP_MAX, 2, false, false, false, false); MicroDexed[instance_id]->setPBController(configuration.dexed[instance_id].pb_range, configuration.dexed[instance_id].pb_step); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].pb_step), configuration.dexed[0].pb_step); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].pb_step), configuration.dexed[1].pb_step); #endif } } void UI_func_mw_range(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("MW Range", configuration.dexed[instance_id].mw_range, 1.0, MW_RANGE_MIN, MW_RANGE_MAX, 2, false, false, false, true); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].mw_range = constrain(configuration.dexed[instance_id].mw_range + ENCODER[ENC_R].speed(), MW_RANGE_MIN, MW_RANGE_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].mw_range = constrain(configuration.dexed[instance_id].mw_range - ENCODER[ENC_R].speed(), MW_RANGE_MIN, MW_RANGE_MAX); lcd_display_bar_int("MW Range", configuration.dexed[instance_id].mw_range, 1.0, MW_RANGE_MIN, MW_RANGE_MAX, 2, false, false, false, false); MicroDexed[instance_id]->setMWController(configuration.dexed[instance_id].mw_range, configuration.dexed[instance_id].mw_assign, configuration.dexed[instance_id].mw_mode); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].mw_range), configuration.dexed[0].mw_range); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].mw_range), configuration.dexed[1].mw_range); #endif } } void UI_func_mw_assign(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("MW Assign")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].mw_assign = constrain(configuration.dexed[instance_id].mw_assign + 1, MW_ASSIGN_MIN, MW_ASSIGN_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].mw_assign = constrain(configuration.dexed[instance_id].mw_assign - 1, MW_ASSIGN_MIN, MW_ASSIGN_MAX); MicroDexed[instance_id]->setMWController(configuration.dexed[instance_id].mw_range, configuration.dexed[instance_id].mw_assign, configuration.dexed[instance_id].mw_mode); } lcd.setCursor(0, 1); switch (configuration.dexed[instance_id].mw_assign) { case 0: lcd.print(F("[ NONE ]")); break; case 1: lcd.print(F("[PTCH ]")); break; case 2: lcd.print(F("[ AMP ]")); break; case 3: lcd.print(F("[PTCH AMP ]")); break; case 4: lcd.print(F("[ EG-BS]")); break; case 5: lcd.print(F("[PTCH EG-BS]")); break; case 6: lcd.print(F("[ AMP EG-BS]")); break; case 7: lcd.print(F("[PTCH AMP EG-BS]")); break; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].mw_assign), configuration.dexed[0].mw_assign); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].mw_assign), configuration.dexed[1].mw_assign); #endif } } void UI_func_mw_mode(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("MW Mode")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].mw_mode = constrain(configuration.dexed[instance_id].mw_mode + 1, MW_MODE_MIN, MW_MODE_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].mw_mode = constrain(configuration.dexed[instance_id].mw_mode - 1, MW_MODE_MIN, MW_MODE_MAX); MicroDexed[instance_id]->setMWController(configuration.dexed[instance_id].mw_range, configuration.dexed[instance_id].mw_assign, configuration.dexed[instance_id].mw_mode); MicroDexed[instance_id]->controllers.refresh(); } lcd.setCursor(0, 1); switch (configuration.dexed[instance_id].mw_mode) { case 0: lcd.print(F("[LINEAR ]")); break; case 1: lcd.print(F("[REVERSE LINEAR]")); break; case 2: lcd.print(F("[DIRECT ]")); break; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].mw_mode), configuration.dexed[0].mw_mode); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].mw_mode), configuration.dexed[1].mw_mode); #endif } } void UI_func_fc_range(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("FC Range", configuration.dexed[instance_id].fc_range, 1.0, FC_RANGE_MIN, FC_RANGE_MAX, 2, false, false, false, true); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].fc_range = constrain(configuration.dexed[instance_id].fc_range + ENCODER[ENC_R].speed(), FC_RANGE_MIN, FC_RANGE_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].fc_range = constrain(configuration.dexed[instance_id].fc_range - ENCODER[ENC_R].speed(), FC_RANGE_MIN, FC_RANGE_MAX); lcd_display_bar_int("FC Range", configuration.dexed[instance_id].fc_range, 1.0, FC_RANGE_MIN, FC_RANGE_MAX, 2, false, false, false, false); MicroDexed[instance_id]->setFCController(configuration.dexed[instance_id].fc_range, configuration.dexed[instance_id].fc_assign, configuration.dexed[instance_id].fc_mode); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].fc_range), configuration.dexed[0].fc_range); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].fc_range), configuration.dexed[1].fc_range); #endif } } void UI_func_fc_assign(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("FC Assign")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].fc_assign = constrain(configuration.dexed[instance_id].fc_assign + 1, FC_ASSIGN_MIN, FC_ASSIGN_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].fc_assign = constrain(configuration.dexed[instance_id].fc_assign - 1, FC_ASSIGN_MIN, FC_ASSIGN_MAX); MicroDexed[instance_id]->setFCController(configuration.dexed[instance_id].fc_range, configuration.dexed[instance_id].fc_assign, configuration.dexed[instance_id].fc_mode); } lcd.setCursor(0, 1); switch (configuration.dexed[instance_id].fc_assign) { case 0: lcd.print(F("[ NONE ]")); break; case 1: lcd.print(F("[PTCH ]")); break; case 2: lcd.print(F("[ AMP ]")); break; case 3: lcd.print(F("[PTCH AMP ]")); break; case 4: lcd.print(F("[ EG-BS]")); break; case 5: lcd.print(F("[PTCH EG-BS]")); break; case 6: lcd.print(F("[ AMP EG-BS]")); break; case 7: lcd.print(F("[PTCH AMP EG-BS]")); break; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].fc_assign), configuration.dexed[0].fc_assign); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].fc_assign), configuration.dexed[1].fc_assign); #endif } } void UI_func_fc_mode(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("FC Mode")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].fc_mode = constrain(configuration.dexed[instance_id].fc_mode + 1, FC_MODE_MIN, FC_MODE_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].fc_mode = constrain(configuration.dexed[instance_id].fc_mode - 1, FC_MODE_MIN, FC_MODE_MAX); MicroDexed[instance_id]->setFCController(configuration.dexed[instance_id].fc_range, configuration.dexed[instance_id].fc_assign, configuration.dexed[instance_id].fc_mode); MicroDexed[instance_id]->controllers.refresh(); } lcd.setCursor(0, 1); switch (configuration.dexed[instance_id].fc_mode) { case 0: lcd.print(F("[LINEAR ]")); break; case 1: lcd.print(F("[REVERSE LINEAR]")); break; case 2: lcd.print(F("[DIRECT ]")); break; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].fc_mode), configuration.dexed[0].fc_mode); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].fc_mode), configuration.dexed[1].fc_mode); #endif } } void UI_func_bc_range(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("BC Range", configuration.dexed[instance_id].bc_range, 1.0, BC_RANGE_MIN, BC_RANGE_MAX, 2, false, false, false, true); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].bc_range = constrain(configuration.dexed[instance_id].bc_range + ENCODER[ENC_R].speed(), BC_RANGE_MIN, BC_RANGE_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].bc_range = constrain(configuration.dexed[instance_id].bc_range - ENCODER[ENC_R].speed(), BC_RANGE_MIN, BC_RANGE_MAX); lcd_display_bar_int("BC Range", configuration.dexed[instance_id].bc_range, 1.0, BC_RANGE_MIN, BC_RANGE_MAX, 2, false, false, false, false); MicroDexed[instance_id]->setBCController(configuration.dexed[instance_id].bc_range, configuration.dexed[instance_id].bc_assign, configuration.dexed[instance_id].bc_mode); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].bc_range), configuration.dexed[0].bc_range); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].bc_range), configuration.dexed[1].bc_range); #endif } } void UI_func_bc_assign(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("BC Assign")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].bc_assign = constrain(configuration.dexed[instance_id].bc_assign + 1, BC_ASSIGN_MIN, BC_ASSIGN_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].bc_assign = constrain(configuration.dexed[instance_id].bc_assign - 1, BC_ASSIGN_MIN, BC_ASSIGN_MAX); MicroDexed[instance_id]->setBCController(configuration.dexed[instance_id].bc_range, configuration.dexed[instance_id].bc_assign, configuration.dexed[instance_id].bc_mode); } lcd.setCursor(0, 1); switch (configuration.dexed[instance_id].bc_assign) { case 0: lcd.print(F("[ NONE ]")); break; case 1: lcd.print(F("[PTCH ]")); break; case 2: lcd.print(F("[ AMP ]")); break; case 3: lcd.print(F("[PTCH AMP ]")); break; case 4: lcd.print(F("[ EG-BS]")); break; case 5: lcd.print(F("[PTCH EG-BS]")); break; case 6: lcd.print(F("[ AMP EG-BS]")); break; case 7: lcd.print(F("[PTCH AMP EG-BS]")); break; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].bc_assign), configuration.dexed[0].bc_assign); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].bc_assign), configuration.dexed[1].bc_assign); #endif } } void UI_func_bc_mode(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("BC Mode")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].bc_mode = constrain(configuration.dexed[instance_id].bc_mode + 1, BC_MODE_MIN, BC_MODE_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].bc_mode = constrain(configuration.dexed[instance_id].bc_mode - 1, BC_MODE_MIN, BC_MODE_MAX); MicroDexed[instance_id]->setBCController(configuration.dexed[instance_id].bc_range, configuration.dexed[instance_id].bc_assign, configuration.dexed[instance_id].bc_mode); MicroDexed[instance_id]->controllers.refresh(); } lcd.setCursor(0, 1); switch (configuration.dexed[instance_id].bc_mode) { case 0: lcd.print(F("[DIRECT ]")); break; case 1: lcd.print(F("[LINEAR]")); break; case 2: lcd.print(F("[REVERSE]")); break; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].bc_mode), configuration.dexed[0].bc_mode); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].bc_mode), configuration.dexed[1].bc_mode); #endif } } void UI_func_at_range(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("AT Range", configuration.dexed[instance_id].at_range, 1.0, AT_RANGE_MIN, AT_RANGE_MAX, 2, false, false, false, true); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].at_range = constrain(configuration.dexed[instance_id].at_range + ENCODER[ENC_R].speed(), AT_RANGE_MIN, AT_RANGE_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].at_range = constrain(configuration.dexed[instance_id].at_range - ENCODER[ENC_R].speed(), AT_RANGE_MIN, AT_RANGE_MAX); lcd_display_bar_int("AT Range", configuration.dexed[instance_id].at_range, 1.0, AT_RANGE_MIN, AT_RANGE_MAX, 2, false, false, false, false); MicroDexed[instance_id]->setATController(configuration.dexed[instance_id].at_range, configuration.dexed[instance_id].at_assign, configuration.dexed[instance_id].at_mode); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].at_range), configuration.dexed[0].at_range); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].at_range), configuration.dexed[1].at_range); #endif } } void UI_func_at_assign(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("AT Assign")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].at_assign = constrain(configuration.dexed[instance_id].at_assign + 1, AT_ASSIGN_MIN, AT_ASSIGN_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].at_assign = constrain(configuration.dexed[instance_id].at_assign - 1, AT_ASSIGN_MIN, AT_ASSIGN_MAX); MicroDexed[instance_id]->setATController(configuration.dexed[instance_id].at_range, configuration.dexed[instance_id].at_assign, configuration.dexed[instance_id].at_mode); } lcd.setCursor(0, 1); switch (configuration.dexed[instance_id].at_assign) { case 0: lcd.print(F("[ NONE ]")); break; case 1: lcd.print(F("[PTCH ]")); break; case 2: lcd.print(F("[ AMP ]")); break; case 3: lcd.print(F("[PTCH AMP ]")); break; case 4: lcd.print(F("[ EG-BS]")); break; case 5: lcd.print(F("[PTCH EG-BS]")); break; case 6: lcd.print(F("[ AMP EG-BS]")); break; case 7: lcd.print(F("[PTCH AMP EG-BS]")); break; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].at_assign), configuration.dexed[0].at_assign); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].at_assign), configuration.dexed[1].at_assign); #endif } } void UI_func_at_mode(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("AT Mode")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].at_mode = constrain(configuration.dexed[instance_id].at_mode + 1, AT_MODE_MIN, AT_MODE_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].at_mode = constrain(configuration.dexed[instance_id].at_mode - 1, AT_MODE_MIN, AT_MODE_MAX); MicroDexed[instance_id]->setATController(configuration.dexed[instance_id].at_range, configuration.dexed[instance_id].at_assign, configuration.dexed[instance_id].at_mode); MicroDexed[instance_id]->controllers.refresh(); } lcd.setCursor(0, 1); switch (configuration.dexed[instance_id].at_mode) { case 0: lcd.print(F("[DIRECT ]")); break; case 1: lcd.print(F("[LINEAR]")); break; case 2: lcd.print(F("[REVERSE]")); break; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].at_mode), configuration.dexed[0].at_mode); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].at_mode), configuration.dexed[1].at_mode); #endif } } void UI_func_portamento_mode(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("Portamento Mode")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].portamento_mode = constrain(configuration.dexed[instance_id].portamento_mode + 1, PORTAMENTO_MODE_MIN, PORTAMENTO_MODE_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].portamento_mode = constrain(configuration.dexed[instance_id].portamento_mode - 1, PORTAMENTO_MODE_MIN, PORTAMENTO_MODE_MAX); MicroDexed[instance_id]->setPortamentoMode(configuration.dexed[instance_id].portamento_mode, configuration.dexed[instance_id].portamento_glissando, configuration.dexed[instance_id].portamento_time); } lcd.setCursor(0, 1); switch (configuration.dexed[instance_id].portamento_mode) { case 0: if (configuration.dexed[instance_id].monopoly == 1) lcd.print(F("[RETAIN ]")); else lcd.print(F("[FINGERED]")); break; case 1: if (configuration.dexed[instance_id].monopoly == 1) lcd.print(F("[FOLLOW ]")); else lcd.print(F("[FULL ]")); break; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].portamento_mode), configuration.dexed[0].portamento_mode); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].portamento_mode), configuration.dexed[1].portamento_mode); #endif } } void UI_func_portamento_glissando(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("Portam. Gliss.")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].portamento_glissando = constrain(configuration.dexed[instance_id].portamento_glissando + 1, PORTAMENTO_GLISSANDO_MIN, PORTAMENTO_GLISSANDO_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].portamento_glissando = constrain(configuration.dexed[instance_id].portamento_glissando - 1, PORTAMENTO_GLISSANDO_MIN, PORTAMENTO_GLISSANDO_MAX); MicroDexed[instance_id]->setPortamentoMode(configuration.dexed[instance_id].portamento_mode, configuration.dexed[instance_id].portamento_glissando, configuration.dexed[instance_id].portamento_time); } lcd.setCursor(0, 1); switch (configuration.dexed[instance_id].portamento_glissando) { case 0: lcd.print(F("[OFF]")); break; case 1: lcd.print(F("[ON ]")); break; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].portamento_glissando), configuration.dexed[0].portamento_glissando); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].portamento_glissando), configuration.dexed[1].portamento_glissando); #endif } } void UI_func_portamento_time(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("Portam. Time", configuration.dexed[instance_id].portamento_time, 1.0, PORTAMENTO_TIME_MIN, PORTAMENTO_TIME_MAX, 2, false, false, false, true); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].portamento_time = constrain(configuration.dexed[instance_id].portamento_time + ENCODER[ENC_R].speed(), PORTAMENTO_TIME_MIN, PORTAMENTO_TIME_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].portamento_time = constrain(configuration.dexed[instance_id].portamento_time - ENCODER[ENC_R].speed(), PORTAMENTO_TIME_MIN, PORTAMENTO_TIME_MAX); lcd_display_bar_int("Portam. Time", configuration.dexed[instance_id].portamento_time, 1.0, PORTAMENTO_TIME_MIN, PORTAMENTO_TIME_MAX, 2, false, false, false, false); MicroDexed[instance_id]->setPortamentoMode(configuration.dexed[instance_id].portamento_mode, configuration.dexed[instance_id].portamento_glissando, configuration.dexed[instance_id].portamento_time); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].portamento_time), configuration.dexed[0].portamento_time); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].portamento_time), configuration.dexed[1].portamento_time); #endif } } void UI_func_OP1(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; UI_handle_OP(param, 0, instance_id); } void UI_func_OP2(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; UI_handle_OP(param, 1, instance_id); } void UI_func_OP3(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; UI_handle_OP(param, 2, instance_id); } void UI_func_OP4(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; UI_handle_OP(param, 3, instance_id); } void UI_func_OP5(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; UI_handle_OP(param, 4, instance_id); } void UI_func_OP6(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; UI_handle_OP(param, 5, instance_id); } void UI_handle_OP(uint8_t param, uint8_t op, uint8_t instance_id) { bool state = bitRead(configuration.dexed[instance_id].op_enabled, op); if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("Operator ")); lcd.print(op + 1); lcd.setCursor(0, 1); if (state == true) { lcd.print(F("[ENABLED ]")); } else { lcd.print(F("[DISABLED]")); } } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkUp() && state == true) { bitClear(configuration.dexed[instance_id].op_enabled, op); state = false; } else if (LCDML.BT_checkDown() && state == false) { bitSet(configuration.dexed[instance_id].op_enabled, op); state = true; } if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { lcd.setCursor(0, 1); if (state == true) { lcd.print(F("[ENABLED ]")); } else { lcd.print(F("[DISABLED]")); } MicroDexed[instance_id]->setOPs(configuration.dexed[instance_id].op_enabled); MicroDexed[instance_id]->doRefreshVoice(); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].op_enabled), configuration.dexed[0].op_enabled); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].op_enabled), configuration.dexed[1].op_enabled); #endif } } void UI_func_information(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { char version_string[LCD_cols + 1]; encoderDir[ENC_R].reset(); generate_version_string(version_string, sizeof(version_string)); // setup function lcd.setCursor(0, 0); lcd.print(version_string); lcd.setCursor(0, 1); lcd.print(sd_string); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { ; } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); } } void UI_func_midi_soft_thru(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("MIDI Soft THRU")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.sys.soft_midi_thru = constrain(configuration.sys.soft_midi_thru + 1, SOFT_MIDI_THRU_MIN, SOFT_MIDI_THRU_MAX); else if (LCDML.BT_checkUp()) configuration.sys.soft_midi_thru = constrain(configuration.sys.soft_midi_thru - 1, SOFT_MIDI_THRU_MIN, SOFT_MIDI_THRU_MAX); } lcd.setCursor(0, 1); switch (configuration.sys.soft_midi_thru) { case 0: lcd.print(F("[OFF]")); break; case 1: lcd.print(F("[ON ]")); break; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, sys.soft_midi_thru), configuration.sys.soft_midi_thru); } } void UI_func_velocity_level(uint8_t param) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("Velocity Lvl", configuration.dexed[instance_id].velocity_level, 1.0, VELOCITY_LEVEL_MIN, VELOCITY_LEVEL_MAX, 3, false, false, false, true); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) configuration.dexed[instance_id].velocity_level = constrain(configuration.dexed[instance_id].velocity_level + ENCODER[ENC_R].speed(), VELOCITY_LEVEL_MIN, VELOCITY_LEVEL_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[instance_id].velocity_level = constrain(configuration.dexed[instance_id].velocity_level - ENCODER[ENC_R].speed(), VELOCITY_LEVEL_MIN, VELOCITY_LEVEL_MAX); lcd_display_bar_int("Velocity Lvl", configuration.dexed[instance_id].velocity_level, 1.0, VELOCITY_LEVEL_MIN, VELOCITY_LEVEL_MAX, 3, false, false, false, false); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); if (instance_id == 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[0].velocity_level), configuration.dexed[0].velocity_level); #if NUM_DEXED > 1 else EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, dexed[1].velocity_level), configuration.dexed[1].velocity_level); #endif } } void UI_func_eeprom_reset(uint8_t param) { static bool yesno = false; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); // setup function lcd.print("Reset EEPROM?"); lcd.setCursor(0, 1); lcd.print("[NO ]"); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()) || (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort())) { if (LCDML.BT_checkDown()) yesno = true; else if (LCDML.BT_checkUp()) yesno = false; else if (LCDML.BT_checkEnter()) { if (yesno == true) { LCDML.DISP_clear(); lcd.print("Firmware reset:"); initial_values_from_eeprom(yesno); lcd.setCursor(0, 1); lcd.print("Done."); delay(500); _softRestart(); } } if (yesno == true) { lcd.setCursor(1, 1); lcd.print("YES"); } else { lcd.setCursor(1, 1); lcd.print("NO "); } } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd.setCursor(0, 1); lcd.print("Canceled "); delay(500); encoderDir[ENC_R].reset(); } } void UI_func_voice_select(uint8_t param) { uint8_t instance_id = 0; static uint8_t menu_voice_select = MENU_VOICE_SOUND; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); strip_extension(bank_names[instance_id][configuration.performance.bank[instance_id]], bank_name[instance_id]); lcd.show(0, 0, 2, configuration.performance.bank[instance_id]); lcd.show(1, 0, 2, configuration.performance.voice[instance_id] + 1); lcd.show(0, 4, 10, bank_name[instance_id]); lcd.show(1, 4, 10, voice_names[instance_id][configuration.performance.voice[instance_id]]); switch (menu_voice_select) { case MENU_VOICE_BANK: lcd.show(0, 2, 2, " ["); lcd.show(0, 14, 1, "]"); lcd.show(1, 2, 2, " "); lcd.show(1, 14, 1, " "); break; case MENU_VOICE_SOUND: lcd.show(0, 2, 2, " "); lcd.show(0, 14, 1, " "); lcd.show(1, 2, 2, " ["); lcd.show(1, 14, 1, "]"); break; } } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()) || (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort())) { uint8_t bank_tmp; int8_t voice_tmp; if (LCDML.BT_checkUp()) switch (menu_voice_select) { case MENU_VOICE_BANK: bank_tmp = constrain(configuration.performance.bank[instance_id] - ENCODER[ENC_R].speed(), 0, MAX_BANKS - 1); configuration.performance.bank[instance_id] = bank_tmp; #ifdef DISPLAY_LCD_SPI change_disp_sd(false); #endif load_sd_voice(configuration.performance.bank[instance_id], configuration.performance.voice[instance_id], instance_id); get_voice_names_from_bank(configuration.performance.bank[instance_id], instance_id); #ifdef DISPLAY_LCD_SPI change_disp_sd(true); #endif break; case MENU_VOICE_SOUND: voice_tmp = configuration.performance.voice[instance_id] - ENCODER[ENC_R].speed(); if (voice_tmp < 0 && configuration.performance.bank[instance_id] - 1 >= 0) { configuration.performance.bank[instance_id]--; configuration.performance.bank[instance_id] = constrain(configuration.performance.bank[instance_id], 0, MAX_BANKS - 1); } else if (voice_tmp < 0 && configuration.performance.bank[instance_id] - 1 <= 0) { voice_tmp = 0; } if (voice_tmp < 0) voice_tmp = MAX_VOICES + voice_tmp; configuration.performance.voice[instance_id] = voice_tmp; #ifdef DISPLAY_LCD_SPI change_disp_sd(false); #endif load_sd_voice(configuration.performance.bank[instance_id], configuration.performance.voice[instance_id], instance_id); get_voice_names_from_bank(configuration.performance.bank[instance_id], instance_id); #ifdef DISPLAY_LCD_SPI change_disp_sd(true); #endif break; } else if (LCDML.BT_checkDown()) { switch (menu_voice_select) { case MENU_VOICE_BANK: bank_tmp = constrain(configuration.performance.bank[instance_id] + ENCODER[ENC_R].speed(), 0, MAX_BANKS - 1); configuration.performance.bank[instance_id] = bank_tmp; #ifdef DISPLAY_LCD_SPI change_disp_sd(false); #endif load_sd_voice(configuration.performance.bank[instance_id], configuration.performance.voice[instance_id], instance_id); get_voice_names_from_bank(configuration.performance.bank[instance_id], instance_id); #ifdef DISPLAY_LCD_SPI change_disp_sd(true); #endif break; case MENU_VOICE_SOUND: voice_tmp = configuration.performance.voice[instance_id] + ENCODER[ENC_R].speed(); if (voice_tmp >= MAX_VOICES && configuration.performance.bank[instance_id] + 1 < MAX_BANKS) { voice_tmp %= MAX_VOICES; configuration.performance.bank[instance_id]++; configuration.performance.bank[instance_id] = constrain(configuration.performance.bank[instance_id], 0, MAX_BANKS - 1); } else if (voice_tmp >= MAX_VOICES && configuration.performance.bank[instance_id] + 1 >= MAX_BANKS) { voice_tmp = MAX_VOICES - 1; } configuration.performance.voice[instance_id] = voice_tmp; #ifdef DISPLAY_LCD_SPI change_disp_sd(false); #endif load_sd_voice(configuration.performance.bank[instance_id], configuration.performance.voice[instance_id], instance_id); get_voice_names_from_bank(configuration.performance.bank[instance_id], instance_id); #ifdef DISPLAY_LCD_SPI change_disp_sd(true); #endif break; } } else if (LCDML.BT_checkEnter()) { if (menu_voice_select == MENU_VOICE_BANK) menu_voice_select = MENU_VOICE_SOUND; else menu_voice_select = MENU_VOICE_BANK; } strip_extension(bank_names[instance_id][configuration.performance.bank[instance_id]], bank_name[instance_id]); lcd.show(0, 0, 2, configuration.performance.bank[instance_id]); lcd.show(1, 0, 2, configuration.performance.voice[instance_id] + 1); lcd.show(0, 4, 10, bank_name[instance_id]); lcd.show(1, 4, 10, voice_names[instance_id][configuration.performance.voice[instance_id]]); switch (menu_voice_select) { case MENU_VOICE_BANK: lcd.show(0, 2, 2, " ["); lcd.show(0, 14, 1, "]"); lcd.show(1, 2, 2, " "); lcd.show(1, 14, 1, " "); break; case MENU_VOICE_SOUND: lcd.show(0, 2, 2, " "); lcd.show(0, 14, 1, " "); lcd.show(1, 2, 2, " ["); lcd.show(1, 14, 1, "]"); break; } } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); if (instance_id == 0) { //eeprom_update_var(offsetof(configuration_s, performance.voice[0]), configuration.performance.voice[0], "configuration.performance.voice[0]"); //eeprom_update_var(offsetof(configuration_s, performance.bank[0]), configuration.performance.bank[0], "configuration.performance.bank[0]"); EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, performance.voice[0]), configuration.performance.voice[0]); EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, performance.bank[0]), configuration.performance.bank[0]); } #if NUM_DEXED > 1 else { EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, performance.voice[0]), configuration.performance.voice[1]); EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, performance.bank[0]), configuration.performance.bank[1]); } #endif } } void UI_func_volume(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_L].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("Master Vol.", configuration.sys.vol, 1.0, VOLUME_MIN, VOLUME_MAX, 3, false, false, false, true); back_from_volume = 0; } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_L].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_L].Up())) { back_from_volume = 0; if (LCDML.BT_checkDown()) { configuration.sys.vol = constrain(configuration.sys.vol + ENCODER[ENC_L].speed(), VOLUME_MIN, VOLUME_MAX); } else if (LCDML.BT_checkUp()) { configuration.sys.vol = constrain(configuration.sys.vol - ENCODER[ENC_L].speed(), VOLUME_MIN, VOLUME_MAX); } } lcd_display_bar_int("Master Vol.", configuration.sys.vol, 1.0, VOLUME_MIN, VOLUME_MAX, 3, false, false, false, false); set_volume(configuration.sys.vol, configuration.sys.mono); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, sys.vol), configuration.sys.vol); encoderDir[ENC_L].reset(); } } void UI_func_load_performance(uint8_t param) { static uint8_t mode; if (LCDML.FUNC_setup()) // ****** SETUP ********* { char tmp[10]; mode = 0; encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("Load Perf. SD")); lcd.setCursor(0, 1); sprintf(tmp, "[%2d]", configuration.sys.performance_number); lcd.print(tmp); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()) || (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort())) { if (LCDML.BT_checkDown()) { configuration.sys.performance_number = constrain(configuration.sys.performance_number + ENCODER[ENC_L].speed(), PERFORMANCE_NUM_MIN, PERFORMANCE_NUM_MAX); } else if (LCDML.BT_checkUp()) { configuration.sys.performance_number = constrain(configuration.sys.performance_number - ENCODER[ENC_L].speed(), PERFORMANCE_NUM_MIN, PERFORMANCE_NUM_MAX); } else if (LCDML.BT_checkEnter()) { mode = 0xff; lcd.setCursor(0, 1); if (load_sd_performance(configuration.sys.performance_number) == false) lcd.print("Does not exist."); else { load_sd_voice(configuration.performance.bank[0], configuration.performance.voice[0], 0); load_sd_voiceconfig(configuration.performance.voiceconfig_number[0], 0); set_voiceconfig_params(0); #if NUM_DEXED > 1 set_voiceconfig_params(1); load_sd_voice(configuration.performance.bank[0], configuration.performance.voice[1], 1); load_sd_voiceconfig(configuration.performance.voiceconfig_number[1], 1); #endif load_sd_fx(configuration.performance.fx_number); set_fx_params(); lcd.print("Done. "); } delay(500); LCDML.FUNC_goBackToMenu(); } lcd.setCursor(0, 1); char tmp[10]; sprintf(tmp, "[%2d]", configuration.sys.performance_number); lcd.print(tmp); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { if (mode < 0xff) { lcd.setCursor(0, 1); lcd.print("Canceled "); delay(500); } else eeprom_update_performance(); encoderDir[ENC_R].reset(); } } void UI_func_save_performance(uint8_t param) { static bool overwrite; static bool yesno; static uint8_t mode; if (LCDML.FUNC_setup()) // ****** SETUP ********* { char tmp[FILENAME_LEN]; yesno = false; mode = 0; encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("Save Perf. SD")); lcd.setCursor(0, 1); sprintf(tmp, "[%2d]", configuration.sys.performance_number); lcd.print(tmp); sprintf(tmp, "/%s/%s%d.syx", PERFORMANCE_CONFIG_PATH, PERFORMANCE_CONFIG_NAME, configuration.sys.performance_number); if (SD.exists(tmp)) overwrite = true; else overwrite = false; } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()) || (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort())) { if (LCDML.BT_checkDown()) { if (mode == 0) configuration.sys.performance_number = constrain(configuration.sys.performance_number + ENCODER[ENC_L].speed(), PERFORMANCE_NUM_MIN, PERFORMANCE_NUM_MAX); else yesno = true; } else if (LCDML.BT_checkUp()) { if (mode == 0) configuration.sys.performance_number = constrain(configuration.sys.performance_number - ENCODER[ENC_L].speed(), PERFORMANCE_NUM_MIN, PERFORMANCE_NUM_MAX); else yesno = false; } else if (LCDML.BT_checkEnter()) { if (mode == 0 && overwrite == true) { mode = 1; lcd.setCursor(0, 1); lcd.print(F("Overwrite: [ ]")); } else { mode = 0xff; if (overwrite == false || yesno == true) { if (yesno == true) { char tmp[FILENAME_LEN]; sprintf(tmp, "/%s/%s%d.syx", PERFORMANCE_CONFIG_PATH, PERFORMANCE_CONFIG_NAME, configuration.sys.performance_number); SD.remove(tmp); } save_sd_performance(configuration.performance.fx_number); lcd.setCursor(0, 1); lcd.print("Done. "); delay(500); } LCDML.FUNC_goBackToMenu(); } } if (mode == 0) { char tmp[FILENAME_LEN]; sprintf(tmp, "/%s/%s%d.syx", PERFORMANCE_CONFIG_PATH, PERFORMANCE_CONFIG_NAME, configuration.sys.performance_number); if (SD.exists(tmp)) overwrite = true; else overwrite = false; lcd.setCursor(0, 1); sprintf(tmp, "[%2d]", configuration.sys.performance_number); lcd.print(tmp); } else { lcd.setCursor(12, 1); if (yesno == true) lcd.print(F("YES")); else lcd.print(F("NO ")); } } encoderDir[ENC_R].reset(); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { if (mode < 0xff) { lcd.setCursor(0, 1); lcd.print("Canceled "); delay(500); } EEPROM.update(EEPROM_START_ADDRESS + offsetof(sys_s, performance_number), configuration.sys.performance_number); encoderDir[ENC_R].reset(); } } void UI_func_load_voiceconfig(uint8_t param) { #if NUMDEXED > 1 static int8_t instance_id; #else uint8_t instance_id = 0; #endif static uint8_t mode; if (LCDML.FUNC_setup()) // ****** SETUP ********* { char tmp[10]; instance_id = 0; encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("Load Voice Cfg")); #if NUMDEXED > 1 mode = 0; lcd.setCursor(0, 1); lcd.print(F("Instance [0]")); #else mode = 1; lcd.setCursor(0, 1); sprintf(tmp, "[%2d]", configuration.performance.voiceconfig_number[instance_id]); lcd.print(tmp); #endif } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()) || (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort())) { if (LCDML.BT_checkDown()) { if (mode == 0) instance_id = (instance_id + 1) % 2; else if (mode == 1) configuration.performance.voiceconfig_number[instance_id] = constrain(configuration.performance.voiceconfig_number[instance_id] + ENCODER[ENC_L].speed(), VOICECONFIG_NUM_MIN, VOICECONFIG_NUM_MAX); } else if (LCDML.BT_checkUp()) { if (mode == 0) instance_id = (instance_id - 1) % 2; else if (mode == 1) configuration.performance.voiceconfig_number[instance_id] = constrain(configuration.performance.voiceconfig_number[instance_id] - ENCODER[ENC_L].speed(), VOICECONFIG_NUM_MIN, VOICECONFIG_NUM_MAX); } else if (LCDML.BT_checkEnter()) { mode = 0xff; lcd.setCursor(0, 1); if (load_sd_voiceconfig(configuration.performance.voiceconfig_number[instance_id], instance_id) == false) lcd.print("Does not exist. "); else lcd.print("Done. "); delay(500); LCDML.FUNC_goBackToMenu(); } if (mode == 0) { lcd.setCursor(10, 1); lcd.print(instance_id); } else if (mode == 1) { lcd.setCursor(0, 1); char tmp[10]; sprintf(tmp, "[%2d]", configuration.performance.voiceconfig_number[instance_id]); lcd.print(tmp); } } encoderDir[ENC_R].reset(); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { if (mode < 0xff) { lcd.setCursor(0, 1); lcd.print("Canceled "); delay(500); } else eeprom_update_dexed(instance_id); #if NUM_DEXED > 1 if (instance_id > 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(performance_s, voiceconfig_number[1]), configuration.performance.voiceconfig_number[1]); else #endif EEPROM.update(EEPROM_START_ADDRESS + offsetof(performance_s, voiceconfig_number[0]), configuration.performance.voiceconfig_number[0]); encoderDir[ENC_R].reset(); } } void UI_func_save_voiceconfig(uint8_t param) { #if NUMDEXED > 1 static int8_t instance_id; #else uint8_t instance_id = 0; #endif static bool overwrite; static bool yesno; static uint8_t mode; if (LCDML.FUNC_setup()) // ****** SETUP ********* { char tmp[FILENAME_LEN]; yesno = false; instance_id = 0; encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("Save Config SD")); #if NUMDEXED > 1 mode = 0; lcd.setCursor(0, 1); lcd.print(F("Instance [0]")); #else mode = 1; lcd.setCursor(0, 1); sprintf(tmp, "[%2d]", configuration.performance.voiceconfig_number[instance_id]); lcd.print(tmp); sprintf(tmp, "/%s/%s%d.syx", VOICE_CONFIG_PATH, VOICE_CONFIG_NAME, configuration.performance.voiceconfig_number[instance_id]); if (SD.exists(tmp)) overwrite = true; else overwrite = false; #endif } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()) || (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort())) { if (LCDML.BT_checkDown()) { if (mode == 0) instance_id = (instance_id + 1) % 2; else if (mode == 1) configuration.performance.voiceconfig_number[instance_id] = constrain(configuration.performance.voiceconfig_number[instance_id] + ENCODER[ENC_L].speed(), VOICECONFIG_NUM_MIN, VOICECONFIG_NUM_MAX); else yesno = true; } else if (LCDML.BT_checkUp()) { if (mode == 0) instance_id = (instance_id - 1) % 2; else if (mode == 1) configuration.performance.voiceconfig_number[instance_id] = constrain(configuration.performance.voiceconfig_number[instance_id] - ENCODER[ENC_L].speed(), VOICECONFIG_NUM_MIN, VOICECONFIG_NUM_MAX); else yesno = false; } else if (LCDML.BT_checkEnter()) { if (mode == 1 && overwrite == true) { mode = 2; lcd.setCursor(0, 1); lcd.print(F("Overwrite: [ ]")); } else { mode = 0xff; if (overwrite == false || yesno == true) { if (yesno == true) { char tmp[FILENAME_LEN]; sprintf(tmp, "/%s/%s%d.syx", VOICE_CONFIG_PATH, VOICE_CONFIG_NAME, configuration.performance.voiceconfig_number[instance_id]); SD.remove(tmp); } save_sd_voiceconfig(configuration.performance.voiceconfig_number[instance_id], instance_id); lcd.setCursor(0, 1); lcd.print("Done. "); delay(500); } LCDML.FUNC_goBackToMenu(); } } if (mode == 0) { lcd.setCursor(10, 1); lcd.print(configuration.performance.voiceconfig_number[instance_id]); } else if (mode == 1) { char tmp[FILENAME_LEN]; sprintf(tmp, "/%s/%s%d.syx", VOICE_CONFIG_PATH, VOICE_CONFIG_NAME, configuration.performance.voiceconfig_number[instance_id]); if (SD.exists(tmp)) overwrite = true; else overwrite = false; lcd.setCursor(0, 1); sprintf(tmp, "[%2d]", configuration.performance.voiceconfig_number[instance_id]); lcd.print(tmp); } else if (mode == 2) { lcd.setCursor(12, 1); if (yesno == true) lcd.print(F("YES")); else lcd.print(F("NO ")); } } encoderDir[ENC_R].reset(); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { if (mode < 0xff) { lcd.setCursor(0, 1); lcd.print("Canceled "); delay(500); } #if NUM_DEXED > 1 if (instance_id > 0) EEPROM.update(EEPROM_START_ADDRESS + offsetof(performance_s, voiceconfig_number[1]), configuration.performance.voiceconfig_number[1]); else #endif EEPROM.update(EEPROM_START_ADDRESS + offsetof(performance_s, voiceconfig_number[0]), configuration.performance.voiceconfig_number[0]); encoderDir[ENC_R].reset(); } } void UI_func_load_fx(uint8_t param) { static uint8_t mode; if (LCDML.FUNC_setup()) // ****** SETUP ********* { char tmp[10]; mode = 0; encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("Load FX SD")); lcd.setCursor(0, 1); sprintf(tmp, "[%d]", configuration.performance.fx_number); lcd.print(tmp); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()) || (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort())) { if (LCDML.BT_checkDown()) { configuration.performance.fx_number = constrain(configuration.performance.fx_number + ENCODER[ENC_L].speed(), FX_NUM_MIN, FX_NUM_MAX); } else if (LCDML.BT_checkUp()) { configuration.performance.fx_number = constrain(configuration.performance.fx_number - ENCODER[ENC_L].speed(), FX_NUM_MIN, FX_NUM_MAX); } else if (LCDML.BT_checkEnter()) { mode = 0xff; lcd.setCursor(0, 1); if (load_sd_fx(configuration.performance.fx_number) == false) lcd.print("Does not exist. "); else lcd.print("Done. "); delay(500); LCDML.FUNC_goBackToMenu(); } lcd.setCursor(0, 1); char tmp[10]; sprintf(tmp, "[%2d]", configuration.performance.fx_number); lcd.print(tmp); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { if (mode < 0xff) { lcd.setCursor(0, 1); lcd.print("Canceled "); delay(500); } else eeprom_update_fx(); EEPROM.update(EEPROM_START_ADDRESS + offsetof(performance_s, fx_number), configuration.performance.fx_number); encoderDir[ENC_R].reset(); } } void UI_func_save_fx(uint8_t param) { static bool overwrite; static bool yesno; static uint8_t mode; if (LCDML.FUNC_setup()) // ****** SETUP ********* { char tmp[FILENAME_LEN]; yesno = false; mode = 0; encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("Save FX")); lcd.setCursor(0, 1); sprintf(tmp, "[%d]", configuration.performance.fx_number); lcd.print(tmp); sprintf(tmp, "/%s/%s%d.syx", FX_CONFIG_PATH, FX_CONFIG_NAME, configuration.performance.fx_number); if (SD.exists(tmp)) overwrite = true; else overwrite = false; } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()) || (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort())) { if (LCDML.BT_checkDown()) { if (mode == 0) configuration.performance.fx_number = constrain(configuration.performance.fx_number + ENCODER[ENC_L].speed(), FX_NUM_MIN, FX_NUM_MAX); else yesno = true; } else if (LCDML.BT_checkUp()) { if (mode == 0) configuration.performance.fx_number = constrain(configuration.performance.fx_number - ENCODER[ENC_L].speed(), FX_NUM_MIN, FX_NUM_MAX); else yesno = false; } else if (LCDML.BT_checkEnter()) { if (mode == 0 && overwrite == true) { mode = 1; lcd.setCursor(0, 1); lcd.print(F("Overwrite: [ ]")); } else { mode = 0xff; if (overwrite == false || yesno == true) { if (yesno == true) { char tmp[FILENAME_LEN]; sprintf(tmp, "/%s/%s%d.syx", FX_CONFIG_PATH, FX_CONFIG_NAME, configuration.performance.fx_number); SD.remove(tmp); } save_sd_fx(configuration.performance.fx_number); lcd.setCursor(0, 1); lcd.print("Done. "); delay(500); } LCDML.FUNC_goBackToMenu(); } } if (mode == 0) { char tmp[FILENAME_LEN]; sprintf(tmp, "/%s/%s%d.syx", FX_CONFIG_PATH, FX_CONFIG_NAME, configuration.performance.fx_number); if (SD.exists(tmp)) overwrite = true; else overwrite = false; lcd.setCursor(0, 1); sprintf(tmp, "[%2d]", configuration.performance.fx_number); lcd.print(tmp); } else { lcd.setCursor(12, 1); if (yesno == true) lcd.print(F("YES")); else lcd.print(F("NO ")); } } encoderDir[ENC_R].reset(); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { if (mode < 0xff) { lcd.setCursor(0, 1); lcd.print("Canceled "); delay(500); } EEPROM.update(EEPROM_START_ADDRESS + offsetof(performance_s, fx_number), configuration.performance.fx_number); encoderDir[ENC_R].reset(); } } void UI_func_save_voice(uint8_t param) { static bool yesno; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("Save Voice")); lcd.setCursor(0, 1); lcd.print(F("[NO ]")); if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() || LCDML.BT_checkUp())) { yesno = !yesno; if (yesno == true) { lcd.setCursor(1, 1); lcd.print(F("YES")); } else { lcd.setCursor(1, 1); lcd.print(F("NO ")); } } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { if (yesno == true) { LCDML.DISP_clear(); lcd.print(F("Save Cfg default")); // Storing on inside bank TBD lcd.setCursor(0, 1); lcd.print(F("Done. ")); delay(500); } encoderDir[ENC_R].reset(); } } } void UI_func_sysex_receive_bank(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("MIDI Recv Bank")); lcd.setCursor(0, 1); lcd.print(F("Not implemented.")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) { ; } else if (LCDML.BT_checkUp()) { ; } } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); } } void UI_func_sysex_send_bank(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("MIDI Send Bank")); lcd.setCursor(0, 1); lcd.print(F("Not implemented.")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) { ; } else if (LCDML.BT_checkUp()) { ; } } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); } } void UI_func_sysex_send_voice(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("MIDI Send Voice")); lcd.setCursor(0, 1); lcd.print(F("Not implemented.")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) { ; } else if (LCDML.BT_checkUp()) { ; } } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); } } void UI_func_sysex_receive_voice(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("MIDI Receive Voice")); lcd.setCursor(0, 1); lcd.print(F("Not implemented.")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) { ; } else if (LCDML.BT_checkUp()) { ; } } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); } } void UI_function_not_enabled(void) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("Function not")); lcd.setCursor(0, 1); lcd.print(F("enbaled!")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { ; } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); } } void UI_function_not_implemented(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("Function not")); lcd.setCursor(0, 1); lcd.print(F("implemented!")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { ; } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); } } void lcd_display_int(int16_t var, uint8_t size, bool zeros, bool brackets, bool sign) { lcd_display_float(float(var), size, 0, zeros, brackets, sign); } void lcd_display_float(float var, uint8_t size_number, uint8_t size_fraction, bool zeros, bool brackets, bool sign) { char s[LCD_cols + 1]; char f[LCD_cols + 1]; if (size_fraction > 0) { if (zeros == true && sign == true) sprintf(f, "%%+0%d.%df", size_number + size_fraction + 2, size_fraction); else if (zeros == true && sign == false) sprintf(f, "%%+0%d.%df", size_number + size_fraction + 1, size_fraction); else if (zeros == false && sign == true) sprintf(f, "%%+%d.%df", size_number + size_fraction + 2, size_fraction); else if (zeros == false && sign == false) sprintf(f, "%%%d.%df", size_number + size_fraction + 1, size_fraction); sprintf(s, f, var); } else { if (zeros == true && sign == true) sprintf(f, "%%+0%dd", size_number + 1); else if (zeros == true && sign == false) sprintf(f, "%%%0dd", size_number); else if (zeros == false && sign == true) sprintf(f, "%%+%dd", size_number + 1); else if (zeros == false && sign == false) sprintf(f, "%%%dd", size_number); sprintf(s, f, int(var)); } if (brackets == true) { char tmp[LCD_cols + 1]; strcpy(tmp, s); sprintf(s, "[%s]", tmp); } lcd.print(s); } inline void lcd_display_bar_int(const char* title, uint32_t value, float factor, int32_t min_value, int32_t max_value, uint8_t size, bool zeros, bool brackets, bool sign, bool init) { lcd_display_bar_float(title, float(value), factor, min_value, max_value, size, 0, zeros, brackets, sign, init); } void lcd_display_bar_float(const char* title, float value, float factor, int32_t min_value, int32_t max_value, uint8_t size_number, uint8_t size_fraction, bool zeros, bool brackets, bool sign, bool init) { uint8_t size = 0; float v = float((value - min_value) * LCD_cols) / (max_value - min_value); float _vi = 0.0; uint8_t vf = uint8_t(modff(v, &_vi) * 10.0 + 0.5); uint8_t vi = uint8_t(_vi); if (size_fraction == 0) size = size_number; else size = size_number + size_fraction + 1; if (brackets == true) size += 2; if (sign == true) size += 1; if (init == true) { // Title lcd.setCursor(0, 0); lcd.print(title); // Value-Brackets if (brackets == true) { lcd.setCursor(LCD_cols - size, 0); lcd.print(F("[")); lcd.setCursor(LCD_cols - 1, 0); lcd.print(F("]")); } } // Value lcd.setCursor(LCD_cols - size, 0); lcd_display_float(value * factor, size_number, size_fraction, zeros, brackets, sign); // Bar lcd.setCursor(0, 1); if (vi == 0) { lcd.write((uint8_t)vf / 2.0 - 0.5); lcd.print(F(" ")); } else { for (uint8_t i = 0; i < vi; i++) lcd.write((uint8_t)4); // full block if (vi < LCD_cols) lcd.write((uint8_t)vf / 2.0 - 0.5); for (uint8_t i = LCD_cols - vi; i < LCD_cols; i++) lcd.print(F(" ")); // empty block } } inline void lcd_display_meter_int(const char* title, uint32_t value, float factor, float offset, int32_t min_value, int32_t max_value, uint8_t size, bool zeros, bool brackets, bool sign, bool init) { lcd_display_meter_float(title, float(value), factor, offset, min_value, max_value, size, 0, zeros, brackets, sign, init); } void lcd_display_meter_float(const char* title, float value, float factor, float offset, int32_t min_value, int32_t max_value, uint8_t size_number, uint8_t size_fraction, bool zeros, bool brackets, bool sign, bool init) { uint8_t size = 0; float v = float((value - min_value) * LCD_cols) / (max_value - min_value); float _vi = 0.0; uint8_t vf = uint8_t(modff(v, &_vi) * 10.0 + 0.5); uint8_t vi = uint8_t(_vi); if (size_fraction == 0) size = size_number; else size = size_number + size_fraction + 1; if (brackets == true) size += 2; if (sign == true) size += 1; if (init == true) { // Title lcd.setCursor(0, 0); lcd.print(title); // Value-Brackets if (brackets == true) { lcd.setCursor(LCD_cols - size, 0); lcd.print(F("[")); lcd.setCursor(LCD_cols - 1, 0); lcd.print(F("]")); } } // Value lcd.setCursor(LCD_cols - size, 0); lcd_display_float((value + offset) * factor, size_number, size_fraction, zeros, brackets, sign); // Bar lcd.setCursor(0, 1); if (vi == 0) { lcd.write((uint8_t)vf / 2.0 - 0.5); lcd.print(F(" ")); } else { for (uint8_t i = 0; i < LCD_cols; i++) lcd.print(F(" ")); // empty block lcd.setCursor(vi - 1, 1); lcd.write((uint8_t)vf / 2.0 - 0.5); } } void lcd_special_chars(uint8_t mode) { switch (mode) { case SCROLLBAR: // set special chars for scrollbar for (uint8_t i = 0; i < 5; i++) { #ifdef I2C_DISPLAY lcd.createChar(i, (uint8_t*)scroll_bar[i]); #else flipped_scroll_bar[i] = rotTile(scroll_bar[i]); #endif } break; case BLOCKBAR: // set special chars for volumebar for (uint8_t i = 0; i < 5; i++) { #ifdef I2C_DISPLAY lcd.createChar(i, (uint8_t*)block_bar[i]); #else flipped_block_bar[i] = rotTile(block_bar[i]); #endif } break; case METERBAR: // set special chars for volumebar for (uint8_t i = 0; i < 5; i++) { #ifdef I2C_DISPLAY lcd.createChar(i, (uint8_t*)meter_bar[i]); #else flipped_block_bar[i] = rotTile(meter_bar[i]); #endif } break; } } void eeprom_update_var(uint16_t pos, uint8_t val, const char* val_string) { #ifdef DEBUG char tmp[80]; sprintf(tmp, "EEPROM update '%s' at position %d with value %d.", val_string, pos, val); Serial.println(tmp); #endif EEPROM.update(EEPROM_START_ADDRESS + pos, val); } #endif #endif