Several fixes for storing.

pull/32/head
Holger Wirtz 4 years ago
parent 7c39166e2a
commit 9677c3788b
  1. 212
      MicroDexed.ino
  2. 61
      UI.hpp
  3. 161
      dexed_sd.cpp
  4. 3
      dexed_sd.h

@ -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
******************************************************************************/

@ -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();
}
}

@ -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);
}

@ -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);

Loading…
Cancel
Save