diff --git a/MicroDexed.ino b/MicroDexed.ino index 4f6aedd..4e7d3ab 100644 --- a/MicroDexed.ino +++ b/MicroDexed.ino @@ -443,12 +443,8 @@ void setup() master_mixer_r.gain(DEXED, 1.0); master_mixer_l.gain(DEXED, 1.0); - master_mixer_r.gain(CHORUS, mapfloat(configuration.fx.chorus_level, CHORUS_LEVEL_MIN, CHORUS_LEVEL_MAX, 0.0, 1.0)); - master_mixer_l.gain(CHORUS, mapfloat(configuration.fx.chorus_level, CHORUS_LEVEL_MIN, CHORUS_LEVEL_MAX, 0.0, 1.0)); - master_mixer_r.gain(DELAY, mapfloat(configuration.fx.delay_level, DELAY_LEVEL_MIN, DELAY_LEVEL_MAX, 0.0, 1.0)); - master_mixer_l.gain(DELAY, mapfloat(configuration.fx.delay_level, DELAY_LEVEL_MIN, DELAY_LEVEL_MAX, 0.0, 1.0)); - master_mixer_r.gain(REVERB, mapfloat(configuration.fx.reverb_level, REVERB_LEVEL_MIN, REVERB_LEVEL_MAX, 0.0, 1.0)); - master_mixer_l.gain(REVERB, mapfloat(configuration.fx.reverb_level, REVERB_LEVEL_MIN, REVERB_LEVEL_MAX, 0.0, 1.0)); + + set_fx_params(); for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) { @@ -459,91 +455,10 @@ void setup() dexed_mixer_r.gain(instance_id, 1.0); dexed_mixer_l.gain(instance_id, 1.0); -#if defined(USE_FX) - // INIT REVERB - reverb_send_mixer_r.gain(instance_id, mapfloat(configuration.dexed[instance_id].reverb_send, REVERB_SEND_MIN, REVERB_SEND_MAX, 0.0, 1.0)); - reverb_send_mixer_l.gain(instance_id, mapfloat(configuration.dexed[instance_id].reverb_send, REVERB_SEND_MIN, REVERB_SEND_MAX, 0.0, 1.0)); - - // INIT DELAY - delay_send_mixer_r.gain(instance_id, mapfloat(configuration.dexed[instance_id].delay_send, DELAY_SEND_MIN, DELAY_SEND_MAX, 0.0, 1.0)); - delay_send_mixer_l.gain(instance_id, mapfloat(configuration.dexed[instance_id].delay_send, DELAY_SEND_MIN, DELAY_SEND_MAX, 0.0, 1.0)); - - // INIT CHORUS - chorus_send_mixer_r.gain(instance_id, mapfloat(configuration.dexed[instance_id].chorus_send, CHORUS_SEND_MIN, CHORUS_SEND_MAX, 0.0, 1.0)); - chorus_send_mixer_l.gain(instance_id, mapfloat(configuration.dexed[instance_id].chorus_send, CHORUS_SEND_MIN, CHORUS_SEND_MAX, 0.0, 1.0)); - - // DEXED FILTER - //MicroDexed[instance_id]->fx.Gain = mapfloat(configuration.dexed[instance_id].sound_intensity, SOUND_INTENSITY_MIN, SOUND_INTENSITY_MAX, 0.0, SOUND_INTENSITY_AMP_MAX); - MicroDexed[instance_id]->fx.Gain = 1.0; - MicroDexed[instance_id]->fx.Reso = mapfloat(configuration.dexed[instance_id].filter_resonance, FILTER_RESONANCE_MIN, FILTER_RESONANCE_MAX, 1.0, 0.0); - MicroDexed[instance_id]->fx.Cutoff = mapfloat(configuration.dexed[instance_id].filter_cutoff, FILTER_CUTOFF_MIN, FILTER_CUTOFF_MAX, 1.0, 0.0); - MicroDexed[instance_id]->doRefreshVoice(); -#endif - - // Dexed output level - dexed_level[instance_id]->gain(mapfloat(configuration.dexed[instance_id].sound_intensity, SOUND_INTENSITY_MIN, SOUND_INTENSITY_MAX, 0.0, SOUND_INTENSITY_AMP_MAX)); - - // PANORAMA - mono2stereo[instance_id]->panorama(mapfloat(configuration.dexed[instance_id].pan, PANORAMA_MIN, PANORAMA_MAX, -1.0, 1.0)); + set_voiceconfig_params(instance_id); } -#if defined(USE_FX) - // DELAY - delay_r.delay(0, mapfloat(configuration.fx.delay_time * 10, DELAY_TIME_MIN, DELAY_TIME_MAX, 0.0, float(DELAY_TIME_MAX))); - delay_l.delay(0, mapfloat(configuration.fx.delay_time * 10, DELAY_TIME_MIN, DELAY_TIME_MAX, 0.0, float(DELAY_TIME_MAX))); - // delay_fb_mixer is the feedback-adding mixer - delay_fb_mixer_r.gain(0, 1.0); // original signal - delay_fb_mixer_r.gain(1, mapfloat(configuration.fx.delay_feedback, DELAY_FEEDBACK_MIN, DELAY_FEEDBACK_MAX, 0.0, 1.0)); // amount of feedback - delay_fb_mixer_l.gain(0, 1.0); // original signal - delay_fb_mixer_l.gain(1, mapfloat(configuration.fx.delay_feedback, DELAY_FEEDBACK_MIN, DELAY_FEEDBACK_MAX, 0.0, 1.0)); // amount of feedback - - // CHORUS - switch (configuration.fx.chorus_waveform) - { - case 0: - chorus_modulator.begin(WAVEFORM_TRIANGLE); - break; - case 1: - chorus_modulator.begin(WAVEFORM_SINE); - break; - default: - chorus_modulator.begin(WAVEFORM_TRIANGLE); - } - chorus_modulator.phase(0); - chorus_modulator.frequency(configuration.fx.chorus_frequency / 10.0); - chorus_modulator.amplitude(mapfloat(configuration.fx.chorus_depth, CHORUS_DEPTH_MIN, CHORUS_DEPTH_MAX, 0.0, 1.0)); - chorus_modulator.offset(0.0); -#if MOD_FILTER_OUTPUT == MOD_BUTTERWORTH_FILTER_OUTPUT - // Butterworth filter, 12 db/octave - modchorus_filter_r.setLowpass(0, MOD_FILTER_CUTOFF_HZ, 0.707); - modchorus_filter_l.setLowpass(0, MOD_FILTER_CUTOFF_HZ, 0.707); -#elif MOD_FILTER_OUTPUT == MOD_LINKWITZ_RILEY_FILTER_OUTPUT - // Linkwitz-Riley filter, 48 dB/octave - modchorus_filter_r.setLowpass(0, MOD_FILTER_CUTOFF_HZ, 0.54); - modchorus_filter_r.setLowpass(1, MOD_FILTER_CUTOFF_HZ, 1.3); - modchorus_filter_r.setLowpass(2, MOD_FILTER_CUTOFF_HZ, 0.54); - modchorus_filter_r.setLowpass(3, MOD_FILTER_CUTOFF_HZ, 1.3); - modchorus_filter_l.setLowpass(0, MOD_FILTER_CUTOFF_HZ, 0.54); - modchorus_filter_l.setLowpass(1, MOD_FILTER_CUTOFF_HZ, 1.3); - modchorus_filter_l.setLowpass(2, MOD_FILTER_CUTOFF_HZ, 0.54); - modchorus_filter_l.setLowpass(3, MOD_FILTER_CUTOFF_HZ, 1.3); -#endif - - // REVERB - freeverb_r.roomsize(mapfloat(configuration.fx.reverb_roomsize, REVERB_ROOMSIZE_MIN, REVERB_ROOMSIZE_MAX, 0.0, 1.0)); - freeverb_r.damping(mapfloat(configuration.fx.reverb_damping, REVERB_DAMPING_MIN, REVERB_DAMPING_MAX, 0.0, 1.0)); - freeverb_l.roomsize(mapfloat(configuration.fx.reverb_roomsize, REVERB_ROOMSIZE_MIN, REVERB_ROOMSIZE_MAX, 0.0, 1.0)); - freeverb_l.damping(mapfloat(configuration.fx.reverb_damping, REVERB_DAMPING_MIN, REVERB_DAMPING_MAX, 0.0, 1.0)); -#endif - - // MONO/STEREO - if (configuration.sys.mono == 0) - modchorus_inverter.gain(-1.0); // stereo mode - else - modchorus_inverter.gain(1.0); // mono mode - - // set initial volume - set_volume(configuration.sys.vol, configuration.sys.mono); + set_sys_params(); // Initialize processor and memory measurements AudioProcessorUsageMaxReset(); @@ -708,7 +623,6 @@ void handleControlChange(byte inChannel, byte inCtrl, byte inValue) if (inValue < MAX_BANKS - 1) { configuration.performance.bank[instance_id] = inValue; - //eeprom_write(); } break; case 1: @@ -736,7 +650,6 @@ void handleControlChange(byte inChannel, byte inCtrl, byte inValue) case 5: // Portamento time configuration.dexed[instance_id].portamento_time = inValue; MicroDexed[instance_id]->setPortamentoMode(configuration.dexed[instance_id].portamento_mode, configuration.dexed[instance_id].portamento_glissando, configuration.dexed[instance_id].portamento_time); - //eeprom_write(); break; case 7: // Instance Volume #ifdef DEBUG @@ -748,7 +661,6 @@ void handleControlChange(byte inChannel, byte inCtrl, byte inValue) #else dexed_level[instance_id]->gain(mapfloat(configuration.dexed[instance_id].sound_intensity, SOUND_INTENSITY_MIN, SOUND_INTENSITY_MAX, 0.0, SOUND_INTENSITY_AMP_MAX)); #endif - //eeprom_write(); break; case 10: // Pan #ifdef DEBUG @@ -756,14 +668,12 @@ void handleControlChange(byte inChannel, byte inCtrl, byte inValue) #endif configuration.dexed[instance_id].pan = map(inValue, 0, 0x7f, PANORAMA_MIN, PANORAMA_MAX); mono2stereo[instance_id]->panorama(mapfloat(configuration.dexed[instance_id].pan, PANORAMA_MIN, PANORAMA_MAX, -1.0, 1.0)); - //eeprom_write(); break; case 32: // BankSelect LSB #ifdef DEBUG Serial.println(F("BANK-SELECT CC")); #endif configuration.performance.bank[instance_id] = inValue; - //eeprom_write(); break; case 64: MicroDexed[instance_id]->setSustain(inValue > 63); @@ -781,37 +691,31 @@ void handleControlChange(byte inChannel, byte inCtrl, byte inValue) break; case 65: MicroDexed[instance_id]->setPortamentoMode(configuration.dexed[instance_id].portamento_mode, configuration.dexed[instance_id].portamento_glissando, configuration.dexed[instance_id].portamento_time); - //eeprom_write(); break; #if defined(USE_FX) case 103: // CC 103: filter resonance configuration.dexed[instance_id].filter_resonance = map(inValue, 0, 0x7f, FILTER_RESONANCE_MIN, FILTER_RESONANCE_MAX); MicroDexed[instance_id]->fx.Reso = mapfloat(configuration.dexed[instance_id].filter_resonance, FILTER_RESONANCE_MIN, FILTER_RESONANCE_MAX, 1.0, 0.0); - //eeprom_write(); break; case 104: // CC 104: filter cutoff configuration.dexed[instance_id].filter_cutoff = map(inValue, 0, 0x7f, FILTER_CUTOFF_MIN, FILTER_CUTOFF_MAX); MicroDexed[instance_id]->fx.Cutoff = mapfloat(configuration.dexed[instance_id].filter_cutoff, FILTER_CUTOFF_MIN, FILTER_CUTOFF_MAX, 1.0, 0.0); - //eeprom_write(); break; case 105: // CC 105: delay time configuration.fx.delay_time = map(inValue, 0, 0x7f, DELAY_TIME_MIN, DELAY_TIME_MAX); delay_r.delay(0, configuration.fx.delay_time * 10); delay_l.delay(0, configuration.fx.delay_time * 10); - //eeprom_write(); case 106: // CC 106: delay feedback configuration.fx.delay_feedback = map(inValue, 0, 0x7f, DELAY_FEEDBACK_MIN , DELAY_FEEDBACK_MAX); //delay_fb_mixer_r.gain(0, 1.0); // original signal delay_fb_mixer_r.gain(1, mapfloat(configuration.fx.delay_feedback, DELAY_FEEDBACK_MIN, DELAY_FEEDBACK_MAX, 0.0, 1.0)); // amount of feedback //delay_fb_mixer_l.gain(0, 1.0); // original signal delay_fb_mixer_l.gain(1, mapfloat(configuration.fx.delay_feedback, DELAY_FEEDBACK_MIN, DELAY_FEEDBACK_MAX, 0.0, 1.0)); // amount of feedback - //eeprom_write(); break; case 107: // CC 107: delay volume configuration.dexed[instance_id].delay_send = map(inValue, 0, 0x7f, DELAY_SEND_MIN, DELAY_SEND_MAX); master_mixer_r.gain(DELAY, mapfloat(configuration.fx.delay_level, DELAY_LEVEL_MIN, DELAY_LEVEL_MAX, 0.0, 1.0)); master_mixer_l.gain(DELAY, mapfloat(configuration.fx.delay_level, DELAY_LEVEL_MIN, DELAY_LEVEL_MAX, 0.0, 1.0)); - //eeprom_write(); break; #endif case 120: @@ -825,11 +729,9 @@ void handleControlChange(byte inChannel, byte inCtrl, byte inValue) break; case 126: MicroDexed[instance_id]->setMonoMode(true); - //eeprom_write(); break; case 127: MicroDexed[instance_id]->setMonoMode(false); - //eeprom_write(); break; } } @@ -1591,6 +1493,112 @@ bool eeprom_get_performance() return (true); } +/****************************************************************************** + PARAMETER-HELPERS + ******************************************************************************/ + +void set_fx_params(void) +{ + master_mixer_r.gain(CHORUS, mapfloat(configuration.fx.chorus_level, CHORUS_LEVEL_MIN, CHORUS_LEVEL_MAX, 0.0, 1.0)); + master_mixer_l.gain(CHORUS, mapfloat(configuration.fx.chorus_level, CHORUS_LEVEL_MIN, CHORUS_LEVEL_MAX, 0.0, 1.0)); + master_mixer_r.gain(DELAY, mapfloat(configuration.fx.delay_level, DELAY_LEVEL_MIN, DELAY_LEVEL_MAX, 0.0, 1.0)); + master_mixer_l.gain(DELAY, mapfloat(configuration.fx.delay_level, DELAY_LEVEL_MIN, DELAY_LEVEL_MAX, 0.0, 1.0)); + master_mixer_r.gain(REVERB, mapfloat(configuration.fx.reverb_level, REVERB_LEVEL_MIN, REVERB_LEVEL_MAX, 0.0, 1.0)); + master_mixer_l.gain(REVERB, mapfloat(configuration.fx.reverb_level, REVERB_LEVEL_MIN, REVERB_LEVEL_MAX, 0.0, 1.0)); + +#if defined(USE_FX) + // DELAY + delay_r.delay(0, mapfloat(configuration.fx.delay_time * 10, DELAY_TIME_MIN, DELAY_TIME_MAX, 0.0, float(DELAY_TIME_MAX))); + delay_l.delay(0, mapfloat(configuration.fx.delay_time * 10, DELAY_TIME_MIN, DELAY_TIME_MAX, 0.0, float(DELAY_TIME_MAX))); + // delay_fb_mixer is the feedback-adding mixer + delay_fb_mixer_r.gain(0, 1.0); // original signal + delay_fb_mixer_r.gain(1, mapfloat(configuration.fx.delay_feedback, DELAY_FEEDBACK_MIN, DELAY_FEEDBACK_MAX, 0.0, 1.0)); // amount of feedback + delay_fb_mixer_l.gain(0, 1.0); // original signal + delay_fb_mixer_l.gain(1, mapfloat(configuration.fx.delay_feedback, DELAY_FEEDBACK_MIN, DELAY_FEEDBACK_MAX, 0.0, 1.0)); // amount of feedback + + // CHORUS + switch (configuration.fx.chorus_waveform) + { + case 0: + chorus_modulator.begin(WAVEFORM_TRIANGLE); + break; + case 1: + chorus_modulator.begin(WAVEFORM_SINE); + break; + default: + chorus_modulator.begin(WAVEFORM_TRIANGLE); + } + chorus_modulator.phase(0); + chorus_modulator.frequency(configuration.fx.chorus_frequency / 10.0); + chorus_modulator.amplitude(mapfloat(configuration.fx.chorus_depth, CHORUS_DEPTH_MIN, CHORUS_DEPTH_MAX, 0.0, 1.0)); + chorus_modulator.offset(0.0); +#if MOD_FILTER_OUTPUT == MOD_BUTTERWORTH_FILTER_OUTPUT + // Butterworth filter, 12 db/octave + modchorus_filter_r.setLowpass(0, MOD_FILTER_CUTOFF_HZ, 0.707); + modchorus_filter_l.setLowpass(0, MOD_FILTER_CUTOFF_HZ, 0.707); +#elif MOD_FILTER_OUTPUT == MOD_LINKWITZ_RILEY_FILTER_OUTPUT + // Linkwitz-Riley filter, 48 dB/octave + modchorus_filter_r.setLowpass(0, MOD_FILTER_CUTOFF_HZ, 0.54); + modchorus_filter_r.setLowpass(1, MOD_FILTER_CUTOFF_HZ, 1.3); + modchorus_filter_r.setLowpass(2, MOD_FILTER_CUTOFF_HZ, 0.54); + modchorus_filter_r.setLowpass(3, MOD_FILTER_CUTOFF_HZ, 1.3); + modchorus_filter_l.setLowpass(0, MOD_FILTER_CUTOFF_HZ, 0.54); + modchorus_filter_l.setLowpass(1, MOD_FILTER_CUTOFF_HZ, 1.3); + modchorus_filter_l.setLowpass(2, MOD_FILTER_CUTOFF_HZ, 0.54); + modchorus_filter_l.setLowpass(3, MOD_FILTER_CUTOFF_HZ, 1.3); +#endif + + // REVERB + freeverb_r.roomsize(mapfloat(configuration.fx.reverb_roomsize, REVERB_ROOMSIZE_MIN, REVERB_ROOMSIZE_MAX, 0.0, 1.0)); + freeverb_r.damping(mapfloat(configuration.fx.reverb_damping, REVERB_DAMPING_MIN, REVERB_DAMPING_MAX, 0.0, 1.0)); + freeverb_l.roomsize(mapfloat(configuration.fx.reverb_roomsize, REVERB_ROOMSIZE_MIN, REVERB_ROOMSIZE_MAX, 0.0, 1.0)); + freeverb_l.damping(mapfloat(configuration.fx.reverb_damping, REVERB_DAMPING_MIN, REVERB_DAMPING_MAX, 0.0, 1.0)); +#endif +} + +void set_voiceconfig_params(uint8_t instance_id) +{ +#if defined(USE_FX) + // INIT REVERB + reverb_send_mixer_r.gain(instance_id, mapfloat(configuration.dexed[instance_id].reverb_send, REVERB_SEND_MIN, REVERB_SEND_MAX, 0.0, 1.0)); + reverb_send_mixer_l.gain(instance_id, mapfloat(configuration.dexed[instance_id].reverb_send, REVERB_SEND_MIN, REVERB_SEND_MAX, 0.0, 1.0)); + + // INIT DELAY + delay_send_mixer_r.gain(instance_id, mapfloat(configuration.dexed[instance_id].delay_send, DELAY_SEND_MIN, DELAY_SEND_MAX, 0.0, 1.0)); + delay_send_mixer_l.gain(instance_id, mapfloat(configuration.dexed[instance_id].delay_send, DELAY_SEND_MIN, DELAY_SEND_MAX, 0.0, 1.0)); + + // INIT CHORUS + chorus_send_mixer_r.gain(instance_id, mapfloat(configuration.dexed[instance_id].chorus_send, CHORUS_SEND_MIN, CHORUS_SEND_MAX, 0.0, 1.0)); + chorus_send_mixer_l.gain(instance_id, mapfloat(configuration.dexed[instance_id].chorus_send, CHORUS_SEND_MIN, CHORUS_SEND_MAX, 0.0, 1.0)); + + // DEXED FILTER + //MicroDexed[instance_id]->fx.Gain = mapfloat(configuration.dexed[instance_id].sound_intensity, SOUND_INTENSITY_MIN, SOUND_INTENSITY_MAX, 0.0, SOUND_INTENSITY_AMP_MAX); + MicroDexed[instance_id]->fx.Gain = 1.0; + MicroDexed[instance_id]->fx.Reso = mapfloat(configuration.dexed[instance_id].filter_resonance, FILTER_RESONANCE_MIN, FILTER_RESONANCE_MAX, 1.0, 0.0); + MicroDexed[instance_id]->fx.Cutoff = mapfloat(configuration.dexed[instance_id].filter_cutoff, FILTER_CUTOFF_MIN, FILTER_CUTOFF_MAX, 1.0, 0.0); + MicroDexed[instance_id]->doRefreshVoice(); +#endif + + // Dexed output level + dexed_level[instance_id]->gain(mapfloat(configuration.dexed[instance_id].sound_intensity, SOUND_INTENSITY_MIN, SOUND_INTENSITY_MAX, 0.0, SOUND_INTENSITY_AMP_MAX)); + + // PANORAMA + mono2stereo[instance_id]->panorama(mapfloat(configuration.dexed[instance_id].pan, PANORAMA_MIN, PANORAMA_MAX, -1.0, 1.0)); + +} + +void set_sys_params(void) +{ + // MONO/STEREO + if (configuration.sys.mono == 0) + modchorus_inverter.gain(-1.0); // stereo mode + else + modchorus_inverter.gain(1.0); // mono mode + + // set initial volume + set_volume(configuration.sys.vol, configuration.sys.mono); +} + /****************************************************************************** HELPERS ******************************************************************************/ diff --git a/UI.hpp b/UI.hpp index f7d7bad..aed00be 100644 --- a/UI.hpp +++ b/UI.hpp @@ -478,8 +478,6 @@ void lcdml_menu_control(void) encoderDir[ENC_L].reset(); encoderDir[ENC_R].reset(); - //eeprom_write(); - if (LCDML.MENU_getLastActivFunctionID() < 0xff) LCDML.OTHER_jumpToID(LCDML.MENU_getLastActivFunctionID()); else @@ -567,8 +565,8 @@ void lcdml_menu_control(void) LCDML.FUNC_setGBAToLastFunc(); else LCDML.FUNC_setGBAToLastCursorPos(); - //LCDML.FUNC_setGBA(); + //LCDML.FUNC_setGBA(); LCDML.OTHER_jumpToFunc(UI_func_voice_select); } else if ((millis() - g_LCDML_CONTROL_button_press_time[ENC_R]) >= g_LCDML_CONTROL_button_short_press) @@ -577,6 +575,8 @@ void lcdml_menu_control(void) Serial.println(F("ENC-R short")); #endif encoderDir[ENC_R].ButtonShort(true); + + //LCDML.FUNC_setGBA(); LCDML.BT_enter(); } } @@ -1786,7 +1786,7 @@ void UI_func_stereo_mono(uint8_t param) if (LCDML.FUNC_close()) // ****** STABLE END ********* { encoderDir[ENC_R].reset(); - EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, sys.vol), configuration.sys.vol); + EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, sys.mono), configuration.sys.mono); } } @@ -3078,7 +3078,6 @@ void UI_func_midi_soft_thru(uint8_t param) if (LCDML.FUNC_close()) // ****** STABLE END ********* { - //eeprom_write(); encoderDir[ENC_R].reset(); EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, sys.soft_midi_thru), configuration.sys.soft_midi_thru); } @@ -3245,7 +3244,6 @@ void UI_func_voice_select(uint8_t param) #ifdef DISPLAY_LCD_SPI change_disp_sd(true); #endif - //eeprom_write(); break; case MENU_VOICE_SOUND: voice_tmp = configuration.performance.voice[instance_id] - ENCODER[ENC_R].speed(); @@ -3270,7 +3268,6 @@ void UI_func_voice_select(uint8_t param) #ifdef DISPLAY_LCD_SPI change_disp_sd(true); #endif - //eeprom_write(); break; } else if (LCDML.BT_checkDown()) @@ -3288,7 +3285,6 @@ void UI_func_voice_select(uint8_t param) #ifdef DISPLAY_LCD_SPI change_disp_sd(true); #endif - //eeprom_write(); break; case MENU_VOICE_SOUND: voice_tmp = configuration.performance.voice[instance_id] + ENCODER[ENC_R].speed(); @@ -3312,7 +3308,6 @@ void UI_func_voice_select(uint8_t param) #ifdef DISPLAY_LCD_SPI change_disp_sd(true); #endif - //eeprom_write(); break; } @@ -3352,7 +3347,6 @@ void UI_func_voice_select(uint8_t param) if (LCDML.FUNC_close()) // ****** STABLE END ********* { - //eeprom_write(); encoderDir[ENC_R].reset(); if (instance_id == 0) { @@ -3409,7 +3403,6 @@ void UI_func_volume(uint8_t param) { lcd_special_chars(SCROLLBAR); - //eeprom_write(); EEPROM.update(EEPROM_START_ADDRESS + offsetof(configuration_s, sys.vol), configuration.sys.vol); encoderDir[ENC_L].reset(); } @@ -3454,12 +3447,11 @@ void UI_func_load_performance(uint8_t param) { mode = 0xff; - //eeprom_write(); lcd.setCursor(0, 1); if (load_sd_performance(configuration.sys.performance_number) == false) lcd.print("Does not exist."); else - lcd.print("Done. "); + lcd.print("Done. "); delay(500); if (LCDML.MENU_getLastActivFunctionID() < 0xff) @@ -3557,9 +3549,14 @@ void UI_func_save_performance(uint8_t param) else { mode = 0xff; - //eeprom_write(); if (overwrite == false || yesno == true) { + if (yesno == true) + { + char tmp[FILENAME_LEN]; + sprintf(tmp, "/%s%d.syx", PERFORMANCE_CONFIG_NAME, configuration.sys.performance_number); + SD.remove(tmp); + } save_sd_performance(configuration.performance.fx_number); lcd.setCursor(0, 1); lcd.print("Done. "); @@ -3676,9 +3673,10 @@ void UI_func_load_voiceconfig(uint8_t param) mode = 0xff; lcd.setCursor(0, 1); if (load_sd_voiceconfig(configuration.performance.voiceconfig_number[instance_id], instance_id) == false) - lcd.print("Does not exist."); + lcd.print("Does not exist. "); else - lcd.print("Done. "); + lcd.print("Done. "); + delay(500); if (LCDML.MENU_getLastActivFunctionID() < 0xff) @@ -3751,12 +3749,12 @@ void UI_func_save_voiceconfig(uint8_t param) #else mode = 1; lcd.setCursor(0, 1); - if (configuration.performance.voice[instance_id] == 0) + if (configuration.performance.voiceconfig_number[instance_id] == 0) lcd.print(F("[DEFAULT]")); else { char tmp[10]; - sprintf(tmp, "[%7d]", configuration.performance.voice[instance_id]); + sprintf(tmp, "[%7d]", configuration.performance.voiceconfig_number[instance_id]); lcd.print(tmp); } @@ -3802,9 +3800,14 @@ void UI_func_save_voiceconfig(uint8_t param) else { mode = 0xff; - //eeprom_write(); if (overwrite == false || yesno == true) { + if (yesno == true) + { + char tmp[FILENAME_LEN]; + sprintf(tmp, "/%s%d.syx", VOICE_CONFIG_NAME, configuration.performance.voiceconfig_number[instance_id]); + SD.remove(tmp); + } save_sd_voiceconfig(configuration.performance.voiceconfig_number[instance_id], instance_id); lcd.setCursor(0, 1); lcd.print("Done. "); @@ -3905,12 +3908,13 @@ void UI_func_load_fx(uint8_t param) else if (LCDML.BT_checkEnter()) { mode = 0xff; - //eeprom_write(); + lcd.setCursor(0, 1); if (load_sd_fx(configuration.performance.fx_number) == false) - lcd.print("Does not exist."); + lcd.print("Does not exist. "); else - lcd.print("Done. "); + lcd.print("Done. "); + delay(500); if (LCDML.MENU_getLastActivFunctionID() < 0xff) @@ -4008,9 +4012,14 @@ void UI_func_save_fx(uint8_t param) else { mode = 0xff; - //eeprom_write(); if (overwrite == false || yesno == true) { + if (yesno == true) + { + char tmp[FILENAME_LEN]; + sprintf(tmp, "/%s%d.syx", FX_CONFIG_NAME, configuration.performance.fx_number); + SD.remove(tmp); + } save_sd_fx(configuration.performance.fx_number); lcd.setCursor(0, 1); lcd.print("Done. "); @@ -4109,7 +4118,7 @@ void UI_func_save_voice(uint8_t param) // Storing on inside bank TBD lcd.setCursor(0, 1); - lcd.print(F("Done.")); + lcd.print(F("Done. ")); delay(500); } @@ -4147,7 +4156,6 @@ void UI_func_sysex_receive_bank(uint8_t param) if (LCDML.FUNC_close()) // ****** STABLE END ********* { - //eeprom_write(); encoderDir[ENC_R].reset(); } } @@ -4181,7 +4189,6 @@ void UI_func_sysex_send_bank(uint8_t param) if (LCDML.FUNC_close()) // ****** STABLE END ********* { - //eeprom_write(); encoderDir[ENC_R].reset(); } } @@ -4215,7 +4222,6 @@ void UI_func_sysex_send_voice(uint8_t param) if (LCDML.FUNC_close()) // ****** STABLE END ********* { - //eeprom_write(); encoderDir[ENC_R].reset(); } } @@ -4249,7 +4255,6 @@ void UI_func_sysex_receive_voice(uint8_t param) if (LCDML.FUNC_close()) // ****** STABLE END ********* { - //eeprom_write(); encoderDir[ENC_R].reset(); } } diff --git a/dexed_sd.cpp b/dexed_sd.cpp index e13f6aa..781afa7 100644 --- a/dexed_sd.cpp +++ b/dexed_sd.cpp @@ -75,8 +75,7 @@ bool load_sd_voice(uint8_t b, uint8_t v, uint8_t instance_id) show_patch(instance_id); #endif configuration.dexed[instance_id].transpose = MicroDexed[instance_id]->data[DEXED_VOICE_OFFSET + DEXED_TRANSPOSE]; - - load_sd_voiceconfig(v, instance_id); // check for coice config to load + sysex.close(); return (ret); } @@ -200,7 +199,9 @@ bool load_sd_voiceconfig(uint8_t vc, uint8_t instance_id) if (sysex) { get_sd_data(sysex, 0x42, (uint8_t*)&configuration.dexed[instance_id]); - eeprom_update_dexed(instance_id); + set_voiceconfig_params(instance_id); + sysex.close(); + return (true); } #ifdef DEBUG @@ -246,25 +247,23 @@ bool save_sd_voiceconfig(uint8_t vc, uint8_t instance_id) #endif sysex = SD.open(filename, FILE_WRITE); - if (!sysex) + if (sysex) + { + if (write_sd_data(sysex, 0x42, (uint8_t*)&configuration.dexed[instance_id], sizeof(configuration.dexed[instance_id]))) + { + sysex.close(); + return (true); + } + sysex.close(); + } + else { #ifdef DEBUG Serial.print(F("E : Cannot open ")); Serial.print(filename); Serial.println(F(" on SD.")); #endif - return (false); } - - if (write_sd_data(sysex, 0x42, (uint8_t*)&configuration.dexed[instance_id], sizeof(configuration.dexed[instance_id]))) - { - sysex.close(); - return (true); - } -#ifdef DEBUG - else - Serial.println(F("E : Cannot save voice data")); -#endif } return (false); @@ -297,7 +296,9 @@ bool load_sd_fx(uint8_t fx) if (sysex) { get_sd_data(sysex, 0x43, (uint8_t*)&configuration.fx); - eeprom_update_fx(); + set_fx_params(); + sysex.close(); + return (true); } #ifdef DEBUG @@ -341,7 +342,16 @@ bool save_sd_fx(uint8_t fx) #endif sysex = SD.open(filename, FILE_WRITE); - if (!sysex) + if (sysex) + { + if (write_sd_data(sysex, 0x43, (uint8_t*)&configuration.fx, sizeof(configuration.fx))) + { + sysex.close(); + return (true); + } + sysex.close(); + } + else { #ifdef DEBUG Serial.print(F("E : Cannot open ")); @@ -350,16 +360,6 @@ bool save_sd_fx(uint8_t fx) #endif return (false); } - - if (write_sd_data(sysex, 0x43, (uint8_t*)&configuration.fx, sizeof(configuration.fx))) - { - sysex.close(); - return (true); - } -#ifdef DEBUG - else - Serial.println(F("E : Cannot save fx data")); -#endif } return (false); @@ -392,7 +392,8 @@ bool load_sd_performance(uint8_t p) if (sysex) { get_sd_data(sysex, 0x44, (uint8_t*)&configuration.performance); - eeprom_update_performance(); + sysex.close(); + return (true); } #ifdef DEBUG @@ -435,7 +436,16 @@ bool save_sd_performance(uint8_t p) #endif sysex = SD.open(filename, FILE_WRITE); - if (!sysex) + if (sysex) + { + if (write_sd_data(sysex, 0x44, (uint8_t*)&configuration.performance, sizeof(configuration.performance))) + { + sysex.close(); + return (true); + } + sysex.close(); + } + else { #ifdef DEBUG Serial.print(F("E : Cannot open ")); @@ -444,16 +454,6 @@ bool save_sd_performance(uint8_t p) #endif return (false); } - - if (write_sd_data(sysex, 0x44, (uint8_t*)&configuration.performance, sizeof(configuration.performance))) - { - sysex.close(); - return (true); - } -#ifdef DEBUG - else - Serial.println(F("E : Cannot save performance data")); -#endif } return (false); } @@ -467,6 +467,12 @@ bool get_sd_data(File sysex, uint8_t format, uint8_t* conf) int32_t bulk_checksum_calc = 0; int8_t bulk_checksum; +#ifdef DEBUG + Serial.print(F("Reading ")); + Serial.print(sysex.size()); + Serial.println(F(" bytes.")); +#endif + if (sysex.read() != 0xf0) // check sysex start-byte { #ifdef DEBUG @@ -488,7 +494,7 @@ bool get_sd_data(File sysex, uint8_t format, uint8_t* conf) #endif return (false); } - sysex.seek(sysex.size()); + sysex.seek(sysex.size() - 1); if (sysex.read() != 0xf7) // check sysex end-byte { #ifdef DEBUG @@ -497,38 +503,51 @@ bool get_sd_data(File sysex, uint8_t format, uint8_t* conf) return (false); } - sysex.seek(sysex.size() - 1); // Bulk checksum + sysex.seek(sysex.size() - 2); // Bulk checksum bulk_checksum = sysex.read(); sysex.seek(3); // start of bulk data - for (n = 0; n < sysex.size() - 3; n++) + for (n = 0; n < sysex.size() - 6; n++) { uint8_t d = sysex.read(); bulk_checksum_calc -= d; - *conf++ = d; - } - bulk_checksum_calc &= 0x7f; - #ifdef DEBUG - Serial.print(F("Bulk checksum : 0x")); - Serial.print(bulk_checksum_calc, HEX); - Serial.print(F(" [0x")); - Serial.print(bulk_checksum, HEX); - Serial.println(F("]")); + Serial.print(F("SYSEX data read: 0x")); + Serial.println(d, HEX); #endif + } + bulk_checksum_calc &= 0x7f; - if (bulk_checksum_calc != bulk_checksum) + if (int8_t(bulk_checksum_calc) != bulk_checksum) { #ifdef DEBUG Serial.print(F("E : Bulk checksum mismatch : 0x")); - Serial.print(bulk_checksum_calc, HEX); + Serial.print(int8_t(bulk_checksum_calc), HEX); Serial.print(F(" != 0x")); Serial.println(bulk_checksum, HEX); #endif return (false); } #ifdef DEBUG - Serial.println(F("Voice config loaded.")); + else + { + Serial.print(F("Bulk checksum : 0x")); + Serial.print(int8_t(bulk_checksum_calc), HEX); + Serial.print(F(" [0x")); + Serial.print(bulk_checksum, HEX); + Serial.println(F("]")); + } +#endif + + sysex.seek(3); // start of bulk data + for (n = 0; n < sysex.size() - 6; n++) + { + uint8_t d = sysex.read(); + *(conf++) = d; + } + +#ifdef DEBUG + Serial.println(F("SD data loaded.")); #endif return (true); @@ -536,18 +555,52 @@ bool get_sd_data(File sysex, uint8_t format, uint8_t* conf) bool write_sd_data(File sysex, uint8_t format, uint8_t* data, uint16_t len) { +#ifdef DEBUG + Serial.print(F("Storing SYSEX format 0x")); + Serial.print(format, HEX); + Serial.print(F(" with length of ")); + Serial.print(len, DEC); + Serial.println(F(" bytes.")); +#endif + // write sysex start sysex.write(0xf0); +#ifdef DEBUG + Serial.println(F("Write SYSEX start: 0xf0")); +#endif // write sysex vendor is unofficial SYSEX-ID for MicroDexed sysex.write(0x67); +#ifdef DEBUG + Serial.println(F("Write SYSEX vendor: 0x67")); +#endif // write sysex format number sysex.write(format); +#ifdef DEBUG + Serial.print(F("Write SYSEX format: 0x")); + Serial.println(format, HEX); +#endif // write data sysex.write(data, len); +#ifdef DEBUG + for (uint16_t i = 0; i < len; i++) + { + Serial.print(F("Write SYSEX data: 0x")); + Serial.println(data[i], HEX); + } +#endif // write checksum sysex.write(calc_checksum(data, len)); +#ifdef DEBUG + uint8_t checksum = calc_checksum(data, len); + sysex.write(checksum); + Serial.print(F("Write SYSEX checksum: 0x")); + Serial.println(checksum, HEX); +#endif // write sysex end sysex.write(0xf7); +#ifdef DEBUG + Serial.println(F("Write SYSEX end: 0xf7")); +#endif return (true); } diff --git a/dexed_sd.h b/dexed_sd.h index 84b7fc9..1879711 100644 --- a/dexed_sd.h +++ b/dexed_sd.h @@ -47,6 +47,9 @@ extern uint32_t crc32(byte * calc_start, uint16_t calc_bytes); extern void eeprom_update_dexed(uint8_t instance_id); extern void eeprom_update_performance(void); extern void eeprom_update_fx(void); +extern void set_fx_params(void); +extern void set_voiceconfig_params(uint8_t instance_id); +extern void set_sys_params(void); bool load_sd_voice(uint8_t b, uint8_t v, uint8_t instance_id); bool get_sd_voice(File sysex, uint8_t voice_number, uint8_t* data);