/* 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,2019 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" #define ENCODER_USE_INTERRUPTS #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 void set_volume(uint8_t v, int8_t p, 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); #ifdef DISPLAY_LCD_SPI extern void change_disp_sd(bool d); #endif extern AudioEffectDelay delay1; #ifdef USE_REVERB extern AudioEffectFreeverbStereo freeverbs1; extern AudioMixer4 reverb_mixer; #endif extern AudioEffectModulatedDelay modchorus; extern AudioSynthWaveform modulator; extern AudioMixer4 chorus_mixer; extern AudioMixer4 delay_mixer; extern AudioMixer4 delay_fb_mixer; extern AudioMixer4 master_mixer_r; extern AudioMixer4 master_mixer_l; extern AudioAmplifier volume_r; extern AudioAmplifier volume_l; extern AudioEffectStereoMono stereomono1; extern AudioSourceMicroDexed * MicroDexed[NUM_DEXED]; extern uint8_t selected_dexed_instance; /*********************************************************************** 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 }; enum { ENC_R, ENC_L }; enum { MENU_START, MENU_VOICE, MENU_EDIT, MENU_VOLUME }; enum {MENU_VOICE_BANK, MENU_VOICE_SOUND}; uint8_t menu_state = MENU_START; uint8_t menu_voice = 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 encoder_right_up(void); void encoder_right_down(void); void encoder_right_button_long(void); void encoder_right_button_short(void); void encoder_left_up(void); void encoder_left_down(void); void encoder_left_button_long(void); void encoder_left_button_short(void); void lcdml_voice_menu_control(void); void UI_func_sound(uint8_t param); 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_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_delay_time(uint8_t param); void UI_func_delay_feedback(uint8_t param); void UI_func_delay_send(uint8_t param); void UI_func_filter_cutoff(uint8_t param); void UI_func_filter_resonance(uint8_t param); 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_loudness(uint8_t param); void UI_func_panorama(uint8_t param); void UI_func_stereo_mono(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_fc_range(uint8_t param); void UI_func_fc_assign(uint8_t param); void UI_func_bc_range(uint8_t param); void UI_func_bc_assign(uint8_t param); void UI_func_at_range(uint8_t param); void UI_func_at_assign(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_voice_selection(uint8_t param); void UI_func_volume(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); // 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); // LCDML_add(id, prev_layer, new_num, lang_char_array, callback_function) #if NUM_DEXED > 1 LCDML_add(0, LCDML_0, 1, "Setup", NULL); LCDML_add(1, LCDML_0_1, 1, "Instance 1", NULL); LCDML_add(2, LCDML_0_1_1, 1, "MIDI Channel 1", UI_func_midi_channel); LCDML_add(3, LCDML_0_1_1, 2, "Transpose 1", UI_func_transpose); LCDML_add(4, LCDML_0_1_1, 3, "Tune 1", UI_func_tune); LCDML_add(5, LCDML_0_1_1, 4, "Loudness 1", UI_func_loudness); LCDML_add(6, LCDML_0_1_1, 5, "Reverb Send 1", UI_func_reverb_send); LCDML_add(7, LCDML_0_1_1, 6, "Chorus Send 1", UI_func_chorus_send); LCDML_add(8, LCDML_0_1_1, 7, "Delay Send 1", UI_func_delay_send); LCDML_add(9, LCDML_0_1_1, 8, "Filter 1", NULL); LCDML_add(10, LCDML_0_1_1_6, 1, "Cutoff 1", UI_func_filter_cutoff); LCDML_add(11, LCDML_0_1_1_6, 2, "Resonance 1", UI_func_filter_resonance); LCDML_add(12, LCDML_0_1_1, 9, "Panorama 1", UI_func_panorama); LCDML_add(13, LCDML_0_1_1, 10, "Polyphony 1", UI_func_polyphony); LCDML_add(14, LCDML_0_1_1, 11, "Engine 1", UI_func_engine); LCDML_add(15, LCDML_0_1_1, 12, "Mono/Poly 1", UI_func_mono_poly); LCDML_add(16, LCDML_0_1_1, 13, "Pitchbend 1", NULL); LCDML_add(17, LCDML_0_1_1_13, 1, "PB Range 1", UI_func_pb_range); LCDML_add(18, LCDML_0_1_1_13, 2, "PB Step 1", UI_func_pb_step); LCDML_add(19, LCDML_0_1_1, 14, "Mod Wheel 1", NULL); LCDML_add(20, LCDML_0_1_1_14, 1, "MW Range 1", UI_func_mw_range); LCDML_add(21, LCDML_0_1_1_14, 2, "MW Assign 1", UI_func_mw_assign); LCDML_add(22, LCDML_0_1_1, 15, "Foot Ctrl 1", NULL); LCDML_add(23, LCDML_0_1_1_15, 1, "FC Range 1", UI_func_fc_range); LCDML_add(24, LCDML_0_1_1_15, 2, "FC Assign 1", UI_func_fc_assign); LCDML_add(25, LCDML_0_1_1, 16, "Breath Ctrl 1", NULL); LCDML_add(26, LCDML_0_1_1_16, 1, "BC Range 1", UI_func_bc_range); LCDML_add(27, LCDML_0_1_1_16, 2, "BC Assign 1", UI_func_bc_assign); LCDML_add(28, LCDML_0_1_1, 17, "Aftertouch 1", NULL); LCDML_add(29, LCDML_0_1_1_17, 1, "AT Range 1", UI_func_at_range); LCDML_add(30, LCDML_0_1_1_17, 2, "AT Assign 1", UI_func_at_assign); LCDML_add(31, LCDML_0_1_1, 18, "Portamento 1", NULL); LCDML_add(32, LCDML_0_1_1_18, 1, "Port. Mode 1", UI_func_portamento_mode); LCDML_add(33, LCDML_0_1_1_18, 2, "Port. Gliss 1", UI_func_portamento_glissando); LCDML_add(34, LCDML_0_1_1_18, 3, "Port. Time 1", UI_func_portamento_time); LCDML_add(35, LCDML_0_1_1, 19, "Operator 1", NULL); LCDML_add(36, LCDML_0_1_1_19, 1, "OP1 1", UI_func_OP1); LCDML_add(37, LCDML_0_1_1_19, 2, "OP2 1", UI_func_OP2); LCDML_add(38, LCDML_0_1_1_19, 3, "OP3 1", UI_func_OP3); LCDML_add(39, LCDML_0_1_1_19, 4, "OP4 1", UI_func_OP4); LCDML_add(40, LCDML_0_1_1_19, 5, "OP5 1", UI_func_OP5); LCDML_add(41, LCDML_0_1_1_19, 6, "OP6 1", UI_func_OP6); LCDML_add(42, LCDML_0_1, 2, "Instance 2", NULL); LCDML_add(43, LCDML_0_1_2, 1, "MIDI Channel 2", UI_func_midi_channel); LCDML_add(44, LCDML_0_1_2, 2, "Loudness 2", UI_func_loudness); LCDML_add(45, LCDML_0_1_2, 3, "Transpose 2", UI_func_transpose); LCDML_add(46, LCDML_0_1_2, 4, "Tune 2", UI_func_tune); LCDML_add(47, LCDML_0_1_2, 5, "Reverb Send 2", UI_func_reverb_send); LCDML_add(48, LCDML_0_1_2, 6, "Chorus Send 2", UI_func_chorus_send); LCDML_add(49, LCDML_0_1_2, 7, "Delay Send 2", UI_func_delay_send); LCDML_add(50, LCDML_0_1_2, 8, "Filter 1", NULL); LCDML_add(51, LCDML_0_1_2_6, 1, "Cutoff 1", UI_func_filter_cutoff); LCDML_add(52, LCDML_0_1_2_6, 2, "Resonance 1", UI_func_filter_resonance); LCDML_add(53, LCDML_0_1_2, 9, "Panorama 2", UI_func_panorama); LCDML_add(54, LCDML_0_1_2, 10, "Polyphony 2", UI_func_polyphony); LCDML_add(55, LCDML_0_1_2, 11, "Engine 2", UI_func_engine); LCDML_add(56, LCDML_0_1_2, 12, "Mono/Poly 2", UI_func_mono_poly); LCDML_add(57, LCDML_0_1_2, 13, "Pitchbend 2", NULL); LCDML_add(58, LCDML_0_1_2_13, 1, "PB Range 2", UI_func_pb_range); LCDML_add(59, LCDML_0_1_2_13, 2, "PB Step 2", UI_func_pb_step); LCDML_add(60, LCDML_0_1_2, 14, "Mod Wheel 2", NULL); LCDML_add(61, LCDML_0_1_2_14, 1, "MW Range 2", UI_func_mw_range); LCDML_add(62, LCDML_0_1_2_14, 2, "MW Assign 2", UI_func_mw_assign); LCDML_add(63, LCDML_0_1_2, 15, "Foot Ctrl 2", NULL); LCDML_add(64, LCDML_0_1_2_15, 1, "FC Range 2", UI_func_fc_range); LCDML_add(65, LCDML_0_1_2_15, 2, "FC Assign 2", UI_func_fc_assign); LCDML_add(66, LCDML_0_1_2, 16, "Breat Ctrl 2", NULL); LCDML_add(67, LCDML_0_1_2_16, 1, "BC Range 2", UI_func_bc_range); LCDML_add(68, LCDML_0_1_2_16, 2, "BC Assign 2", UI_func_bc_assign); LCDML_add(69, LCDML_0_1_2, 17, "Aftertouch 2", NULL); LCDML_add(70, LCDML_0_1_2_17, 1, "AT Range 2", UI_func_at_range); LCDML_add(71, LCDML_0_1_2_17, 2, "AT Assign 2", UI_func_at_assign); LCDML_add(72, LCDML_0_1_2, 18, "Portamento 2", NULL); LCDML_add(73, LCDML_0_1_2_18, 1, "Port. Mode 2", UI_func_portamento_mode); LCDML_add(74, LCDML_0_1_2_18, 2, "Port. Gliss 2", UI_func_portamento_glissando); LCDML_add(75, LCDML_0_1_2_18, 3, "Port. Time 2", UI_func_portamento_time); LCDML_add(76, LCDML_0_1_2, 19, "Operator 2", NULL); LCDML_add(77, LCDML_0_1_2_19, 1, "OP1 2", UI_func_OP1); LCDML_add(78, LCDML_0_1_2_19, 2, "OP2 2", UI_func_OP2); LCDML_add(79, LCDML_0_1_2_19, 3, "OP3 2", UI_func_OP3); LCDML_add(80, LCDML_0_1_2_19, 4, "OP4 2", UI_func_OP4); LCDML_add(81, LCDML_0_1_2_19, 5, "OP5 2", UI_func_OP5); LCDML_add(82, LCDML_0_1_2_19, 6, "OP6 2", UI_func_OP6); LCDML_add(83, LCDML_0, 2, "Effect", NULL); LCDML_add(84, LCDML_0_2, 1, "Reverb", NULL); LCDML_add(85, LCDML_0_2_1, 1, "Roomsize", UI_func_reverb_roomsize); LCDML_add(86, LCDML_0_2_1, 2, "Damping", UI_func_reverb_damping); LCDML_add(87, LCDML_0_2, 2, "Chorus", NULL); LCDML_add(88, LCDML_0_2_2, 1, "Frequency", UI_func_chorus_frequency); LCDML_add(89, LCDML_0_2_2, 2, "Waveform", UI_func_chorus_waveform); LCDML_add(90, LCDML_0_2_2, 3, "Depth", UI_func_chorus_depth); LCDML_add(91, LCDML_0_2, 3, "Delay", NULL); LCDML_add(92, LCDML_0_2_3, 1, "Time", UI_func_delay_time); LCDML_add(93, LCDML_0_2_3, 2, "Feedback", UI_func_delay_feedback); LCDML_add(94, LCDML_0, 3, "Store", NULL); LCDML_add(95, LCDML_0, 4, "System", NULL); LCDML_add(96, LCDML_0_4, 1, "Stereo/Mono", UI_func_stereo_mono); LCDML_add(97, LCDML_0, 5, "Info", UI_func_information); #define _LCDML_DISP_cnt 97 #define MENU_ID_OF_INSTANCE_2 42 #else LCDML_add(0, LCDML_0, 1, "Setup", NULL); LCDML_add(1, LCDML_0_1, 1, "MIDI Channel", UI_func_midi_channel); LCDML_add(2, LCDML_0_1, 2, "Loudness", UI_func_loudness); LCDML_add(3, LCDML_0_1, 3, "Transpose", UI_func_transpose); LCDML_add(4, LCDML_0_1, 4, "Tune", UI_func_tune); LCDML_add(5, LCDML_0_1, 5, "Reverb Send", UI_func_reverb_send); LCDML_add(6, LCDML_0_1, 6, "Chorus Send", UI_func_chorus_send); LCDML_add(7, LCDML_0_1, 7, "Delay Send", UI_func_delay_send); LCDML_add(8, LCDML_0_1, 8, "Filter", NULL); LCDML_add(9, LCDML_0_1_6, 1, "Cutoff", UI_func_filter_cutoff); LCDML_add(10, LCDML_0_1_6, 2, "Resonance", UI_func_filter_resonance); LCDML_add(11, LCDML_0_1, 9, "Panorama", UI_func_panorama); LCDML_add(12, LCDML_0_1, 10, "Polyphony", UI_func_polyphony); LCDML_add(13, LCDML_0_1, 11, "Engine", UI_func_engine); LCDML_add(14, LCDML_0_1, 12, "Mono/Poly", UI_func_mono_poly); LCDML_add(15, LCDML_0_1, 13, "Pitchbend", NULL); LCDML_add(16, LCDML_0_1_13, 1, "PB Range", UI_func_pb_range); LCDML_add(17, LCDML_0_1_13, 2, "PB Step", UI_func_pb_step); LCDML_add(18, LCDML_0_1, 14, "Mod Wheel", NULL); LCDML_add(19, LCDML_0_1_14, 1, "MW Range", UI_func_mw_range); LCDML_add(20, LCDML_0_1_14, 2, "MW Assign", UI_func_mw_assign); LCDML_add(21, LCDML_0_1, 15, "Foot Ctrl", NULL); LCDML_add(22, LCDML_0_1_15, 1, "FC Range", UI_func_fc_range); LCDML_add(23, LCDML_0_1_15, 2, "FC Assign", UI_func_fc_assign); LCDML_add(24, LCDML_0_1, 16, "Breath Ctrl", NULL); LCDML_add(25, LCDML_0_1_16, 1, "BC Range", UI_func_bc_range); LCDML_add(26, LCDML_0_1_16, 2, "BC Assign", UI_func_bc_assign); LCDML_add(27, LCDML_0_1, 17, "Aftertouch", NULL); LCDML_add(28, LCDML_0_1_17, 1, "AT Range", UI_func_at_range); LCDML_add(29, LCDML_0_1_17, 2, "AT Assign", UI_func_at_assign); LCDML_add(30, LCDML_0_1, 18, "Portamento", NULL); LCDML_add(31, LCDML_0_1_18, 1, "Port. Mode", UI_func_portamento_mode); LCDML_add(32, LCDML_0_1_18, 2, "Port. Gliss", UI_func_portamento_glissando); LCDML_add(33, LCDML_0_1_18, 3, "Port. Time", UI_func_portamento_time); LCDML_add(34, LCDML_0_1, 19, "Operator", NULL); LCDML_add(35, LCDML_0_1_19, 1, "OP1", UI_func_OP1); LCDML_add(36, LCDML_0_1_19, 2, "OP2", UI_func_OP2); LCDML_add(37, LCDML_0_1_19, 3, "OP3", UI_func_OP3); LCDML_add(38, LCDML_0_1_19, 4, "OP4", UI_func_OP4); LCDML_add(39, LCDML_0_1_19, 5, "OP5", UI_func_OP5); LCDML_add(40, LCDML_0_1_19, 6, "OP6", UI_func_OP6); LCDML_add(41, LCDML_0, 2, "Effect", NULL); LCDML_add(42, LCDML_0_2, 1, "Reverb", NULL); LCDML_add(43, LCDML_0_2_1, 1, "Roomsize", UI_func_reverb_roomsize); LCDML_add(44, LCDML_0_2_1, 2, "Damping", UI_func_reverb_damping); LCDML_add(45, LCDML_0_2, 2, "Chorus", NULL); LCDML_add(46, LCDML_0_2_2, 1, "Frequency", UI_func_chorus_frequency); LCDML_add(47, LCDML_0_2_2, 2, "Waveform", UI_func_chorus_waveform); LCDML_add(48, LCDML_0_2_2, 3, "Depth", UI_func_chorus_depth); LCDML_add(49, LCDML_0_2, 3, "Delay", NULL); LCDML_add(50, LCDML_0_2_3, 1, "Time", UI_func_delay_time); LCDML_add(51, LCDML_0_2_3, 2, "Feedback", UI_func_delay_feedback); LCDML_add(52, LCDML_0, 3, "Store", NULL); LCDML_add(53, LCDML_0, 4, "System", NULL); LCDML_add(54, LCDML_0_4, 1, "Stereo/Mono", UI_func_stereo_mono); LCDML_add(55, LCDML_0, 5, "Info", UI_func_information); #define _LCDML_DISP_cnt 55 #define MENU_ID_OF_INSTANCE_2 41 #endif // create menu LCDML_createMenu(_LCDML_DISP_cnt); /*********************************************************************** CONTROL ***********************************************************************/ #define g_LCDML_CONTROL_button_long_press LONG_BUTTON_PRESS #define g_LCDML_CONTROL_button_short_press BUT_DEBOUNCE_MS //#define ENCODER_OPTIMIZE_INTERRUPTS //Only when using pin2/3 (or 20/21 on mega) Encoder ENCODER[NUM_ENCODER] = {Encoder(ENC_R_PIN_B, ENC_R_PIN_A), Encoder(ENC_L_PIN_B, ENC_L_PIN_A)}; 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}; #ifdef U8X8_DISPLAY const uint8_t * flipped_scroll_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")); #ifdef I2C_DISPLAY // set special chars for scrollbar lcd.createChar(0, (uint8_t*)scroll_bar[0]); lcd.createChar(1, (uint8_t*)scroll_bar[1]); lcd.createChar(2, (uint8_t*)scroll_bar[2]); lcd.createChar(3, (uint8_t*)scroll_bar[3]); lcd.createChar(4, (uint8_t*)scroll_bar[4]); #else for (int x = 0; x < 5; x++) { flipped_scroll_bar[x] = rotTile(scroll_bar[x]); } #endif // 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_selection, VOICE_SELECTION_MS); // set to 10 seconds } 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); } if (back_from_volume > BACK_FROM_VOLUME_MS && menu_state == MENU_VOLUME) { UI_func_voice_selection(0); return; } //Volatile Variable 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 handlying (from LCDMenuLib2) ************************************************************************************/ // RIGHT if (g_LCDML_CONTROL_Encoder_position[ENC_R] <= -3) { if (!button[ENC_R]) { LCDML.BT_left(); g_LCDML_CONTROL_button_prev[ENC_R] = LOW; g_LCDML_CONTROL_button_press_time[ENC_R] = -1; } else { encoder_right_up(); } 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]) { LCDML.BT_right(); g_LCDML_CONTROL_button_prev[ENC_R] = LOW; g_LCDML_CONTROL_button_press_time[ENC_R] = -1; } else { encoder_right_down(); } 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[ENC_R] 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[ENC_R] 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) { encoder_right_button_long(); } else if ((millis() - g_LCDML_CONTROL_button_press_time[ENC_R]) >= g_LCDML_CONTROL_button_short_press) { encoder_right_button_short(); } } } // LEFT if (g_LCDML_CONTROL_Encoder_position[ENC_L] <= -3) { if (!button[ENC_L]) { //LCDML.BT_left(); g_LCDML_CONTROL_button_prev[ENC_L] = LOW; g_LCDML_CONTROL_button_press_time[ENC_L] = -1; } else { encoder_left_up(); } 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]) { //LCDML.BT_right(); g_LCDML_CONTROL_button_prev[ENC_L] = LOW; g_LCDML_CONTROL_button_press_time[ENC_L] = -1; } else { encoder_left_down(); } 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[ENC_L] 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[ENC_L] 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) { //LCDML.BT_quit(); encoder_left_button_long(); } else if ((millis() - g_LCDML_CONTROL_button_press_time[ENC_L]) >= g_LCDML_CONTROL_button_short_press) { //LCDML.BT_enter(); encoder_left_button_short(); } } } } /************************************************************************************ RIGHT Encoder functions ************************************************************************************/ void encoder_right_up(void) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2 && LCDML.FUNC_getID() != 255) instance_id = 1; switch (menu_state) { case MENU_EDIT: case MENU_VOLUME: menu_state = MENU_EDIT; LCDML.BT_down(); break; case MENU_VOICE: #ifdef DEBUG Serial.println(F("State: MENU_VOICE, Encoder left up")); #endif switch (menu_voice) { case MENU_VOICE_BANK: if (configuration.dexed[instance_id].bank < MAX_BANKS - 1) { configuration.dexed[instance_id].bank++; #ifdef DISPLAY_LCD_SPI change_disp_sd(false); #endif load_sysex(configuration.dexed[instance_id].bank, configuration.dexed[instance_id].voice, instance_id); get_voice_names_from_bank(configuration.dexed[instance_id].bank, instance_id); #ifdef DISPLAY_LCD_SPI change_disp_sd(true); #endif eeprom_write(); } break; case MENU_VOICE_SOUND: if (configuration.dexed[instance_id].voice < MAX_VOICES - 1) configuration.dexed[instance_id].voice++; else { if (configuration.dexed[instance_id].bank < MAX_BANKS - 1) { configuration.dexed[instance_id].bank++; configuration.dexed[instance_id].voice = 0; } } #ifdef DISPLAY_LCD_SPI change_disp_sd(false); #endif load_sysex(configuration.dexed[instance_id].bank, configuration.dexed[instance_id].voice, instance_id); get_voice_names_from_bank(configuration.dexed[instance_id].bank, instance_id); #ifdef DISPLAY_LCD_SPI change_disp_sd(true); #endif eeprom_write(); } UI_func_voice_selection(0); break; } } void encoder_right_down(void) { uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2 && LCDML.FUNC_getID() != 255) instance_id = 1; switch (menu_state) { case MENU_EDIT: case MENU_VOLUME: menu_state = MENU_EDIT; LCDML.BT_up(); break; case MENU_VOICE: #ifdef DEBUG Serial.println(F("State: MENU_VOICE, Encoder left down")); #endif switch (menu_voice) { case MENU_VOICE_BANK: if (configuration.dexed[instance_id].bank > 0) { configuration.dexed[instance_id].bank--; #ifdef DISPLAY_LCD_SPI change_disp_sd(false); #endif load_sysex(configuration.dexed[instance_id].bank, configuration.dexed[instance_id].voice, instance_id); get_voice_names_from_bank(configuration.dexed[instance_id].bank, instance_id); #ifdef DISPLAY_LCD_SPI change_disp_sd(true); #endif eeprom_write(); } break; case MENU_VOICE_SOUND: if (configuration.dexed[instance_id].voice > 0) configuration.dexed[instance_id].voice--; else { if (configuration.dexed[instance_id].bank > 0) { configuration.dexed[instance_id].bank--; configuration.dexed[instance_id].voice = 31; } } #ifdef DISPLAY_LCD_SPI change_disp_sd(false); #endif load_sysex(configuration.dexed[instance_id].bank, configuration.dexed[instance_id].voice, instance_id); get_voice_names_from_bank(configuration.dexed[instance_id].bank, instance_id); #ifdef DISPLAY_LCD_SPI change_disp_sd(true); #endif eeprom_write(); } UI_func_voice_selection(0); break; } } void encoder_right_button_long(void) { #ifdef DEBUG Serial.println(F("Encoder right long press")); #endif LCDML.BT_quit(); } void encoder_right_button_short(void) { #ifdef DEBUG Serial.println(F("Encoder right short press")); #endif if (menu_state == MENU_EDIT) { LCDML.BT_enter(); } else if (menu_state == MENU_VOICE) { #ifdef DEBUG Serial.println(F("State: MENU_VOICE, button short press")); #endif if (menu_voice == MENU_VOICE_BANK) menu_voice = MENU_VOICE_SOUND; else menu_voice = MENU_VOICE_BANK; UI_func_voice_selection(0); } } /************************************************************************************ LEFT Encoder functions ************************************************************************************/ void encoder_left_up(void) { #ifdef DEBUG Serial.println(F("Volume +")); #endif configuration.vol = constrain(configuration.vol + VOLUME_ENC_STEPS, VOLUME_MIN, VOLUME_MAX); eeprom_write(); set_volume(configuration.vol, configuration.pan, configuration.mono); UI_func_volume(0); } void encoder_left_down(void) { #ifdef DEBUG Serial.println(F("Volume -")); #endif configuration.vol = constrain(configuration.vol - VOLUME_ENC_STEPS, VOLUME_MIN, VOLUME_MAX); eeprom_write(); set_volume(configuration.vol, configuration.pan, configuration.mono); UI_func_volume(0); } void encoder_left_button_long(void) { #ifdef DEBUG Serial.println(F("Encoder left long press")); #endif if (menu_state == MENU_EDIT) { menu_state = MENU_VOICE; UI_func_voice_selection(0); } else if (menu_state == MENU_VOICE) { menu_state = MENU_EDIT; LCDML.MENU_goRoot(); } } void encoder_left_button_short(void) { #ifdef DEBUG Serial.println(F("Encoder left short press")); #endif if (menu_state == MENU_EDIT) { //LCDML.FUNC_goBackToMenu(); LCDML.BT_quit(); } else if (menu_state == MENU_VOICE) { menu_state = MENU_EDIT; LCDML.MENU_goRoot(); } } /*********************************************************************** 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 ***********************************************************************/ void UI_func_reverb_roomsize(uint8_t param) { #ifdef USE_REVERB if (LCDML.FUNC_setup()) // ****** SETUP ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("Reverb Roomsize")); #ifdef DEBUG Serial.println(F("Entering UI_func_reverb_roomsize()")); Serial.print(F("configuration.roomsize=")); Serial.println(configuration.reverb_roomsize, DEC); #endif } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.reverb_roomsize < REVERB_ROOMSIZE_MAX) { configuration.reverb_roomsize++; } } else if (LCDML.BT_checkUp()) { if (configuration.reverb_roomsize > REVERB_ROOMSIZE_MIN) { configuration.reverb_roomsize--; } } freeverbs1.roomsize(mapfloat(configuration.reverb_roomsize, REVERB_ROOMSIZE_MIN, REVERB_ROOMSIZE_MAX, 0.0, 1.0)); } lcd.setCursor(0, 1); lcd_display_int(configuration.reverb_roomsize, 3, true, true, false); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { #ifdef DEBUG Serial.println(F("Leaving UI_func_reverb_roomsize()")); Serial.print(F("reverb_roomsize=")); Serial.println(configuration.reverb_roomsize, DEC); #endif eeprom_write(); } #else UI_function_not_enabled(); #endif } void UI_func_reverb_damping(uint8_t param) { #ifdef USE_REVERB if (LCDML.FUNC_setup()) // ****** SETUP ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("Reverb Damping")); #ifdef DEBUG Serial.println(F("Entering UI_func_reverb_damping()")); Serial.print(F("reverb_damping=")); Serial.println(configuration.reverb_damping, DEC); #endif } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.reverb_damping < REVERB_DAMPING_MAX) { configuration.reverb_damping++; } } else if (LCDML.BT_checkUp()) { if (configuration.reverb_damping > REVERB_DAMPING_MIN) { configuration.reverb_damping--; } } freeverbs1.damping(mapfloat(configuration.reverb_damping, REVERB_DAMPING_MIN, REVERB_DAMPING_MAX, 0.0, 1.0)); } lcd.setCursor(0, 1); lcd_display_int(configuration.reverb_damping, 3, true, true, false); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { #ifdef DEBUG Serial.println(F("Leaving UI_func_reverb_damping()")); Serial.print(F("configuration.reverb_damping=")); Serial.println(configuration.reverb_damping, DEC); #endif eeprom_write(); } #else UI_function_not_enabled(); #endif } void UI_func_reverb_send(uint8_t param) { #ifdef USE_REVERB uint8_t instance_id = 0; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; if (LCDML.FUNC_setup()) // ****** SETUP ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("Reverb Send")); #ifdef DEBUG Serial.println(F("Entering UI_func_reverb_send()")); Serial.print(F("configuration.dexed[")); Serial.print(instance_id, DEC); Serial.print(F("].reverb_send=")); Serial.println(configuration.dexed[instance_id].reverb_send, DEC); #endif } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.dexed[instance_id].reverb_send < REVERB_SEND_MAX) { configuration.dexed[instance_id].reverb_send++; } } else if (LCDML.BT_checkUp()) { if (configuration.dexed[instance_id].reverb_send > REVERB_SEND_MIN) { configuration.dexed[instance_id].reverb_send--; } } reverb_mixer.gain(instance_id, configuration.dexed[instance_id].reverb_send / 100.0); } lcd.setCursor(0, 1); lcd_display_int(configuration.dexed[instance_id].reverb_send, 3, true, true, false); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { #ifdef DEBUG Serial.println(F("Leaving UI_func_reverb_send()")); Serial.print(F("configuration.dexed[")); Serial.print(instance_id, DEC); Serial.print(F("].reverb_send=")); Serial.println(configuration.dexed[instance_id].reverb_send, DEC); #endif eeprom_write(); } #else UI_function_not_enabled(); #endif } void UI_func_chorus_frequency(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("Chorus Frequency")); #ifdef DEBUG Serial.println(F("Entering UI_func_chorus_frequency()")); Serial.print(F("configuration.chorus_frequency=")); Serial.println(configuration.chorus_frequency, DEC); #endif } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.chorus_frequency < CHORUS_FREQUENCY_MAX) { configuration.chorus_frequency++; } } else if (LCDML.BT_checkUp()) { if (configuration.chorus_frequency > CHORUS_FREQUENCY_MIN) { configuration.chorus_frequency--; } } modulator.frequency(configuration.chorus_frequency / 10.0); } lcd.setCursor(0, 1); lcd_display_float(configuration.chorus_frequency / 10.0, 2, 1, false, true, false); lcd.print(F(" Hz")); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { #ifdef DEBUG Serial.println(F("Leaving UI_func_chorus_frequency()")); Serial.print(F("configuration.chorus_frequency=")); Serial.println(configuration.chorus_frequency, DEC); #endif eeprom_write(); } } void UI_func_chorus_waveform(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("Chorus Waveform")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown()) { if (configuration.chorus_waveform < CHORUS_WAVEFORM_MAX) { configuration.chorus_waveform++; } } else if (LCDML.BT_checkUp()) { if (configuration.chorus_waveform > CHORUS_WAVEFORM_MIN) { configuration.chorus_waveform--; } } lcd.setCursor(0, 1); switch (configuration.chorus_waveform) { case 0: modulator.begin(WAVEFORM_TRIANGLE); lcd.print(F("[TRIANGLE]")); break; case 1: modulator.begin(WAVEFORM_SINE); lcd.print(F("[SINE ]")); break; default: modulator.begin(WAVEFORM_TRIANGLE); lcd.print(F("[TRIANGLE]")); break; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { // you can here reset some global vars or do nothing eeprom_write(); } } void UI_func_chorus_depth(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("Chorus Depth")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.chorus_depth < CHORUS_DEPTH_MAX) { configuration.chorus_depth++; } } else if (LCDML.BT_checkUp()) { if (configuration.chorus_depth > CHORUS_DEPTH_MIN) { configuration.chorus_depth--; } } modulator.amplitude(configuration.chorus_depth / 100.0); } lcd.setCursor(0, 1); lcd_display_int(configuration.chorus_depth, 3, true, true, false); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { // you can here reset some global vars or do nothing eeprom_write(); } } 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 ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("Chorus Send")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.dexed[instance_id].chorus_send < CHORUS_SEND_MAX) { configuration.dexed[instance_id].chorus_send++; } } else if (LCDML.BT_checkUp()) { if (configuration.dexed[instance_id].chorus_send > CHORUS_SEND_MIN) { configuration.dexed[instance_id].chorus_send--; } } chorus_mixer.gain(instance_id, configuration.dexed[instance_id].chorus_send / 100.0); } lcd.setCursor(0, 1); lcd_display_int(configuration.dexed[instance_id].chorus_send, 3, true, true, false); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { // you can here reset some global vars or do nothing eeprom_write(); } } void UI_func_delay_time(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("Delay Time")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.delay_time < DELAY_TIME_MAX / 10) { configuration.delay_time += 1; } } else if (LCDML.BT_checkUp()) { if (configuration.delay_time > DELAY_TIME_MIN) { configuration.delay_time -= 1; } } delay1.delay(0, configuration.delay_time * 10); } lcd.setCursor(0, 1); lcd_display_int(configuration.delay_time * 10, 3, true, true, false); lcd.print(F(" ms")); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { // you can here reset some global vars or do nothing eeprom_write(); } } void UI_func_delay_feedback(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("Delay Feedback")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.delay_feedback < DELAY_FEEDBACK_MAX) { configuration.delay_feedback++; } } else if (LCDML.BT_checkUp()) { if (configuration.delay_feedback > DELAY_FEEDBACK_MIN) { configuration.delay_feedback--; } } delay_fb_mixer.gain(1, configuration.delay_feedback / 100.0 ); // amount of feedback //delay_fb_mixer.gain(0, 1.0 - configuration.delay_feedback / 200.0); // original signal } lcd.setCursor(0, 1); lcd_display_int(configuration.delay_feedback, 3, true, true, false); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { // you can here reset some global vars or do nothing eeprom_write(); } } 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 ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("Delay Send")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.dexed[instance_id].delay_send < DELAY_SEND_MAX) { configuration.dexed[instance_id].delay_send++; } } else if (LCDML.BT_checkUp()) { if (configuration.dexed[instance_id].delay_send > DELAY_SEND_MIN) { configuration.dexed[instance_id].delay_send--; } } delay_mixer.gain(instance_id, configuration.dexed[instance_id].delay_send / 100.0); } lcd.setCursor(0, 1); lcd_display_int(configuration.dexed[instance_id].delay_send, 3, true, true, false); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { // you can here reset some global vars or do nothing eeprom_write(); } } 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 ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("Filter Cut-Off")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.dexed[instance_id].filter_cutoff < FILTER_CUTOFF_MAX) { configuration.dexed[instance_id].filter_cutoff++; } } else if (LCDML.BT_checkUp()) { if (configuration.dexed[instance_id].filter_cutoff > FILTER_CUTOFF_MIN) { configuration.dexed[instance_id].filter_cutoff--; } } MicroDexed[instance_id]->fx.Cutoff = mapfloat(configuration.dexed[instance_id].filter_cutoff, FILTER_CUTOFF_MIN, FILTER_CUTOFF_MAX, 1.0, 0.0); } lcd.setCursor(0, 1); lcd_display_int(configuration.dexed[instance_id].filter_cutoff, 3, true, true, false); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { // you can here reset some global vars or do nothing eeprom_write(); } } 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 ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("Filter Resonance")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.dexed[instance_id].filter_resonance < FILTER_RESONANCE_MAX) { configuration.dexed[instance_id].filter_resonance++; } } else if (LCDML.BT_checkUp()) { if (configuration.dexed[instance_id].filter_resonance > FILTER_RESONANCE_MIN) { configuration.dexed[instance_id].filter_resonance--; } } MicroDexed[instance_id]->fx.Reso = mapfloat(configuration.dexed[instance_id].filter_resonance, FILTER_RESONANCE_MIN, FILTER_RESONANCE_MAX, 1.0, 0.0); } lcd.setCursor(0, 1); lcd_display_int(configuration.dexed[instance_id].filter_resonance, 3, true, true, false); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { // you can here reset some global vars or do nothing eeprom_write(); } } 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 ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("Transpose")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.dexed[instance_id].transpose < TRANSPOSE_MAX) { configuration.dexed[instance_id].transpose++; } } else if (LCDML.BT_checkUp()) { if (configuration.dexed[instance_id].transpose > TRANSPOSE_MIN) { configuration.dexed[instance_id].transpose--; } } MicroDexed[instance_id]->notesOff(); MicroDexed[instance_id]->data[DEXED_VOICE_OFFSET + DEXED_TRANSPOSE] = configuration.dexed[instance_id].transpose; } lcd.setCursor(0, 1); lcd_display_int(configuration.dexed[instance_id].transpose, 2, true, true, false); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { // you can here reset some global vars or do nothing eeprom_write(); } } 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 ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("Tune")); lcd.setCursor(6, 1); lcd.print(F("cent")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.dexed[instance_id].tune < TUNE_MAX) { if (configuration.dexed[instance_id].tune == 99) { MicroDexed[instance_id]->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_TRANSPOSE]++; configuration.dexed[instance_id].transpose++; } configuration.dexed[instance_id].tune++; } } else if (LCDML.BT_checkUp()) { if (configuration.dexed[instance_id].tune > TUNE_MIN) { if (configuration.dexed[instance_id].tune == 100) { MicroDexed[instance_id]->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_TRANSPOSE]--; configuration.dexed[instance_id].transpose--; } configuration.dexed[instance_id].tune--; } } MicroDexed[instance_id]->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_MASTER_TUNE] = configuration.dexed[instance_id].tune; MicroDexed[instance_id]->controllers.masterTune = (int(MicroDexed[instance_id]->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_MASTER_TUNE] % 100 / 100.0 * 0x4000) << 11) * (1.0 / 12); MicroDexed[instance_id]->doRefreshVoice(); } lcd.setCursor(0, 1); lcd_display_int(configuration.dexed[instance_id].tune - 100, 1, false, true, true); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { // you can here reset some global vars or do nothing eeprom_write(); } } 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 ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("MIDI Channel")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown()) { if (configuration.dexed[instance_id].midi_channel < MIDI_CHANNEL_MAX) { configuration.dexed[instance_id].midi_channel++; } } else if (LCDML.BT_checkUp()) { if (configuration.dexed[instance_id].midi_channel > MIDI_CHANNEL_MIN) { configuration.dexed[instance_id].midi_channel--; } } 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 eeprom_write(); } } void UI_func_loudness(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 ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("Loudness")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.dexed[instance_id].loudness < LOUDNESS_MAX) { configuration.dexed[instance_id].loudness++; } } else if (LCDML.BT_checkUp()) { if (configuration.dexed[instance_id].loudness > LOUDNESS_MIN) { configuration.dexed[instance_id].loudness--; } } MicroDexed[instance_id]->fx.Gain = configuration.dexed[instance_id].loudness / 100.0; } lcd.setCursor(0, 1); lcd_display_int(configuration.dexed[instance_id].loudness, 3, true, true, false); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { // you can here reset some global vars or do nothing eeprom_write(); } } void UI_func_panorama(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("Panorama")); if (configuration.mono > 0) { lcd.setCursor(0, 1); lcd.print(F("MONO-disabled")); } } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() && configuration.mono == 0) { if (configuration.pan < PANORAMA_MAX) { configuration.pan++; } } else if (LCDML.BT_checkUp() && configuration.mono == 0) { if (configuration.pan > PANORAMA_MIN) { configuration.pan--; } } if (configuration.mono == 0) { lcd.setCursor(0, 1); lcd_display_int(configuration.pan, 2, false, true, true); set_volume(configuration.vol, configuration.pan, configuration.mono); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { // you can here reset some global vars or do nothing eeprom_write(); } } void UI_func_stereo_mono(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("Stereo/Mono")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown()) { if (configuration.mono < MONO_MAX) { configuration.mono++; } } else if (LCDML.BT_checkUp()) { if (configuration.mono > MONO_MIN) { configuration.mono--; } } lcd.setCursor(0, 1); switch (configuration.mono) { case 0: lcd.print(F("[STEREO]")); stereomono1.stereo(true); break; case 1: lcd.print(F("[MONO ]")); stereomono1.stereo(false); break; case 2: lcd.print(F("[MONO-R]")); stereomono1.stereo(false); break; case 3: lcd.print(F("[MONO-L]")); stereomono1.stereo(false); break; } set_volume(configuration.vol, configuration.pan, configuration.mono); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { // you can here reset some global vars or do nothing eeprom_write(); } } 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 ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("Polyphony")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.dexed[instance_id].polyphony < POLYPHONY_MAX) { configuration.dexed[instance_id].polyphony++; } } else if (LCDML.BT_checkUp()) { if (configuration.dexed[instance_id].polyphony > POLYPHONY_MIN) { configuration.dexed[instance_id].polyphony--; } } MicroDexed[instance_id]->setMaxNotes(configuration.dexed[instance_id].polyphony); } lcd.setCursor(0, 1); lcd_display_int(configuration.dexed[instance_id].polyphony, 2, false, true, false); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { // you can here reset some global vars or do nothing eeprom_write(); } } 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 ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("Engine")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.dexed[instance_id].engine < ENGINE_MAX) { configuration.dexed[instance_id].engine++; } } else if (LCDML.BT_checkUp()) { if (configuration.dexed[instance_id].engine > ENGINE_MIN) { configuration.dexed[instance_id].engine--; } } 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 ********* { // you can here reset some global vars or do nothing eeprom_write(); } } 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 ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("Mono/Polyphonic")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.dexed[instance_id].monopoly < MONOPOLY_MAX) { configuration.dexed[instance_id].monopoly++; } } else if (LCDML.BT_checkUp()) { if (configuration.dexed[instance_id].monopoly > MONOPOLY_MIN) { configuration.dexed[instance_id].monopoly--; } } 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 ********* { // you can here reset some global vars or do nothing eeprom_write(); } } 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 ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("PB Range")); #ifdef DEBUG Serial.println(F("Entering UI_func_pb_range()")); Serial.print(F("configuration.dexed[")); Serial.print(instance_id, DEC); Serial.print(F("].pb_range=")); Serial.println(configuration.dexed[instance_id].pb_range, DEC); #endif } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.dexed[instance_id].pb_range < PB_RANGE_MAX) { configuration.dexed[instance_id].pb_range++; } } else if (LCDML.BT_checkUp()) { if (configuration.dexed[instance_id].pb_range > PB_RANGE_MIN) { configuration.dexed[instance_id].pb_range--; } } MicroDexed[instance_id]->setPBController(configuration.dexed[instance_id].pb_range, configuration.dexed[instance_id].pb_step); } lcd.setCursor(0, 1); lcd_display_int(configuration.dexed[instance_id].pb_range, 2, false, true, false); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { #ifdef DEBUG Serial.println(F("Entering UI_func_pb_range()")); Serial.print(F("configuration.dexed[")); Serial.print(instance_id, DEC); Serial.print(F("].pb_range=")); Serial.println(configuration.dexed[instance_id].pb_range, DEC); #endif eeprom_write(); } } 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 ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("PB Step")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.dexed[instance_id].pb_step < PB_STEP_MAX) { configuration.dexed[instance_id].pb_step++; } } else if (LCDML.BT_checkUp()) { if (configuration.dexed[instance_id].pb_step > PB_STEP_MIN) { configuration.dexed[instance_id].pb_step--; } } MicroDexed[instance_id]->setPBController(configuration.dexed[instance_id].pb_range, configuration.dexed[instance_id].pb_step); } lcd.setCursor(0, 1); lcd_display_int(configuration.dexed[instance_id].pb_step, 2, false, true, false); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { // you can here reset some global vars or do nothing eeprom_write(); } } 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 ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("MW Range")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.dexed[instance_id].mw_range < MW_RANGE_MAX) { configuration.dexed[instance_id].mw_range++; } } else if (LCDML.BT_checkUp()) { if (configuration.dexed[instance_id].mw_range > MW_RANGE_MIN) { configuration.dexed[instance_id].mw_range--; } } MicroDexed[instance_id]->setMWController(configuration.dexed[instance_id].mw_range, configuration.dexed[instance_id].mw_assign); } lcd.setCursor(0, 1); lcd_display_int(configuration.dexed[instance_id].mw_range, 2, false, true, false); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { // you can here reset some global vars or do nothing eeprom_write(); } } 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 ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("MW Assign")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.dexed[instance_id].mw_assign < MW_ASSIGN_MAX) { configuration.dexed[instance_id].mw_assign++; } } else if (LCDML.BT_checkUp()) { if (configuration.dexed[instance_id].mw_assign > MW_ASSIGN_MIN) { configuration.dexed[instance_id].mw_assign--; } } MicroDexed[instance_id]->setMWController(configuration.dexed[instance_id].mw_range, configuration.dexed[instance_id].mw_assign); } 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 ********* { // you can here reset some global vars or do nothing eeprom_write(); } } 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 ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("FC Range")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.dexed[instance_id].fc_range < FC_RANGE_MAX) { configuration.dexed[instance_id].fc_range++; } } else if (LCDML.BT_checkUp()) { if (configuration.dexed[instance_id].fc_range > FC_RANGE_MIN) { configuration.dexed[instance_id].fc_range--; } } MicroDexed[instance_id]->setFCController(configuration.dexed[instance_id].fc_range, configuration.dexed[instance_id].fc_assign); } lcd.setCursor(0, 1); lcd_display_int(configuration.dexed[instance_id].fc_range, 2, false, true, false); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { // you can here reset some global vars or do nothing eeprom_write(); } } 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 ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("FC Assign")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.dexed[instance_id].fc_assign < FC_ASSIGN_MAX) { configuration.dexed[instance_id].fc_assign++; } } else if (LCDML.BT_checkUp()) { if (configuration.dexed[instance_id].fc_assign > FC_ASSIGN_MIN) { configuration.dexed[instance_id].fc_assign--; } } MicroDexed[instance_id]->setFCController(configuration.dexed[instance_id].fc_range, configuration.dexed[instance_id].fc_assign); } 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 ********* { // you can here reset some global vars or do nothing eeprom_write(); } } 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 ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("BC Range")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.dexed[instance_id].bc_range < BC_RANGE_MAX) { configuration.dexed[instance_id].bc_range++; } } else if (LCDML.BT_checkUp()) { if (configuration.dexed[instance_id].bc_range > BC_RANGE_MIN) { configuration.dexed[instance_id].bc_range--; } } MicroDexed[instance_id]->setBCController(configuration.dexed[instance_id].bc_range, configuration.dexed[instance_id].bc_assign); } lcd.setCursor(0, 1); lcd_display_int(configuration.dexed[instance_id].bc_range, 2, false, true, false); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { // you can here reset some global vars or do nothing eeprom_write(); } } 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 ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("BC Assign")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.dexed[instance_id].bc_assign < BC_ASSIGN_MAX) { configuration.dexed[instance_id].bc_assign++; } } else if (LCDML.BT_checkUp()) { if (configuration.dexed[instance_id].bc_assign > BC_ASSIGN_MIN) { configuration.dexed[instance_id].bc_assign--; } } MicroDexed[instance_id]->setBCController(configuration.dexed[instance_id].bc_range, configuration.dexed[instance_id].bc_assign); } 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 ********* { // you can here reset some global vars or do nothing eeprom_write(); } } 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 ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("AT Range")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.dexed[instance_id].at_range < AT_RANGE_MAX) { configuration.dexed[instance_id].at_range++; } } else if (LCDML.BT_checkUp()) { if (configuration.dexed[instance_id].at_range > AT_RANGE_MIN) { configuration.dexed[instance_id].at_range--; } } MicroDexed[instance_id]->setATController(configuration.dexed[instance_id].at_range, configuration.dexed[instance_id].at_assign); } lcd.setCursor(0, 1); lcd_display_int(configuration.dexed[instance_id].at_range, 2, false, true, false); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { // you can here reset some global vars or do nothing eeprom_write(); } } 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 ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("AT Assign")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.dexed[instance_id].at_assign < AT_ASSIGN_MAX) { configuration.dexed[instance_id].at_assign++; } } else if (LCDML.BT_checkUp()) { if (configuration.dexed[instance_id].at_assign > AT_ASSIGN_MIN) { configuration.dexed[instance_id].at_assign--; } } MicroDexed[instance_id]->setATController(configuration.dexed[instance_id].at_range, configuration.dexed[instance_id].at_assign); } 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 ********* { // you can here reset some global vars or do nothing eeprom_write(); } } 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 ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("Portamento Mode")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.dexed[instance_id].portamento_mode < PORTAMENTO_MODE_MAX) { configuration.dexed[instance_id].portamento_mode++; } } else if (LCDML.BT_checkUp()) { if (configuration.dexed[instance_id].portamento_mode > PORTAMENTO_MODE_MIN) { configuration.dexed[instance_id].portamento_mode--; } } 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 ********* { // you can here reset some global vars or do nothing eeprom_write(); } } 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 ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("Portam. Gliss.")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.dexed[instance_id].portamento_glissando < PORTAMENTO_GLISSANDO_MAX) { configuration.dexed[instance_id].portamento_glissando++; } } else if (LCDML.BT_checkUp()) { if (configuration.dexed[instance_id].portamento_glissando > PORTAMENTO_GLISSANDO_MIN) { configuration.dexed[instance_id].portamento_glissando--; } } 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 ********* { // you can here reset some global vars or do nothing eeprom_write(); } } 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 ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("Portam. Time")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (configuration.dexed[instance_id].portamento_time < PORTAMENTO_TIME_MAX) { configuration.dexed[instance_id].portamento_time++; } } else if (LCDML.BT_checkUp()) { if (configuration.dexed[instance_id].portamento_time > PORTAMENTO_TIME_MIN) { configuration.dexed[instance_id].portamento_time--; } } 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); lcd_display_int(configuration.dexed[instance_id].portamento_time, 2, false, true, false); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { // you can here reset some global vars or do nothing eeprom_write(); } } 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, 0, 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 ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("Operator ")); lcd.print(op + 1); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } else if (LCDML.BT_checkUp() && state == true) bitClear(configuration.dexed[instance_id].op_enabled, op); else if (LCDML.BT_checkDown() && state == false) bitSet(configuration.dexed[instance_id].op_enabled, op); } 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 ********* { // you can here reset some global vars or do nothing eeprom_write(); } } void UI_func_information(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("MicroDexed")); lcd.setCursor(0, 1); lcd.print(VERSION); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { // loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set // the quit button works in every DISP function without any checks; it starts the loop_end function if (LCDML.BT_checkEnter()) { // check if any button is pressed (enter, up, down, left, right) // LCDML_goToMenu stops a running menu function and goes to the menu LCDML.FUNC_goBackToMenu(); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { // you can here reset some global vars or do nothing } } void UI_func_voice_selection(uint8_t param) { #ifdef DEBUG Serial.println(F("UI_func_voice_selection()")); #endif menu_state = MENU_VOICE; strip_extension(bank_names[selected_dexed_instance][configuration.dexed[selected_dexed_instance].bank], bank_name[selected_dexed_instance]); //LCDML.DISP_clear(); // display bank and voice number lcd.show(0, 0, 2, configuration.dexed[selected_dexed_instance].bank); lcd.show(1, 0, 2, configuration.dexed[selected_dexed_instance].voice + 1); // display names lcd.show(0, 4, 10, bank_name[selected_dexed_instance]); lcd.show(1, 4, 10, voice_names[selected_dexed_instance][configuration.dexed[selected_dexed_instance].voice]); // display selected Dexed instance if (selected_dexed_instance == 1) { #if NUM_DEXED > 1 lcd.show(0, 15, 1, "o"); #else lcd.show(0, 15, 1, " "); #endif lcd.show(1, 15, 1, "*"); } else { selected_dexed_instance = 0; lcd.show(0, 15, 1, "*"); #if NUM_DEXED > 1 lcd.show(1, 15, 1, "o"); #else lcd.show(1, 15, 1, " "); #endif } // display selections switch (menu_voice) { 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; } for (int x = 2; x < LCD_rows; x++) { lcd.show(x, 0, LCD_cols, " "); } } void UI_func_volume(uint8_t param) { #ifdef DEBUG Serial.println(F("UI_func_volume()")); #endif back_from_volume = 0; if (menu_state != MENU_VOLUME) { lcd.show(0, 0, LCD_cols, "Volume:"); lcd.show(1, 0, LCD_cols, "[ ]"); menu_state = MENU_VOLUME; } lcd.setCursor(8, 0); lcd_display_int(configuration.vol, 3, true, false, false); lcd.setCursor(1, 1); for (uint8_t i = 0; i < LCD_cols - 2; i++) { if (i < int(((LCD_cols - 2) * configuration.vol / 100.0) + 0.5)) lcd.print(F("*")); else lcd.print(F(" ")); } set_volume(configuration.vol, configuration.pan, configuration.mono); eeprom_write(); } void UI_function_not_enabled(void) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("Function not")); lcd.setCursor(0, 1); lcd.print(F("enabled!")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { // you can here reset some global vars or do nothing } } void UI_function_not_implemented(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { // setup function lcd.setCursor(0, 0); lcd.print(F("Function not")); lcd.setCursor(0, 1); lcd.print(F("implemented!")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkEnter()) { LCDML.FUNC_goBackToMenu(); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { // you can here reset some global vars or do nothing } } void lcd_display_int(int16_t var, uint8_t size, bool zeros, bool brackets, bool sign) { int16_t tmp = 0; uint16_t p; bool non_zero_found = false; if (size < 1) return; if (brackets == true) lcd.print(F("[")); if (sign == true) { size++; if (var < 0) { lcd.print(F("-")); var = abs(var); } else if (var > 0) lcd.print(F("+")); else lcd.print(F(" ")); } if (var == 0 && zeros == false) { for (int8_t i = size - 1 ; i > 0; i--) lcd.print(F(" ")); lcd.print(F("0")); } else { for (int8_t i = size - 1 ; i >= 0; i--) { p = int(pow(10, i)); tmp = int(var / p); if (tmp == 0) { if (zeros == true) lcd.print(F("0")); else { if (non_zero_found == true) lcd.print(F("0")); else lcd.print(F(" ")); } } else { non_zero_found = true; lcd.print(tmp); } var -= (tmp * p); } } if (brackets == true) lcd.print(F("]")); } void lcd_display_float(float var, uint8_t size_number, uint8_t size_fraction, bool zeros, bool brackets, bool sign) { float fraction; float number; if (size_number < 1 || size_fraction < 1) return; fraction = modff(var, &number); if (brackets == true) lcd.print(F("[")); if (int(number) == 0) { if (zeros == true) lcd.print(F("00")); else lcd.print(F(" 0")); } else lcd_display_int(int(number), size_number, zeros, false, sign); lcd.print(F(".")); lcd_display_int(round(fraction * pow(10, size_fraction)), size_fraction, true, false, false); if (brackets == true) lcd.print(F("]")); } #endif #endif