/* MicroDexed MicroDexed is a port of the Dexed sound engine (https://github.com/asb2m10/dexed) for the Teensy-3.5/3.6/4.x with audio shield. Dexed ist heavily based on https://github.com/google/music-synthesizer-for-android (c)2018-2021 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 #include #include "config.h" #include "disp_plus.h" #include "synth_dexed.h" #include "effect_modulated_delay.h" #include "effect_stereo_mono.h" #ifdef USE_PLATEREVERB #include "effect_platervbstereo.h" #else #include "effect_freeverbf.h" #endif #include "template_mixer.hpp" #include "drumset.h" #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 PeriodicTimer timer1; extern void sequencer(void); extern bool check_sd_performance_exists(uint8_t number); extern config_t configuration; extern void set_volume(uint8_t v, uint8_t m); extern bool load_sysex(uint8_t b, uint8_t v); extern void generate_version_string(char* buffer, uint8_t len); extern void _softRestart(void); //extern float pseudo_log_curve(float value); extern float midi_volume_transform(uint8_t midi_amp); extern float volume_transform(float amp); extern uint8_t selected_instance_id; extern char receive_bank_filename[FILENAME_LEN]; #if NUM_DRUMS > 0 #include "drums.h" extern void get_sd_seq_name_json(uint8_t number); extern drum_config_t drum_config[NUM_DRUMSET_CONFIG]; extern char seq_name[FILENAME_LEN]; extern char seq_name_temp[FILENAME_LEN]; extern uint8_t seq_vel[NUM_SEQ_PATTERN][16]; extern uint8_t seq_patternchain[4][NUM_SEQ_TRACKS]; extern uint8_t seq_content_type[NUM_SEQ_PATTERN]; extern uint8_t seq_track_type[NUM_SEQ_TRACKS]; extern uint8_t seq_step; extern uint8_t seq_chord_key_ammount; extern int seq_tempo_ms; extern uint8_t seq_bpm; extern uint8_t seq_chain_lenght; extern bool seq_running; extern bool seq_recording; extern bool smartfilter; extern uint8_t seq_state_last_loadsave; extern uint8_t seq_active_track; extern uint8_t seq_menu; extern uint8_t seq_temp_select_menu; extern uint8_t seq_temp_active_menu; extern uint8_t seq_chain_active_chainstep; //for editor extern uint8_t seq_chain_active_step; extern int seq_transpose; extern uint8_t seq_inst_dexed[NUM_SEQ_TRACKS]; extern uint8_t arp_step; extern uint8_t arp_note; extern uint8_t arp_chord; extern uint8_t arp_octave; extern uint8_t arp_lenght; extern uint8_t arp_style; extern uint8_t arp_speed; extern uint8_t seq_element_shift; extern int seq_oct_shift; extern char arp_style_names[4][3]; extern char seq_chord_names[7][4]; extern uint8_t seq_data_buffer[16]; extern uint8_t seq_data[NUM_SEQ_PATTERN][16]; extern float drums_volume; extern uint8_t drum_midi_channel; uint8_t seq_active_function = 99; uint8_t activesample; #endif #ifdef DISPLAY_LCD_SPI extern void change_disp_sd(bool d); #endif #ifdef SGTL5000_AUDIO_ENHANCE #include "control_sgtl5000plus.h" extern AudioControlSGTL5000Plus sgtl5000; #else extern AudioControlSGTL5000 sgtl5000; #endif #if defined(USE_FX) extern AudioSynthWaveform* chorus_modulator[NUM_DEXED]; extern AudioEffectModulatedDelay* modchorus[NUM_DEXED]; extern AudioMixer<4>* chorus_mixer[NUM_DEXED]; extern AudioMixer<4>* delay_fb_mixer[NUM_DEXED]; extern AudioEffectDelay* delay_fx[NUM_DEXED]; extern AudioMixer<4>* delay_mixer[NUM_DEXED]; #endif extern AudioEffectMonoStereo* mono2stereo[NUM_DEXED]; extern AudioMixer<4> microdexed_peak_mixer; extern AudioAnalyzePeak microdexed_peak; #if defined(USE_FX) extern AudioMixer<4> reverb_mixer_r; extern AudioMixer<4> reverb_mixer_l; #ifdef USE_PLATEREVERB extern AudioEffectPlateReverb reverb; #else extern AudioEffectFreeverbStereoFloat freeverb; #endif #endif extern AudioMixer<4> master_mixer_r; extern AudioMixer<4> master_mixer_l; extern AudioEffectStereoMono stereo2mono; extern AudioAnalyzePeak master_peak_r; extern AudioAnalyzePeak master_peak_l; extern char sd_string[LCD_cols + 1]; extern char g_voice_name[NUM_DEXED][VOICE_NAME_LEN]; extern char g_bank_name[NUM_DEXED][BANK_NAME_LEN]; extern int perform_attack_mod[NUM_DEXED]; extern int perform_release_mod[NUM_DEXED]; extern float midi_ticks_factor[10]; extern uint8_t midi_bpm; /*********************************************************************** GLOBAL ************************************************************************/ elapsedMillis back_from_volume; uint8_t instance_num[8][8]; const char accepted_chars[] = " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-abcdefghijklmnopqrstuvwxyz"; const char noteNames[12][3] = { "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B" }; uint8_t active_perform_page = 1; uint8_t orig_attack_values[2][7]; uint8_t orig_release_values[2][7]; int temp_int; bool menu_select_toggle; float temp_float; #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} }; const uint8_t special_chars[22][8] = { {B11111, B11011, B10011, B11011, B11011, B11011, B11011, B11111}, // [0] 1 small invers {B11111, B11011, B10101, B11101, B11011, B10111, B10001, B11111}, // [1] 2 small invers {B11111, B11011, B10011, B11011, B11011, B11011, B11011, B11111}, // [2] 1 OP invers {B11111, B11011, B10101, B11101, B11011, B10111, B10001, B11111}, // [3] 2 OP invers {B11111, B10001, B11101, B11011, B11101, B10101, B11011, B11111}, // [4] 3 OP invers {B11111, B10111, B10111, B10101, B10001, B11101, B11101, B11111}, // [5] 4 OP invers {B11111, B10001, B10111, B10011, B11101, B11101, B10011, B11111}, // [6] 5 OP invers {B11111, B11001, B10111, B10011, B10101, B10101, B11011, B11111}, // [7] 6 OP invers {B00000, B00000, B00000, B00000, B00000, B00000, B00000, B11111}, // [8] Level 1 {B00000, B00000, B00000, B00000, B00000, B00000, B11111, B11111}, // [9] Level 2 {B00000, B00000, B00000, B00000, B00000, B11111, B11111, B11111}, // [10] Level 3 {B00000, B00000, B00000, B00000, B11111, B11111, B11111, B11111}, // [11] Level 4 {B00000, B00000, B00000, B11111, B11111, B11111, B11111, B11111}, // [12] Level 5 {B00000, B00000, B11111, B11111, B11111, B11111, B11111, B11111}, // [13] Level 6 {B00000, B11111, B11111, B11111, B11111, B11111, B11111, B11111}, // [14] Level 7 {B11111, B11111, B11111, B11111, B11111, B11111, B11111, B11111}, // [15] Level 8 {B00100, B00110, B00101, B00101, B01101, B11101, B11100, B11000}, // [16] Note {B01110, B10001, B10001, B01110, B00100, B00100, B00110, B00110}, // [17] Disabled 2nd instance symbol {B11111, B10001, B10111, B10001, B10111, B10111, B10111, B11111}, // [18] Favorites Icon {B01000, B01100, B01110, B01111, B01110, B01100, B01000, B00000}, // [19] Play Symbol {B00000, B01110, B11111, B11111, B11111, B01110, B00000, B00000}, // [20] Record Symbol {B00000, B00000, B01110, B01110, B01110, B00000, B00000, B00000} // [21] Stop Symbol }; enum { SCROLLBAR, BLOCKBAR, METERBAR }; enum { ENC_R, ENC_L }; enum {MENU_VOICE_BANK, MENU_VOICE_SOUND}; void lcdml_menu_display(void); void lcdml_menu_clear(void); void lcdml_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_lowpass(uint8_t param); void UI_func_reverb_lodamp(uint8_t param); void UI_func_reverb_hidamp(uint8_t param); void UI_func_reverb_diffusion(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_level(uint8_t param); void UI_func_delay_time(uint8_t param); void UI_func_delay_feedback(uint8_t param); void UI_func_delay_level(uint8_t param); void UI_func_reverb_send(uint8_t param); void UI_func_filter_cutoff(uint8_t param); void UI_func_filter_resonance(uint8_t param); void UI_func_drum_reverb_send(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_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_handle_OP(uint8_t param); void UI_func_information(uint8_t param); void UI_func_seq_pattern_editor(uint8_t param); void UI_func_seq_vel_editor(uint8_t param); void UI_func_seq_live_transpose_oct(uint8_t param); void UI_func_arp_shift(uint8_t param); void UI_func_seq_chord_keys_ammount(uint8_t param); void UI_func_seq_lenght(uint8_t param); void UI_func_seq_tempo(uint8_t param); void UI_func_seq_pat_chain(uint8_t param); void UI_func_arpeggio(uint8_t param); void UI_func_seq_mute_matrix(uint8_t param); void UI_func_seq_track_setup(uint8_t param); void UI_func_dexed_assign(uint8_t param); void UI_func_seq_display_style(uint8_t param); void UI_func_set_performance_name(uint8_t param); void UI_func_volume(uint8_t param); void UI_func_smart_filter(uint8_t param); void UI_func_drum_midi_channel(uint8_t param); void UI_func_load_performance(uint8_t param); void UI_func_save_performance(uint8_t param); void UI_func_save_voice(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_bank(uint8_t param); void UI_func_sysex_send_bank(uint8_t param); void UI_func_eq_1(uint8_t param); void UI_func_eq_2(uint8_t param); void UI_func_eq_3(uint8_t param); void UI_func_eq_4(uint8_t param); void UI_func_eq_5(uint8_t param); void UI_func_eq_6(uint8_t param); void UI_func_eq_7(uint8_t param); void UI_function_not_enabled(void); void UI_function_not_implemented(uint8_t param); void UI_func_favorites(uint8_t param); void UI_update_instance_icons(); bool UI_select_name(uint8_t y, uint8_t x, char* edit_string, uint8_t len, bool init); uint8_t search_accepted_char(uint8_t c); 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 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 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 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 sign, bool init); void lcd_active_instance_number(uint8_t instance_id); void lcd_OP_active_instance_number(uint8_t instance_id, uint8_t op); void lcd_special_chars(uint8_t mode); void lcd_display_delay_sync(uint8_t sync); void string_trim(char *s); void save_favorite(uint8_t b, uint8_t v, uint8_t instance_id); void draw_favorite_icon(uint8_t b, uint8_t v, uint8_t instance_id); bool check_favorite(uint8_t b, uint8_t v, uint8_t instance_id); bool quick_check_favorites_in_bank(uint8_t b, uint8_t instance_id); void locate_previous_non_favorite(); void locate_previous_favorite(); void locate_next_favorite(); void locate_next_non_favorite(); void locate_random_non_favorite(); void UI_func_drums_main_volume(uint8_t param); void UI_func_drum_volume(uint8_t param); void UI_func_drum_pan(uint8_t param); void UI_func_drum_pitch(uint8_t param); void UI_func_drum_tune_offset(uint8_t param); char* basename(const char* filename); char* strip_extension(char* filename); // 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(USE_FX) #if defined(TEENSY4) #include "UI_FX_T4.h" #else #include "UI_FX.h" #endif #else #include "UI_NO_FX.h" #endif int favsearcher = 0; // create menu LCDML_createMenu(_LCDML_DISP_cnt); /*********************************************************************** CONTROL ***********************************************************************/ class EncoderDirection { public: EncoderDirection(void) { reset(); } void reset(void) { button_short = false; button_long = false; button_pressed = 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 ButtonPressed(bool state) { button_pressed = state; } bool ButtonPressed(void) { return (button_pressed); } 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 button_pressed; bool left; bool right; bool up; bool down; }; //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[7]; const uint8_t * flipped_meter_bar[7]; 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 smart_filter(uint8_t dir) { bool found = false; //search backwards if (dir == 0) { if (smartfilter) { do { if (found == false) activesample = constrain(activesample - 1, 0, NUM_DRUMSET_CONFIG - 2); for (uint8_t d = 0; d < 10; d++) { if (seq_content_type[d] == 0) { for (uint8_t y = 0; y < 16; y++) { if (drum_config[activesample].midinote == seq_data[d][y] || drum_config[activesample].midinote == seq_vel[d][y]) { found = true; break; } } } } } while (found == false && activesample > 0 ); } else activesample = constrain(activesample - 1, 0, NUM_DRUMSET_CONFIG - 2); } else //search forwards { if (smartfilter) { do { if (found == false) activesample = constrain(activesample + 1, 0, NUM_DRUMSET_CONFIG - 2); for (uint8_t d = 0; d < 10; d++) { if (seq_content_type[d] == 0) { for (uint8_t y = 0; y < 16; y++) { if (drum_config[activesample].midinote == seq_data[d][y] || drum_config[activesample].midinote == seq_vel[d][y]) { found = true; break; } } } } } while (found == false && activesample < NUM_DRUMSET_CONFIG - 2 ); } else activesample = constrain(activesample + 1, 0, NUM_DRUMSET_CONFIG - 2); } } void setup_ui(void) { // LCD Begin #ifdef I2C_DISPLAY lcd.init(); lcd.backlight(); lcd.clear(); lcd.noCursor(); #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 void toggle_sequencer_play_status() { if (seq_running == false && seq_recording == false) { handleStart(); } else if (seq_running == true && seq_recording == false) { handleStop(); } } /*********************************************************************** 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)) { 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 { encoderDir[ENC_R].ButtonPressed(true); 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 { encoderDir[ENC_R].ButtonPressed(false); 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]) >= LONG_BUTTON_PRESS) { #ifdef DEBUG Serial.println("ENC-R long released"); #endif //LCDML.BT_quit(); encoderDir[ENC_R].ButtonLong(true); } else if ((millis() - g_LCDML_CONTROL_button_press_time[ENC_R]) >= BUT_DEBOUNCE_MS) { #ifdef DEBUG Serial.println(F("ENC-R short")); #endif encoderDir[ENC_R].ButtonShort(true); LCDML.BT_enter(); } } } if (encoderDir[ENC_R].ButtonPressed() == true && (millis() - g_LCDML_CONTROL_button_press_time[ENC_R]) >= LONG_BUTTON_PRESS) { #ifdef DEBUG Serial.println("ENC-R long recognized"); #endif encoderDir[ENC_R].ButtonLong(true); // if (seq_running) { // seq_running = false; // seq_recording = false; // seq_step = 0; // seq_chain_active_step = 0; // MicroDexed[0]->panic(); // } if (LCDML.FUNC_getID() == LCDML.OTHER_getIDFromFunction(UI_func_voice_select)) { LCDML.BT_enter(); LCDML.OTHER_updateFunc(); LCDML.loop_menu(); encoderDir[ENC_R].ButtonPressed(false); encoderDir[ENC_R].ButtonLong(false); } else { if (LCDML.FUNC_getID() < 0xff) LCDML.FUNC_setGBAToLastFunc(); else LCDML.FUNC_setGBAToLastCursorPos(); LCDML.OTHER_jumpToFunc(UI_func_voice_select); encoderDir[ENC_R].reset(); } } // 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)) { 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)) { 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 { encoderDir[ENC_L].ButtonPressed(true); 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 { encoderDir[ENC_L].ButtonPressed(false); 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]) >= LONG_BUTTON_PRESS) { #ifdef DEBUG Serial.println(F("ENC-L long released")); #endif //encoderDir[ENC_L].ButtonLong(true); //LCDML.BT_quit(); } else if ((millis() - g_LCDML_CONTROL_button_press_time[ENC_L]) >= BUT_DEBOUNCE_MS) { //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 if (LCDML.FUNC_getID() == 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()); } else LCDML.BT_quit(); } } } if (encoderDir[ENC_L].ButtonPressed() == true && (millis() - g_LCDML_CONTROL_button_press_time[ENC_L]) >= LONG_BUTTON_PRESS) { #ifdef DEBUG Serial.println(F("ENC-L long recognized")); #endif // when in Voice select Menu, long left-press sets/unsets favorite if (LCDML.FUNC_getID() == LCDML.OTHER_getIDFromFunction(UI_func_voice_select)) save_favorite(configuration.performance.bank[selected_instance_id], configuration.performance.voice[selected_instance_id], selected_instance_id); // when not in Voice select Menu, long left-press starts/stops sequencer else if (LCDML.FUNC_getID() != LCDML.OTHER_getIDFromFunction(UI_func_voice_select)) toggle_sequencer_play_status(); //for (uint8_t i = 0; i < NUM_DEXED; i++) // MicroDexed[i]->panic(); encoderDir[ENC_L].reset(); encoderDir[ENC_R].reset(); } } /*********************************************************************** 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, 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); #ifdef USE_PLATEREVERB reverb.size(mapfloat(configuration.fx.reverb_roomsize, REVERB_ROOMSIZE_MIN, REVERB_ROOMSIZE_MAX, 0.0, 1.0)); #else freeverb.roomsize(mapfloat(configuration.fx.reverb_roomsize, REVERB_ROOMSIZE_MIN, REVERB_ROOMSIZE_MAX, 0.0, 1.0)); #endif } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } #if USE_PLATEREVERB != 1 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, 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); freeverb.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(); } } #else void UI_func_reverb_lowpass(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("Reverb Lowpass", configuration.fx.reverb_lowpass, 1.0, REVERB_LOWPASS_MIN, REVERB_LOWPASS_MAX, 3, 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_lowpass = constrain(configuration.fx.reverb_lowpass + ENCODER[ENC_R].speed(), REVERB_LOWPASS_MIN, REVERB_LOWPASS_MAX); else if (LCDML.BT_checkUp()) configuration.fx.reverb_lowpass = constrain(configuration.fx.reverb_lowpass - ENCODER[ENC_R].speed(), REVERB_LOWPASS_MIN, REVERB_LOWPASS_MAX); } lcd_display_bar_int("Reverb Lowpass", configuration.fx.reverb_lowpass, 1.0, REVERB_LOWPASS_MIN, REVERB_LOWPASS_MAX, 3, false, false, false); reverb.lowpass(mapfloat(configuration.fx.reverb_lowpass, REVERB_LOWPASS_MIN, REVERB_LOWPASS_MAX, 0.0, 1.0)); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_reverb_lodamp(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("Reverb Lodamp.", configuration.fx.reverb_lodamp, 1.0, REVERB_LODAMP_MIN, REVERB_LODAMP_MAX, 3, 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_lodamp = constrain(configuration.fx.reverb_lodamp + ENCODER[ENC_R].speed(), REVERB_LODAMP_MIN, REVERB_LODAMP_MAX); else if (LCDML.BT_checkUp()) configuration.fx.reverb_lodamp = constrain(configuration.fx.reverb_lodamp - ENCODER[ENC_R].speed(), REVERB_LODAMP_MIN, REVERB_LODAMP_MAX); } lcd_display_bar_int("Reverb Lodamp.", configuration.fx.reverb_lodamp, 1.0, REVERB_LODAMP_MIN, REVERB_LODAMP_MAX, 3, false, false, false); reverb.lodamp(mapfloat(configuration.fx.reverb_lodamp, REVERB_LODAMP_MIN, REVERB_LODAMP_MAX, 0.0, 1.0)); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_reverb_hidamp(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("Reverb Hidamp.", configuration.fx.reverb_hidamp, 1.0, REVERB_HIDAMP_MIN, REVERB_HIDAMP_MAX, 3, 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_hidamp = constrain(configuration.fx.reverb_hidamp + ENCODER[ENC_R].speed(), REVERB_HIDAMP_MIN, REVERB_HIDAMP_MAX); else if (LCDML.BT_checkUp()) configuration.fx.reverb_hidamp = constrain(configuration.fx.reverb_hidamp - ENCODER[ENC_R].speed(), REVERB_HIDAMP_MIN, REVERB_HIDAMP_MAX); } lcd_display_bar_int("Reverb Hidamp.", configuration.fx.reverb_hidamp, 1.0, REVERB_HIDAMP_MIN, REVERB_HIDAMP_MAX, 3, false, false, false); reverb.hidamp(mapfloat(configuration.fx.reverb_hidamp, REVERB_HIDAMP_MIN, REVERB_HIDAMP_MAX, 0.0, 1.0)); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_reverb_diffusion(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("Reverb Diff.", configuration.fx.reverb_diffusion, 1.0, REVERB_DIFFUSION_MIN, REVERB_DIFFUSION_MAX, 3, 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_diffusion = constrain(configuration.fx.reverb_diffusion + ENCODER[ENC_R].speed(), REVERB_DIFFUSION_MIN, REVERB_DIFFUSION_MAX); else if (LCDML.BT_checkUp()) configuration.fx.reverb_diffusion = constrain(configuration.fx.reverb_diffusion - ENCODER[ENC_R].speed(), REVERB_DIFFUSION_MIN, REVERB_DIFFUSION_MAX); } lcd_display_bar_int("Reverb Diff.", configuration.fx.reverb_diffusion, 1.0, REVERB_DIFFUSION_MIN, REVERB_DIFFUSION_MAX, 3, false, false, false); reverb.diffusion(mapfloat(configuration.fx.reverb_diffusion, REVERB_DIFFUSION_MIN, REVERB_DIFFUSION_MAX, 0.0, 1.0)); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } #endif // PLATEREVERB != 1 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, 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, true); //master_mixer_r.gain(3, pseudo_log_curve(mapfloat(configuration.fx.reverb_level, REVERB_LEVEL_MIN, REVERB_LEVEL_MAX, 0.0, 1.0))); //master_mixer_l.gain(3, pseudo_log_curve(mapfloat(configuration.fx.reverb_level, REVERB_LEVEL_MIN, REVERB_LEVEL_MAX, 0.0, 1.0))); master_mixer_r.gain(3, volume_transform(mapfloat(configuration.fx.reverb_level, REVERB_LEVEL_MIN, REVERB_LEVEL_MAX, 0.0, VOL_MAX_FLOAT))); master_mixer_l.gain(3, volume_transform(mapfloat(configuration.fx.reverb_level, REVERB_LEVEL_MIN, REVERB_LEVEL_MAX, 0.0, VOL_MAX_FLOAT))); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } 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[selected_instance_id], 0.1, CHORUS_FREQUENCY_MIN, CHORUS_FREQUENCY_MAX, 2, 1, false, false, true); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.fx.chorus_frequency[selected_instance_id] = constrain(configuration.fx.chorus_frequency[selected_instance_id] + ENCODER[ENC_R].speed(), CHORUS_FREQUENCY_MIN, CHORUS_FREQUENCY_MAX); else if (LCDML.BT_checkUp()) configuration.fx.chorus_frequency[selected_instance_id] = constrain(configuration.fx.chorus_frequency[selected_instance_id] - ENCODER[ENC_R].speed(), CHORUS_FREQUENCY_MIN, CHORUS_FREQUENCY_MAX); #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } lcd_display_bar_float("Chorus Frq.", configuration.fx.chorus_frequency[selected_instance_id], 0.1, CHORUS_FREQUENCY_MIN, CHORUS_FREQUENCY_MAX, 2, 1, false, false, false); chorus_modulator[selected_instance_id]->frequency(configuration.fx.chorus_frequency[selected_instance_id] / 10.0); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } 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 Wavefrm")); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) configuration.fx.chorus_waveform[selected_instance_id] = constrain(configuration.fx.chorus_waveform[selected_instance_id] + 1, CHORUS_WAVEFORM_MIN, CHORUS_WAVEFORM_MAX); else if (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()) configuration.fx.chorus_waveform[selected_instance_id] = constrain(configuration.fx.chorus_waveform[selected_instance_id] - 1, CHORUS_WAVEFORM_MIN, CHORUS_WAVEFORM_MAX); #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif lcd.setCursor(0, 1); switch (configuration.fx.chorus_waveform[selected_instance_id]) { case 0: chorus_modulator[selected_instance_id]->begin(WAVEFORM_TRIANGLE); lcd.print(F("[TRIANGLE]")); break; case 1: chorus_modulator[selected_instance_id]->begin(WAVEFORM_SINE); lcd.print(F("[SINE ]")); break; default: chorus_modulator[selected_instance_id]->begin(WAVEFORM_TRIANGLE); lcd.print(F("[TRIANGLE]")); break; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } 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[selected_instance_id], 1.0, CHORUS_DEPTH_MIN, CHORUS_DEPTH_MAX, 3, false, false, true); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.fx.chorus_depth[selected_instance_id] = constrain(configuration.fx.chorus_depth[selected_instance_id] + ENCODER[ENC_R].speed(), CHORUS_DEPTH_MIN, CHORUS_DEPTH_MAX); else if (LCDML.BT_checkUp()) configuration.fx.chorus_depth[selected_instance_id] = constrain(configuration.fx.chorus_depth[selected_instance_id] - ENCODER[ENC_R].speed(), CHORUS_DEPTH_MIN, CHORUS_DEPTH_MAX); #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } lcd_display_bar_int("Chorus Dpt.", configuration.fx.chorus_depth[selected_instance_id], 1.0, CHORUS_DEPTH_MIN, CHORUS_DEPTH_MAX, 3, false, false, false); chorus_modulator[selected_instance_id]->amplitude(configuration.fx.chorus_depth[selected_instance_id] / 100.0); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } 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[selected_instance_id], 1.0, CHORUS_LEVEL_MIN, CHORUS_LEVEL_MAX, 3, false, false, true); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.fx.chorus_level[selected_instance_id] = constrain(configuration.fx.chorus_level[selected_instance_id] + ENCODER[ENC_R].speed(), CHORUS_LEVEL_MIN, CHORUS_LEVEL_MAX); MD_sendControlChange(configuration.dexed[selected_instance_id].midi_channel, 93, configuration.fx.chorus_level[selected_instance_id]); } else if (LCDML.BT_checkUp()) { configuration.fx.chorus_level[selected_instance_id] = constrain(configuration.fx.chorus_level[selected_instance_id] - ENCODER[ENC_R].speed(), CHORUS_LEVEL_MIN, CHORUS_LEVEL_MAX); MD_sendControlChange(configuration.dexed[selected_instance_id].midi_channel, 93, configuration.fx.chorus_level[selected_instance_id]); } #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } lcd_display_bar_int("Chorus Lvl.", configuration.fx.chorus_level[selected_instance_id], 1.0, CHORUS_LEVEL_MIN, CHORUS_LEVEL_MAX, 3, false, false, false); //chorus_mixer[selected_instance_id]->gain(0, pseudo_log_curve(1.0 - mapfloat(configuration.fx.chorus_level[selected_instance_id], CHORUS_LEVEL_MIN, CHORUS_LEVEL_MAX, 0.0, 0.5))); //chorus_mixer[selected_instance_id]->gain(1, pseudo_log_curve(mapfloat(configuration.fx.chorus_level[selected_instance_id], CHORUS_LEVEL_MIN, CHORUS_LEVEL_MAX, 0.0, 0.5))); //chorus_mixer[selected_instance_id]->gain(0, 1.0 - mapfloat(configuration.fx.chorus_level[selected_instance_id], CHORUS_LEVEL_MIN, CHORUS_LEVEL_MAX, 0.0, 0.5)); chorus_mixer[selected_instance_id]->gain(1, mapfloat(configuration.fx.chorus_level[selected_instance_id], CHORUS_LEVEL_MIN, CHORUS_LEVEL_MAX, 0.0, 0.5)); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_delay_time(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); if (configuration.fx.delay_sync[selected_instance_id] > 0) { lcd_display_delay_sync(configuration.fx.delay_sync[selected_instance_id]); //goto MIDI Sync } else { #if DELAY_TIME_MAX >= 100 lcd_display_bar_int("Delay Time", configuration.fx.delay_time[selected_instance_id], 10.0, DELAY_TIME_MIN, DELAY_TIME_MAX, 4, false, false, true); #else lcd_display_bar_int("Delay Time", configuration.fx.delay_time[selected_instance_id], 10.0, DELAY_TIME_MIN, DELAY_TIME_MAX, 3, false, false, true); #endif } lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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 (configuration.fx.delay_time[selected_instance_id] == DELAY_TIME_MIN && configuration.fx.delay_sync[selected_instance_id] > DELAY_SYNC_MIN) { // MIDI-sync delay configuration.fx.delay_sync[selected_instance_id] = constrain(configuration.fx.delay_sync[selected_instance_id] - 1, DELAY_SYNC_MIN, DELAY_SYNC_MAX); } else { configuration.fx.delay_time[selected_instance_id] = constrain(configuration.fx.delay_time[selected_instance_id] + ENCODER[ENC_R].speed(), DELAY_TIME_MIN, DELAY_TIME_MAX); MD_sendControlChange(configuration.dexed[selected_instance_id].midi_channel, 105, configuration.fx.delay_time[selected_instance_id]); } } else if (LCDML.BT_checkUp()) { if (configuration.fx.delay_time[selected_instance_id] == DELAY_TIME_MIN && configuration.fx.delay_sync[selected_instance_id] > DELAY_SYNC_MIN) { // MIDI-sync delay configuration.fx.delay_sync[selected_instance_id] = constrain(configuration.fx.delay_sync[selected_instance_id] + 1, DELAY_SYNC_MIN, DELAY_SYNC_MAX); } else { if (configuration.fx.delay_time[selected_instance_id] == DELAY_TIME_MIN) configuration.fx.delay_sync[selected_instance_id] = DELAY_SYNC_MIN + 1; else { configuration.fx.delay_time[selected_instance_id] = constrain(configuration.fx.delay_time[selected_instance_id] - ENCODER[ENC_R].speed(), DELAY_TIME_MIN, DELAY_TIME_MAX); MD_sendControlChange(configuration.dexed[selected_instance_id].midi_channel, 105, configuration.fx.delay_time[selected_instance_id]); } } } #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } if (configuration.fx.delay_sync[selected_instance_id] > 0) { lcd_display_delay_sync(configuration.fx.delay_sync[selected_instance_id]);//MIDI Sync Delay } else { #if DELAY_TIME_MAX >= 100 lcd_display_bar_int("Delay Time", configuration.fx.delay_time[selected_instance_id], 10.0, DELAY_TIME_MIN, DELAY_TIME_MAX, 4, false, false, true); #else lcd_display_bar_int("Delay Time", configuration.fx.delay_time[selected_instance_id], 10.0, DELAY_TIME_MIN, DELAY_TIME_MAX, 3, false, false, true); #endif if (configuration.fx.delay_time[selected_instance_id] <= DELAY_TIME_MIN) delay_fx[selected_instance_id]->disable(0); else delay_fx[selected_instance_id]->delay(0, constrain(configuration.fx.delay_time[selected_instance_id], DELAY_TIME_MIN, DELAY_TIME_MAX) * 10); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } 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[selected_instance_id], 1.0, DELAY_FEEDBACK_MIN, DELAY_FEEDBACK_MAX, 3, false, false, true); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.fx.delay_feedback[selected_instance_id] = constrain(configuration.fx.delay_feedback[selected_instance_id] + ENCODER[ENC_R].speed(), DELAY_FEEDBACK_MIN, DELAY_FEEDBACK_MAX); MD_sendControlChange(configuration.dexed[selected_instance_id].midi_channel, 106, configuration.fx.delay_feedback[selected_instance_id]); } else if (LCDML.BT_checkUp()) { configuration.fx.delay_feedback[selected_instance_id] = constrain(configuration.fx.delay_feedback[selected_instance_id] - ENCODER[ENC_R].speed(), DELAY_FEEDBACK_MIN, DELAY_FEEDBACK_MAX); MD_sendControlChange(configuration.dexed[selected_instance_id].midi_channel, 106, configuration.fx.delay_feedback[selected_instance_id]); } #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } lcd_display_bar_int("Delay Feedb.", configuration.fx.delay_feedback[selected_instance_id], 1.0, DELAY_FEEDBACK_MIN, DELAY_FEEDBACK_MAX, 3, false, false, false); delay_fb_mixer[selected_instance_id]->gain(1, midi_volume_transform(map(configuration.fx.delay_feedback[selected_instance_id], DELAY_FEEDBACK_MIN, DELAY_FEEDBACK_MAX, 0, 127))); // amount of feedback } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } 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[selected_instance_id], 1.0, DELAY_LEVEL_MIN, DELAY_LEVEL_MAX, 3, false, false, true); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.fx.delay_level[selected_instance_id] = constrain(configuration.fx.delay_level[selected_instance_id] + ENCODER[ENC_R].speed(), DELAY_LEVEL_MIN, DELAY_LEVEL_MAX); MD_sendControlChange(configuration.dexed[selected_instance_id].midi_channel, 107, configuration.fx.delay_level[selected_instance_id]); } else if (LCDML.BT_checkUp()) { configuration.fx.delay_level[selected_instance_id] = constrain(configuration.fx.delay_level[selected_instance_id] - ENCODER[ENC_R].speed(), DELAY_LEVEL_MIN, DELAY_LEVEL_MAX); MD_sendControlChange(configuration.dexed[selected_instance_id].midi_channel, 107, configuration.fx.delay_level[selected_instance_id]); } #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } lcd_display_bar_int("Delay Lvl.", configuration.fx.delay_level[selected_instance_id], 1.0, DELAY_LEVEL_MIN, DELAY_LEVEL_MAX, 3, false, false, false); delay_mixer[selected_instance_id]->gain(1, midi_volume_transform(map(configuration.fx.delay_level[selected_instance_id], DELAY_LEVEL_MIN, DELAY_LEVEL_MAX, 0, 127))); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_reverb_send(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("Reverb Send", configuration.fx.reverb_send[selected_instance_id], 1.0, REVERB_SEND_MIN, REVERB_SEND_MAX, 3, false, false, true); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.fx.reverb_send[selected_instance_id] = constrain(configuration.fx.reverb_send[selected_instance_id] + ENCODER[ENC_R].speed(), REVERB_SEND_MIN, REVERB_SEND_MAX); MD_sendControlChange(configuration.dexed[selected_instance_id].midi_channel, 91, configuration.fx.reverb_send[selected_instance_id]); } else if (LCDML.BT_checkUp()) { configuration.fx.reverb_send[selected_instance_id] = constrain(configuration.fx.reverb_send[selected_instance_id] - ENCODER[ENC_R].speed(), REVERB_SEND_MIN, REVERB_SEND_MAX); MD_sendControlChange(configuration.dexed[selected_instance_id].midi_channel, 91, configuration.fx.reverb_send[selected_instance_id]); } #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } lcd_display_bar_int("Reverb Send", configuration.fx.reverb_send[selected_instance_id], 1.0, REVERB_SEND_MIN, REVERB_SEND_MAX, 3, false, false, false); reverb_mixer_r.gain(selected_instance_id, volume_transform(mapfloat(configuration.fx.reverb_send[selected_instance_id], REVERB_SEND_MIN, REVERB_SEND_MAX, 0.0, VOL_MAX_FLOAT))); reverb_mixer_l.gain(selected_instance_id, volume_transform(mapfloat(configuration.fx.reverb_send[selected_instance_id], REVERB_SEND_MIN, REVERB_SEND_MAX, 0.0, VOL_MAX_FLOAT))); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_filter_cutoff(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("Filter Cutoff", configuration.fx.filter_cutoff[selected_instance_id], 1.0, FILTER_CUTOFF_MIN, FILTER_CUTOFF_MAX, 3, false, false, true); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.fx.filter_cutoff[selected_instance_id] = constrain(configuration.fx.filter_cutoff[selected_instance_id] + ENCODER[ENC_R].speed(), FILTER_CUTOFF_MIN, FILTER_CUTOFF_MAX); MD_sendControlChange(configuration.dexed[selected_instance_id].midi_channel, 104, configuration.fx.filter_cutoff[selected_instance_id]); } else if (LCDML.BT_checkUp()) { configuration.fx.filter_cutoff[selected_instance_id] = constrain(configuration.fx.filter_cutoff[selected_instance_id] - ENCODER[ENC_R].speed(), FILTER_CUTOFF_MIN, FILTER_CUTOFF_MAX); MD_sendControlChange(configuration.dexed[selected_instance_id].midi_channel, 104, configuration.fx.filter_cutoff[selected_instance_id]); } #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } lcd_display_bar_int("Filter Cutoff", configuration.fx.filter_cutoff[selected_instance_id], 1.0, FILTER_CUTOFF_MIN, FILTER_CUTOFF_MAX, 3, false, false, false); MicroDexed[selected_instance_id]->setFilterCutoff(mapfloat(configuration.fx.filter_cutoff[selected_instance_id], FILTER_CUTOFF_MIN, FILTER_CUTOFF_MAX, 1.0, 0.0)); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_filter_resonance(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("Filter Reso.", configuration.fx.filter_resonance[selected_instance_id], 1.0, FILTER_RESONANCE_MIN, FILTER_RESONANCE_MAX, 3, false, false, true); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.fx.filter_resonance[selected_instance_id] = constrain(configuration.fx.filter_resonance[selected_instance_id] + ENCODER[ENC_R].speed(), FILTER_RESONANCE_MIN, FILTER_RESONANCE_MAX); MD_sendControlChange(configuration.dexed[selected_instance_id].midi_channel, 103, configuration.fx.filter_resonance[selected_instance_id]); } else if (LCDML.BT_checkUp()) { configuration.fx.filter_resonance[selected_instance_id] = constrain(configuration.fx.filter_resonance[selected_instance_id] - ENCODER[ENC_R].speed(), FILTER_RESONANCE_MIN, FILTER_RESONANCE_MAX); MD_sendControlChange(configuration.dexed[selected_instance_id].midi_channel, 103, configuration.fx.filter_resonance[selected_instance_id]); } #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } lcd_display_bar_int("Filter Reso.", configuration.fx.filter_resonance[selected_instance_id], 1.0, FILTER_RESONANCE_MIN, FILTER_RESONANCE_MAX, 3, false, false, false); MicroDexed[selected_instance_id]->setFilterResonance(mapfloat(configuration.fx.filter_resonance[selected_instance_id], FILTER_RESONANCE_MIN, FILTER_RESONANCE_MAX, 1.0, 0.0)); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } #endif void UI_func_transpose(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(METERBAR); lcd_display_meter_int("Transpose", configuration.dexed[selected_instance_id].transpose, 1.0, -24.0, TRANSPOSE_MIN, TRANSPOSE_MAX, 2, false, true, true); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.dexed[selected_instance_id].transpose = constrain(configuration.dexed[selected_instance_id].transpose + ENCODER[ENC_R].speed(), TRANSPOSE_MIN, TRANSPOSE_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[selected_instance_id].transpose = constrain(configuration.dexed[selected_instance_id].transpose - ENCODER[ENC_R].speed(), TRANSPOSE_MIN, TRANSPOSE_MAX); #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } lcd_display_meter_int("Transpose", configuration.dexed[selected_instance_id].transpose, 1.0, -24.0, TRANSPOSE_MIN, TRANSPOSE_MAX, 2, false, true, true); MicroDexed[selected_instance_id]->setTranspose(configuration.dexed[selected_instance_id].transpose); MicroDexed[selected_instance_id]->notesOff(); send_sysex_param(configuration.dexed[selected_instance_id].midi_channel, 144, configuration.dexed[selected_instance_id].transpose, 0); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_tune(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(METERBAR); lcd_display_meter_int("Fine Tune", configuration.dexed[selected_instance_id].tune, 1.0, -100.0, TUNE_MIN, TUNE_MAX, 3, false, true, true); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.dexed[selected_instance_id].tune = constrain(configuration.dexed[selected_instance_id].tune + ENCODER[ENC_R].speed(), TUNE_MIN, TUNE_MAX); MD_sendControlChange(configuration.dexed[selected_instance_id].midi_channel, 94, configuration.dexed[selected_instance_id].tune); } else if (LCDML.BT_checkUp()) { configuration.dexed[selected_instance_id].tune = constrain(configuration.dexed[selected_instance_id].tune - ENCODER[ENC_R].speed(), TUNE_MIN, TUNE_MAX); MD_sendControlChange(configuration.dexed[selected_instance_id].midi_channel, 94, configuration.dexed[selected_instance_id].tune); } #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } lcd_display_meter_int("Fine Tune", configuration.dexed[selected_instance_id].tune, 1.0, -100.0, TUNE_MIN, TUNE_MAX, 3, false, true, false); MicroDexed[selected_instance_id]->setMasterTune((int((configuration.dexed[selected_instance_id].tune - 100) / 100.0 * 0x4000) << 11) * (1.0 / 12)); MicroDexed[selected_instance_id]->doRefreshVoice(); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_midi_channel(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("MIDI Channel")); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) configuration.dexed[selected_instance_id].midi_channel = constrain(configuration.dexed[selected_instance_id].midi_channel + ENCODER[ENC_R].speed(), MIDI_CHANNEL_MIN, MIDI_CHANNEL_MAX); else if (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()) configuration.dexed[selected_instance_id].midi_channel = constrain(configuration.dexed[selected_instance_id].midi_channel - ENCODER[ENC_R].speed(), MIDI_CHANNEL_MIN, MIDI_CHANNEL_MAX); #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif lcd.setCursor(0, 1); if (configuration.dexed[selected_instance_id].midi_channel == 0) { lcd.print(F("[OMNI]")); } else { lcd_display_int(configuration.dexed[selected_instance_id].midi_channel, 4, false, true, false); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } 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) { char note_name[4]; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); getNoteName(note_name, configuration.dexed[selected_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("]")); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.dexed[selected_instance_id].lowest_note = constrain(configuration.dexed[selected_instance_id].lowest_note + ENCODER[ENC_R].speed(), INSTANCE_LOWEST_NOTE_MIN, INSTANCE_LOWEST_NOTE_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[selected_instance_id].lowest_note = constrain(configuration.dexed[selected_instance_id].lowest_note - ENCODER[ENC_R].speed(), INSTANCE_LOWEST_NOTE_MIN, INSTANCE_LOWEST_NOTE_MAX); #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } getNoteName(note_name, configuration.dexed[selected_instance_id].lowest_note); lcd.setCursor(1, 1); lcd.print(note_name); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_highest_note(uint8_t param) { char note_name[4]; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); getNoteName(note_name, configuration.dexed[selected_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("]")); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.dexed[selected_instance_id].highest_note = constrain(configuration.dexed[selected_instance_id].highest_note + ENCODER[ENC_R].speed(), INSTANCE_HIGHEST_NOTE_MIN, INSTANCE_HIGHEST_NOTE_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[selected_instance_id].highest_note = constrain(configuration.dexed[selected_instance_id].highest_note - ENCODER[ENC_R].speed(), INSTANCE_HIGHEST_NOTE_MIN, INSTANCE_HIGHEST_NOTE_MAX); #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } getNoteName(note_name, configuration.dexed[selected_instance_id].highest_note); lcd.setCursor(1, 1); lcd.print(note_name); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_sound_intensity(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("Voice Level", configuration.dexed[selected_instance_id].sound_intensity, 1.0, SOUND_INTENSITY_MIN, SOUND_INTENSITY_MAX, 3, false, false, true); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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())) { encoderDir[ENC_R].reset(); if (LCDML.BT_checkDown()) { configuration.dexed[selected_instance_id].sound_intensity = constrain(configuration.dexed[selected_instance_id].sound_intensity + ENCODER[ENC_R].speed(), SOUND_INTENSITY_MIN, SOUND_INTENSITY_MAX); MD_sendControlChange(configuration.dexed[selected_instance_id].midi_channel, 7, configuration.dexed[selected_instance_id].sound_intensity); } else if (LCDML.BT_checkUp()) { configuration.dexed[selected_instance_id].sound_intensity = constrain(configuration.dexed[selected_instance_id].sound_intensity - ENCODER[ENC_R].speed(), SOUND_INTENSITY_MIN, SOUND_INTENSITY_MAX); MD_sendControlChange(configuration.dexed[selected_instance_id].midi_channel, 7, configuration.dexed[selected_instance_id].sound_intensity); } #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } lcd_display_bar_int("Voice Level", configuration.dexed[selected_instance_id].sound_intensity, 1.0, SOUND_INTENSITY_MIN, SOUND_INTENSITY_MAX, 3, false, false, false); MicroDexed[selected_instance_id]->setGain(midi_volume_transform(map(configuration.dexed[selected_instance_id].sound_intensity, SOUND_INTENSITY_MIN, SOUND_INTENSITY_MAX, 0, 127))); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_panorama(uint8_t param) { 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[selected_instance_id].pan, 0.05, -20.0, PANORAMA_MIN, PANORAMA_MAX, 1, 1, false, true, true); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkDown() && encoderDir[ENC_R].Down() && configuration.sys.mono == 0) { configuration.dexed[selected_instance_id].pan = constrain(configuration.dexed[selected_instance_id].pan + ENCODER[ENC_R].speed(), PANORAMA_MIN, PANORAMA_MAX); MD_sendControlChange(configuration.dexed[selected_instance_id].midi_channel, 10, map(configuration.dexed[selected_instance_id].pan, PANORAMA_MIN, PANORAMA_MAX, 0, 127)); } else if (LCDML.BT_checkUp() && encoderDir[ENC_R].Up() && configuration.sys.mono == 0) { configuration.dexed[selected_instance_id].pan = constrain(configuration.dexed[selected_instance_id].pan - ENCODER[ENC_R].speed(), PANORAMA_MIN, PANORAMA_MAX); MD_sendControlChange(configuration.dexed[selected_instance_id].midi_channel, 10, map(configuration.dexed[selected_instance_id].pan, PANORAMA_MIN, PANORAMA_MAX, 0, 127)); } #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif if (configuration.sys.mono == 0) { lcd_display_meter_float("Panorama", configuration.dexed[selected_instance_id].pan, 0.05, -20.0, PANORAMA_MIN, PANORAMA_MAX, 1, 1, false, true, false); mono2stereo[selected_instance_id]->panorama(mapfloat(configuration.dexed[selected_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(); } } void UI_func_favorites(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_L].reset(); lcd.setCursor(0, 0); lcd.print(F("Favorites")); lcd.setCursor(0, 1); switch (configuration.sys.favorites) { case 0: lcd.print(F("[ All presets ]")); break; case 1: lcd.print(F("[ FAVs. only ]")); break; case 2: lcd.print(F("[non-FAVs. only]")); break; case 3: lcd.print(F("[random non-FAV]")); break; } } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkDown()) configuration.sys.favorites = constrain(configuration.sys.favorites + 1, 0, 3); else if (LCDML.BT_checkUp()) configuration.sys.favorites = constrain(configuration.sys.favorites - 1, 0, 3); lcd.setCursor(0, 1); switch (configuration.sys.favorites) { case 0: lcd.print(F("[ All presets ]")); break; case 1: lcd.print(F("[ FAVs. only ]")); break; case 2: lcd.print(F("[non-FAVs. only]")); break; case 3: lcd.print(F("[random non-FAV]")); break; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* encoderDir[ENC_L].reset(); } 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(); } void UI_func_polyphony(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); #if NUM_DEXED>1 lcd_display_bar_int("Polyphony", configuration.dexed[selected_instance_id].polyphony, 1.0, POLYPHONY_MIN, POLYPHONY_MAX - configuration.dexed[(selected_instance_id + 1) % NUM_DEXED].polyphony, 2, false, false, true); #else lcd_display_bar_int("Polyphony", configuration.dexed[selected_instance_id].polyphony, 1.0, POLYPHONY_MIN, POLYPHONY_MAX, 2, false, false, true); #endif lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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 NUM_DEXED>1 if (configuration.dexed[selected_instance_id].polyphony < POLYPHONY_MAX - configuration.dexed[(selected_instance_id + 1) % NUM_DEXED].polyphony) configuration.dexed[selected_instance_id].polyphony = constrain(configuration.dexed[selected_instance_id].polyphony + 1, POLYPHONY_MIN, POLYPHONY_MAX - configuration.dexed[(selected_instance_id + 1) % NUM_DEXED].polyphony); #else configuration.dexed[selected_instance_id].polyphony = constrain(configuration.dexed[selected_instance_id].polyphony + 1, POLYPHONY_MIN, POLYPHONY_MAX); #endif } else if (LCDML.BT_checkUp()) { if (configuration.dexed[selected_instance_id].polyphony - 1 < 0) configuration.dexed[selected_instance_id].polyphony = 0; else { #if NUM_DEXED>1 configuration.dexed[selected_instance_id].polyphony = constrain(configuration.dexed[selected_instance_id].polyphony - 1, POLYPHONY_MIN, POLYPHONY_MAX - configuration.dexed[(selected_instance_id + 1) % NUM_DEXED].polyphony); #else configuration.dexed[selected_instance_id].polyphony = constrain(configuration.dexed[selected_instance_id].polyphony - 1, POLYPHONY_MIN, POLYPHONY_MAX); #endif } } #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } lcd_active_instance_number(selected_instance_id); #endif } #if NUM_DEXED>1 lcd_display_bar_int("Polyphony", configuration.dexed[selected_instance_id].polyphony, 1.0, POLYPHONY_MIN, POLYPHONY_MAX - configuration.dexed[(selected_instance_id + 1) % NUM_DEXED].polyphony, 2, false, false, false); #else lcd_display_bar_int("Polyphony", configuration.dexed[selected_instance_id].polyphony, 1.0, POLYPHONY_MIN, POLYPHONY_MAX, 2, false, false, false); #endif MicroDexed[selected_instance_id]->setMaxNotes(configuration.dexed[selected_instance_id].polyphony); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_mono_poly(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("Mono/Poly")); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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[selected_instance_id].monopoly = constrain(configuration.dexed[selected_instance_id].monopoly + 1, MONOPOLY_MIN, MONOPOLY_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[selected_instance_id].monopoly = constrain(configuration.dexed[selected_instance_id].monopoly - 1, MONOPOLY_MIN, MONOPOLY_MAX); MicroDexed[selected_instance_id]->setMonoMode(!configuration.dexed[selected_instance_id].monopoly); configuration.dexed[selected_instance_id].monopoly = MicroDexed[selected_instance_id]->getMonoMode(); } #if NUM_DEXED > 1 if (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } lcd_active_instance_number(selected_instance_id); #endif } lcd.setCursor(0, 1); switch (configuration.dexed[selected_instance_id].monopoly) { case 1: lcd.print(F("[MONOPHONIC]")); break; case 0: lcd.print(F("[POLYPHONIC]")); break; } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_note_refresh(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("Note Refresh")); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.dexed[selected_instance_id].note_refresh = constrain(configuration.dexed[selected_instance_id].note_refresh + 1, NOTE_REFRESH_MIN, NOTE_REFRESH_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[selected_instance_id].note_refresh = constrain(configuration.dexed[selected_instance_id].note_refresh - 1, NOTE_REFRESH_MIN, NOTE_REFRESH_MAX); #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } MicroDexed[selected_instance_id]->setRefreshMode(configuration.dexed[selected_instance_id].note_refresh); lcd.setCursor(0, 1); switch (configuration.dexed[selected_instance_id].note_refresh) { case 0: lcd.print(F("[NORMAL ]")); break; case 1: lcd.print(F("[RETRIGGERED]")); break; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_pb_range(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("PB Range", configuration.dexed[selected_instance_id].pb_range, 1.0, PB_RANGE_MIN, PB_RANGE_MAX, 2, false, false, true); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.dexed[selected_instance_id].pb_range = constrain(configuration.dexed[selected_instance_id].pb_range + ENCODER[ENC_R].speed(), PB_RANGE_MIN, PB_RANGE_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[selected_instance_id].pb_range = constrain(configuration.dexed[selected_instance_id].pb_range - ENCODER[ENC_R].speed(), PB_RANGE_MIN, PB_RANGE_MAX); #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } lcd_display_bar_int("PB Range", configuration.dexed[selected_instance_id].pb_range, 1.0, PB_RANGE_MIN, PB_RANGE_MAX, 2, false, false, false); MicroDexed[selected_instance_id]->setPBController(configuration.dexed[selected_instance_id].pb_range, configuration.dexed[selected_instance_id].pb_step); send_sysex_param(configuration.dexed[selected_instance_id].midi_channel, 65, configuration.dexed[selected_instance_id].pb_range, 2); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_pb_step(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("PB Step", configuration.dexed[selected_instance_id].pb_step, 1.0, PB_STEP_MIN, PB_STEP_MAX, 2, false, false, true); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.dexed[selected_instance_id].pb_step = constrain(configuration.dexed[selected_instance_id].pb_step + ENCODER[ENC_R].speed(), PB_STEP_MIN, PB_STEP_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[selected_instance_id].pb_step = constrain(configuration.dexed[selected_instance_id].pb_step - ENCODER[ENC_R].speed(), PB_STEP_MIN, PB_STEP_MAX); #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } lcd_display_bar_int("PB Step", configuration.dexed[selected_instance_id].pb_step, 1.0, PB_STEP_MIN, PB_STEP_MAX, 2, false, false, false); MicroDexed[selected_instance_id]->setPBController(configuration.dexed[selected_instance_id].pb_range, configuration.dexed[selected_instance_id].pb_step); send_sysex_param(configuration.dexed[selected_instance_id].midi_channel, 66, configuration.dexed[selected_instance_id].pb_step, 2); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_mw_range(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("MW Range", configuration.dexed[selected_instance_id].mw_range, 1.0, MW_RANGE_MIN, MW_RANGE_MAX, 2, false, false, true); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.dexed[selected_instance_id].mw_range = constrain(configuration.dexed[selected_instance_id].mw_range + ENCODER[ENC_R].speed(), MW_RANGE_MIN, MW_RANGE_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[selected_instance_id].mw_range = constrain(configuration.dexed[selected_instance_id].mw_range - ENCODER[ENC_R].speed(), MW_RANGE_MIN, MW_RANGE_MAX); #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } lcd_display_bar_int("MW Range", configuration.dexed[selected_instance_id].mw_range, 1.0, MW_RANGE_MIN, MW_RANGE_MAX, 2, false, false, false); MicroDexed[selected_instance_id]->setMWController(configuration.dexed[selected_instance_id].mw_range, configuration.dexed[selected_instance_id].mw_assign, configuration.dexed[selected_instance_id].mw_mode); send_sysex_param(configuration.dexed[selected_instance_id].midi_channel, 70, configuration.dexed[selected_instance_id].mw_range, 2); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_mw_assign(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("MW Assign")); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.dexed[selected_instance_id].mw_assign = constrain(configuration.dexed[selected_instance_id].mw_assign + 1, MW_ASSIGN_MIN, MW_ASSIGN_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[selected_instance_id].mw_assign = constrain(configuration.dexed[selected_instance_id].mw_assign - 1, MW_ASSIGN_MIN, MW_ASSIGN_MAX); #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } MicroDexed[selected_instance_id]->setMWController(configuration.dexed[selected_instance_id].mw_range, configuration.dexed[selected_instance_id].mw_assign, configuration.dexed[selected_instance_id].mw_mode); send_sysex_param(configuration.dexed[selected_instance_id].midi_channel, 71, configuration.dexed[selected_instance_id].mw_assign, 2); lcd.setCursor(0, 1); switch (configuration.dexed[selected_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]")); break; case 5: lcd.print(F("[PTCH EG]")); break; case 6: lcd.print(F("[ AMP EG]")); break; case 7: lcd.print(F("[PTCH AMP EG]")); break; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_mw_mode(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("MW Mode")); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.dexed[selected_instance_id].mw_mode = constrain(configuration.dexed[selected_instance_id].mw_mode + 1, MW_MODE_MIN, MW_MODE_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[selected_instance_id].mw_mode = constrain(configuration.dexed[selected_instance_id].mw_mode - 1, MW_MODE_MIN, MW_MODE_MAX); #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } MicroDexed[selected_instance_id]->setMWController(configuration.dexed[selected_instance_id].mw_range, configuration.dexed[selected_instance_id].mw_assign, configuration.dexed[selected_instance_id].mw_mode); MicroDexed[selected_instance_id]->ControllersRefresh(); lcd.setCursor(0, 1); switch (configuration.dexed[selected_instance_id].mw_mode) { case 0: lcd.print(F("[LINEAR ]")); break; case 1: lcd.print(F("[REVERSE LIN.]")); break; case 2: lcd.print(F("[DIRECT ]")); break; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_fc_range(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("FC Range", configuration.dexed[selected_instance_id].fc_range, 1.0, FC_RANGE_MIN, FC_RANGE_MAX, 2, false, false, true); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.dexed[selected_instance_id].fc_range = constrain(configuration.dexed[selected_instance_id].fc_range + ENCODER[ENC_R].speed(), FC_RANGE_MIN, FC_RANGE_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[selected_instance_id].fc_range = constrain(configuration.dexed[selected_instance_id].fc_range - ENCODER[ENC_R].speed(), FC_RANGE_MIN, FC_RANGE_MAX); #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } lcd_display_bar_int("FC Range", configuration.dexed[selected_instance_id].fc_range, 1.0, FC_RANGE_MIN, FC_RANGE_MAX, 2, false, false, false); MicroDexed[selected_instance_id]->setFCController(configuration.dexed[selected_instance_id].fc_range, configuration.dexed[selected_instance_id].fc_assign, configuration.dexed[selected_instance_id].fc_mode); send_sysex_param(configuration.dexed[selected_instance_id].midi_channel, 72, configuration.dexed[selected_instance_id].fc_range, 2); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_fc_assign(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("FC Assign")); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.dexed[selected_instance_id].fc_assign = constrain(configuration.dexed[selected_instance_id].fc_assign + 1, FC_ASSIGN_MIN, FC_ASSIGN_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[selected_instance_id].fc_assign = constrain(configuration.dexed[selected_instance_id].fc_assign - 1, FC_ASSIGN_MIN, FC_ASSIGN_MAX); #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } MicroDexed[selected_instance_id]->setFCController(configuration.dexed[selected_instance_id].fc_range, configuration.dexed[selected_instance_id].fc_assign, configuration.dexed[selected_instance_id].fc_mode); send_sysex_param(configuration.dexed[selected_instance_id].midi_channel, 73, configuration.dexed[selected_instance_id].fc_assign, 2); lcd.setCursor(0, 1); switch (configuration.dexed[selected_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]")); break; case 5: lcd.print(F("[PTCH EG]")); break; case 6: lcd.print(F("[ AMP EG]")); break; case 7: lcd.print(F("[PTCH AMP EG]")); break; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_fc_mode(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("FC Mode")); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.dexed[selected_instance_id].fc_mode = constrain(configuration.dexed[selected_instance_id].fc_mode + 1, FC_MODE_MIN, FC_MODE_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[selected_instance_id].fc_mode = constrain(configuration.dexed[selected_instance_id].fc_mode - 1, FC_MODE_MIN, FC_MODE_MAX); #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } MicroDexed[selected_instance_id]->setFCController(configuration.dexed[selected_instance_id].fc_range, configuration.dexed[selected_instance_id].fc_assign, configuration.dexed[selected_instance_id].fc_mode); MicroDexed[selected_instance_id]->ControllersRefresh(); lcd.setCursor(0, 1); switch (configuration.dexed[selected_instance_id].fc_mode) { case 0: lcd.print(F("[LINEAR ]")); break; case 1: lcd.print(F("[REVERSE LIN.]")); break; case 2: lcd.print(F("[DIRECT ]")); break; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_bc_range(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("BC Range", configuration.dexed[selected_instance_id].bc_range, 1.0, BC_RANGE_MIN, BC_RANGE_MAX, 2, false, false, true); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.dexed[selected_instance_id].bc_range = constrain(configuration.dexed[selected_instance_id].bc_range + ENCODER[ENC_R].speed(), BC_RANGE_MIN, BC_RANGE_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[selected_instance_id].bc_range = constrain(configuration.dexed[selected_instance_id].bc_range - ENCODER[ENC_R].speed(), BC_RANGE_MIN, BC_RANGE_MAX); #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } lcd_display_bar_int("BC Range", configuration.dexed[selected_instance_id].bc_range, 1.0, BC_RANGE_MIN, BC_RANGE_MAX, 2, false, false, false); MicroDexed[selected_instance_id]->setBCController(configuration.dexed[selected_instance_id].bc_range, configuration.dexed[selected_instance_id].bc_assign, configuration.dexed[selected_instance_id].bc_mode); send_sysex_param(configuration.dexed[selected_instance_id].midi_channel, 74, configuration.dexed[selected_instance_id].bc_range, 2); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_bc_assign(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("BC Assign")); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.dexed[selected_instance_id].bc_assign = constrain(configuration.dexed[selected_instance_id].bc_assign + 1, BC_ASSIGN_MIN, BC_ASSIGN_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[selected_instance_id].bc_assign = constrain(configuration.dexed[selected_instance_id].bc_assign - 1, BC_ASSIGN_MIN, BC_ASSIGN_MAX); #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } MicroDexed[selected_instance_id]->setBCController(configuration.dexed[selected_instance_id].bc_range, configuration.dexed[selected_instance_id].bc_assign, configuration.dexed[selected_instance_id].bc_mode); send_sysex_param(configuration.dexed[selected_instance_id].midi_channel, 75, configuration.dexed[selected_instance_id].bc_assign, 2); lcd.setCursor(0, 1); switch (configuration.dexed[selected_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]")); break; case 5: lcd.print(F("[PTCH EG]")); break; case 6: lcd.print(F("[ AMP EG]")); break; case 7: lcd.print(F("[PTCH AMP EG]")); break; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_bc_mode(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("BC Mode")); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.dexed[selected_instance_id].bc_mode = constrain(configuration.dexed[selected_instance_id].bc_mode + 1, BC_MODE_MIN, BC_MODE_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[selected_instance_id].bc_mode = constrain(configuration.dexed[selected_instance_id].bc_mode - 1, BC_MODE_MIN, BC_MODE_MAX); #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } MicroDexed[selected_instance_id]->setBCController(configuration.dexed[selected_instance_id].bc_range, configuration.dexed[selected_instance_id].bc_assign, configuration.dexed[selected_instance_id].bc_mode); MicroDexed[selected_instance_id]->ControllersRefresh(); lcd.setCursor(0, 1); switch (configuration.dexed[selected_instance_id].bc_mode) { case 0: lcd.print(F("[LINEAR ]")); break; case 1: lcd.print(F("[REVERSE LIN.]")); break; case 2: lcd.print(F("[DIRECT ]")); break; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_at_range(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("AT Range", configuration.dexed[selected_instance_id].at_range, 1.0, AT_RANGE_MIN, AT_RANGE_MAX, 2, false, false, true); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.dexed[selected_instance_id].at_range = constrain(configuration.dexed[selected_instance_id].at_range + ENCODER[ENC_R].speed(), AT_RANGE_MIN, AT_RANGE_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[selected_instance_id].at_range = constrain(configuration.dexed[selected_instance_id].at_range - ENCODER[ENC_R].speed(), AT_RANGE_MIN, AT_RANGE_MAX); #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } lcd_display_bar_int("AT Range", configuration.dexed[selected_instance_id].at_range, 1.0, AT_RANGE_MIN, AT_RANGE_MAX, 2, false, false, false); MicroDexed[selected_instance_id]->setATController(configuration.dexed[selected_instance_id].at_range, configuration.dexed[selected_instance_id].at_assign, configuration.dexed[selected_instance_id].at_mode); send_sysex_param(configuration.dexed[selected_instance_id].midi_channel, 76, configuration.dexed[selected_instance_id].at_range, 2); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_at_assign(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("AT Assign")); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.dexed[selected_instance_id].at_assign = constrain(configuration.dexed[selected_instance_id].at_assign + 1, AT_ASSIGN_MIN, AT_ASSIGN_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[selected_instance_id].at_assign = constrain(configuration.dexed[selected_instance_id].at_assign - 1, AT_ASSIGN_MIN, AT_ASSIGN_MAX); #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } MicroDexed[selected_instance_id]->setATController(configuration.dexed[selected_instance_id].at_range, configuration.dexed[selected_instance_id].at_assign, configuration.dexed[selected_instance_id].at_mode); send_sysex_param(configuration.dexed[selected_instance_id].midi_channel, 77, configuration.dexed[selected_instance_id].at_assign, 2); lcd.setCursor(0, 1); switch (configuration.dexed[selected_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]")); break; case 5: lcd.print(F("[PTCH EG]")); break; case 6: lcd.print(F("[ AMP EG]")); break; case 7: lcd.print(F("[PTCH AMP EG]")); break; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_at_mode(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("AT Mode")); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.dexed[selected_instance_id].at_mode = constrain(configuration.dexed[selected_instance_id].at_mode + 1, AT_MODE_MIN, AT_MODE_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[selected_instance_id].at_mode = constrain(configuration.dexed[selected_instance_id].at_mode - 1, AT_MODE_MIN, AT_MODE_MAX); #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } MicroDexed[selected_instance_id]->setATController(configuration.dexed[selected_instance_id].at_range, configuration.dexed[selected_instance_id].at_assign, configuration.dexed[selected_instance_id].at_mode); MicroDexed[selected_instance_id]->ControllersRefresh(); lcd.setCursor(0, 1); switch (configuration.dexed[selected_instance_id].at_mode) { case 0: lcd.print(F("[LINEAR ]")); break; case 1: lcd.print(F("[REVERSE LIN.]")); break; case 2: lcd.print(F("[DIRECT ]")); break; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_portamento_mode(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("Port. Mode")); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.dexed[selected_instance_id].portamento_mode = constrain(configuration.dexed[selected_instance_id].portamento_mode + 1, PORTAMENTO_MODE_MIN, PORTAMENTO_MODE_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[selected_instance_id].portamento_mode = constrain(configuration.dexed[selected_instance_id].portamento_mode - 1, PORTAMENTO_MODE_MIN, PORTAMENTO_MODE_MAX); #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } MicroDexed[selected_instance_id]->setPortamentoMode(configuration.dexed[selected_instance_id].portamento_mode, configuration.dexed[selected_instance_id].portamento_glissando, configuration.dexed[selected_instance_id].portamento_time); send_sysex_param(configuration.dexed[selected_instance_id].midi_channel, 67, configuration.dexed[selected_instance_id].portamento_mode, 2); lcd.setCursor(0, 1); switch (configuration.dexed[selected_instance_id].portamento_mode) { case 0: if (configuration.dexed[selected_instance_id].monopoly == 1) lcd.print(F("[RETAIN ]")); else lcd.print(F("[FINGERED]")); break; case 1: if (configuration.dexed[selected_instance_id].monopoly == 1) lcd.print(F("[FOLLOW ]")); else lcd.print(F("[FULL ]")); break; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_portamento_glissando(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("Port. Gliss.")); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.dexed[selected_instance_id].portamento_glissando = constrain(configuration.dexed[selected_instance_id].portamento_glissando + 1, PORTAMENTO_GLISSANDO_MIN, PORTAMENTO_GLISSANDO_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[selected_instance_id].portamento_glissando = constrain(configuration.dexed[selected_instance_id].portamento_glissando - 1, PORTAMENTO_GLISSANDO_MIN, PORTAMENTO_GLISSANDO_MAX); #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } MicroDexed[selected_instance_id]->setPortamentoMode(configuration.dexed[selected_instance_id].portamento_mode, configuration.dexed[selected_instance_id].portamento_glissando, configuration.dexed[selected_instance_id].portamento_time); send_sysex_param(configuration.dexed[selected_instance_id].midi_channel, 68, configuration.dexed[selected_instance_id].portamento_glissando, 2); lcd.setCursor(0, 1); switch (configuration.dexed[selected_instance_id].portamento_glissando) { case 0: lcd.print(F("[OFF]")); break; case 1: lcd.print(F("[ON ]")); break; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_portamento_time(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("Port. Time", configuration.dexed[selected_instance_id].portamento_time, 1.0, PORTAMENTO_TIME_MIN, PORTAMENTO_TIME_MAX, 2, false, false, true); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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.dexed[selected_instance_id].portamento_time = constrain(configuration.dexed[selected_instance_id].portamento_time + ENCODER[ENC_R].speed(), PORTAMENTO_TIME_MIN, PORTAMENTO_TIME_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[selected_instance_id].portamento_time = constrain(configuration.dexed[selected_instance_id].portamento_time - ENCODER[ENC_R].speed(), PORTAMENTO_TIME_MIN, PORTAMENTO_TIME_MAX); #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } lcd_display_bar_int("Portam. Time", configuration.dexed[selected_instance_id].portamento_time, 1.0, PORTAMENTO_TIME_MIN, PORTAMENTO_TIME_MAX, 2, false, false, false); MicroDexed[selected_instance_id]->setPortamentoMode(configuration.dexed[selected_instance_id].portamento_mode, configuration.dexed[selected_instance_id].portamento_glissando, configuration.dexed[selected_instance_id].portamento_time); send_sysex_param(configuration.dexed[selected_instance_id].midi_channel, 69, configuration.dexed[selected_instance_id].portamento_time, 2); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_handle_OP(uint8_t param) { static uint8_t op_selected; lcd_OP_active_instance_number(selected_instance_id, configuration.dexed[selected_instance_id].op_enabled); if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("OP Enable")); lcd.setCursor(0, 1); for (uint8_t i = 2; i < 8; i++) lcd.write(i); UI_update_instance_icons(); lcd.setCursor(op_selected, 1); lcd.blink(); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()) { #if NUM_DEXED>1 if (op_selected == 0) { selected_instance_id = !selected_instance_id; op_selected = 5; lcd_OP_active_instance_number(selected_instance_id, configuration.dexed[selected_instance_id].op_enabled); } else #endif op_selected = constrain(op_selected - 1, 0, 5); } else if (LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) { #if NUM_DEXED>1 if (op_selected == 5) { selected_instance_id = !selected_instance_id; op_selected = 0; lcd_OP_active_instance_number(selected_instance_id, configuration.dexed[selected_instance_id].op_enabled); } else #endif op_selected = constrain(op_selected + 1, 0, 5); } else if (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort()) { if (bitRead(configuration.dexed[selected_instance_id].op_enabled, op_selected)) bitClear(configuration.dexed[selected_instance_id].op_enabled, op_selected); else bitSet(configuration.dexed[selected_instance_id].op_enabled, op_selected); lcd_OP_active_instance_number(selected_instance_id, configuration.dexed[selected_instance_id].op_enabled); } lcd.setCursor(op_selected, 1); MicroDexed[selected_instance_id]->setOPAll(configuration.dexed[selected_instance_id].op_enabled); MicroDexed[selected_instance_id]->doRefreshVoice(); send_sysex_param(configuration.dexed[selected_instance_id].midi_channel, 155, configuration.dexed[selected_instance_id].op_enabled, 0); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd.noBlink(); lcd.noCursor(); lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_drum_reverb_send(uint8_t param) { char displayname[8] = {0, 0, 0, 0, 0, 0, 0}; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); temp_int = (int)(drum_config[activesample].reverb_send * 100); lcd.setCursor(0, 0); lcd.print("Drum Rev. Send"); lcd.setCursor(1, 1); sprintf(displayname, "%02d", activesample); lcd.print(displayname); lcd.show(4, 5, 6, basename(drum_config[activesample].name)); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (menu_select_toggle == false) { 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()) { // activesample = constrain(activesample + ENCODER[ENC_R].speed(), 0, NUM_DRUMSET_CONFIG - 2); smart_filter(1); } else if (LCDML.BT_checkUp()) { // activesample = constrain(activesample - ENCODER[ENC_R].speed(), 0, NUM_DRUMSET_CONFIG - 2); smart_filter(0); } } } else { 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()) { temp_int = constrain(temp_int + ENCODER[ENC_R].speed(), 0, REVERB_SEND_MAX); } else if (LCDML.BT_checkUp()) { temp_int = constrain(temp_int - ENCODER[ENC_R].speed(), 0, REVERB_SEND_MAX); } } } if (LCDML.BT_checkEnter()) { if (menu_select_toggle) { menu_select_toggle = false; } else { menu_select_toggle = true; temp_int = (int)(drum_config[activesample].reverb_send * 100); } } if (menu_select_toggle == false) { lcd.setCursor(11, 1); lcd.print(" "); lcd.setCursor(15, 1); lcd.print(" "); lcd.setCursor(0, 1); lcd.print("["); lcd.setCursor(3, 1); lcd.print("]"); lcd.setCursor(1, 1); sprintf(displayname, "%02d", activesample); lcd.print(displayname); lcd.show(4, 5, 6, basename(drum_config[activesample].name)); sprintf(displayname, "%03d", (int)(drum_config[activesample].reverb_send * 100) ); lcd.setCursor(12, 1); lcd.print(displayname); } else { lcd.setCursor(0, 1); lcd.print(" "); lcd.setCursor(3, 1); lcd.print(" "); lcd.setCursor(11, 1); lcd.print("["); lcd.setCursor(15, 1); lcd.print("]"); sprintf(displayname, "%03d", temp_int); lcd.setCursor(12, 1); lcd.print(displayname); drum_config[activesample].reverb_send = mapfloat(temp_int, 0, 100, 0.0, 1.0); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); } } void UI_func_drum_midi_channel(uint8_t param) { 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() && encoderDir[ENC_R].Down()) drum_midi_channel = constrain(drum_midi_channel + ENCODER[ENC_R].speed(), MIDI_CHANNEL_MIN, MIDI_CHANNEL_MAX); else if (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()) drum_midi_channel = constrain(drum_midi_channel - ENCODER[ENC_R].speed(), MIDI_CHANNEL_MIN, MIDI_CHANNEL_MAX); lcd.setCursor(0, 1); if (drum_midi_channel == 0) { lcd.print(F("[OMNI]")); } else { lcd_display_int(drum_midi_channel, 4, false, true, false); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* encoderDir[ENC_R].reset(); } void UI_func_drums_main_volume(uint8_t param) { char displayname[4] = {0, 0, 0, 0}; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); temp_int = mapfloat(drums_volume, 0.0, VOL_MAX_FLOAT, 0, 100); lcd.setCursor(0, 0); lcd.print(" Drums M.Volume "); } 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()) { temp_int = constrain(temp_int + ENCODER[ENC_R].speed(), 0, 100); } else if (LCDML.BT_checkUp()) { temp_int = constrain(temp_int - ENCODER[ENC_R].speed(), 0, 100); } } lcd.setCursor(5, 1); sprintf(displayname, "%03d", temp_int); lcd.print(displayname); lcd.setCursor(8, 1); lcd.print("/100"); master_mixer_r.gain (2, volume_transform(mapfloat(temp_int, 0, 100, 0.0, VOL_MAX_FLOAT))); master_mixer_l.gain (2, volume_transform(mapfloat(temp_int, 0, 100, 0.0, VOL_MAX_FLOAT))); drums_volume = mapfloat(temp_int, 0, 100, 0.0, VOL_MAX_FLOAT); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); } } void UI_func_drum_tune_offset(uint8_t param) { char displayname[8] = {0, 0, 0, 0, 0, 0, 0}; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); temp_int = (int)(drum_config[activesample].p_offset * 200); lcd.setCursor(0, 0); lcd.print("DrumSmp. Tune"); lcd.setCursor(1, 1); lcd.setCursor(1, 1); sprintf(displayname, "%02d", activesample); lcd.print(displayname); lcd.show(1, 4, 7, basename(drum_config[activesample].name)); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (menu_select_toggle == false) { 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()) { activesample = constrain(activesample + ENCODER[ENC_R].speed(), 0, NUM_DRUMSET_CONFIG - 2); } else if (LCDML.BT_checkUp()) { activesample = constrain(activesample - ENCODER[ENC_R].speed(), 0, NUM_DRUMSET_CONFIG - 2); } } } else { 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()) { temp_int = constrain(temp_int + ENCODER[ENC_R].speed(), 0, 400); } else if (LCDML.BT_checkUp()) { temp_int = constrain(temp_int - ENCODER[ENC_R].speed(), 0, 400); } } } if (LCDML.BT_checkEnter()) { if (menu_select_toggle) { menu_select_toggle = false; } else { menu_select_toggle = true; temp_int = (int)(drum_config[activesample].p_offset * 200); } } if (menu_select_toggle == false) { lcd.setCursor(11, 1); lcd.print(" "); lcd.setCursor(15, 1); lcd.print(" "); lcd.setCursor(0, 1); lcd.print("["); lcd.setCursor(3, 1); lcd.print("]"); lcd.setCursor(1, 1); sprintf(displayname, "%02d", activesample); lcd.print(displayname); lcd.show(1, 4, 7, basename(drum_config[activesample].name)); sprintf(displayname, "%03d", (int)(drum_config[activesample].p_offset * 200) ); lcd.setCursor(12, 1); lcd.print(displayname); } else { temp_float = mapfloat(temp_int, 0, 400, 0.0, 2.0); lcd.setCursor(0, 1); lcd.print(" "); lcd.setCursor(3, 1); lcd.print(" "); lcd.setCursor(11, 1); lcd.print("["); lcd.setCursor(15, 1); lcd.print("]"); sprintf(displayname, "%03d", temp_int); lcd.setCursor(12, 1); lcd.print(displayname); drum_config[activesample].p_offset = temp_float; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); } } void UI_func_drum_pitch(uint8_t param) { char displayname[8] = {0, 0, 0, 0, 0, 0, 0}; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); temp_int = (int)(drum_config[activesample].pitch * 200); lcd.setCursor(0, 0); lcd.print("DrumSmp. Pitch"); lcd.setCursor(1, 1); lcd.setCursor(1, 1); sprintf(displayname, "%02d", activesample); lcd.print(displayname); lcd.show(1, 4, 7, basename(drum_config[activesample].name)); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (menu_select_toggle == false) { 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()) { activesample = constrain(activesample + ENCODER[ENC_R].speed(), 0, NUM_DRUMSET_CONFIG - 2); } else if (LCDML.BT_checkUp()) { activesample = constrain(activesample - ENCODER[ENC_R].speed(), 0, NUM_DRUMSET_CONFIG - 2); } } } else { 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()) { temp_int = constrain(temp_int + ENCODER[ENC_R].speed(), 0, 400); } else if (LCDML.BT_checkUp()) { temp_int = constrain(temp_int - ENCODER[ENC_R].speed(), 0, 400); } } } if (LCDML.BT_checkEnter()) { if (menu_select_toggle) { menu_select_toggle = false; } else { menu_select_toggle = true; temp_int = (int)(drum_config[activesample].pitch * 200); } } if (menu_select_toggle == false) { lcd.setCursor(11, 1); lcd.print(" "); lcd.setCursor(15, 1); lcd.print(" "); lcd.setCursor(0, 1); lcd.print("["); lcd.setCursor(3, 1); lcd.print("]"); lcd.setCursor(1, 1); sprintf(displayname, "%02d", activesample); lcd.print(displayname); lcd.show(1, 4, 7, basename(drum_config[activesample].name)); sprintf(displayname, "%03d", (int)(drum_config[activesample].pitch * 200) ); lcd.setCursor(12, 1); lcd.print(displayname); } else { temp_float = mapfloat(temp_int, 0, 400, 0.0, 2.0); lcd.setCursor(0, 1); lcd.print(" "); lcd.setCursor(3, 1); lcd.print(" "); lcd.setCursor(11, 1); lcd.print("["); lcd.setCursor(15, 1); lcd.print("]"); sprintf(displayname, "%03d", temp_int); lcd.setCursor(12, 1); lcd.print(displayname); drum_config[activesample].pitch = temp_float; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); } } void UI_func_drum_volume(uint8_t param) { char displayname[8] = {0, 0, 0, 0, 0, 0, 0}; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); temp_int = (int)(drum_config[activesample].vol_max * 100); lcd.setCursor(0, 0); lcd.print("DrumSmp. Volume"); lcd.setCursor(1, 1); lcd.setCursor(1, 1); sprintf(displayname, "%02d", activesample); lcd.print(displayname); lcd.show(1, 4, 7, basename(drum_config[activesample].name)); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (menu_select_toggle == false) { 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()) { // activesample = constrain(activesample + ENCODER[ENC_R].speed(), 0, NUM_DRUMSET_CONFIG - 2); smart_filter(1); } else if (LCDML.BT_checkUp()) { // activesample = constrain(activesample - ENCODER[ENC_R].speed(), 0, NUM_DRUMSET_CONFIG - 2); smart_filter(0); } } } else { 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()) { temp_int = constrain(temp_int + ENCODER[ENC_R].speed(), 0, 100); } else if (LCDML.BT_checkUp()) { temp_int = constrain(temp_int - ENCODER[ENC_R].speed(), 0, 100); } } } if (LCDML.BT_checkEnter()) { if (menu_select_toggle) { menu_select_toggle = false; } else { menu_select_toggle = true; temp_int = (int)(drum_config[activesample].vol_max * 100); } } if (menu_select_toggle == false) { lcd.setCursor(11, 1); lcd.print(" "); lcd.setCursor(15, 1); lcd.print(" "); lcd.setCursor(0, 1); lcd.print("["); lcd.setCursor(3, 1); lcd.print("]"); lcd.setCursor(1, 1); sprintf(displayname, "%02d", activesample); lcd.print(displayname); lcd.show(1, 4, 7, basename(drum_config[activesample].name)); sprintf(displayname, "%03d", (int)(drum_config[activesample].vol_max * 100) ); lcd.setCursor(12, 1); lcd.print(displayname); } else { temp_float = mapfloat(temp_int, 0, 100, 0.0, 1.0); lcd.setCursor(0, 1); lcd.print(" "); lcd.setCursor(3, 1); lcd.print(" "); lcd.setCursor(11, 1); lcd.print("["); lcd.setCursor(15, 1); lcd.print("]"); sprintf(displayname, "%03d", temp_int); lcd.setCursor(12, 1); lcd.print(displayname); drum_config[activesample].vol_max = temp_float; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); } } void UI_func_arp_shift(uint8_t param) { char displayname[4] = {0, 0, 0, 0}; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print("Arp/Chord Transp"); lcd.setCursor(0, 1); lcd.print("Oct"); lcd.setCursor(4, 1); sprintf(displayname, "%02d", seq_oct_shift); lcd.print(displayname); lcd.setCursor(8, 1); lcd.print("Shift"); lcd.setCursor(14, 1); lcd.print(seq_element_shift); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (menu_select_toggle == false) { 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()) { seq_oct_shift = constrain(seq_oct_shift + ENCODER[ENC_R].speed(), -2, 2); } else if (LCDML.BT_checkUp()) { seq_oct_shift = constrain(seq_oct_shift - ENCODER[ENC_R].speed(), -2, 2); } } } else { 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()) { seq_element_shift = constrain(seq_element_shift + ENCODER[ENC_R].speed(), 0, 6); } else if (LCDML.BT_checkUp()) { seq_element_shift = constrain(seq_element_shift - ENCODER[ENC_R].speed(), 0, 6); } } } if (LCDML.BT_checkEnter()) { menu_select_toggle = !menu_select_toggle; } if (menu_select_toggle == false) { lcd.setCursor(13, 1); lcd.print(" "); lcd.setCursor(15, 1); lcd.print(" "); lcd.setCursor(3, 1); lcd.print("["); lcd.setCursor(6, 1); lcd.print("]"); lcd.setCursor(4, 1); sprintf(displayname, "%02d", seq_oct_shift); lcd.print(displayname); } else { lcd.setCursor(3, 1); lcd.print(" "); lcd.setCursor(6, 1); lcd.print(" "); lcd.setCursor(13, 1); lcd.print("["); lcd.setCursor(15, 1); lcd.print("]"); lcd.setCursor(14, 1); lcd.print(seq_element_shift); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); } } void UI_func_drum_pan(uint8_t param) { char displayname[8] = {0, 0, 0, 0, 0, 0, 0}; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); temp_int = mapfloat(drum_config[activesample].pan, -1.0, 1.0, -99, 99); lcd.setCursor(0, 0); lcd.print("DrmSmp. Panorama"); lcd.setCursor(1, 1); sprintf(displayname, "%02d", activesample); lcd.print(displayname); lcd.show(1, 4, 6, basename(drum_config[activesample].name)); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (menu_select_toggle == false) { 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()) { //activesample = constrain(activesample + ENCODER[ENC_R].speed(), 0, NUM_DRUMSET_CONFIG - 2); smart_filter(1); } else if (LCDML.BT_checkUp()) { //activesample = constrain(activesample - ENCODER[ENC_R].speed(), 0, NUM_DRUMSET_CONFIG - 2); smart_filter(0); } } } else { 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()) { temp_int = constrain(temp_int + ENCODER[ENC_R].speed(), -99, 99); } else if (LCDML.BT_checkUp()) { temp_int = constrain(temp_int - ENCODER[ENC_R].speed(), -99, 99); } } } if (LCDML.BT_checkEnter()) { if (menu_select_toggle) { menu_select_toggle = false; } else { menu_select_toggle = true; } } if (menu_select_toggle == false) { lcd.setCursor(11, 1); lcd.print(" "); lcd.setCursor(15, 1); lcd.print(" "); lcd.setCursor(0, 1); lcd.print("["); lcd.setCursor(3, 1); lcd.print("]"); lcd.setCursor(1, 1); sprintf(displayname, "%02d", activesample); lcd.print(displayname); lcd.show(1, 4, 6, basename(drum_config[activesample].name)); } else { lcd.setCursor(0, 1); lcd.print(" "); lcd.setCursor(3, 1); lcd.print(" "); lcd.setCursor(11, 1); lcd.print("["); lcd.setCursor(15, 1); lcd.print("]"); drum_config[activesample].pan = mapfloat(temp_int, -99, 99, -1.0, 1.0); } temp_int = mapfloat(drum_config[activesample].pan, -1.0, 1.0, -99, 99); lcd.setCursor(12, 1); if (temp_int > 1) { lcd.print("R"); } else if (temp_int < 0) { lcd.print("L"); } else { lcd.print("C"); } sprintf(displayname, "%02d", abs(temp_int)); lcd.setCursor(13, 1); lcd.print( displayname); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); } } const char* seq_find_drum_name_from_note(uint8_t note) { bool found = false; const char* shortname; for (uint8_t d = 0; d < NUM_DRUMSET_CONFIG - 1; d++) { if (note == drum_config[d].midinote) { shortname = basename(drum_config[d].name); found = true; break; } } if (found == false) shortname = " "; return shortname; } const char* seq_find_shortname(uint8_t sstep) { const char* shortname; bool found = false; if (seq_content_type[seq_active_track] == 0 && seq_vel[seq_active_track][sstep] < 210) //is Drumtrack and not a pitched sample { for (uint8_t d = 0; d < NUM_DRUMSET_CONFIG - 1; d++) { if (seq_data[seq_active_track][sstep] == drum_config[d].midinote) { shortname = drum_config[d].shortname; found = true; break; } } if (found == false) shortname = "-"; } else { if (seq_data[seq_active_track][sstep] > 0 && seq_data[seq_active_track][sstep] != 130) shortname = noteNames[seq_data[seq_active_track][sstep] % 12]; else if (seq_data[seq_active_track][sstep] == 130) shortname = "~"; // note has tie/latch else shortname = "-"; } return shortname; } void seq_printAllSeqSteps() { lcd.setCursor(0, 1); for (uint8_t i = 0; i < 16; i++) { lcd.print(seq_find_shortname(i)[0]); } } #ifdef TESTDISPLAY20x4 void seq_printVelGraphBar() { lcd.setCursor(0, 2); for (uint8_t i = 0; i < 16; i++) { if (seq_vel[seq_active_track][i] == 0) lcd.print(" "); else if (seq_vel[seq_active_track][i] > 0 && seq_vel[seq_active_track][i] <= 20) lcd.write(1); else if (seq_vel[seq_active_track][i] > 21 && seq_vel[seq_active_track][i] <= 40) lcd.write(2); else if (seq_vel[seq_active_track][i] > 41 && seq_vel[seq_active_track][i] <= 60) lcd.write(3); else if (seq_vel[seq_active_track][i] > 61 && seq_vel[seq_active_track][i] <= 80) lcd.write(4); else if (seq_vel[seq_active_track][i] > 81 && seq_vel[seq_active_track][i] <= 90) lcd.write(5); else if (seq_vel[seq_active_track][i] > 91 && seq_vel[seq_active_track][i] <= 105) lcd.write(6); else if (seq_vel[seq_active_track][i] > 105 && seq_vel[seq_active_track][i] <= 128) lcd.write(7); else lcd.print("C"); } } #endif void UI_func_seq_display_style(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print("Seq. Disp. Style"); lcd.setCursor(0, 1); lcd.print("Pat."); lcd.setCursor(9, 1); lcd.print("="); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (menu_select_toggle == false) { 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()) { seq_active_track = constrain(seq_active_track + ENCODER[ENC_R].speed(), 0, NUM_SEQ_PATTERN - 1); } else if (LCDML.BT_checkUp()) { seq_active_track = constrain(seq_active_track - ENCODER[ENC_R].speed(), 0, NUM_SEQ_PATTERN - 1); } } } else { 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()) { seq_content_type[seq_active_track] = constrain(seq_content_type[seq_active_track] + ENCODER[ENC_R].speed(), 0, 2); } else if (LCDML.BT_checkUp()) { seq_content_type[seq_active_track] = constrain(seq_content_type[seq_active_track] - ENCODER[ENC_R].speed(), 0, 2); } } } if (LCDML.BT_checkEnter()) { menu_select_toggle = !menu_select_toggle; } if (menu_select_toggle == false) { lcd.setCursor(10, 1); lcd.print(" "); lcd.setCursor(15, 1); lcd.print(" "); lcd.setCursor(4, 1); lcd.print("["); if (seq_active_track < 10) lcd.print ("0"); lcd.print(seq_active_track); lcd.print("]"); } else { lcd.setCursor(4, 1); lcd.print(" "); lcd.setCursor(7, 1); lcd.print(" "); lcd.setCursor(10, 1); lcd.print("["); lcd.setCursor(15, 1); lcd.print("]"); } lcd.setCursor(11, 1); if (seq_content_type[seq_active_track] == 0) lcd.print("Drum"); else if (seq_content_type[seq_active_track] == 1) lcd.print("Inst"); else lcd.print("Chrd"); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); } } void UI_func_seq_live_transpose_oct(uint8_t param) { //Select octave for live transpose of sequencer instrument track. Should be one of the lowest octaves available on the keyboard. //Allowed range: C1-C5 to not restrict too much, even for very unusual user setups/configurations. char note_name[4]; char note_name2[4]; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); getNoteName(note_name, seq_transpose); getNoteName(note_name2, seq_transpose + 12); lcd.setCursor(0, 0); lcd.print(F("Live Transp.Oct.")); lcd.setCursor(0, 1); lcd.print(F("[")); lcd.print(note_name); lcd.print(F("] - ")); lcd.print(("[")); lcd.print(note_name2); lcd.print(("]")); } 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()) seq_transpose = constrain(seq_transpose + ENCODER[ENC_R].speed(), 24, 60); else if (LCDML.BT_checkUp()) seq_transpose = constrain(seq_transpose - ENCODER[ENC_R].speed(), 24, 60); } getNoteName(note_name, seq_transpose); getNoteName(note_name2, seq_transpose + 12); lcd.setCursor(0, 1); lcd.print(F("[")); lcd.print(note_name); lcd.print(F("] - ")); lcd.print(("[")); lcd.print(note_name2); lcd.print(("]")); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); } } void UI_func_seq_chord_keys_ammount(uint8_t param) { char displayname[4] = {0, 0, 0, 0}; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print("ChordTrack Keys:"); lcd.setCursor(8, 1); lcd.print("Keys"); } 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()) seq_chord_key_ammount = constrain(seq_chord_key_ammount + ENCODER[ENC_R].speed(), 1, 7); else if (LCDML.BT_checkUp()) seq_chord_key_ammount = constrain(seq_chord_key_ammount - ENCODER[ENC_R].speed(), 1, 7); } lcd.setCursor(4, 1); lcd.print("["); sprintf(displayname, "%02d", seq_chord_key_ammount); lcd.print(displayname); lcd.print("]"); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); } } void UI_func_seq_lenght(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(" Seq. lenght "); } 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()) seq_chain_lenght = constrain(seq_chain_lenght + ENCODER[ENC_R].speed(), 0, 3); else if (LCDML.BT_checkUp()) seq_chain_lenght = constrain(seq_chain_lenght - ENCODER[ENC_R].speed(), 0, 3); } lcd.setCursor(3, 1); lcd.print((seq_chain_lenght + 1) * 16 ); lcd.setCursor(7, 1); lcd.print("Steps"); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); } } void UI_func_seq_tempo(uint8_t param) { char tmp[7]; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(" Seq. Tempo "); lcd.setCursor(5, 1); lcd.print("BPM"); lcd.setCursor(14, 1); lcd.print("ms"); } 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()) seq_bpm = constrain(seq_bpm + ENCODER[ENC_R].speed(), 50, 190); else if (LCDML.BT_checkUp()) seq_bpm = constrain(seq_bpm - ENCODER[ENC_R].speed(), 50, 190); } seq_tempo_ms = 60000000 / seq_bpm / 4; lcd.setCursor(0, 1); sprintf(tmp, "[%3d]", seq_bpm); lcd.print(tmp); lcd.setCursor(11, 1); sprintf(tmp, "%3d", seq_tempo_ms / 1000); lcd.print(tmp); #ifdef USE_FX for (uint8_t i = 0; i < MAX_DEXED; i++) { if (configuration.fx.delay_sync[i] > 0) { uint16_t midi_sync_delay_time = uint16_t(60000.0 * midi_ticks_factor[configuration.fx.delay_sync[i]] / seq_bpm); delay_fx[i]->delay(0, constrain(midi_sync_delay_time, DELAY_TIME_MIN, DELAY_TIME_MAX * 10)); } } #endif //timer1.stop(); timer1.begin(sequencer, seq_tempo_ms / 2); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); } } void UI_func_seq_vel_editor(uint8_t param) { char tmp[5]; if (LCDML.FUNC_setup()) // ****** SETUP ********* { // setup function encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print("V:"); sprintf(tmp, "%03d", seq_vel[seq_active_track][seq_menu - 1]); lcd.setCursor(2, 0); lcd.print(tmp); lcd.setCursor(12, 0); lcd.print("["); lcd.setCursor(13, 0); if (seq_active_track < 10) lcd.print("0"); lcd.print(seq_active_track); lcd.setCursor(15, 0); lcd.print("]"); seq_printAllSeqSteps(); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (seq_active_function == 99) { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) seq_menu = constrain(seq_menu + 1, 0, 16); else if (LCDML.BT_checkUp()) seq_menu = constrain(seq_menu - 1, 0, 16); } } else if (seq_active_function == 0) { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) seq_active_track = constrain(seq_active_track + 1, 0, NUM_SEQ_PATTERN - 1); else if (LCDML.BT_checkUp()) seq_active_track = constrain(seq_active_track - 1, 0, NUM_SEQ_PATTERN - 1); } } if ( seq_data[seq_active_track][seq_menu - 1] > 0 ) { if (seq_vel[seq_active_track][seq_menu - 1] < 210) //it is a normal sample { if (seq_active_function == 1 && seq_content_type[seq_active_track] < 2 ) { //if is Drum or normal Instrument Track if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) seq_vel[seq_active_track][seq_menu - 1] = constrain(seq_vel[seq_active_track][seq_menu - 1] + 1, 0, 127); else if (LCDML.BT_checkUp()) seq_vel[seq_active_track][seq_menu - 1] = constrain(seq_vel[seq_active_track][seq_menu - 1] - 1, 0, 127); } } else if (seq_active_function == 1 && seq_content_type[seq_active_track] > 1 ) { //is in Chord or Arp Mode if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) seq_vel[seq_active_track][seq_menu - 1] = constrain(seq_vel[seq_active_track][seq_menu - 1] + 1, 200, 205); else if (LCDML.BT_checkUp()) seq_vel[seq_active_track][seq_menu - 1] = constrain(seq_vel[seq_active_track][seq_menu - 1] - 1, 200, 205); } } } else { //is in pitched Sample Mode if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) seq_vel[seq_active_track][seq_menu - 1] = constrain(seq_vel[seq_active_track][seq_menu - 1] + 1, 210, 215); else if (LCDML.BT_checkUp()) seq_vel[seq_active_track][seq_menu - 1] = constrain(seq_vel[seq_active_track][seq_menu - 1] - 1, 210, 215); } } } if (LCDML.BT_checkEnter()) //handle button presses during menu >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> { if ( seq_menu == 0 && seq_active_function == 99) { seq_active_function = 0; } else if ( seq_menu == 0 && seq_active_function == 0) { seq_active_function = 99; } else if (seq_menu > 0 && seq_active_function == 99) { seq_active_function = 1; } else seq_active_function = 99; } //button check end <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< if ( seq_content_type[seq_active_track] > 1 && seq_vel[seq_active_track][seq_menu - 1] < 200) seq_vel[seq_active_track][seq_menu - 1] = 200; if (seq_active_function == 0) { lcd.setCursor(0, 0); if (seq_content_type[seq_active_track] == 0) lcd.print("Drum Track "); else if (seq_content_type[seq_active_track] == 1) lcd.print("Instr. Track "); else lcd.print("Chord Track "); } if (seq_menu > 0 && seq_content_type[seq_active_track] == 0) { lcd.setCursor(0, 0); if (seq_vel[seq_active_track][seq_menu - 1] < 210 && seq_vel[seq_active_track][seq_menu - 1] > 0) //it is a normal sample { lcd.print("V:"); sprintf(tmp, "%03d", seq_vel[seq_active_track][seq_menu - 1]); lcd.setCursor(2, 0); lcd.print(tmp); } else { // else it is a live-pitched sample if (seq_vel[seq_active_track][seq_menu - 1] > 0) { lcd.setCursor(0, 0); lcd.print("Smp:["); lcd.setCursor(12, 0); lcd.print("]"); lcd.show(0, 5, 7, basename(drum_config[seq_vel[seq_active_track][seq_menu - 1] - 210].name)); } } } if (seq_menu == 0) { lcd.setCursor(12, 0); lcd.print("["); if (seq_active_track < 10) lcd.print("0"); lcd.print(seq_active_track); lcd.print("]"); lcd.setCursor(0, 1); seq_printAllSeqSteps(); } else if (seq_menu == 1) { lcd.setCursor(12, 0); lcd.print(" "); lcd.setCursor(15, 0); lcd.print(" "); lcd.setCursor(0, 1); lcd.write(219); // cursor symbol lcd.setCursor(1, 1); lcd.print(seq_find_shortname(1)[0] ); if (seq_vel[seq_active_track][seq_menu - 1] < 210 && seq_content_type[seq_active_track] < 2) //it is a normal sample { sprintf(tmp, "%03d", seq_vel[seq_active_track][seq_menu - 1]); lcd.setCursor(2, 0); lcd.print(tmp); } } else if (seq_menu > 1) { lcd.setCursor(seq_menu - 1, 1); lcd.write(219); // cursor symbol lcd.setCursor(seq_menu - 2, 1); lcd.print(seq_find_shortname(seq_menu - 2)[0] ); if (seq_menu < 16) { lcd.setCursor(seq_menu , 1); lcd.print(seq_find_shortname(seq_menu)[0] ); } } if (seq_menu > 0) { lcd.setCursor(4, 0); if (seq_data[seq_active_track][seq_menu - 1] > 0) { if (seq_content_type[seq_active_track] == 0) //is Drumtrack { lcd.setCursor(0, 0); if (seq_vel[seq_active_track][seq_menu - 1] < 210) //it is a normal sample { lcd.print("V:"); sprintf(tmp, "%03d", seq_vel[seq_active_track][seq_menu - 1]); lcd.print(tmp); //lcd.setCursor(7, 0); //lcd.print(" "); lcd.show(0, 6, 5, seq_find_drum_name_from_note( seq_data[seq_active_track][seq_menu - 1]) ); } else { // else it is a live-pitched sample lcd.setCursor(0, 0); lcd.print("Smp:["); lcd.setCursor(12, 0); lcd.print("]"); lcd.setCursor(1, 0); lcd.show(0, 5, 7, basename(drum_config[seq_vel[seq_active_track][seq_menu - 1] - 210].name)); } } else { if ( seq_data[seq_active_track][seq_menu - 1] != 130 ) //note not latched { if (seq_content_type[seq_active_track] < 2) { lcd.setCursor(0, 0); lcd.print("Vel:"); sprintf(tmp, "%03d", seq_vel[seq_active_track][seq_menu - 1]); lcd.setCursor(4, 0); lcd.print(tmp); lcd.print(" "); } lcd.setCursor(8, 0); lcd.print(noteNames[seq_data[seq_active_track][seq_menu - 1] % 12 ][0] ); if (noteNames[seq_data[seq_active_track][seq_menu - 1] % 12 ][1] != '\0' ) { lcd.print(noteNames[seq_data[seq_active_track][seq_menu - 1] % 12 ][1] ); } lcd.print( (seq_data[seq_active_track][seq_menu - 1] / 12) - 1); lcd.print(" "); } else { //note is latched lcd.setCursor(0, 0); lcd.print("latched note "); } if (seq_content_type[seq_active_track] > 1) { lcd.setCursor(0, 0); if (seq_vel[seq_active_track][seq_menu - 1] == 200) lcd.print("Major " ); else if (seq_vel[seq_active_track][seq_menu - 1] == 201) lcd.print("Minor " ); else if (seq_vel[seq_active_track][seq_menu - 1] == 202) lcd.print("Seven " ); else if (seq_vel[seq_active_track][seq_menu - 1] == 203) lcd.print("Aug " ); else if (seq_vel[seq_active_track][seq_menu - 1] == 204) lcd.print("Dim " ); else if (seq_vel[seq_active_track][seq_menu - 1] == 205) lcd.print("Major7 " ); } } } else { lcd.setCursor(0, 0); lcd.print(" "); } } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); } } void seq_clear_active_pattern() { memset(seq_data[seq_active_track], 0, sizeof(seq_data[seq_active_track])); memset(seq_vel[seq_active_track], 0, sizeof(seq_vel[seq_active_track])); } void seq_clear_all_patterns() { for (uint8_t i = 0; i < NUM_SEQ_PATTERN - 1; i++) { memset(seq_data[i], 0, sizeof(seq_data[i])); memset(seq_vel[i], 0, sizeof(seq_vel[i])); } } void seq_refresh_display_play_status() { if (seq_running == false && seq_recording == false) { lcd.createChar(0, (uint8_t*)special_chars[19]); //play symbol #ifdef TESTDISPLAY20x4 lcd.setCursor(14, 0); #else lcd.setCursor(10, 0); #endif lcd.write(0); } else if (seq_running == true && seq_recording == false) { seq_note_in = 0; lcd.createChar(0, (uint8_t*)special_chars[20]); //record symbol #ifdef TESTDISPLAY20x4 lcd.setCursor(14, 0); #else lcd.setCursor(10, 0); #endif lcd.write(0); } else if (seq_running == true && seq_recording == true) { seq_note_in = 0; lcd.createChar(0, (uint8_t*)special_chars[21]); //stop symbol #ifdef TESTDISPLAY20x4 lcd.setCursor(14, 0); #else lcd.setCursor(10, 0); #endif lcd.write(0); } } void arp_refresh_display_play_status() { if (seq_running == false ) { lcd.createChar(0, (uint8_t*)special_chars[19]); //play symbol lcd.setCursor(13, 0); lcd.write(0); } else if (seq_running == true ) { seq_note_in = 0; lcd.createChar(0, (uint8_t*)special_chars[21]); //stop symbol lcd.setCursor(13, 0); lcd.write(0); } } void seq_print_current_note() { lcd.print(noteNames[seq_data[seq_active_track][seq_menu - 3] % 12 ][0] ); if (noteNames[seq_data[seq_active_track][seq_menu - 3] % 12 ][1] != '\0' ) { lcd.print(noteNames[seq_data[seq_active_track][seq_menu - 3] % 12 ][1] ); } lcd.print( (seq_data[seq_active_track][seq_menu - 3] / 12) - 1); lcd.print(" "); } void check_variable_samples_basespeed() { for (uint8_t i = 0; i < 6; i++) { if (drum_config[i].p_offset == 0) drum_config[i].p_offset = 1; } } void UI_func_seq_pattern_editor(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { check_variable_samples_basespeed(); lcd.createChar(0, (uint8_t*)special_chars[19]); //play symbol + record symbol switching #ifdef TESTDISPLAY20x4 lcd.createChar(1, (uint8_t*)special_chars[9]); //bar graph lcd.createChar(2, (uint8_t*)special_chars[10]); //bar graph lcd.createChar(3, (uint8_t*)special_chars[11]); //bar graph lcd.createChar(4, (uint8_t*)special_chars[12]); //bar graph lcd.createChar(5, (uint8_t*)special_chars[13]); //bar graph lcd.createChar(6, (uint8_t*)special_chars[14]); //bar graph lcd.createChar(7, (uint8_t*)special_chars[15]); //bar graph #endif temp_int = seq_data[seq_active_track][0]; encoderDir[ENC_R].reset(); seq_note_in = 0; // setup function seq_refresh_display_play_status(); #ifdef TESTDISPLAY20x4 lcd.setCursor(17, 0); #else lcd.setCursor(13, 0); #endif if (seq_active_track < 10)lcd.print("0"); lcd.print(seq_active_track); seq_printAllSeqSteps(); #ifdef TESTDISPLAY20x4 seq_printVelGraphBar(); #endif } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (seq_active_function == 40 ) { // pitch edit sample if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) { seq_data[seq_active_track][seq_menu - 3] = constrain(seq_data[seq_active_track][seq_menu - 3] + 1, 1, 108); } else if (LCDML.BT_checkUp()) { seq_data[seq_active_track][seq_menu - 3] = constrain(seq_data[seq_active_track][seq_menu - 3] - 1, 1, 108); } } } else if (seq_menu == 33) { // is in sub-function - fill pattern seq_active_function = 95; if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) { seq_temp_active_menu = constrain(seq_temp_active_menu + 1, 0, 3); } else if (LCDML.BT_checkUp()) { seq_temp_active_menu = constrain(seq_temp_active_menu - 1, 0, 3); } } } else if (seq_menu == 32) { // is in sub-function - fill pattern seq_active_function = 97; if (seq_content_type[seq_active_track] == 0) { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) { seq_temp_select_menu = constrain(seq_temp_select_menu + 1, 0, NUM_DRUMSET_CONFIG - 1); } else if (LCDML.BT_checkUp()) { seq_temp_select_menu = constrain(seq_temp_select_menu - 1, 0, NUM_DRUMSET_CONFIG - 1); } } } else { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) seq_temp_select_menu = constrain(seq_temp_select_menu + 1, 0, 108 ); else if (LCDML.BT_checkUp()) seq_temp_select_menu = constrain(seq_temp_select_menu - 1, 0, 108 ); } } } else if (seq_menu == 30 || seq_menu == 31 ) { // is in sub-function - swap pattern or copy pattern seq_active_function = 98; if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) { temp_int = constrain(temp_int + 1, 0, NUM_SEQ_PATTERN - 1); if (temp_int == seq_active_track)temp_int++; if (temp_int > NUM_SEQ_PATTERN - 1)temp_int = 0; } else if (LCDML.BT_checkUp()) { temp_int = constrain(temp_int - 1, 0, NUM_SEQ_PATTERN - 1); if (temp_int == seq_active_track)temp_int--; if (temp_int < 0)temp_int = NUM_SEQ_PATTERN - 1; } } } else if (seq_menu == 34) { // is in transpose edit seq_active_function = 94; if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) { temp_int = constrain(temp_int + 1, -36, 36); if (temp_int > 36)temp_int = 36; } else if (LCDML.BT_checkUp()) { temp_int = constrain(temp_int - 1, -36, 36); if (temp_int < -36)temp_int = -36; } } } else if (seq_active_function == 99 ) { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) seq_menu = constrain(seq_menu + 1, 0, 18); else if (LCDML.BT_checkUp()) seq_menu = constrain(seq_menu - 1, 0, 18); } } else if (seq_active_function == 0 ) { if (seq_content_type[seq_active_track] == 0) // is in Drumedit mode { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) activesample = constrain(activesample + 1, 0, NUM_DRUMSET_CONFIG + 5 ); else if (LCDML.BT_checkUp()) activesample = constrain(activesample - 1, 0, NUM_DRUMSET_CONFIG + 5 ); } } else //is in Instrument Mode { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) temp_int = constrain(temp_int + 1, 0, 116 ); else if (LCDML.BT_checkUp()) temp_int = constrain(temp_int - 1, 0, 116 ); } } } else if (seq_active_function == 2) { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) seq_active_track = constrain(seq_active_track + 1, 0, NUM_SEQ_PATTERN - 1); else if (LCDML.BT_checkUp()) seq_active_track = constrain(seq_active_track - 1, 0, NUM_SEQ_PATTERN - 1); lcd.setCursor(1, 0); if (seq_content_type[seq_active_track] == 0) lcd.print("Drum "); else if (seq_content_type[seq_active_track] == 1) lcd.print("Instr "); else if (seq_content_type[seq_active_track] == 2) lcd.print("Chord "); else lcd.print("Arp "); } } if (LCDML.BT_checkEnter()) //handle button presses during menu >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> { if (seq_menu > 2 && seq_menu < 19 && seq_vel[seq_active_track][seq_menu - 3] > 209 && seq_active_function != 40 && activesample != NUM_DRUMSET_CONFIG - 1) //edit pitch of sample { seq_active_function = 40; } else if ( seq_active_function == 40 ) // get out of pitch edit for samples { lcd.setCursor(8, 0); lcd.print(" "); seq_active_function = 0; activesample = 0; seq_refresh_display_play_status(); seq_printAllSeqSteps(); } else if (seq_menu == 34 ) //transpose pattern { seq_menu = 0; seq_active_function = 0; activesample = 0; temp_int = seq_data[seq_active_track][0]; lcd.setCursor(8, 0); lcd.print(" "); lcd.setCursor(12, 0); lcd.print(" "); lcd.setCursor(13, 0); if (seq_active_track < 10)lcd.print("0"); lcd.print(seq_active_track); seq_refresh_display_play_status(); seq_printAllSeqSteps(); } else if (seq_menu == 32 && seq_active_function == 97) //fill pattern every 1/4, 1/8, 1/16 step with active sample/note step 1 { seq_active_function = 96; seq_menu = 33; } else if (seq_menu == 33 && seq_active_function == 95) //fill pattern every 1/4, 1/8, 1/16 step with active sample/note step 2 { if (seq_content_type[seq_active_track] == 0) { //Drumtrack for (uint8_t i = 0; i < 16; i++) { seq_data[seq_active_track][i] = drum_config[seq_temp_select_menu].midinote; seq_vel[seq_active_track][i] = 120; if (seq_temp_active_menu == 0) i = i + 3; else if (seq_temp_active_menu == 1) i = i + 1; } } else { //Inst. Track for (uint8_t i = 0; i < 16; i++) { seq_data[seq_active_track][i] = seq_temp_select_menu; seq_vel[seq_active_track][i] = 120; if (seq_temp_active_menu == 0) i = i + 3; else if (seq_temp_active_menu == 1) i = i + 1; } } seq_menu = 0; seq_active_function = 0; activesample = 0; temp_int = seq_data[seq_active_track][0]; lcd.setCursor(8, 0); lcd.print(" "); seq_refresh_display_play_status(); seq_printAllSeqSteps(); } else if (seq_menu == 31 && seq_active_function != 40) //copy patterns { memcpy( seq_data[temp_int], seq_data[seq_active_track], sizeof(seq_data[0])); memcpy( seq_vel[temp_int], seq_vel[seq_active_track], sizeof(seq_vel[0])); seq_content_type[temp_int] = seq_content_type[seq_active_track]; seq_menu = 0; seq_active_function = 0; activesample = 0; temp_int = seq_data[seq_active_track][0]; lcd.setCursor(8, 0); lcd.print(" "); seq_refresh_display_play_status(); seq_printAllSeqSteps(); } else if (seq_menu == 30 && seq_active_function != 40) //swap patterns { uint8_t data_temp[1][16]; uint8_t vel_temp[1][16]; uint8_t content_type_temp; memcpy( data_temp[0], seq_data[seq_active_track], sizeof(data_temp[0])); memcpy( vel_temp[0], seq_vel[seq_active_track], sizeof(vel_temp[0])); content_type_temp = seq_content_type[seq_active_track]; memcpy( seq_data[seq_active_track], seq_data[temp_int], sizeof(data_temp[0])); memcpy( seq_vel[seq_active_track], seq_vel[temp_int], sizeof(vel_temp[0])); seq_content_type[seq_active_track] = seq_content_type[temp_int]; memcpy( seq_data[temp_int], data_temp[0], sizeof(data_temp[0])); memcpy( seq_vel[temp_int], vel_temp[0], sizeof(vel_temp[0])); seq_content_type[temp_int] = content_type_temp; seq_menu = 0; seq_active_function = 0; activesample = 0; lcd.setCursor(8, 0); lcd.print(" "); temp_int = seq_data[seq_active_track][0]; seq_refresh_display_play_status(); seq_printAllSeqSteps(); } if ( seq_menu == 0 && seq_active_function == 99) { seq_active_function = 0; } else if ( seq_menu == 0 && seq_active_function == 0) { if ( (seq_content_type[seq_active_track] == 0 && activesample == NUM_DRUMSET_CONFIG + 5) || (seq_content_type[seq_active_track] > 0 && temp_int == 116) ) { //transpose pattern lcd.setCursor(0, 0); lcd.print("Transpose:[ 00]"); for (uint8_t i = 0; i < 16; i++) { seq_data_buffer[i] = seq_data[seq_active_track][i]; } seq_menu = 34; temp_int = 0; seq_temp_select_menu = 0; seq_temp_active_menu = 0; } if ( (seq_content_type[seq_active_track] == 0 && activesample == NUM_DRUMSET_CONFIG + 4) || (seq_content_type[seq_active_track] > 0 && temp_int == 115) ) { //fill patterns lcd.setCursor(0, 0); lcd.print("Fill Pattern:"); lcd.setCursor(9, 1); lcd.print(" "); seq_menu = 32; seq_temp_select_menu = 0; seq_temp_active_menu = 0; } else if ( (seq_content_type[seq_active_track] == 0 && activesample == NUM_DRUMSET_CONFIG + 3) || (seq_content_type[seq_active_track] > 0 && temp_int == 114) ) { //swap patterns: Active pattern <-> destination pattern lcd.setCursor(0, 0); lcd.print("SwapPattern:"); temp_int = seq_active_track + 1; if (temp_int > NUM_SEQ_PATTERN - 1)temp_int = 0; seq_menu = 30; } else if ( ( seq_content_type[seq_active_track] == 0 && activesample == NUM_DRUMSET_CONFIG + 2) || ( seq_content_type[seq_active_track] > 0 && temp_int == 113) ) { //copy pattern lcd.setCursor(0, 0); lcd.print("Copy Pattern:"); temp_int = seq_active_track + 1; if (temp_int > NUM_SEQ_PATTERN - 1)temp_int = 0; seq_menu = 31; } else if ( (seq_content_type[seq_active_track] == 0 && activesample == NUM_DRUMSET_CONFIG + 1) || (seq_content_type[seq_active_track] > 0 && temp_int == 112) ) { //clear all patterns seq_clear_all_patterns(); seq_printAllSeqSteps(); } else if ( (seq_content_type[seq_active_track] == 0 && activesample == NUM_DRUMSET_CONFIG) || (seq_content_type[seq_active_track] > 0 && temp_int == 111) ) { //clear pattern seq_clear_active_pattern(); seq_printAllSeqSteps(); } seq_active_function = 99; } if ( seq_menu == 1 && seq_active_function != 40) { if (seq_running == false && seq_recording == false) { handleStart(); } else if (seq_running == true && seq_recording == false) { seq_running = true; seq_recording = true; seq_note_in = 0; } else if (seq_running == true && seq_recording == true) { handleStop(); } } else if ( seq_menu == 2 && seq_active_function != 40) { if (seq_active_function != 2) seq_active_function = 2; else seq_active_function = 99; if (seq_content_type[seq_active_track] == 0) { if (activesample < NUM_DRUMSET_CONFIG - 1) lcd.show(0, 1, 6, basename(drum_config[activesample].name)); } else { if (temp_int < 109) { lcd.setCursor(3, 0); lcd.print(" "); lcd.setCursor(1, 0); lcd.print(noteNames[temp_int % 12 ]); lcd.print( (temp_int / 12) - 1); } } } else if (seq_menu > 2 && seq_menu < 30 && seq_active_function != 40) { if (seq_active_function == 99) { if (seq_content_type[seq_active_track] == 0) { //Drumtrack if ( drum_config[activesample].midinote > 209 ) //it is a pitched sample { seq_vel[seq_active_track][seq_menu - 3] = drum_config[activesample].midinote; //seq_data[seq_active_track][seq_menu - 3] = MIDI_C4; } else // if (activesample == NUM_DRUMSET_CONFIG - 1) //user selected EMPTY note for pitched sample // { // seq_data[seq_active_track][seq_menu - 3] = 0; // seq_vel[seq_active_track][seq_menu - 3] = 0; // } // else //check if note is already there, if not -> insert it, else remove it from grid. if (seq_data[seq_active_track][seq_menu - 3] == drum_config[activesample].midinote) { seq_data[seq_active_track][seq_menu - 3] = 0; seq_vel[seq_active_track][seq_menu - 3] = 0; } else { seq_data[seq_active_track][seq_menu - 3] = drum_config[activesample].midinote; seq_vel[seq_active_track][seq_menu - 3] = 120; } } else { //Inst. Track if (temp_int == 109 || seq_data[seq_active_track][seq_menu - 3] == temp_int ) { //clear note seq_data[seq_active_track][seq_menu - 3] = 0; seq_vel[seq_active_track][seq_menu - 3] = 0; } else if (temp_int == 110) { //latch note seq_data[seq_active_track][seq_menu - 3] = 130; //seq_vel[seq_active_track][seq_menu - 3] = 0; } else { seq_data[seq_active_track][seq_menu - 3] = temp_int; seq_vel[seq_active_track][seq_menu - 3] = 120; } } } else seq_active_function = 99; } } //button check end <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< if (seq_menu == 34 && seq_active_function == 94) { //transpose char displayname[4] = {0, 0, 0, 0}; lcd.setCursor(10, 0); lcd.print("["); lcd.setCursor(11, 0); if (temp_int > 0) { lcd.print("+"); } else if (temp_int < 0) { lcd.print("-"); } else { lcd.print(" "); } sprintf(displayname, "%02d", abs(temp_int)); lcd.print( displayname); lcd.print("]"); for (uint8_t i = 0; i < 16; i++) { if (seq_content_type[seq_active_track] == 0) { //drums if (seq_data_buffer[i] != 0 && seq_data_buffer[i] + temp_int >= 0 && seq_data_buffer[i] + temp_int < 254 && seq_vel[seq_active_track][i] >= 210 ) // pitched drums only seq_data[seq_active_track][i] = seq_data_buffer[i] + temp_int; } else //instruments if (seq_content_type[seq_active_track] > 0) { if (seq_data_buffer[i] != 0 && seq_data_buffer[i] != 130 && seq_data_buffer[i] + temp_int > 0 && seq_data_buffer[i] + temp_int < 254) seq_data[seq_active_track][i] = seq_data_buffer[i] + temp_int; } } seq_printAllSeqSteps(); } else if (seq_menu == 33) { //fill pattern 2nd parameter lcd.setCursor(4, 1); lcd.print(" "); lcd.setCursor(9, 1); lcd.print(" "); lcd.setCursor(10, 1); lcd.print("["); lcd.setCursor(15, 1); lcd.print("]"); lcd.setCursor(11, 1); if (seq_temp_active_menu == 0) lcd.print(" 1/4"); else if (seq_temp_active_menu == 1) lcd.print(" 1/8"); else if (seq_temp_active_menu == 2) lcd.print("1/16"); } else if (seq_menu == 32 ) { //fill pattern if (seq_content_type[seq_active_track] == 0) { //drum lcd.setCursor(0, 1); lcd.print("with"); lcd.setCursor(4, 1); lcd.print("["); lcd.setCursor(9, 1); lcd.print("]"); lcd.show(1, 5, 4, basename(drum_config[seq_temp_select_menu].name)); lcd.setCursor(11, 1); if (seq_temp_active_menu == 0) lcd.print(" 1/4"); else if (seq_temp_active_menu == 1) lcd.print(" 1/8"); else if (seq_temp_active_menu == 2) lcd.print("1/16"); } else { //inst lcd.setCursor(0, 1); lcd.print("with"); lcd.setCursor(4, 1); lcd.print("["); lcd.setCursor(5, 1); lcd.print(noteNames[seq_temp_select_menu % 12 ]); lcd.print( (seq_temp_select_menu / 12) - 1); lcd.print(" "); lcd.setCursor(9, 1); lcd.print("]"); lcd.setCursor(11, 1); if (seq_temp_active_menu == 0) lcd.print(" 1/4"); else if (seq_temp_active_menu == 1) lcd.print(" 1/8"); else if (seq_temp_active_menu == 2) lcd.print("1/16"); } } else if (seq_menu == 31) { //copy pattern lcd.setCursor(12, 0); lcd.print("["); lcd.setCursor(15, 0); lcd.print("]"); lcd.setCursor(0, 1); lcd.print(" to:[ ]"); lcd.setCursor(13, 1); if (temp_int < 10) lcd.print("0"); lcd.print(temp_int); } else if (seq_menu == 30) { //swap pattern lcd.setCursor(12, 0); lcd.print("["); lcd.setCursor(15, 0); lcd.print("]"); lcd.setCursor(0, 1); lcd.print(" with:[ ]"); lcd.setCursor(13, 1); if (temp_int < 10) lcd.print("0"); lcd.print(temp_int); } else if (seq_menu == 0) { #ifdef TESTDISPLAY20x4 lcd.setCursor(13, 0); lcd.print(" "); lcd.setCursor(15, 0); lcd.print(" "); #else lcd.setCursor(9, 0); lcd.print(" "); lcd.setCursor(11, 0); lcd.print(" "); #endif lcd.setCursor(0, 0); lcd.print("["); if (seq_content_type[seq_active_track] == 0) //Drum Mode { if (activesample < NUM_DRUMSET_CONFIG - 1) { lcd.show(0, 1, 6, basename(drum_config[activesample].name)); } else if (activesample == NUM_DRUMSET_CONFIG - 1) { lcd.setCursor(1, 0); lcd.print("EMPTY "); } else if (activesample == NUM_DRUMSET_CONFIG ) { lcd.setCursor(1, 0); lcd.print("ClrPat"); } else if (activesample == NUM_DRUMSET_CONFIG + 1) { lcd.setCursor(1, 0); lcd.print("ClrAll"); } else if (activesample == NUM_DRUMSET_CONFIG + 2) { lcd.setCursor(1, 0); lcd.print("Copy P"); } else if (activesample == NUM_DRUMSET_CONFIG + 3) { lcd.setCursor(1, 0); lcd.print("Swap P"); } else if (activesample == NUM_DRUMSET_CONFIG + 4) { lcd.setCursor(1, 0); lcd.print("Fill P"); } else if (activesample == NUM_DRUMSET_CONFIG + 5) { lcd.setCursor(1, 0); lcd.print("Transp"); } lcd.setCursor(7, 0); lcd.print("]"); } else //Inst. Mode { if (temp_int < 109) { lcd.setCursor(3, 0); lcd.print(" "); lcd.setCursor(1, 0); lcd.print(noteNames[temp_int % 12 ]); lcd.print( (temp_int / 12) - 1); } else if (temp_int == 109) { lcd.setCursor(1, 0); lcd.print("EMPTY "); } else if (temp_int == 110) { lcd.setCursor(1, 0); lcd.print("LATCH "); } else if (temp_int == 111) { lcd.setCursor(1, 0); lcd.print("ClrPat"); } else if (temp_int == 112) { lcd.setCursor(1, 0); lcd.print("ClrAll"); } else if (temp_int == 113) { lcd.setCursor(1, 0); lcd.print("Copy P"); } else if (temp_int == 114) { lcd.setCursor(1, 0); lcd.print("Swap P"); } else if (temp_int == 115) { lcd.setCursor(1, 0); lcd.print("Fill P"); } else if (temp_int == 116) { lcd.setCursor(1, 0); lcd.print("Transp"); } lcd.setCursor(7, 0); lcd.print("]"); } } else if (seq_menu == 1) { lcd.setCursor(0, 0); lcd.print(" "); lcd.setCursor(7, 0); lcd.print(" "); #ifdef TESTDISPLAY20x4 lcd.setCursor(16, 0); lcd.print(" "); lcd.setCursor(19, 0); lcd.print(" "); #else lcd.setCursor(12, 0); lcd.print(" "); lcd.setCursor(15, 0); lcd.print(" "); #endif #ifdef TESTDISPLAY20x4 lcd.setCursor(13, 0); lcd.print("["); seq_refresh_display_play_status(); lcd.setCursor(15, 0); lcd.print("]"); #else lcd.setCursor(9, 0); lcd.print("["); seq_refresh_display_play_status(); lcd.setCursor(11, 0); lcd.print("]"); #endif } if (seq_menu == 2) { #ifdef TESTDISPLAY20x4 lcd.setCursor(13, 0); lcd.print(" "); lcd.setCursor(15, 0); lcd.print(" "); lcd.setCursor(16, 0); lcd.print("["); lcd.setCursor(17, 0); if (seq_active_track < 10) lcd.print("0"); lcd.print(seq_active_track); lcd.setCursor(19, 0); lcd.print("]"); #else lcd.setCursor(9, 0); lcd.print(" "); lcd.setCursor(11, 0); lcd.print(" "); lcd.setCursor(12, 0); lcd.print("["); lcd.setCursor(13, 0); if (seq_active_track < 10) lcd.print("0"); lcd.print(seq_active_track); lcd.setCursor(15, 0); lcd.print("]"); if (seq_content_type[seq_active_track] == 0) //Drum Mode { lcd.setCursor(0, 0); lcd.print(" "); lcd.show(0, 1, 6, basename(drum_config[activesample].name)); lcd.print(" "); } #endif lcd.setCursor(0, 1); seq_printAllSeqSteps(); #ifdef TESTDISPLAY20x4 seq_printVelGraphBar(); #endif } if (seq_menu == 3) { #ifdef TESTDISPLAY20x4 lcd.setCursor(16, 0); lcd.print(" "); lcd.setCursor(19, 0); lcd.print(" "); #else lcd.setCursor(12, 0); lcd.print(" "); lcd.setCursor(15, 0); lcd.print(" "); #endif // lcd.setCursor(0, 1); // lcd.print("_"); // lcd.setCursor(1, 1); // lcd.print(seq_find_shortname(1)[0]); } if (seq_menu > 2 && seq_menu < 19 && seq_active_function != 40) { if (seq_menu == 3) lcd.setCursor(0, 1); else lcd.setCursor(seq_menu - 3, 1); lcd.write(219); // cursor symbol if (seq_menu > 3) { lcd.setCursor(seq_menu - 4, 1); lcd.print(seq_find_shortname(seq_menu - 4)[0]); } if (seq_menu < 18) { lcd.setCursor(seq_menu - 2, 1); lcd.print(seq_find_shortname(seq_menu - 2)[0]); } if (seq_vel[seq_active_track][seq_menu - 3] > 209 && activesample != NUM_DRUMSET_CONFIG - 1 ) //is pitched sample and selected item is not set to EMPTY { lcd.setCursor(0, 0); lcd.print("[EDIT "); seq_print_current_note(); lcd.setCursor(8, 0); lcd.print("?]"); } else //print current sample name on active step if not empty if (seq_data[seq_active_track][seq_menu - 3] > 0) { lcd.setCursor(0, 0); lcd.print(" "); lcd.show(0, 1, 6, seq_find_drum_name_from_note( seq_data[seq_active_track][seq_menu - 3]) ); lcd.print(" "); } else { //if step empty, print selected, active sample if (seq_data[seq_active_track][seq_menu - 3] == 0) lcd.setCursor(0, 0); lcd.print(" "); lcd.show(0, 1, 6, basename(drum_config[activesample].name)); lcd.print(" "); } } else if (seq_active_function == 40 && activesample != NUM_DRUMSET_CONFIG - 1) { //is in pitch edit function 40 lcd.setCursor(1, 0); lcd.show(0, 1, 4, basename(drum_config[activesample].name)); lcd.setCursor(5, 0); lcd.print("-"); lcd.setCursor(6, 0); seq_print_current_note(); lcd.setCursor(9, 0); lcd.print("]"); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); seq_menu = 0; seq_active_function = 99; lcd_special_chars(SCROLLBAR); } } void UI_func_arpeggio(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.createChar(0, (uint8_t*)special_chars[19]); //play symbol lcd.createChar(2, (uint8_t*)special_chars[21]); //stop symbol seq_temp_select_menu = 0; seq_temp_active_menu = 0; lcd.setCursor( 0, 0); lcd.print("Len"); lcd.setCursor(7, 0); lcd.print( seq_chord_names[arp_chord][0]); lcd.print( seq_chord_names[arp_chord][1]); lcd.print( seq_chord_names[arp_chord][2]); lcd.print( seq_chord_names[arp_chord][3]); lcd.setCursor( 0, 1); lcd.print("Style"); lcd.setCursor( 11, 1); lcd.print("1/16"); arp_refresh_display_play_status(); } 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 (seq_temp_active_menu == 0) { if (LCDML.BT_checkDown()) seq_temp_select_menu = constrain(seq_temp_select_menu + ENCODER[ENC_R].speed(), 0, 3); else if (LCDML.BT_checkUp()) seq_temp_select_menu = constrain(seq_temp_select_menu - ENCODER[ENC_R].speed(), 0, 3); } else if (seq_temp_active_menu == 1) // Octave setting { if (LCDML.BT_checkDown()) arp_lenght = constrain(arp_lenght + ENCODER[ENC_R].speed(), 0, 9); else if (LCDML.BT_checkUp()) arp_lenght = constrain(arp_lenght - ENCODER[ENC_R].speed(), 0, 9); } else if (seq_temp_active_menu == 2) // Style setting { if (LCDML.BT_checkDown()) arp_style = constrain(arp_style + ENCODER[ENC_R].speed(), 0, 3); else if (LCDML.BT_checkUp()) arp_style = constrain(arp_style - ENCODER[ENC_R].speed(), 0, 3); } else if (seq_temp_active_menu == 3) // Arp Speed setting { if (LCDML.BT_checkDown()) arp_speed = constrain(arp_speed + ENCODER[ENC_R].speed(), 0, 1); else if (LCDML.BT_checkUp()) arp_speed = constrain(arp_speed - ENCODER[ENC_R].speed(), 0, 1); } if (LCDML.BT_checkEnter()) //handle button presses during menu >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> { if ( seq_temp_select_menu == 0 && seq_temp_active_menu == 0 ) { seq_temp_active_menu = 1; } else if ( seq_temp_select_menu == 0 && seq_temp_active_menu == 1 ) { seq_temp_active_menu = 0; } if ( seq_temp_select_menu == 1 && seq_temp_active_menu == 0 ) { seq_temp_active_menu = 2; } else if ( seq_temp_select_menu == 1 && seq_temp_active_menu == 2 ) { seq_temp_active_menu = 0; } else if ( seq_temp_select_menu == 2 ) { if (seq_running) { seq_running = !seq_running; handleStop(); arp_refresh_display_play_status(); seq_step = 0; arp_octave = 0; arp_step = 0; seq_chain_active_step = 0; } else { seq_running = !seq_running; arp_refresh_display_play_status(); handleStart(); } } else if ( seq_temp_select_menu == 3 && seq_temp_active_menu == 0 ) { seq_temp_active_menu = 3; } else if ( seq_temp_select_menu == 3 && seq_temp_active_menu == 3 ) { seq_temp_active_menu = 0; } } } lcd.setCursor( 4, 0); if (arp_lenght == 0) lcd.print("A"); else lcd.print(arp_lenght); //play all elements or from 1-xx elements lcd.setCursor( 6, 1); lcd.print( arp_style_names[arp_style][0] ); lcd.print( arp_style_names[arp_style][1] ); lcd.print( arp_style_names[arp_style][2] ); lcd.setCursor( 11, 1); if (arp_speed == 0)lcd.print("1/16"); else if (arp_speed == 1)lcd.print("1/8 "); if (seq_temp_select_menu == 0) { lcd.setCursor( 3, 0); lcd.print("["); lcd.setCursor( 5, 0); lcd.print("]"); lcd.setCursor( 5, 1); lcd.print(" "); lcd.setCursor( 9, 1); lcd.print(" "); lcd.setCursor( 13, 1); lcd.print(" "); lcd.setCursor( 15, 1); lcd.print(" "); } else if (seq_temp_select_menu == 1) { lcd.setCursor( 5, 1); lcd.print("["); lcd.setCursor( 9, 1); lcd.print("]"); lcd.setCursor( 3, 0); lcd.print(" "); lcd.setCursor( 5, 0); lcd.print(" "); lcd.setCursor( 13, 0); lcd.print(" "); lcd.setCursor( 15, 0); lcd.print(" "); } else if (seq_temp_select_menu == 2) { lcd.setCursor( 5, 1); lcd.print(" "); lcd.setCursor( 9, 1); lcd.print(" "); lcd.setCursor( 13, 0); lcd.print("["); lcd.setCursor( 15, 0); lcd.print("]"); lcd.setCursor( 10, 1); lcd.print(" "); lcd.setCursor( 15, 1); lcd.print(" "); } else if (seq_temp_select_menu == 3) { lcd.setCursor( 13, 0); lcd.print(" "); lcd.setCursor( 15, 0); lcd.print(" "); lcd.setCursor( 10, 1); lcd.print("["); lcd.setCursor( 15, 1); lcd.print("]"); lcd.setCursor( 3, 0); lcd.print(" "); lcd.setCursor( 5, 0); lcd.print(" "); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); lcd_special_chars(SCROLLBAR); } } void UI_func_seq_pat_chain(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { // setup function seq_temp_select_menu = 0; seq_temp_active_menu = 99; seq_menu = 0; lcd.setCursor( 0, 0); lcd.print("ChainStep:"); lcd.setCursor( 13, 0); lcd.print(seq_chain_active_chainstep + 1); lcd.setCursor( 14, 0); lcd.print("/"); lcd.setCursor( 15, 0); lcd.print(seq_chain_lenght + 1); lcd.setCursor( 0, 1); lcd.print("T"); lcd.setCursor(10 , 1); lcd.print("=P"); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (seq_temp_active_menu == 99) { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) seq_menu = constrain(seq_menu + 1, 0, 2); //menu select else if (LCDML.BT_checkUp()) seq_menu = constrain(seq_menu - 1, 0, 2); } } else if (seq_temp_active_menu == 90) { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) seq_temp_select_menu = constrain(seq_temp_select_menu + 1, 0, NUM_SEQ_TRACKS - 1); else if (LCDML.BT_checkUp()) seq_temp_select_menu = constrain(seq_temp_select_menu - 1, 0, NUM_SEQ_TRACKS - 1); } } else if (seq_temp_active_menu == 20) { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) seq_chain_active_chainstep = constrain(seq_chain_active_chainstep + 1, 0, seq_chain_lenght); else if (LCDML.BT_checkUp()) seq_chain_active_chainstep = constrain(seq_chain_active_chainstep - 1, 0, seq_chain_lenght); } } else if (seq_temp_active_menu == 18) { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) { seq_patternchain[seq_chain_active_chainstep][seq_temp_select_menu] = constrain(seq_patternchain[seq_chain_active_chainstep][seq_temp_select_menu] + 1, 0, NUM_SEQ_PATTERN ); } else if (LCDML.BT_checkUp()) { seq_patternchain[seq_chain_active_chainstep][seq_temp_select_menu] = constrain(seq_patternchain[seq_chain_active_chainstep][seq_temp_select_menu] - 1, 0, NUM_SEQ_PATTERN ); } } } if (LCDML.BT_checkEnter()) //handle button presses during menu >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> { if (seq_temp_active_menu == 99 && seq_menu == 0 ) { seq_temp_active_menu = 20; } else if (seq_temp_active_menu == 99 && seq_menu == 1 ) { seq_temp_active_menu = 90; } else if (seq_temp_active_menu == 99 && seq_menu == 2 ) { seq_temp_active_menu = 18; } else seq_temp_active_menu = 99; } if (seq_menu == 0) // Chainselect modify { lcd.setCursor( 12, 1); lcd.print(" "); lcd.setCursor( 15, 1); lcd.print(" "); lcd.setCursor(1 , 1); lcd.print(" "); lcd.setCursor(3 , 1); lcd.print(" "); lcd.setCursor( 11, 0); lcd.print("["); lcd.setCursor( 13, 0); lcd.print("]"); } else if (seq_menu == 1 ) { lcd.setCursor( 12, 1); lcd.print(" "); lcd.setCursor( 15, 1); lcd.print(" "); lcd.setCursor( 11, 0); lcd.print(" "); lcd.setCursor( 13, 0); lcd.print(" "); lcd.setCursor(1 , 1); lcd.print("["); lcd.setCursor(3 , 1); lcd.print("]"); } else if (seq_menu == 2 ) { lcd.setCursor( 11, 0); lcd.print(" "); lcd.setCursor( 13, 0); lcd.print(" "); lcd.setCursor(1 , 1); lcd.print(" "); lcd.setCursor(3 , 1); lcd.print(" "); lcd.setCursor( 12, 1); lcd.print("["); lcd.setCursor( 15, 1); lcd.print("]"); } lcd.setCursor( 12, 0); lcd.print(seq_chain_active_chainstep + 1); lcd.setCursor(2 , 1); lcd.print( seq_temp_select_menu + 1); lcd.setCursor(4 , 1); if (seq_track_type[seq_temp_select_menu] == 0 ) lcd.print("(Drum)"); else if (seq_track_type[seq_temp_select_menu] == 1 ) lcd.print("(Inst)"); else if (seq_track_type[seq_temp_select_menu] == 2 ) lcd.print("(Chrd)"); else lcd.print("(Arp.)"); lcd.setCursor( 13, 1); if (seq_patternchain[seq_chain_active_chainstep][seq_temp_select_menu] == NUM_SEQ_PATTERN)lcd.print("--"); //empty pattern else { if (seq_patternchain[seq_chain_active_chainstep][seq_temp_select_menu] < 10) lcd.print("0"); lcd.print(seq_patternchain[seq_chain_active_chainstep][seq_temp_select_menu] ); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); } } #ifdef TESTDISPLAY20x4 void UI_func_seq_mute_matrix(uint8_t param) // for test display 20x4 { if (LCDML.FUNC_setup()) // ****** SETUP ********* { // setup function seq_temp_active_menu = 99; seq_temp_select_menu = 1; seq_menu = 0; temp_int = 0; //y offset lcd.setCursor( 0, 0); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { uint8_t xscroll; if (seq_temp_active_menu == 99) { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) { seq_temp_select_menu = constrain(seq_temp_select_menu + 1, 0, NUM_SEQ_TRACKS + 1); if (seq_temp_select_menu == NUM_SEQ_TRACKS + 1 && temp_int != 3) //next chain step { lcd.setCursor( 14 , temp_int); lcd.print(" "); lcd.setCursor( 18 , temp_int); lcd.print(" "); seq_temp_select_menu = 1; if (temp_int < 3)temp_int++; } if (seq_temp_select_menu == NUM_SEQ_TRACKS + 1 && temp_int == 3) seq_temp_select_menu = NUM_SEQ_TRACKS; } else if (LCDML.BT_checkUp()) { seq_temp_select_menu = constrain(seq_temp_select_menu - 1, 0, NUM_SEQ_TRACKS + 1); if (seq_temp_select_menu == 0 && temp_int > 0) //prev chain step { lcd.setCursor( 2 , temp_int); lcd.print(" "); lcd.setCursor( 6 , temp_int); lcd.print(" "); seq_temp_select_menu = NUM_SEQ_TRACKS - 1 ; if (temp_int >= 0)temp_int = temp_int - 1; lcd.setCursor( 14 , temp_int); lcd.print("["); lcd.setCursor( 18 , temp_int); lcd.print("]"); } else if (seq_temp_select_menu < 1 && temp_int == 0 ) seq_temp_select_menu = 1; } } } if (LCDML.BT_checkEnter()) //handle button presses during menu >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> { if (seq_patternchain[temp_int][seq_temp_select_menu - 1] < NUM_SEQ_PATTERN) seq_patternchain[temp_int][seq_temp_select_menu - 1] = seq_patternchain[temp_int][seq_temp_select_menu - 1] + (NUM_SEQ_PATTERN + 10); else if (seq_patternchain[temp_int][seq_temp_select_menu - 1] > NUM_SEQ_PATTERN && seq_patternchain[temp_int][seq_temp_select_menu - 1] != 99) seq_patternchain[temp_int][seq_temp_select_menu - 1] = seq_patternchain[temp_int][seq_temp_select_menu - 1] - (NUM_SEQ_PATTERN + 10); else if (seq_patternchain[temp_int][seq_temp_select_menu - 1] == 99) seq_patternchain[temp_int][seq_temp_select_menu - 1] = NUM_SEQ_PATTERN - 1; } if (seq_temp_select_menu - 1 < 4)xscroll = 0; else if (seq_temp_select_menu - 1 == 4)xscroll = 1; else xscroll = 2; for (uint8_t y = 0; y < 4; y++) { for (uint8_t x = 0; x < NUM_SEQ_TRACKS - 2; x++) { lcd.setCursor( x * 4 + 3, y); if (seq_patternchain[y][x + xscroll] < NUM_SEQ_PATTERN ) { if (seq_track_type[x + xscroll ] == 0 ) lcd.print("D"); else if (seq_track_type[x + xscroll ] == 1 ) lcd.print("I"); else if (seq_track_type[x + xscroll ] == 2 ) lcd.print("C"); else lcd.print("A"); if (seq_patternchain[y][x + xscroll] < 10) lcd.print("0"); lcd.print( seq_patternchain[y][x + xscroll] ); } else lcd.print("OFF"); } } if (xscroll == 0) { //print cursor lcd.setCursor( (seq_temp_select_menu - 1) * 4 + 2, temp_int); lcd.print("["); lcd.setCursor( (seq_temp_select_menu - 1) * 4 + 6, temp_int); lcd.print("]"); if ((seq_temp_select_menu - 1) > 0) { lcd.setCursor( (seq_temp_select_menu - 1) * 4 + 2 - 4 , temp_int); lcd.print(" "); } if ((seq_temp_select_menu - 1) < 4) { lcd.setCursor( (seq_temp_select_menu - 1) * 4 + 6 + 4 , temp_int); lcd.print(" "); } } lcd.setCursor( 0, 0); lcd.print("T"); lcd.print(seq_temp_select_menu); lcd.setCursor( 0, 1); lcd.print("S"); lcd.print(temp_int + 1); // Chain Step } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); } } #else void UI_func_seq_mute_matrix(uint8_t param) // for standard display 16x2 { if (LCDML.FUNC_setup()) // ****** SETUP ********* { // setup function seq_temp_active_menu = 99; seq_temp_select_menu = 1; seq_menu = 0; temp_int = 0; //y offset lcd.setCursor( 0, 0); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { uint8_t xscroll; if (seq_temp_active_menu == 99) { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) { seq_temp_select_menu = constrain(seq_temp_select_menu + 1, 0, NUM_SEQ_TRACKS + 1); if (seq_temp_select_menu == NUM_SEQ_TRACKS + 1 && temp_int != 3) //next chain step { lcd.setCursor( 10 , 1); lcd.print(" "); lcd.setCursor( 14 , 1); lcd.print(" "); seq_temp_select_menu = 1; if (temp_int < 3)temp_int++; } if (seq_temp_select_menu == NUM_SEQ_TRACKS + 1 && temp_int == 3) seq_temp_select_menu = NUM_SEQ_TRACKS; } else if (LCDML.BT_checkUp()) { seq_temp_select_menu = constrain(seq_temp_select_menu - 1, 0, NUM_SEQ_TRACKS + 1); if (seq_temp_select_menu == 0 && temp_int > 0) //prev chain step { lcd.setCursor( 2 , 1); lcd.print(" "); lcd.setCursor( 6 , 1); lcd.print(" "); seq_temp_select_menu = NUM_SEQ_TRACKS - 1 ; if (temp_int >= 0)temp_int = temp_int - 1; lcd.setCursor( 10 , 1); lcd.print("["); lcd.setCursor( 14 , 1); lcd.print("]"); } else if (seq_temp_select_menu < 1 && temp_int == 0 ) seq_temp_select_menu = 1; } } } if (LCDML.BT_checkEnter()) //handle button presses during menu >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> { if (seq_patternchain[temp_int][seq_temp_select_menu - 1] < NUM_SEQ_PATTERN) seq_patternchain[temp_int][seq_temp_select_menu - 1] = seq_patternchain[temp_int][seq_temp_select_menu - 1] + (NUM_SEQ_PATTERN + 10); else if (seq_patternchain[temp_int][seq_temp_select_menu - 1] > NUM_SEQ_PATTERN && seq_patternchain[temp_int][seq_temp_select_menu - 1] != 99) seq_patternchain[temp_int][seq_temp_select_menu - 1] = seq_patternchain[temp_int][seq_temp_select_menu - 1] - (NUM_SEQ_PATTERN + 10); else if (seq_patternchain[temp_int][seq_temp_select_menu - 1] == 99) seq_patternchain[temp_int][seq_temp_select_menu - 1] = NUM_SEQ_PATTERN - 1; } if (seq_temp_select_menu - 1 < 3)xscroll = 0; else xscroll = seq_temp_select_menu - 3; if (xscroll == 0) { //print cursor lcd.setCursor( (seq_temp_select_menu - 1) * 4 + 2, 1); lcd.print("["); lcd.setCursor( (seq_temp_select_menu - 1) * 4 + 6, 1); lcd.print("]"); if ((seq_temp_select_menu - 1) > 0) { lcd.setCursor( (seq_temp_select_menu - 1) * 4 + 2 - 4 , 1); lcd.print(" "); } if ((seq_temp_select_menu - 1) < 4) { lcd.setCursor( (seq_temp_select_menu - 1) * 4 + 6 + 4 , 1); lcd.print(" "); } lcd.setCursor( 3, 0); lcd.print("T1"); lcd.setCursor( 7, 0); lcd.print("T2"); lcd.setCursor( 11, 0); lcd.print("T3"); } else { lcd.setCursor( 3, 0); lcd.print("T"); lcd.print(seq_temp_select_menu - 2); lcd.setCursor( 7, 0); lcd.print("T"); lcd.print(seq_temp_select_menu - 2 + 1); lcd.setCursor( 11, 0); lcd.print("T"); lcd.print(seq_temp_select_menu - 2 + 2); } for (uint8_t x = 0; x < NUM_SEQ_TRACKS - 3; x++) { lcd.setCursor( x * 4 + 3, 1); if (seq_patternchain[temp_int][x + xscroll] < NUM_SEQ_PATTERN ) { if (seq_track_type[x + xscroll] == 0 ) lcd.print("D"); else if (seq_track_type[x + xscroll ] == 1 ) lcd.print("I"); else if (seq_track_type[x + xscroll ] == 2 ) lcd.print("C"); else lcd.print("A"); if (seq_patternchain[temp_int][x + xscroll] < 10) lcd.print("0"); lcd.print( seq_patternchain[temp_int][x + xscroll] ); } else lcd.print("OFF"); } lcd.setCursor( 0, 1); lcd.print("S"); lcd.print(temp_int + 1); // Chain Step } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); } } #endif void UI_func_seq_track_setup(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { // setup function seq_temp_active_menu = 99; seq_temp_select_menu = 0; lcd.setCursor(0 , 0); lcd.print("Track Setup"); lcd.setCursor(0 , 1); lcd.print("Track "); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (seq_temp_active_menu == 99) { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) seq_temp_select_menu = constrain(seq_temp_select_menu + 1, 0, NUM_SEQ_TRACKS - 1); else if (LCDML.BT_checkUp()) seq_temp_select_menu = constrain(seq_temp_select_menu - 1, 0, NUM_SEQ_TRACKS - 1); } } else { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) seq_track_type[seq_temp_active_menu] = constrain(seq_track_type[seq_temp_active_menu] + 1, 0, 3); else if (LCDML.BT_checkUp()) seq_track_type[seq_temp_active_menu] = constrain(seq_track_type[seq_temp_active_menu] - 1, 0, 3); } } if (LCDML.BT_checkEnter()) //handle button presses during menu >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> { if (seq_temp_active_menu == 99) { seq_temp_active_menu = seq_temp_select_menu; } else { seq_temp_active_menu = 99; } } if (seq_temp_active_menu == 99) { lcd.setCursor(8 , 1); lcd.print(" "); lcd.setCursor(15 , 1); lcd.print(" "); lcd.setCursor(5 , 1); lcd.print("["); lcd.setCursor(6 , 1); lcd.print(seq_temp_select_menu + 1); lcd.setCursor(7 , 1); lcd.print("]"); lcd.setCursor(9 , 1); } else { lcd.setCursor(5 , 1); lcd.print(" "); lcd.setCursor(7 , 1); lcd.print(" "); lcd.setCursor(8 , 1); lcd.print("["); lcd.setCursor(15 , 1); lcd.print("]"); lcd.setCursor(9 , 1); } if (seq_track_type[seq_temp_select_menu] == 0 ) lcd.print("Drums "); else if (seq_track_type[seq_temp_select_menu] == 1 ) lcd.print("Instru"); else if (seq_track_type[seq_temp_select_menu] == 2 )lcd.print("Chords"); else lcd.print("Arp "); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); } } void UI_func_dexed_assign(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { // setup function seq_temp_active_menu = 99; seq_temp_select_menu = 0; lcd.setCursor(0 , 0); lcd.print("Dexed Assign"); lcd.setCursor(0 , 1); lcd.print("Track "); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if (seq_temp_active_menu == 99) { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) seq_temp_select_menu = constrain(seq_temp_select_menu + 1, 0, NUM_SEQ_TRACKS - 1); else if (LCDML.BT_checkUp()) seq_temp_select_menu = constrain(seq_temp_select_menu - 1, 0, NUM_SEQ_TRACKS - 1); } } else { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) seq_inst_dexed[seq_temp_active_menu] = constrain(seq_inst_dexed[seq_temp_active_menu] + 1, 0, 1); else if (LCDML.BT_checkUp()) seq_inst_dexed[seq_temp_active_menu] = constrain(seq_inst_dexed[seq_temp_active_menu] - 1, 0, 1); } } if (LCDML.BT_checkEnter()) //handle button presses during menu >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> { if (seq_temp_active_menu == 99) { seq_temp_active_menu = seq_temp_select_menu; } else { seq_temp_active_menu = 99; } } if (seq_temp_active_menu == 99) { lcd.setCursor(8 , 1); lcd.print(" "); lcd.setCursor(15 , 1); lcd.print(" "); lcd.setCursor(5 , 1); lcd.print("["); lcd.setCursor(6 , 1); lcd.print(seq_temp_select_menu + 1); lcd.setCursor(7 , 1); lcd.print("]"); lcd.setCursor(9 , 1); } else { lcd.setCursor(5 , 1); lcd.print(" "); lcd.setCursor(7 , 1); lcd.print(" "); lcd.setCursor(8 , 1); lcd.print("["); lcd.setCursor(15 , 1); lcd.print("]"); lcd.setCursor(9 , 1); } if (seq_inst_dexed[seq_temp_select_menu] == 0 ) lcd.print("dexed0"); else if (seq_inst_dexed[seq_temp_select_menu] == 1 ) lcd.print("dexed1"); else lcd.print("??????"); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); } } void UI_func_load_performance(uint8_t param) { static uint8_t mode; if (LCDML.FUNC_setup()) // ****** SETUP ********* { char tmp[10]; if (seq_state_last_loadsave != 200)temp_int = seq_state_last_loadsave; else temp_int = param; mode = 0; encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("Load Seq. state ")); lcd.setCursor(0, 1); sprintf(tmp, "[%2d]", param); 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()) { temp_int = constrain(temp_int + ENCODER[ENC_L].speed(), 0, 99); } else if (LCDML.BT_checkUp()) { temp_int = constrain(temp_int - ENCODER[ENC_L].speed(), 0, 99); } else if (LCDML.BT_checkEnter()) { mode = 0xff; lcd.setCursor(0, 1); if (load_sd_seq_json(temp_int) == false) lcd.print("Does not exist."); else { load_sd_seq_json(temp_int); seq_state_last_loadsave = temp_int; lcd.print("Done. "); } delay(MESSAGE_WAIT_TIME); LCDML.FUNC_goBackToMenu(); } } lcd.setCursor(0, 1); char tmp[10]; sprintf(tmp, "[%2d]", temp_int); lcd.print(tmp); if (check_sd_performance_exists(temp_int)) { get_sd_seq_name_json(temp_int); if ( seq_name_temp[0] != 0 ) lcd.show(1, 5, 11, seq_name_temp); else lcd.print(" -- DATA --"); } else lcd.print(" "); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { if (mode < 0xff) { lcd.show(1, 0, 16, "Canceled."); delay(MESSAGE_WAIT_TIME); } else 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; if (seq_state_last_loadsave != 200) temp_int = seq_state_last_loadsave; else temp_int = 0; mode = 0; encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("Save Seq. state:")); lcd.setCursor(0, 1); sprintf(tmp, "[%2d]", temp_int); lcd.print(tmp); sprintf(tmp, "/%s/%d-S.json", PERFORMANCE_CONFIG_PATH, temp_int); if (SD.exists(tmp)) overwrite = true; else overwrite = false; if (check_sd_performance_exists(temp_int)) { get_sd_seq_name_json(temp_int); if ( seq_name_temp[0] != 0 ) lcd.show(1, 5, 11, seq_name_temp); else lcd.print(" -- DATA --"); } } 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) temp_int = constrain(temp_int + ENCODER[ENC_L].speed(), 0, 99); else yesno = true; } else if (LCDML.BT_checkUp()) { if (mode == 0) temp_int = constrain(temp_int - ENCODER[ENC_L].speed(), 0, 99); 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/%d-S.json", PERFORMANCE_CONFIG_PATH, temp_int); SD.remove(tmp); } save_sd_seq_json(temp_int); lcd.show(1, 0, 16, "Done."); seq_state_last_loadsave = temp_int; delay(MESSAGE_WAIT_TIME); LCDML.FUNC_goBackToMenu(); } else if (overwrite == true && yesno == false) { char tmp[10]; mode = 0; lcd.setCursor(0, 1); sprintf(tmp, "[%2d] ", temp_int); lcd.print(tmp); } } } if (mode == 0) { char tmp[FILENAME_LEN]; sprintf(tmp, "/%s/%d-S.json", PERFORMANCE_CONFIG_PATH, temp_int); if (SD.exists(tmp)) overwrite = true; else overwrite = false; lcd.setCursor(0, 1); sprintf(tmp, "[%2d]", temp_int); lcd.print(tmp); lcd.setCursor(5, 1); if (overwrite == false) { lcd.print("-- empty --"); } else if (check_sd_performance_exists(temp_int)) { get_sd_seq_name_json(temp_int); if ( seq_name_temp[0] != 0 ) lcd.show(1, 5, 11, seq_name_temp); else lcd.print("-- DATA --"); } else lcd.print(" "); } 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.show(1, 0, 16, "Canceled."); delay(MESSAGE_WAIT_TIME); } encoderDir[ENC_R].reset(); } } 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(); } void UI_func_smart_filter(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("Drm Smart Filter")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) smartfilter = !smartfilter; else if (LCDML.BT_checkUp()) smartfilter = !smartfilter; } lcd.setCursor(0, 1); if (smartfilter) lcd.print(F("[ON ]")); else lcd.print(F("[OFF]")); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); } } void UI_func_velocity_level(uint8_t param) { if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("Velocity Lvl", configuration.dexed[selected_instance_id].velocity_level, 1.0, VELOCITY_LEVEL_MIN, VELOCITY_LEVEL_MAX, 3, false, false, true); lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } 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[selected_instance_id].velocity_level = constrain(configuration.dexed[selected_instance_id].velocity_level + ENCODER[ENC_R].speed(), VELOCITY_LEVEL_MIN, VELOCITY_LEVEL_MAX); else if (LCDML.BT_checkUp()) configuration.dexed[selected_instance_id].velocity_level = constrain(configuration.dexed[selected_instance_id].velocity_level - ENCODER[ENC_R].speed(), VELOCITY_LEVEL_MIN, VELOCITY_LEVEL_MAX); } #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif lcd_display_bar_int("Velocity Lvl", configuration.dexed[selected_instance_id].velocity_level, 1.0, VELOCITY_LEVEL_MIN, VELOCITY_LEVEL_MAX, 3, false, false, false); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_update_instance_icons() { #ifdef TESTDISPLAY20x4 lcd.setCursor(18, 0); lcd.write(0); //Icon for first instance lcd.setCursor(19, 0); lcd.write(1); //Icon for second instance #else lcd.setCursor(14, 0); lcd.write(0); //Icon for first instance lcd.setCursor(15, 0); lcd.write(1); //Icon for second instance #endif } void UI_func_voice_select(uint8_t param) { static uint8_t menu_voice_select = MENU_VOICE_SOUND; if (LCDML.FUNC_setup()) // ****** SETUP ********* { #ifdef TESTDISPLAY20x4 lcd.setCursor(0, 3); lcd.print("MENU"); lcd.setCursor(17, 3); lcd.print("+/-"); #endif encoderDir[ENC_R].reset(); lcd_active_instance_number(selected_instance_id); char bank_name[BANK_NAME_LEN]; char voice_name[VOICE_NAME_LEN]; if (!get_bank_name(configuration.performance.bank[selected_instance_id], bank_name, sizeof(bank_name))) strcpy(bank_name, "*ERROR*"); if (!get_voice_by_bank_name(configuration.performance.bank[selected_instance_id], bank_name, configuration.performance.voice[selected_instance_id], voice_name, sizeof(voice_name))) strcpy(voice_name, "*ERROR*"); UI_update_instance_icons(); lcd.createChar(2, (uint8_t*)special_chars[18]); // favorites symbol #ifdef TEENSY3_6 lcd.createChar(6, (uint8_t*)special_chars[16]); // MIDI activity note symbol lcd.createChar(7, (uint8_t*)special_chars[16]); // MIDI activity note symbol #endif } if (LCDML.FUNC_loop()) // ****** LOOP ********* { char bank_name[BANK_NAME_LEN]; char voice_name[VOICE_NAME_LEN]; if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()) || (LCDML.BT_checkEnter() && (encoderDir[ENC_R].ButtonShort() || encoderDir[ENC_R].ButtonLong()))) { uint8_t bank_tmp; int8_t voice_tmp; // Reset Performance Modifiers to 0 after every preset change for (uint8_t count_tmp = 0; count_tmp < NUM_DEXED; count_tmp++) { perform_attack_mod[count_tmp] = 0; perform_release_mod[count_tmp] = 0; } active_perform_page = 1; if (LCDML.BT_checkUp()) { //start : show all presets if (configuration.sys.favorites == 0) { switch (menu_voice_select) { case MENU_VOICE_BANK: memset(g_bank_name[selected_instance_id], 0, BANK_NAME_LEN); bank_tmp = constrain(configuration.performance.bank[selected_instance_id] - ENCODER[ENC_R].speed(), 0, MAX_BANKS - 1); configuration.performance.bank[selected_instance_id] = bank_tmp; #ifdef DISPLAY_LCD_SPI change_disp_sd(false); #endif load_sd_voice(configuration.performance.bank[selected_instance_id], configuration.performance.voice[selected_instance_id], selected_instance_id); #ifdef DISPLAY_LCD_SPI change_disp_sd(true); #endif break; case MENU_VOICE_SOUND: memset(g_voice_name[selected_instance_id], 0, VOICE_NAME_LEN); voice_tmp = configuration.performance.voice[selected_instance_id] - ENCODER[ENC_R].speed(); if (voice_tmp < 0 && configuration.performance.bank[selected_instance_id] - 1 >= 0) { configuration.performance.bank[selected_instance_id]--; configuration.performance.bank[selected_instance_id] = constrain(configuration.performance.bank[selected_instance_id], 0, MAX_BANKS - 1); } else if (voice_tmp < 0 && configuration.performance.bank[selected_instance_id] - 1 <= 0) { voice_tmp = 0; } if (voice_tmp < 0) voice_tmp = MAX_VOICES + voice_tmp; configuration.performance.voice[selected_instance_id] = constrain(voice_tmp, 0, MAX_VOICES - 1); #ifdef DISPLAY_LCD_SPI change_disp_sd(false); #endif load_sd_voice(configuration.performance.bank[selected_instance_id], configuration.performance.voice[selected_instance_id], selected_instance_id); #ifdef DISPLAY_LCD_SPI change_disp_sd(true); #endif break; } } else //only Favs if (configuration.sys.favorites == 1) { locate_previous_favorite(); #ifdef DISPLAY_LCD_SPI change_disp_sd(false); #endif load_sd_voice(configuration.performance.bank[selected_instance_id], configuration.performance.voice[selected_instance_id], selected_instance_id); #ifdef DISPLAY_LCD_SPI change_disp_sd(true); #endif } else //only non-Favs if (configuration.sys.favorites == 2) { locate_previous_non_favorite(); #ifdef DISPLAY_LCD_SPI change_disp_sd(false); #endif load_sd_voice(configuration.performance.bank[selected_instance_id], configuration.performance.voice[selected_instance_id], selected_instance_id); #ifdef DISPLAY_LCD_SPI change_disp_sd(true); #endif //break; } else //random non-Favs if (configuration.sys.favorites == 3) { locate_random_non_favorite(); #ifdef DISPLAY_LCD_SPI change_disp_sd(false); #endif load_sd_voice(configuration.performance.bank[selected_instance_id], configuration.performance.voice[selected_instance_id], selected_instance_id); #ifdef DISPLAY_LCD_SPI change_disp_sd(true); #endif } } //end UP else if (LCDML.BT_checkDown()) { //start : show all presets if (configuration.sys.favorites == 0) { switch (menu_voice_select) { case MENU_VOICE_BANK: memset(g_bank_name[selected_instance_id], 0, BANK_NAME_LEN); bank_tmp = constrain(configuration.performance.bank[selected_instance_id] + ENCODER[ENC_R].speed(), 0, MAX_BANKS - 1); configuration.performance.bank[selected_instance_id] = bank_tmp; #ifdef DISPLAY_LCD_SPI change_disp_sd(false); #endif load_sd_voice(configuration.performance.bank[selected_instance_id], configuration.performance.voice[selected_instance_id], selected_instance_id); #ifdef DISPLAY_LCD_SPI change_disp_sd(true); #endif break; case MENU_VOICE_SOUND: memset(g_voice_name[selected_instance_id], 0, VOICE_NAME_LEN); voice_tmp = configuration.performance.voice[selected_instance_id] + ENCODER[ENC_R].speed(); if (voice_tmp >= MAX_VOICES && configuration.performance.bank[selected_instance_id] + 1 < MAX_BANKS) { voice_tmp %= MAX_VOICES; configuration.performance.bank[selected_instance_id]++; configuration.performance.bank[selected_instance_id] = constrain(configuration.performance.bank[selected_instance_id], 0, MAX_BANKS - 1); } else if (voice_tmp >= MAX_VOICES && configuration.performance.bank[selected_instance_id] + 1 >= MAX_BANKS) { voice_tmp = MAX_VOICES - 1; } configuration.performance.voice[selected_instance_id] = constrain(voice_tmp, 0, MAX_VOICES - 1); #ifdef DISPLAY_LCD_SPI change_disp_sd(false); #endif load_sd_voice(configuration.performance.bank[selected_instance_id], configuration.performance.voice[selected_instance_id], selected_instance_id); #ifdef DISPLAY_LCD_SPI change_disp_sd(true); #endif break; } } else //only Favs if (configuration.sys.favorites == 1) { locate_next_favorite(); #ifdef DISPLAY_LCD_SPI change_disp_sd(false); #endif load_sd_voice(configuration.performance.bank[selected_instance_id], configuration.performance.voice[selected_instance_id], selected_instance_id); #ifdef DISPLAY_LCD_SPI change_disp_sd(true); #endif //break; } else //only non-Favs if (configuration.sys.favorites == 2) { locate_next_non_favorite(); #ifdef DISPLAY_LCD_SPI change_disp_sd(false); #endif load_sd_voice(configuration.performance.bank[selected_instance_id], configuration.performance.voice[selected_instance_id], selected_instance_id); #ifdef DISPLAY_LCD_SPI change_disp_sd(true); #endif //break; } else //random non-Favs if (configuration.sys.favorites == 3) { locate_random_non_favorite(); #ifdef DISPLAY_LCD_SPI change_disp_sd(false); #endif load_sd_voice(configuration.performance.bank[selected_instance_id], configuration.performance.voice[selected_instance_id], selected_instance_id); #ifdef DISPLAY_LCD_SPI change_disp_sd(true); #endif } } else if (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonPressed()) { if (menu_voice_select == MENU_VOICE_BANK) menu_voice_select = MENU_VOICE_SOUND; else menu_voice_select = MENU_VOICE_BANK; } #if NUM_DEXED > 1 else if (LCDML.BT_checkEnter()) { selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); UI_update_instance_icons(); } #endif } if (strlen(g_bank_name[selected_instance_id]) > 0) { strcpy(bank_name, g_bank_name[selected_instance_id]); } else { if (!get_bank_name(configuration.performance.bank[selected_instance_id], bank_name, sizeof(bank_name))) strcpy(bank_name, "*ERROR*"); } if (strlen(g_voice_name[selected_instance_id]) > 0) { strcpy(voice_name, g_voice_name[selected_instance_id]); } else { if (!get_voice_by_bank_name(configuration.performance.bank[selected_instance_id], bank_name, configuration.performance.voice[selected_instance_id], voice_name, sizeof(voice_name))) strcpy(voice_name, "*ERROR*"); } lcd.show(0, 0, 2, configuration.performance.bank[selected_instance_id]); lcd.show(1, 0, 2, configuration.performance.voice[selected_instance_id] + 1); #ifdef TESTDISPLAY20x4 string_toupper(bank_name); lcd.show(0, 4, 8, bank_name); string_toupper(voice_name); lcd.show(1, 4, 10, voice_name); switch (menu_voice_select) { case MENU_VOICE_BANK: lcd.show(0, 3, 1, "["); lcd.show(0, 12, 1, "]"); lcd.show(1, 3, 1, " "); lcd.show(1, 14, 1, " "); break; case MENU_VOICE_SOUND: lcd.show(0, 3, 1, " "); lcd.show(0, 12, 1, " "); lcd.show(1, 3, 1, "["); lcd.show(1, 14, 1, "]"); break; } #else string_toupper(bank_name); lcd.show(0, 3, 8, bank_name); lcd.show(0, 12, 1, " "); //forced because this char does not clear after fav-search (because the bank name is one char to short to do it). string_toupper(voice_name); lcd.show(1, 3, 10, voice_name); switch (menu_voice_select) { case MENU_VOICE_BANK: lcd.show(0, 2, 1, "["); lcd.show(0, 11, 1, "]"); lcd.show(1, 2, 1, " "); lcd.show(1, 13, 1, " "); break; case MENU_VOICE_SOUND: lcd.show(0, 2, 1, " "); lcd.show(0, 11, 1, " "); lcd.show(1, 2, 1, "["); lcd.show(1, 13, 1, "]"); break; } #endif draw_favorite_icon(configuration.performance.bank[selected_instance_id], configuration.performance.voice[selected_instance_id], selected_instance_id); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } } void UI_func_volume(uint8_t param) { char tmp[6]; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_L].reset(); if (active_perform_page == 1) { //Master Volume lcd_special_chars(BLOCKBAR); lcd_display_bar_int("Master Vol.", configuration.sys.vol, 1.0, VOLUME_MIN, VOLUME_MAX, 3, false, false, true); back_from_volume = 0; } else if (active_perform_page == 2) { // Live Performance Mod - Attack lcd.setCursor(0, 0); lcd.print("Live Modify"); lcd.setCursor(0, 1); lcd.print("Attack = "); lcd.setCursor(13, 1); sprintf(tmp, "%03d", perform_attack_mod[selected_instance_id]); lcd.print(tmp); back_from_volume = 0; } else if (active_perform_page == 3) { // Live Performance Mod - Release lcd.setCursor(0, 0); lcd.print("Live Modify"); lcd.setCursor(11, 1); lcd.print("Release = "); lcd.setCursor(13, 1); sprintf(tmp, "%03d", perform_release_mod[selected_instance_id]); lcd.print(tmp); back_from_volume = 0; } lcd.setCursor(12, 0); lcd.print("P"); lcd.setCursor(13, 0); lcd.print(active_perform_page); lcd.setCursor(14, 0); lcd.print("/3"); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ( LCDML.BT_checkDown() && encoderDir[ENC_R].Down() ) { back_from_volume = 0; active_perform_page++; if (active_perform_page > 3)active_perform_page = 1; } else if ( LCDML.BT_checkUp() && encoderDir[ENC_R].Up() ) { back_from_volume = 0; active_perform_page--; if (active_perform_page < 1)active_perform_page = 3; } if ((LCDML.BT_checkDown() && encoderDir[ENC_L].Down() ) || (LCDML.BT_checkUp() && encoderDir[ENC_L].Up() )) { if (active_perform_page == 1) { 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); } } else if ( active_perform_page == 2) { //Attack if (LCDML.BT_checkDown() ) { if (perform_attack_mod[selected_instance_id] == 0) for (uint8_t i = 0; i < 6; i++) { orig_attack_values[selected_instance_id][i] = MicroDexed[selected_instance_id]->getOPRate(i, ATTACK); } perform_attack_mod[selected_instance_id] = constrain(perform_attack_mod[selected_instance_id] + ENCODER[ENC_L].speed(), -MAX_PERF_MOD, MAX_PERF_MOD); for (uint8_t i = 0; i < 6; i++) MicroDexed[selected_instance_id]->setOPRate(i, ATTACK, orig_attack_values[selected_instance_id][i] - perform_attack_mod[selected_instance_id] ); } else if (LCDML.BT_checkUp() ) { if (perform_attack_mod[selected_instance_id] == 0) // Save initial Values for (uint8_t i = 0; i < 6; i++) { orig_attack_values[selected_instance_id][i] = MicroDexed[selected_instance_id]->getOPRate(i, ATTACK); } perform_attack_mod[selected_instance_id] = constrain(perform_attack_mod[selected_instance_id] - ENCODER[ENC_L].speed(), -MAX_PERF_MOD, MAX_PERF_MOD); for (uint8_t i = 0; i < 6; i++) MicroDexed[selected_instance_id]->setOPRate(i, ATTACK, orig_attack_values[selected_instance_id][i] - perform_attack_mod[selected_instance_id] ); } } else if (active_perform_page == 3) { //Release if (LCDML.BT_checkDown() ) { if (perform_release_mod[selected_instance_id] == 0) // Save initial Values for (uint8_t i = 0; i < 6; i++) { orig_release_values[selected_instance_id][i] = MicroDexed[selected_instance_id]->getOPRate(i, RELEASE); } perform_release_mod[selected_instance_id] = constrain(perform_release_mod[selected_instance_id] + ENCODER[ENC_L].speed(), -MAX_PERF_MOD, MAX_PERF_MOD); for (uint8_t i = 0; i < 6; i++) MicroDexed[selected_instance_id]->setOPRate(i, RELEASE, orig_release_values[selected_instance_id][i] - perform_release_mod[selected_instance_id] ); } else if (LCDML.BT_checkUp() ) { if (perform_release_mod[selected_instance_id] == 0) for (uint8_t i = 0; i < 6; i++) { orig_release_values[selected_instance_id][i] = MicroDexed[selected_instance_id]->getOPRate(i, RELEASE); } perform_release_mod[selected_instance_id] = constrain(perform_release_mod[selected_instance_id] - ENCODER[ENC_L].speed(), -MAX_PERF_MOD, MAX_PERF_MOD); for (uint8_t i = 0; i < 6; i++) MicroDexed[selected_instance_id]->setOPRate(i, RELEASE, orig_release_values[selected_instance_id][i] - perform_release_mod[selected_instance_id] ); } } } lcd.setCursor(13, 0); lcd.print(active_perform_page); if (active_perform_page == 1) { //Master Volume lcd.setCursor(0, 0); lcd.print("Master Vol. "); lcd_special_chars(BLOCKBAR); lcd_display_bar_int("Master Vol.", configuration.sys.vol, 1.0, VOLUME_MIN, VOLUME_MAX, 3, false, false, false); set_volume(configuration.sys.vol, configuration.sys.mono); } else if (active_perform_page == 2) { //Attack lcd.setCursor(0, 0); lcd.print("Live Modify"); lcd.setCursor(0, 1); lcd.print("Attack = "); lcd.setCursor(13, 1); sprintf(tmp, "%03d", perform_attack_mod[selected_instance_id]); lcd.print(tmp); back_from_volume = 0; } else if (active_perform_page == 3) { //Release lcd.setCursor(0, 0); lcd.print("Live Modify"); lcd.setCursor(0, 1); lcd.print("Release = "); lcd.setCursor(13, 1); sprintf(tmp, "%03d", perform_release_mod[selected_instance_id]); lcd.print(tmp); back_from_volume = 0; } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_L].reset(); EEPROM.update(EEPROM_START_ADDRESS + 3, configuration.sys.vol); } } void UI_func_save_voice(uint8_t param) { static bool yesno; static uint8_t mode; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); yesno = false; #if NUM_DEXED == 1 mode = 1; #else mode = 0; #endif #if NUM_DEXED == 1 char bank_name[BANK_NAME_LEN]; if (!get_bank_name(configuration.performance.bank[selected_instance_id], bank_name, sizeof(bank_name))) strcpy(bank_name, "*ERROR*"); lcd.setCursor(0, 0); lcd.print(F("Save to Bank")); lcd.show(1, 0, 2, configuration.performance.bank[selected_instance_id]); lcd.show(1, 3, 10, bank_name); lcd.show(1, 2, 1, "["); lcd.show(1, 13, 1, "]"); #else lcd.setCursor(0, 0); lcd.print(F("Save Instance")); lcd_active_instance_number(selected_instance_id); lcd.setCursor(5, 1); lcd.write(0); lcd.setCursor(10, 1); lcd.write(1); #endif } if (LCDML.FUNC_loop()) // ****** LOOP ********* { char bank_name[BANK_NAME_LEN]; char voice_name[VOICE_NAME_LEN]; if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { switch (mode) { case 0: // Instance selection if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) selected_instance_id = !selected_instance_id; lcd_active_instance_number(selected_instance_id); lcd.setCursor(5, 1); lcd.write(0); lcd.setCursor(10, 1); lcd.write(1); break; case 1: // Bank selection if (LCDML.BT_checkDown()) configuration.performance.bank[selected_instance_id] = constrain(configuration.performance.bank[selected_instance_id] + ENCODER[ENC_R].speed(), 0, MAX_BANKS - 1); else if (LCDML.BT_checkUp() && configuration.performance.bank[selected_instance_id] > 0) configuration.performance.bank[selected_instance_id] = constrain(configuration.performance.bank[selected_instance_id] - ENCODER[ENC_R].speed(), 0, MAX_BANKS - 1); if (!get_bank_name(configuration.performance.bank[selected_instance_id], bank_name, sizeof(bank_name))) strcpy(bank_name, "*ERROR*"); lcd.show(1, 0, 2, configuration.performance.bank[selected_instance_id]); lcd.show(1, 3, 10, bank_name); break; case 2: // Voice selection if (LCDML.BT_checkDown() && configuration.performance.voice[selected_instance_id] < MAX_VOICES - 1) configuration.performance.voice[selected_instance_id] = constrain(configuration.performance.voice[selected_instance_id] + ENCODER[ENC_R].speed(), 0, MAX_VOICES - 1); else if (LCDML.BT_checkUp() && configuration.performance.voice[selected_instance_id] > 0) configuration.performance.voice[selected_instance_id] = constrain(configuration.performance.voice[selected_instance_id] - ENCODER[ENC_R].speed(), 0, MAX_VOICES - 1); if (!get_bank_name(configuration.performance.bank[selected_instance_id], bank_name, sizeof(bank_name))) strncpy(bank_name, "*ERROR*", sizeof(bank_name)); if (!get_voice_by_bank_name(configuration.performance.bank[selected_instance_id], bank_name, configuration.performance.voice[selected_instance_id], voice_name, sizeof(voice_name))) strncpy(voice_name, "*ERROR*", sizeof(voice_name)); lcd.show(1, 0, 2, configuration.performance.voice[selected_instance_id] + 1); lcd.show(1, 3, 10, voice_name); break; case 3: // Yes/No selection yesno = !yesno; if (yesno == true) { lcd.show(1, 1, 3, "YES"); } else { lcd.show(1, 1, 3, "NO"); } break; } } else if (LCDML.BT_checkEnter()) { if (encoderDir[ENC_R].ButtonShort()) mode++; switch (mode) { case 1: if (!get_bank_name(configuration.performance.bank[selected_instance_id], bank_name, sizeof(bank_name))) strncpy(bank_name, "*ERROR*", sizeof(bank_name)); lcd.setCursor(0, 0); lcd.print(F("Save to Bank")); lcd.show(1, 0, 2, configuration.performance.bank[selected_instance_id]); lcd.show(1, 3, 10, bank_name); lcd.show(1, 2, 2, " ["); lcd.show(1, 14, 1, "]"); break; case 2: if (!get_bank_name(configuration.performance.bank[selected_instance_id], bank_name, sizeof(bank_name))) strncpy(bank_name, "*ERROR*", sizeof(bank_name)); if (!get_voice_by_bank_name(configuration.performance.bank[selected_instance_id], bank_name, configuration.performance.voice[selected_instance_id], voice_name, sizeof(voice_name))) strncpy(voice_name, "*ERROR*", sizeof(voice_name)); lcd.show(0, 0, 16, "Save to Bank"); lcd.show(0, 13, 2, configuration.performance.bank[selected_instance_id]); lcd.show(1, 0, 2, configuration.performance.voice[selected_instance_id] + 1); lcd.show(1, 3, 10, voice_name); break; case 3: lcd.show(0, 0, 16, "Overwrite?"); lcd.show(1, 0, 15, "[NO"); lcd.show(1, 4, 1, "]"); break; default: if (yesno == true) { #ifdef DEBUG bool ret = save_sd_voice(configuration.performance.bank[selected_instance_id], configuration.performance.voice[selected_instance_id], selected_instance_id); if (ret == true) Serial.println(F("Saving voice OK.")); else Serial.println(F("Error while saving voice.")); #else save_sd_voice(configuration.performance.bank[selected_instance_id], configuration.performance.voice[selected_instance_id], selected_instance_id); #endif lcd.show(1, 0, 16, "Done."); delay(MESSAGE_WAIT_TIME); mode = 0xff; break; } LCDML.FUNC_goBackToMenu(); } } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); if (mode < 0xff) { lcd.show(1, 0, 16, "Canceled."); delay(MESSAGE_WAIT_TIME); } encoderDir[ENC_R].reset(); } } void UI_func_sysex_receive_bank(uint8_t param) { static bool yesno; static uint8_t mode; static uint8_t bank_number; static uint8_t ui_select_name_state; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); yesno = false; mode = 0; bank_number = configuration.performance.bank[selected_instance_id]; memset(receive_bank_filename, 0, sizeof(receive_bank_filename)); lcd.setCursor(0, 0); lcd.print(F("MIDI Recv Bank")); lcd.setCursor(2, 1); lcd.print(F("[")); lcd.setCursor(14, 1); lcd.print(F("]")); if (!get_bank_name(configuration.performance.bank[selected_instance_id], receive_bank_filename, sizeof(receive_bank_filename))) strcpy(receive_bank_filename, "*ERROR*"); lcd.show(1, 0, 2, bank_number); lcd.show(1, 3, 10, receive_bank_filename); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) { switch (mode) { case 0: bank_number = constrain(bank_number + ENCODER[ENC_R].speed(), 0, MAX_BANKS - 1); if (!get_bank_name(bank_number, receive_bank_filename, sizeof(receive_bank_filename))) strcpy(receive_bank_filename, "*ERROR*"); lcd.show(1, 0, 2, bank_number); lcd.show(1, 3, 10, receive_bank_filename); break; case 1: yesno = !yesno; if (yesno) lcd.show(1, 12, 3, "YES"); else lcd.show(1, 12, 3, "NO"); break; case 2: ui_select_name_state = UI_select_name(1, 1, receive_bank_filename, BANK_NAME_LEN - 1, false); break; } } else if (LCDML.BT_checkUp()) { switch (mode) { case 0: bank_number = constrain(bank_number - ENCODER[ENC_R].speed(), 0, MAX_BANKS - 1); if (!get_bank_name(bank_number, receive_bank_filename, sizeof(receive_bank_filename))) strcpy(receive_bank_filename, "*ERROR*"); lcd.show(1, 0, 2, bank_number); lcd.show(1, 3, 10, receive_bank_filename); break; case 1: yesno = !yesno; if (yesno) lcd.show(1, 12, 3, "YES"); else lcd.show(1, 12, 3, "NO"); break; case 2: ui_select_name_state = UI_select_name(1, 1, receive_bank_filename, BANK_NAME_LEN - 1, false); break; } } } else if (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort()) { if (mode == 0) { if (!strcmp(receive_bank_filename, "*ERROR*")) { yesno = true; strcpy(receive_bank_filename, "NONAME"); mode = 2; lcd.setCursor(0, 1); lcd.print(F("[ ] ")); ui_select_name_state = UI_select_name(1, 1, receive_bank_filename, BANK_NAME_LEN - 1, true); lcd.blink(); } else { mode = 1; lcd.setCursor(0, 1); lcd.print(F("Overwrite: [NO ]")); } } else if (mode == 1 && yesno == true) { mode = 2; lcd.setCursor(0, 1); lcd.print(F("[ ] ")); ui_select_name_state = UI_select_name(1, 1, receive_bank_filename, BANK_NAME_LEN - 1, true); lcd.blink(); } else if (mode == 2) { ui_select_name_state = UI_select_name(1, 1, receive_bank_filename, BANK_NAME_LEN - 1, false); if (ui_select_name_state == true) { if (yesno == true) { #ifdef DEBUG Serial.print(F("Bank name: [")); Serial.print(receive_bank_filename); Serial.println(F("]")); #endif char tmp[FILENAME_LEN]; strcpy(tmp, receive_bank_filename); sprintf(receive_bank_filename, "/%d/%s.syx", bank_number, tmp); #ifdef DEBUG Serial.print(F("Receiving into bank ")); Serial.print(bank_number); Serial.print(F(" as filename ")); Serial.print(receive_bank_filename); Serial.println(F(".")); #endif mode = 0xff; lcd.noBlink(); lcd.setCursor(0, 1); lcd.print(F("Waiting... ")); /// Storing is done in SYSEX code } } } else if (mode >= 1 && yesno == false) { Serial.println(mode, DEC); memset(receive_bank_filename, 0, sizeof(receive_bank_filename)); mode = 0xff; lcd.noBlink(); lcd.setCursor(0, 1); lcd.print(F("Canceled. ")); delay(MESSAGE_WAIT_TIME); LCDML.FUNC_goBackToMenu(); } } encoderDir[ENC_R].reset(); } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); memset(receive_bank_filename, 0, sizeof(receive_bank_filename)); lcd.noBlink(); if (mode < 0xff) { lcd.setCursor(0, 1); lcd.print(F("Canceled. ")); delay(MESSAGE_WAIT_TIME); } } } void UI_func_set_performance_name(uint8_t param) { static uint8_t mode; static uint8_t ui_select_name_state; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); mode = 0; lcd.setCursor(0, 0); lcd.print(F("Perf. Name")); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) { if (mode == 1) ui_select_name_state = UI_select_name(1, 1, seq_name_temp, BANK_NAME_LEN - 1, false); } else if (LCDML.BT_checkUp()) { if (mode == 1) ui_select_name_state = UI_select_name(1, 1, seq_name_temp, BANK_NAME_LEN - 1, false); // if (ui_select_name_state == false) { // lcd.setCursor(12, 1); // lcd.print(" "); // lcd.setCursor(0, 1); // lcd.print("["); // lcd.setCursor(11, 1); // lcd.print("]"); // lcd.blink(); // ui_select_name_state = UI_select_name(1, 1, seq_name_temp, BANK_NAME_LEN - 1, true); // } } } else if (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort()) { if (mode == 1) { ui_select_name_state = UI_select_name(1, 1, seq_name_temp, BANK_NAME_LEN - 1, false); if (ui_select_name_state == true) { strcpy( seq_name, seq_name_temp); mode = 0xff; lcd.noBlink(); lcd.setCursor(0, 1); lcd.print(F("OK. ")); delay(MESSAGE_WAIT_TIME); LCDML.FUNC_goBackToMenu(); } } } if (mode == 0 ) { mode = 1; strcpy(seq_name_temp, seq_name); lcd.setCursor(0, 1); lcd.print(F("[ ] ")); ui_select_name_state = UI_select_name(1, 1, seq_name_temp, BANK_NAME_LEN - 1, true); lcd.blink(); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); lcd.noBlink(); } } void UI_func_sysex_send_bank(uint8_t param) { char bank_name[BANK_NAME_LEN]; static uint8_t bank_number; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); bank_number = configuration.performance.bank[selected_instance_id]; lcd.setCursor(0, 0); lcd.print(F("MIDI Send Bank")); if (!get_bank_name(configuration.performance.bank[selected_instance_id], bank_name, sizeof(bank_name))) strncpy(bank_name, "*ERROR*", sizeof(bank_name)); lcd.show(1, 2, 1, "["); lcd.show(1, 14, 1, "]"); lcd.show(1, 0, 2, configuration.performance.bank[selected_instance_id]); lcd.show(1, 3, 10, bank_name); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) { bank_number = constrain(bank_number + ENCODER[ENC_R].speed(), 0, MAX_BANKS - 1); } else if (LCDML.BT_checkUp()) { bank_number = constrain(bank_number - ENCODER[ENC_R].speed(), 0, MAX_BANKS - 1); } if (!get_bank_name(bank_number, bank_name, sizeof(bank_name))) strcpy(bank_name, "*ERROR*"); lcd.show(1, 0, 2, bank_number); lcd.show(1, 3, 10, bank_name); } else if (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort()) { File sysex; char filename[FILENAME_LEN]; if (get_bank_name(bank_number, bank_name, sizeof(bank_name))) { sprintf(filename, "/%d/%s.syx", bank_number, bank_name); #ifdef DEBUG Serial.print(F("Send bank ")); Serial.print(filename); Serial.println(F(" from SD.")); #endif sysex = SD.open(filename); if (!sysex) { #ifdef DEBUG Serial.println(F("Connot read from SD.")); #endif lcd.show(1, 0, 16, "Read error."); bank_number = 0xff; } else { uint8_t bank_data[4104]; sysex.read(bank_data, 4104); sysex.close(); lcd.show(1, 0, 16, "Sending Ch"); if (configuration.dexed[selected_instance_id].midi_channel == MIDI_CHANNEL_OMNI) { lcd.show(1, 11, 2, "01"); send_sysex_bank(1, bank_data); } else { lcd.show(1, 11, 2, configuration.dexed[selected_instance_id].midi_channel + 1); send_sysex_bank(configuration.dexed[selected_instance_id].midi_channel, bank_data); } lcd.show(1, 0, 16, "Done."); bank_number = 0xff; } } else { lcd.show(1, 0, 16, "No bank."); bank_number = 0xff; } delay(MESSAGE_WAIT_TIME); LCDML.FUNC_goBackToMenu(); } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); if (bank_number < 0xff) { lcd.setCursor(0, 1); lcd.print(F("Canceled. ")); delay(MESSAGE_WAIT_TIME); } } } void UI_func_sysex_send_voice(uint8_t param) { static uint8_t mode; static uint8_t bank_number; static uint8_t voice_number; if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); mode = 0; bank_number = configuration.performance.bank[selected_instance_id]; voice_number = configuration.performance.voice[selected_instance_id]; char bank_name[BANK_NAME_LEN]; if (!get_bank_name(bank_number, bank_name, sizeof(bank_name))) strcpy(bank_name, "*ERROR*"); lcd.setCursor(0, 0); lcd.print(F("MIDI Send Voice")); lcd.show(1, 0, 2, bank_number); lcd.show(1, 3, 10, bank_name); lcd.show(1, 2, 1, "["); lcd.show(1, 13, 1, "]"); } if (LCDML.FUNC_loop()) // ****** LOOP ********* { char bank_name[BANK_NAME_LEN]; char voice_name[VOICE_NAME_LEN]; if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { switch (mode) { case 0: // Bank selection if (LCDML.BT_checkDown()) bank_number = constrain(bank_number + ENCODER[ENC_R].speed(), 0, MAX_BANKS - 1); else if (LCDML.BT_checkUp() && bank_number > 0) bank_number = constrain(bank_number - ENCODER[ENC_R].speed(), 0, MAX_BANKS - 1); if (!get_bank_name(bank_number, bank_name, sizeof(bank_name))) strcpy(bank_name, "*ERROR*"); lcd.show(1, 0, 2, bank_number); lcd.show(1, 3, 10, bank_name); break; case 1: // Voice selection if (LCDML.BT_checkDown() && voice_number < MAX_VOICES - 1) voice_number = constrain(voice_number + ENCODER[ENC_R].speed(), 0, MAX_VOICES - 1); else if (LCDML.BT_checkUp() && voice_number > 0) voice_number = constrain(voice_number - ENCODER[ENC_R].speed(), 0, MAX_VOICES - 1); if (!get_bank_name(bank_number, bank_name, sizeof(bank_name))) strncpy(bank_name, "*ERROR*", sizeof(bank_name)); if (!get_voice_by_bank_name(bank_number, bank_name, voice_number, voice_name, sizeof(voice_name))) strncpy(voice_name, "*ERROR*", sizeof(voice_name)); lcd.show(1, 0, 2, voice_number + 1); lcd.show(1, 3, 10, voice_name); break; } } else if (LCDML.BT_checkEnter()) { if (encoderDir[ENC_R].ButtonShort()) mode++; switch (mode) { case 1: if (!get_bank_name(bank_number, bank_name, sizeof(bank_name))) strncpy(bank_name, "*ERROR*", sizeof(bank_name)); if (!get_voice_by_bank_name(bank_number, bank_name, voice_number, voice_name, sizeof(voice_name))) strncpy(voice_name, "*ERROR*", sizeof(voice_name)); lcd.show(1, 0, 2, voice_number + 1); lcd.show(1, 3, 10, voice_name); break; case 2: File sysex; char filename[FILENAME_LEN]; if (get_bank_name(bank_number, bank_name, sizeof(bank_name))) { sprintf(filename, "/%d/%s.syx", bank_number, bank_name); #ifdef DEBUG Serial.print(F("Send voice ")); Serial.print(voice_number); Serial.print(F(" of ")); Serial.print(filename); Serial.println(F(" from SD.")); #endif sysex = SD.open(filename); if (!sysex) { #ifdef DEBUG Serial.println(F("Connot read from SD.")); #endif lcd.show(1, 0, 16, "Read error."); bank_number = 0xff; } else { uint8_t voice_data[155]; uint8_t encoded_voice_data[128]; sysex.seek(6 + (voice_number * 128)); sysex.read(encoded_voice_data, 128); MicroDexed[selected_instance_id]->decodeVoice(voice_data, encoded_voice_data); lcd.show(1, 0, 16, "Sending Ch"); if (configuration.dexed[selected_instance_id].midi_channel == MIDI_CHANNEL_OMNI) { lcd.show(1, 11, 2, "01"); send_sysex_voice(1, voice_data); } else { lcd.show(1, 11, 2, configuration.dexed[selected_instance_id].midi_channel + 1); send_sysex_voice(configuration.dexed[selected_instance_id].midi_channel, voice_data); } delay(MESSAGE_WAIT_TIME); lcd.show(1, 0, 16, "Done."); sysex.close(); bank_number = 0xff; } } else { lcd.show(1, 0, 16, "No voice."); bank_number = 0xff; } mode = 0xff; delay(MESSAGE_WAIT_TIME); LCDML.FUNC_goBackToMenu(); break; } } } if (LCDML.FUNC_close()) // ****** STABLE END ********* { if (mode < 0xff) { lcd.show(1, 0, 16, "Canceled."); delay(MESSAGE_WAIT_TIME); } encoderDir[ENC_R].reset(); } } void UI_func_eq_1(uint8_t param) { #ifndef SGTL5000_AUDIO_ENHANCE if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("EQ Low-Cut")); lcd.setCursor(0, 1); lcd.print(F("Not implemented.")); } #else if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(METERBAR); } 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.eq_1 = constrain(configuration.fx.eq_1 + ENCODER[ENC_R].speed(), EQ_1_MIN, EQ_1_MAX); } else if (LCDML.BT_checkUp()) { configuration.fx.eq_1 = constrain(configuration.fx.eq_1 - ENCODER[ENC_R].speed(), EQ_1_MIN, EQ_1_MAX); } } lcd_display_meter_int("EQ Low-Cut [Hz]", configuration.fx.eq_1, 1.0, 0.0, EQ_1_MIN, EQ_1_MAX, 3, false, false, true); sgtl5000.setEQFc(1, float(configuration.fx.eq_1)); sgtl5000.setEQGain(1, 6.0); sgtl5000.commitFilter(1); #ifdef DEBUG sgtl5000.show_params(1); #endif } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } #endif } void UI_func_eq_2(uint8_t param) { #ifndef SGTL5000_AUDIO_ENHANCE if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("EQ 120Hz")); lcd.setCursor(0, 1); lcd.print(F("Not implemented.")); } #else if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(METERBAR); } 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.eq_2 = constrain(configuration.fx.eq_2 + ENCODER[ENC_R].speed(), EQ_2_MIN, EQ_2_MAX); } else if (LCDML.BT_checkUp()) { configuration.fx.eq_2 = constrain(configuration.fx.eq_2 - ENCODER[ENC_R].speed(), EQ_2_MIN, EQ_2_MAX); } } lcd_display_meter_float("EQ 120Hz [dB]", configuration.fx.eq_2, 0.1, 0.0, EQ_2_MIN, EQ_2_MAX, 1, 1, false, true, true); sgtl5000.setEQGain(2, mapfloat(configuration.fx.eq_2, EQ_2_MIN, EQ_2_MAX, -9.9, 9.9)); sgtl5000.commitFilter(2); #ifdef DEBUG sgtl5000.show_params(2); #endif } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } #endif } void UI_func_eq_3(uint8_t param) { #ifndef SGTL5000_AUDIO_ENHANCE if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("EQ 220Hz")); lcd.setCursor(0, 1); lcd.print(F("Not implemented.")); } #else if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(METERBAR); } 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.eq_3 = constrain(configuration.fx.eq_3 + ENCODER[ENC_R].speed(), EQ_3_MIN, EQ_3_MAX); } else if (LCDML.BT_checkUp()) { configuration.fx.eq_3 = constrain(configuration.fx.eq_3 - ENCODER[ENC_R].speed(), EQ_3_MIN, EQ_3_MAX); } } lcd_display_meter_float("EQ 220Hz [dB]", configuration.fx.eq_3, 0.1, 0.0, EQ_3_MIN, EQ_3_MAX, 1, 1, false, true, true); sgtl5000.setEQGain(3, mapfloat(configuration.fx.eq_3, EQ_3_MIN, EQ_3_MAX, -9.9, 9.9)); sgtl5000.commitFilter(3); #ifdef DEBUG sgtl5000.show_params(3); #endif } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } #endif } void UI_func_eq_4(uint8_t param) { #ifndef SGTL5000_AUDIO_ENHANCE if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("EQ 1000Hz")); lcd.setCursor(0, 1); lcd.print(F("Not implemented.")); } #else if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(METERBAR); } 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.eq_4 = constrain(configuration.fx.eq_4 + ENCODER[ENC_R].speed(), EQ_4_MIN, EQ_4_MAX); } else if (LCDML.BT_checkUp()) { configuration.fx.eq_4 = constrain(configuration.fx.eq_4 - ENCODER[ENC_R].speed(), EQ_4_MIN, EQ_4_MAX); } } lcd_display_meter_float("EQ 1000Hz [dB]", configuration.fx.eq_4, 0.1, 0.0, EQ_4_MIN, EQ_4_MAX, 1, 1, false, true, true); sgtl5000.setEQGain(4, mapfloat(configuration.fx.eq_4, EQ_4_MIN, EQ_4_MAX, -9.9, 9.9)); sgtl5000.commitFilter(4); #ifdef DEBUG sgtl5000.show_params(4); #endif } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } #endif } void UI_func_eq_5(uint8_t param) { #ifndef SGTL5000_AUDIO_ENHANCE if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("EQ 2000Hz")); lcd.setCursor(0, 1); lcd.print(F("Not implemented.")); } #else if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(METERBAR); } 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.eq_5 = constrain(configuration.fx.eq_5 + ENCODER[ENC_R].speed(), EQ_5_MIN, EQ_5_MAX); } else if (LCDML.BT_checkUp()) { configuration.fx.eq_5 = constrain(configuration.fx.eq_5 - ENCODER[ENC_R].speed(), EQ_5_MIN, EQ_5_MAX); } } lcd_display_meter_float("EQ 2000Hz [dB]", configuration.fx.eq_5, 0.1, 0.0, EQ_5_MIN, EQ_5_MAX, 1, 1, false, true, true); sgtl5000.setEQGain(5, mapfloat(configuration.fx.eq_5, EQ_5_MIN, EQ_5_MAX, -9.9, 9.9)); sgtl5000.commitFilter(5); #ifdef DEBUG sgtl5000.show_params(5); #endif } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } #endif } void UI_func_eq_6(uint8_t param) { #ifndef SGTL5000_AUDIO_ENHANCE if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("EQ 7000Hz")); lcd.setCursor(0, 1); lcd.print(F("Not implemented.")); } #else if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(METERBAR); } 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.eq_6 = constrain(configuration.fx.eq_6 + ENCODER[ENC_R].speed(), EQ_6_MIN, EQ_6_MAX); } else if (LCDML.BT_checkUp()) { configuration.fx.eq_6 = constrain(configuration.fx.eq_6 - ENCODER[ENC_R].speed(), EQ_6_MIN, EQ_6_MAX); } } lcd_display_meter_float("EQ 7000Hz [dB]", configuration.fx.eq_6, 0.1, 0.0, EQ_6_MIN, EQ_6_MAX, 1, 1, false, true, true); sgtl5000.setEQGain(6, mapfloat(configuration.fx.eq_6, EQ_6_MIN, EQ_6_MAX, -9.9, 9.9)); sgtl5000.commitFilter(6); #ifdef DEBUG sgtl5000.show_params(6); #endif } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } #endif } void UI_func_eq_7(uint8_t param) { #ifndef SGTL5000_AUDIO_ENHANCE if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd.setCursor(0, 0); lcd.print(F("EQ High-Cut")); lcd.setCursor(0, 1); lcd.print(F("Not implemented.")); } #else if (LCDML.FUNC_setup()) // ****** SETUP ********* { encoderDir[ENC_R].reset(); lcd_special_chars(METERBAR); } 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.eq_7 = constrain(configuration.fx.eq_7 + ENCODER[ENC_R].speed(), EQ_7_MIN, EQ_7_MAX); } else if (LCDML.BT_checkUp()) { configuration.fx.eq_7 = constrain(configuration.fx.eq_7 - ENCODER[ENC_R].speed(), EQ_7_MIN, EQ_7_MAX); } } lcd_display_meter_float("EQ High-Cut[kHz]", configuration.fx.eq_7, 1.0, 0.0, EQ_7_MIN, EQ_7_MAX, 3, 1, false, false, true); sgtl5000.setEQFc(7, float(configuration.fx.eq_7) * 1000.0); sgtl5000.commitFilter(7); #ifdef DEBUG sgtl5000.show_params(7); #endif } if (LCDML.FUNC_close()) // ****** STABLE END ********* { lcd_special_chars(SCROLLBAR); encoderDir[ENC_R].reset(); } #endif } 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(); } } bool UI_select_name(uint8_t y, uint8_t x, char* edit_string, uint8_t len, bool init) { static int8_t edit_pos; static bool edit_mode; static uint8_t edit_value; static uint8_t last_char_pos; if (init == true) { edit_mode = false; edit_pos = 0; edit_value = search_accepted_char(edit_string[edit_pos]); last_char_pos = strlen(edit_string); string_trim(edit_string); // just to be sure lcd.setCursor(x, y); lcd.print(edit_string); lcd.setCursor(x, y); return (false); } if (LCDML.BT_checkDown() || LCDML.BT_checkUp()) { if (LCDML.BT_checkDown()) { if (edit_mode == true) { edit_value = search_accepted_char(edit_string[edit_pos]); if (edit_value < sizeof(accepted_chars) - 2) edit_value++; if (edit_value == 0 && edit_string[constrain(edit_pos + 1, 0, len)] > 0) edit_value = 1; edit_string[edit_pos] = accepted_chars[edit_value]; lcd.setCursor(x + edit_pos, y); lcd.print(edit_string[edit_pos]); } else { if (edit_string[edit_pos] != 0 && edit_string[edit_pos] != 32) edit_pos = constrain(edit_pos + 1, 0, len); else { if (edit_pos + 1 > last_char_pos) edit_pos = len; } if (edit_pos == len) { lcd.noBlink(); lcd.setCursor(x - 1, y); lcd.print(F(" ")); lcd.setCursor(x + len, y); lcd.print(F(" ")); lcd.setCursor(x + len + 1, y); lcd.print(F("[OK]")); } } } else if (LCDML.BT_checkUp()) { if (edit_mode == true) { edit_value = search_accepted_char(edit_string[edit_pos]); if (edit_value >= 1) edit_value--; if (edit_value == 0 && edit_string[constrain(edit_pos + 1, 0, len)] > 0) edit_value = 1; edit_string[edit_pos] = accepted_chars[edit_value]; lcd.setCursor(x + edit_pos, y); lcd.print(edit_string[edit_pos]); } else { if (edit_pos - 1 > last_char_pos) edit_pos = last_char_pos; else edit_pos = constrain(edit_pos - 1, 0, len - 1); if (edit_pos == last_char_pos) { lcd.setCursor(x - 1, y); lcd.print(F("[")); lcd.setCursor(x + len, y); lcd.print(F("]")); lcd.setCursor(x + len + 1, y); lcd.print(F(" ")); lcd.blink(); } } } } else if (LCDML.BT_checkEnter()) { last_char_pos = strlen(edit_string); if (edit_pos >= len) { edit_pos = 0; edit_mode = false; return (true); } else { last_char_pos = strlen(edit_string); edit_mode = !edit_mode; } if (edit_mode == false && edit_pos < len && edit_string[edit_pos] != 0 && edit_string[edit_pos] != 32) edit_pos++; if (edit_mode == true) { lcd.setCursor(x + len + 1, y); lcd.print(F("*")); } else { lcd.setCursor(x + len + 1, y); lcd.print(F(" ")); } } lcd.setCursor(x + edit_pos, y); encoderDir[ENC_R].reset(); return (false); } uint8_t search_accepted_char(uint8_t c) { //if (c == 0) // c = 32; for (uint8_t i = 0; i < sizeof(accepted_chars) - 1; i++) { Serial.print(i, DEC); Serial.print(":"); Serial.print(c); Serial.print("=="); Serial.println(accepted_chars[i], DEC); if (c == accepted_chars[i]) return (i); } return (0); } 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 sign, bool init) { lcd_display_bar_float(title, float(value), factor, min_value, max_value, size, 0, zeros, 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 sign, bool init) { uint8_t size; float v; float _vi = 0.0; uint8_t vf; uint8_t vi; if (size_fraction == 0) size = size_number; else size = size_number + size_fraction + 1; if (sign == true) size++; v = float((value - min_value) * (LCD_cols - size)) / (max_value - min_value); vf = uint8_t(modff(v, &_vi) * 10.0 + 0.5); vi = uint8_t(_vi); if (sign == true) size += 1; // Title if (init == true) lcd.show(0, 0, LCD_cols - 2, title); //lcd.show(0, 0, LCD_cols - 3, title); // Value lcd.setCursor(LCD_cols - size, 1); lcd_display_float(value * factor, size_number, size_fraction, zeros, false, sign); // TBD // Bar lcd.setCursor(0, 1); if (vi == 0) { lcd.write((uint8_t)(vf / 2.0 - 0.5) + 2); for (uint8_t i = vi + 1; i < LCD_cols - size; i++) lcd.print(F(" ")); // empty block } else { for (uint8_t i = 0; i < vi; i++) lcd.write((uint8_t)4 + 2); // full block if (vi < LCD_cols - size) lcd.write((uint8_t)(vf / 2.0 - 0.5) + 2); for (uint8_t i = vi + 1; i < LCD_cols - size; 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 sign, bool init) { lcd_display_meter_float(title, float(value), factor, offset, min_value, max_value, size, 0, zeros, 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 sign, bool init) { uint8_t size = 0; float v; float _vi = 0.0; uint8_t vf; uint8_t vi; if (size_fraction == 0) size = size_number; else size = size_number + size_fraction + 1; if (sign == true) size++; v = float((value - min_value) * (LCD_cols - size)) / (max_value - min_value); vf = uint8_t(modff(v, &_vi) * 10.0 + 0.5); vi = uint8_t(_vi); if (init == true) { // Title lcd.setCursor(0, 0); lcd.print(title); } // Value lcd.setCursor(LCD_cols - size, 1); lcd_display_float((value + offset) * factor, size_number, size_fraction, zeros, false, sign); // Bar lcd.setCursor(0, 1); if (vi == 0) { lcd.write((uint8_t)(vf / 2.0) + 2); for (uint8_t i = 1; i < LCD_cols - size; i++) lcd.print(F(" ")); // empty block } else if (vi == LCD_cols - size) { for (uint8_t i = 0; i < LCD_cols - size - 1; i++) lcd.print(F(" ")); // empty block lcd.write(4 + 2); } else { for (uint8_t i = 0; i < LCD_cols - size; i++) lcd.print(F(" ")); // empty block lcd.setCursor(vi, 1); lcd.write((uint8_t)(vf / 2.0) + 2); for (uint8_t i = vi + 1; i < LCD_cols - size; i++) lcd.print(F(" ")); // empty block } } uint8_t bit_reverse8(uint8_t v) { uint8_t result = 0; for ( ; v > 0; v >>= 1 ) (result <<= 1) |= (v & 1); return (result); } void lcd_active_instance_number(uint8_t instance_id) { for (uint8_t i = 0; i < 8; i++) { if (instance_id == 0) { if (configuration.dexed[instance_id].polyphony == 0) instance_num[0][i] = bit_reverse8(special_chars[0][i]); else instance_num[0][i] = special_chars[0][i]; if (configuration.dexed[!instance_id].polyphony == 0) { instance_num[1][i] = bit_reverse8(special_chars[1][i]); instance_num[1][i] = ~instance_num[1][i]; } else instance_num[1][i] = ~special_chars[1][i]; } else { if (configuration.dexed[!instance_id].polyphony == 0) { instance_num[0][i] = bit_reverse8(special_chars[0][i]); instance_num[0][i] = ~instance_num[0][i]; } else instance_num[0][i] = ~special_chars[0][i]; if (configuration.dexed[instance_id].polyphony == 0) instance_num[1][i] = bit_reverse8(special_chars[1][i]); else instance_num[1][i] = special_chars[1][i]; } } #if NUM_DEXED == 1 lcd.createChar(0, instance_num[0]); lcd.createChar(1, (uint8_t*)special_chars[17]); #else lcd.createChar(0, instance_num[0]); lcd.createChar(1, instance_num[1]); #endif } void lcd_OP_active_instance_number(uint8_t instance_id, uint8_t op) { uint8_t i, n; for (n = 2; n < 8; n++) { for (i = 0; i < 8; i++) { if (bitRead(op, n - 2)) instance_num[n][i] = special_chars[n][i]; else instance_num[n][i] = ~special_chars[n][i]; } lcd.createChar(n, instance_num[n]); } for (i = 0; i < 8; i++) { if (instance_id == 0) { if (configuration.dexed[instance_id].polyphony == 0) instance_num[0][i] = bit_reverse8(special_chars[0][i]); else instance_num[0][i] = special_chars[0][i]; if (configuration.dexed[!instance_id].polyphony == 0) { instance_num[1][i] = bit_reverse8(special_chars[1][i]); instance_num[1][i] = ~instance_num[1][i]; } else instance_num[1][i] = ~special_chars[1][i]; } else { if (configuration.dexed[!instance_id].polyphony == 0) { instance_num[0][i] = bit_reverse8(special_chars[0][i]); instance_num[0][i] = ~instance_num[0][i]; } else instance_num[0][i] = ~special_chars[0][i]; if (configuration.dexed[instance_id].polyphony == 0) instance_num[1][i] = bit_reverse8(special_chars[1][i]); else instance_num[1][i] = special_chars[1][i]; } } lcd.createChar(0, instance_num[0]); #if NUM_DEXED > 1 lcd.createChar(1, instance_num[1]); #else lcd.createChar(1, (uint8_t *)special_chars[17]); #endif } 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 volume-bar for (uint8_t i = 0; i < 7; i++) { #ifdef I2C_DISPLAY lcd.createChar(i + 2, (uint8_t*)block_bar[i]); #else flipped_block_bar[i] = rotTile(block_bar[i]); #endif } break; case METERBAR: // set special chars for panorama-bar for (uint8_t i = 0; i < 7; i++) { #ifdef I2C_DISPLAY lcd.createChar(i + 2, (uint8_t*)meter_bar[i]); #else flipped_meter_bar[i] = rotTile(meter_bar[i]); #endif } break; } } #ifdef USE_FX void lcd_display_delay_sync(uint8_t sync) { lcd.show(0, 0, LCD_cols - 2, "Delay Sync"); if (seq_running == false)lcd.show(1, 0, 10, "MIDI Sync "); else lcd.show(1, 0, 10, "Seq. Sync "); switch (sync) { case 1: lcd.show(1, 10, 6, "1/16"); break; case 2: lcd.show(1, 10, 6, "1/16T"); break; case 3: lcd.show(1, 10, 6, "1/8"); break; case 4: lcd.show(1, 10, 6, "1/8T"); break; case 5: lcd.show(1, 10, 6, "1/4"); break; case 6: lcd.show(1, 10, 6, "1/4T"); break; case 7: lcd.show(1, 10, 6, "1/2"); break; case 8: lcd.show(1, 10, 6, "1/2T"); break; case 9: lcd.show(1, 10, 6, "1/1"); break; } if (seq_running == false) { uint16_t midi_sync_delay_time = uint16_t(60000.0 * midi_ticks_factor[sync] / midi_bpm + 0.5); if (midi_sync_delay_time > DELAY_MAX_TIME) { #ifdef DEBUG Serial.println(F("Calculated MIDI-Sync delay: ")); Serial.print(round(60000.0 * midi_ticks_factor[sync] / midi_bpm), DEC); Serial.println(F("ms")); Serial.println(F("MIDI-Sync delay: midi_sync_delay_time")); Serial.print(midi_sync_delay_time, DEC); Serial.println(F("ms")); #endif } } else { uint16_t midi_sync_delay_time = uint16_t(60000.0 * midi_ticks_factor[sync] / seq_bpm); delay_fx[selected_instance_id]->delay(0, constrain(midi_sync_delay_time, DELAY_TIME_MIN, DELAY_TIME_MAX * 10)); } lcd.show(1, 15, 1, "!"); } #endif void string_trim(char *s) { int i; while (isspace (*s)) s++; // skip left side white spaces for (i = strlen (s) - 1; (isspace (s[i])); i--) ; // skip right side white spaces s[i + 1] = '\0'; } void locate_previous_non_favorite() { //find prev. non fav in current bank lcd.setCursor(3, 0); lcd.print("= 0 && configuration.performance.bank[selected_instance_id] >= 0) { lcd.setCursor(3, 0); lcd.print("= 1 && favsearcher < 36); // if found, we are done. else quick check in previous banks if ( check_favorite(configuration.performance.bank[selected_instance_id], configuration.performance.voice[selected_instance_id], selected_instance_id) == false && configuration.performance.voice[selected_instance_id] >= 0 && configuration.performance.bank[selected_instance_id] >= 0 && favsearcher < 170) { configuration.performance.voice[selected_instance_id] = 32; do { //seek for previous bank configuration.performance.bank[selected_instance_id]--; favsearcher++; } while (quick_check_favorites_in_bank(configuration.performance.bank[selected_instance_id], selected_instance_id) == false && favsearcher < 132 && configuration.performance.bank[selected_instance_id] >= 0); do { //last try to search if a bank with fav was found configuration.performance.voice[selected_instance_id]--; favsearcher++; } while ( check_favorite(configuration.performance.bank[selected_instance_id], configuration.performance.voice[selected_instance_id], selected_instance_id) == false && configuration.performance.voice[selected_instance_id] >= 1 && favsearcher < 170); } } favsearcher = 0; } void locate_next_favorite() { bool RollOver = false; if (configuration.performance.voice[selected_instance_id] > 30 && configuration.performance.bank[selected_instance_id] >= MAX_BANKS - 1 ) { //if at end of all banks configuration.performance.bank[selected_instance_id] = 0; configuration.performance.voice[selected_instance_id] = 0; RollOver = true; } else if (configuration.performance.voice[selected_instance_id] > 30 && configuration.performance.bank[selected_instance_id] < MAX_BANKS - 1 ) { //if at end of any other bank configuration.performance.bank[selected_instance_id]++; configuration.performance.voice[selected_instance_id] = 0; } if (configuration.performance.voice[selected_instance_id] <= 30 && configuration.performance.bank[selected_instance_id] <= MAX_BANKS ) { lcd.setCursor(3, 0); lcd.print(">SEARCHING"); do { //first find next fav in current bank if (RollOver == false) configuration.performance.voice[selected_instance_id]++; else RollOver = true; favsearcher++; } while ( check_favorite(configuration.performance.bank[selected_instance_id], configuration.performance.voice[selected_instance_id], selected_instance_id) == false && configuration.performance.voice[selected_instance_id] <= 32 && favsearcher < 36); // if found, we are done. else quick check in next banks if ( check_favorite(configuration.performance.bank[selected_instance_id], configuration.performance.voice[selected_instance_id], selected_instance_id) == false && configuration.performance.bank[selected_instance_id] < MAX_BANKS && favsearcher < 170) { configuration.performance.voice[selected_instance_id] = 0; do { //seek in next bank configuration.performance.bank[selected_instance_id]++; if ( configuration.performance.bank[selected_instance_id] > MAX_BANKS - 1 && favsearcher < 190) { configuration.performance.bank[selected_instance_id] = 0; configuration.performance.voice[selected_instance_id] = 0; } favsearcher++; } while (quick_check_favorites_in_bank(configuration.performance.bank[selected_instance_id], selected_instance_id) == false && favsearcher < 132 ); if ( check_favorite(configuration.performance.bank[selected_instance_id], configuration.performance.voice[selected_instance_id], selected_instance_id) == false && configuration.performance.voice[selected_instance_id] <= 32 && favsearcher < 190) { do { //last bank to search if a fav can be found configuration.performance.voice[selected_instance_id]++; favsearcher++; } while ( check_favorite(configuration.performance.bank[selected_instance_id], configuration.performance.voice[selected_instance_id], selected_instance_id) == false && favsearcher < 170); } } } favsearcher = 0; } void locate_next_non_favorite() { //find next non-fav in current bank lcd.setCursor(3, 0); lcd.print(">SEARCHING"); do { configuration.performance.voice[selected_instance_id]++; if (configuration.performance.voice[selected_instance_id] > 31) { configuration.performance.voice[selected_instance_id] = 0; //configuration.performance.bank[selected_instance_id]++; if (configuration.performance.bank[selected_instance_id] > MAX_BANKS - 1) configuration.performance.bank[selected_instance_id] = 0; do { //seek for next bank configuration.performance.bank[selected_instance_id]++; if (configuration.performance.bank[selected_instance_id] > MAX_BANKS - 1) configuration.performance.bank[selected_instance_id] = 0; favsearcher++; } while (quick_check_favorites_in_bank(configuration.performance.bank[selected_instance_id], selected_instance_id) == true && favsearcher < 132); } favsearcher++; } while ( check_favorite(configuration.performance.bank[selected_instance_id], configuration.performance.voice[selected_instance_id], selected_instance_id) == true && favsearcher < 170); favsearcher = 0; } void locate_random_non_favorite() { //find random non-fav do { configuration.performance.voice[selected_instance_id] = random(32); configuration.performance.bank[selected_instance_id] = random(MAX_BANKS - 1); favsearcher++; } while ( check_favorite(configuration.performance.bank[selected_instance_id], configuration.performance.voice[selected_instance_id], selected_instance_id) == true && favsearcher < 100); favsearcher = 0; } bool check_favorite(uint8_t b, uint8_t v, uint8_t instance_id) { b = constrain(b, 0, MAX_BANKS - 1); v = constrain(v, 0, MAX_VOICES - 1); char tmp[18]; File myFav; if (sd_card > 0) { sprintf(tmp, "/%s/%d/%d.fav", FAV_CONFIG_PATH, b, v); #ifdef DEBUG Serial.print("check if Voice is a Favorite: "); Serial.print(tmp); Serial.println(); #endif if (SD.exists(tmp)) { //is Favorite #ifdef DEBUG Serial.println(" - It is in Favorites."); #endif return true; } else { // it was not a favorite #ifdef DEBUG Serial.println(" - It is not in Favorites."); #endif return false; } } else return false; } void draw_favorite_icon(uint8_t b, uint8_t v, uint8_t instance_id) { b = constrain(b, 0, MAX_BANKS - 1); v = constrain(v, 0, MAX_VOICES - 1); char tmp[18]; File myFav; if (sd_card > 0) { sprintf(tmp, "/%s/%d/%d.fav", FAV_CONFIG_PATH, b, v); if (SD.exists(tmp)) { //is Favorite #ifdef TESTDISPLAY20x4 lcd.setCursor(17, 0); #else lcd.setCursor(13, 0); #endif lcd.write(2); //fav symbol } else { // it was not a favorite #ifdef TESTDISPLAY20x4 lcd.setCursor(17, 0); #else lcd.setCursor(13, 0); #endif lcd.print(" "); } } } bool quick_check_favorites_in_bank(uint8_t b, uint8_t instance_id) { b = constrain(b, 0, MAX_BANKS - 1); char tmp[18]; if (sd_card > 0) { sprintf(tmp, "/%s/%d", FAV_CONFIG_PATH, b); #ifdef DEBUG Serial.print("check if there is a Favorite in Bank: "); Serial.print(tmp); Serial.println(); #endif if (SD.exists(tmp) ) { // this bank HAS at least 1 favorite(s) #ifdef DEBUG Serial.println("quickcheck found a FAV in bank!"); #endif return (true); } else { // no favorites in bank stored return (false); #ifdef DEBUG Serial.println(" - It is no Favorite in current Bank."); #endif } } else return false; } void save_favorite(uint8_t b, uint8_t v, uint8_t instance_id) { #ifdef DEBUG Serial.println("Starting saving Favorite."); #endif b = constrain(b, 0, MAX_BANKS - 1); v = constrain(v, 0, MAX_VOICES - 1); char tmp[18]; char tmpfolder[18]; File myFav; uint8_t i = 0, countfavs = 0; if (sd_card > 0) { sprintf(tmp, "/%s/%d/%d.fav", FAV_CONFIG_PATH, b, v); sprintf(tmpfolder, "/%s/%d", FAV_CONFIG_PATH, b); #ifdef DEBUG Serial.println("Save Favorite to SD card..."); Serial.println(tmp); #endif if (!SD.exists(tmp)) { //create Favorite Semaphore if (!SD.exists(tmpfolder)) { SD.mkdir(tmpfolder); } myFav = SD.open(tmp, FILE_WRITE); myFav.close(); Serial.println("Favorite saved..."); #ifdef TESTDISPLAY20x4 lcd.setCursor(17, 0); #else lcd.setCursor(13, 0); #endif lcd.write(2); //fav symbol #ifdef DEBUG Serial.println("Added to Favorites..."); #endif } else { // delete the file, is no longer a favorite SD.remove(tmp); #ifdef DEBUG Serial.println("Removed from Favorites..."); #endif for (i = 0; i < 32; i++) { //if no other favs exist in current bank, remove folder sprintf(tmp, "/%s/%d/%d.fav", FAV_CONFIG_PATH, b, i); if (SD.exists(tmp)) countfavs++; } if (countfavs == 0) { sprintf(tmp, "/%s/%d", FAV_CONFIG_PATH, b); SD.rmdir(tmp); #ifdef DEBUG Serial.println("Fav count in bank:"); Serial.print(countfavs); Serial.println("Removed folder since no voice in bank flagged as favorite any more"); #endif } #ifdef TESTDISPLAY20x4 lcd.setCursor(17, 0); #else lcd.setCursor(13, 0); #endif lcd.print(" "); //remove fav symbol #ifdef DEBUG Serial.println("Removed from Favorites..."); #endif } } } char* basename(const char* filename) { char* p = strrchr (filename, '/'); return p ? p + 1 : (char *) filename; } #endif #endif