|
|
|
@ -396,19 +396,17 @@ bool save_sd_bank(const char* bank_filename, uint8_t* data) |
|
|
|
|
/******************************************************************************
|
|
|
|
|
SD VOICECONFIG |
|
|
|
|
******************************************************************************/ |
|
|
|
|
bool load_sd_voiceconfig(int8_t vc, uint8_t instance_id) |
|
|
|
|
bool load_sd_voiceconfig_json(int8_t vc, uint8_t instance_id) |
|
|
|
|
{ |
|
|
|
|
if (vc < 0) |
|
|
|
|
return (false); |
|
|
|
|
char filename[FILENAME_LEN]; |
|
|
|
|
|
|
|
|
|
vc = constrain(vc, 0, MAX_VOICECONFIG); |
|
|
|
|
|
|
|
|
|
if (sd_card > 0) |
|
|
|
|
{ |
|
|
|
|
File sysex; |
|
|
|
|
char filename[FILENAME_LEN]; |
|
|
|
|
File json; |
|
|
|
|
|
|
|
|
|
sprintf(filename, "/%s/%s%d.syx", VOICE_CONFIG_PATH, VOICE_CONFIG_NAME, vc); |
|
|
|
|
sprintf(filename, "/%s/%s%d.json", VOICE_CONFIG_PATH, VOICE_CONFIG_NAME, vc); |
|
|
|
|
|
|
|
|
|
// first check if file exists...
|
|
|
|
|
AudioNoInterrupts(); |
|
|
|
@ -420,48 +418,87 @@ bool load_sd_voiceconfig(int8_t vc, uint8_t instance_id) |
|
|
|
|
Serial.print(filename); |
|
|
|
|
Serial.println(F("]... loading...")); |
|
|
|
|
#endif |
|
|
|
|
sysex = SD.open(filename); |
|
|
|
|
if (sysex) |
|
|
|
|
json = SD.open(filename); |
|
|
|
|
if (json) |
|
|
|
|
{ |
|
|
|
|
get_sd_data(sysex, 0x42, (uint8_t*)&configuration.dexed[instance_id]); |
|
|
|
|
set_voiceconfig_params(instance_id); |
|
|
|
|
sysex.close(); |
|
|
|
|
StaticJsonDocument<JSON_BUFFER> data_json; |
|
|
|
|
|
|
|
|
|
deserializeJson(data_json, json); |
|
|
|
|
|
|
|
|
|
json.close(); |
|
|
|
|
AudioInterrupts(); |
|
|
|
|
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.println(F("Read JSON data:")); |
|
|
|
|
serializeJsonPretty(data_json, Serial); |
|
|
|
|
Serial.println(); |
|
|
|
|
#endif |
|
|
|
|
configuration.dexed[instance_id].lowest_note = data_json["lowest_note"][instance_id]; |
|
|
|
|
configuration.dexed[instance_id].highest_note = data_json["highest_note"][instance_id]; |
|
|
|
|
configuration.dexed[instance_id].transpose = data_json["transpose"][instance_id]; |
|
|
|
|
configuration.dexed[instance_id].tune = data_json["tune"][instance_id]; |
|
|
|
|
configuration.dexed[instance_id].sound_intensity = data_json["sound_intensity"][instance_id]; |
|
|
|
|
configuration.dexed[instance_id].pan = data_json["pan"][instance_id]; |
|
|
|
|
configuration.dexed[instance_id].polyphony = data_json["polyphony"][instance_id]; |
|
|
|
|
configuration.dexed[instance_id].velocity_level = data_json["velocity_level"][instance_id]; |
|
|
|
|
configuration.dexed[instance_id].monopoly = data_json["monopoly"][instance_id]; |
|
|
|
|
configuration.dexed[instance_id].note_refresh = data_json["note_refresh"][instance_id]; |
|
|
|
|
configuration.dexed[instance_id].pb_range = data_json["pb_range"][instance_id]; |
|
|
|
|
configuration.dexed[instance_id].pb_step = data_json["pb_step"][instance_id]; |
|
|
|
|
configuration.dexed[instance_id].mw_range = data_json["mw_range"][instance_id]; |
|
|
|
|
configuration.dexed[instance_id].mw_assign = data_json["mw_assign"][instance_id]; |
|
|
|
|
configuration.dexed[instance_id].mw_mode = data_json["mw_mode"][instance_id]; |
|
|
|
|
configuration.dexed[instance_id].fc_range = data_json["fc_range"][instance_id]; |
|
|
|
|
configuration.dexed[instance_id].fc_assign = data_json["fc_assign"][instance_id]; |
|
|
|
|
configuration.dexed[instance_id].fc_mode = data_json["fc_mode"][instance_id]; |
|
|
|
|
configuration.dexed[instance_id].bc_range = data_json["bc_range"][instance_id]; |
|
|
|
|
configuration.dexed[instance_id].bc_assign = data_json["bc_assign"][instance_id]; |
|
|
|
|
configuration.dexed[instance_id].bc_mode = data_json["bc_mode"][instance_id]; |
|
|
|
|
configuration.dexed[instance_id].at_range = data_json["at_range"][instance_id]; |
|
|
|
|
configuration.dexed[instance_id].at_assign = data_json["at_assign"][instance_id]; |
|
|
|
|
configuration.dexed[instance_id].at_mode = data_json["at_mode"][instance_id]; |
|
|
|
|
configuration.dexed[instance_id].portamento_mode = data_json["portamento_mode"][instance_id]; |
|
|
|
|
configuration.dexed[instance_id].portamento_glissando = data_json["portamento_glissando"][instance_id]; |
|
|
|
|
configuration.dexed[instance_id].portamento_time = data_json["portamento_time"][instance_id]; |
|
|
|
|
configuration.dexed[instance_id].op_enabled = data_json["op_enabled"][instance_id]; |
|
|
|
|
configuration.dexed[instance_id].midi_channel = data_json["midi_channel"][instance_id]; |
|
|
|
|
|
|
|
|
|
set_voiceconfig_params(instance_id); |
|
|
|
|
|
|
|
|
|
return (true); |
|
|
|
|
} |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
AudioInterrupts(); |
|
|
|
|
Serial.print(F("E : Cannot open ")); |
|
|
|
|
Serial.print(filename); |
|
|
|
|
Serial.println(F(" on SD.")); |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.print(F("No ")); |
|
|
|
|
Serial.print(filename); |
|
|
|
|
Serial.println(F(" available.")); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
AudioInterrupts(); |
|
|
|
|
return (false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool save_sd_voiceconfig(uint8_t vc, uint8_t instance_id) |
|
|
|
|
bool save_sd_voiceconfig_json(uint8_t vc, uint8_t instance_id) |
|
|
|
|
{ |
|
|
|
|
char filename[FILENAME_LEN]; |
|
|
|
|
|
|
|
|
|
vc = constrain(vc, 0, MAX_VOICECONFIG); |
|
|
|
|
|
|
|
|
|
if (sd_card > 0) |
|
|
|
|
{ |
|
|
|
|
File sysex; |
|
|
|
|
char filename[FILENAME_LEN]; |
|
|
|
|
File json; |
|
|
|
|
|
|
|
|
|
sprintf(filename, "/%s/%s%d.syx", VOICE_CONFIG_PATH, VOICE_CONFIG_NAME, vc); |
|
|
|
|
sprintf(filename, "/%s/%s%d.json", VOICE_CONFIG_PATH, VOICE_CONFIG_NAME, vc); |
|
|
|
|
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.print(F("Saving voice config ")); |
|
|
|
@ -474,35 +511,72 @@ bool save_sd_voiceconfig(uint8_t vc, uint8_t instance_id) |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
AudioNoInterrupts(); |
|
|
|
|
sysex = SD.open(filename, FILE_WRITE); |
|
|
|
|
if (sysex) |
|
|
|
|
json = SD.open(filename, FILE_WRITE); |
|
|
|
|
if (json) |
|
|
|
|
{ |
|
|
|
|
if (write_sd_data(sysex, 0x42, (uint8_t*)&configuration.dexed[instance_id], sizeof(configuration.dexed[instance_id]))) |
|
|
|
|
{ |
|
|
|
|
sysex.close(); |
|
|
|
|
AudioInterrupts(); |
|
|
|
|
return (true); |
|
|
|
|
} |
|
|
|
|
sysex.close(); |
|
|
|
|
StaticJsonDocument<JSON_BUFFER> data_json; |
|
|
|
|
|
|
|
|
|
data_json["lowest_note"][instance_id] = configuration.dexed[instance_id].lowest_note; |
|
|
|
|
data_json["highest_note"][instance_id] = configuration.dexed[instance_id].highest_note; |
|
|
|
|
data_json["transpose"][instance_id] = configuration.dexed[instance_id].transpose; |
|
|
|
|
data_json["tune"][instance_id] = configuration.dexed[instance_id].tune; |
|
|
|
|
data_json["sound_intensity"][instance_id] = configuration.dexed[instance_id].sound_intensity; |
|
|
|
|
data_json["pan"][instance_id] = configuration.dexed[instance_id].pan; |
|
|
|
|
data_json["polyphony"][instance_id] = configuration.dexed[instance_id].polyphony; |
|
|
|
|
data_json["velocity_level"][instance_id] = configuration.dexed[instance_id].velocity_level; |
|
|
|
|
data_json["monopoly"][instance_id] = configuration.dexed[instance_id].monopoly; |
|
|
|
|
data_json["monopoly"][instance_id] = configuration.dexed[instance_id].monopoly; |
|
|
|
|
data_json["note_refresh"][instance_id] = configuration.dexed[instance_id].note_refresh; |
|
|
|
|
data_json["pb_range"][instance_id] = configuration.dexed[instance_id].pb_range; |
|
|
|
|
data_json["pb_step"][instance_id] = configuration.dexed[instance_id].pb_step; |
|
|
|
|
data_json["mw_range"][instance_id] = configuration.dexed[instance_id].mw_range; |
|
|
|
|
data_json["mw_assign"][instance_id] = configuration.dexed[instance_id].mw_assign; |
|
|
|
|
data_json["mw_mode"][instance_id] = configuration.dexed[instance_id].mw_mode; |
|
|
|
|
data_json["fc_range"][instance_id] = configuration.dexed[instance_id].fc_range; |
|
|
|
|
data_json["fc_assign"][instance_id] = configuration.dexed[instance_id].fc_assign; |
|
|
|
|
data_json["fc_mode"][instance_id] = configuration.dexed[instance_id].fc_mode; |
|
|
|
|
data_json["bc_range"][instance_id] = configuration.dexed[instance_id].bc_range; |
|
|
|
|
data_json["bc_assign"][instance_id] = configuration.dexed[instance_id].bc_assign; |
|
|
|
|
data_json["bc_mode"][instance_id] = configuration.dexed[instance_id].bc_mode; |
|
|
|
|
data_json["at_range"][instance_id] = configuration.dexed[instance_id].at_range; |
|
|
|
|
data_json["at_assign"][instance_id] = configuration.dexed[instance_id].at_assign; |
|
|
|
|
data_json["at_mode"][instance_id] = configuration.dexed[instance_id].at_mode; |
|
|
|
|
data_json["portamento_mode"][instance_id] = configuration.dexed[instance_id].portamento_mode; |
|
|
|
|
data_json["portamento_glissando"][instance_id] = configuration.dexed[instance_id].portamento_glissando; |
|
|
|
|
data_json["portamento_time"][instance_id] = configuration.dexed[instance_id].portamento_time; |
|
|
|
|
data_json["op_enabled"][instance_id] = configuration.dexed[instance_id].op_enabled; |
|
|
|
|
data_json["midi_channel"][instance_id] = configuration.dexed[instance_id].midi_channel; |
|
|
|
|
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.println(F("Write JSON data:")); |
|
|
|
|
serializeJsonPretty(data_json, Serial); |
|
|
|
|
Serial.println(); |
|
|
|
|
#endif |
|
|
|
|
serializeJsonPretty(data_json, json); |
|
|
|
|
json.close(); |
|
|
|
|
AudioInterrupts(); |
|
|
|
|
|
|
|
|
|
return (true); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
json.close(); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.print(F("E : Cannot open ")); |
|
|
|
|
Serial.print(filename); |
|
|
|
|
Serial.println(F(" on SD.")); |
|
|
|
|
Serial.print(F("E : Cannot open ")); |
|
|
|
|
Serial.print(filename); |
|
|
|
|
Serial.println(F(" on SD.")); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
AudioInterrupts(); |
|
|
|
|
return (false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
|
SD FX |
|
|
|
|
******************************************************************************/ |
|
|
|
|
bool load_sd_fx(int8_t fx) |
|
|
|
|
bool load_sd_fx_json(int8_t fx) |
|
|
|
|
{ |
|
|
|
|
if (fx < 0) |
|
|
|
|
return (false); |
|
|
|
@ -511,10 +585,10 @@ bool load_sd_fx(int8_t fx) |
|
|
|
|
|
|
|
|
|
if (sd_card > 0) |
|
|
|
|
{ |
|
|
|
|
File sysex; |
|
|
|
|
File json; |
|
|
|
|
char filename[FILENAME_LEN]; |
|
|
|
|
|
|
|
|
|
sprintf(filename, "/%s/%s%d.syx", FX_CONFIG_PATH, FX_CONFIG_NAME, fx); |
|
|
|
|
sprintf(filename, "/%s/%s%d.json", FX_CONFIG_PATH, FX_CONFIG_NAME, fx); |
|
|
|
|
|
|
|
|
|
// first check if file exists...
|
|
|
|
|
AudioNoInterrupts(); |
|
|
|
@ -526,29 +600,59 @@ bool load_sd_fx(int8_t fx) |
|
|
|
|
Serial.print(filename); |
|
|
|
|
Serial.println(F("]... loading...")); |
|
|
|
|
#endif |
|
|
|
|
sysex = SD.open(filename); |
|
|
|
|
if (sysex) |
|
|
|
|
json = SD.open(filename); |
|
|
|
|
if (json) |
|
|
|
|
{ |
|
|
|
|
get_sd_data(sysex, 0x43, (uint8_t*)&configuration.fx); |
|
|
|
|
set_fx_params(); |
|
|
|
|
sysex.close(); |
|
|
|
|
StaticJsonDocument<JSON_BUFFER> data_json; |
|
|
|
|
|
|
|
|
|
deserializeJson(data_json, json); |
|
|
|
|
|
|
|
|
|
json.close(); |
|
|
|
|
AudioInterrupts(); |
|
|
|
|
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.println(F("Read JSON data:")); |
|
|
|
|
serializeJsonPretty(data_json, Serial); |
|
|
|
|
Serial.println(); |
|
|
|
|
#endif |
|
|
|
|
for (uint8_t i = 0; i < MAX_DEXED; i++) |
|
|
|
|
{ |
|
|
|
|
configuration.fx.filter_cutoff[i] = data_json["filter_cutoff"][i]; |
|
|
|
|
configuration.fx.filter_resonance[i] = data_json["filter_resonance"][i]; |
|
|
|
|
configuration.fx.chorus_frequency[i] = data_json["chorus_frequency"][i]; |
|
|
|
|
configuration.fx.chorus_waveform[i] = data_json["chorus_waveform"][i]; |
|
|
|
|
configuration.fx.chorus_depth[i] = data_json["chorus_depth"][i]; |
|
|
|
|
configuration.fx.chorus_level[i] = data_json["chorus_level"][i]; |
|
|
|
|
configuration.fx.delay_time[i] = data_json["delay_time"][i]; |
|
|
|
|
configuration.fx.delay_feedback[i] = data_json["delay_feedback"][i]; |
|
|
|
|
configuration.fx.delay_level[i] = data_json["delay_level"][i]; |
|
|
|
|
configuration.fx.delay_sync[i] = data_json["delay_sync"][i]; |
|
|
|
|
configuration.fx.reverb_send[i] = data_json["reverb_send"][i]; |
|
|
|
|
} |
|
|
|
|
configuration.fx.reverb_roomsize = data_json["reverb_roomsize"]; |
|
|
|
|
configuration.fx.reverb_damping = data_json["reverb_damping"]; |
|
|
|
|
configuration.fx.reverb_lowpass = data_json["reverb_lowpass"]; |
|
|
|
|
configuration.fx.reverb_lodamp = data_json["reverb_lodamp"]; |
|
|
|
|
configuration.fx.reverb_hidamp = data_json["reverb_hidamp"]; |
|
|
|
|
configuration.fx.reverb_diffusion = data_json["reverb_diffusion"]; |
|
|
|
|
configuration.fx.reverb_level = data_json["reverb_level"]; |
|
|
|
|
configuration.fx.eq_bass = data_json["eq_bass"]; |
|
|
|
|
configuration.fx.eq_treble = data_json["eq_treble"]; |
|
|
|
|
|
|
|
|
|
set_fx_params(); |
|
|
|
|
|
|
|
|
|
return (true); |
|
|
|
|
} |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
AudioInterrupts(); |
|
|
|
|
Serial.print(F("E : Cannot open ")); |
|
|
|
|
Serial.print(filename); |
|
|
|
|
Serial.println(F(" on SD.")); |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.print(F("No ")); |
|
|
|
|
Serial.print(filename); |
|
|
|
|
Serial.println(F(" available.")); |
|
|
|
@ -556,19 +660,21 @@ bool load_sd_fx(int8_t fx) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
AudioInterrupts(); |
|
|
|
|
return (false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool save_sd_fx(uint8_t fx) |
|
|
|
|
bool save_sd_fx_json(uint8_t fx) |
|
|
|
|
{ |
|
|
|
|
char filename[FILENAME_LEN]; |
|
|
|
|
|
|
|
|
|
fx = constrain(fx, 0, MAX_FX); |
|
|
|
|
|
|
|
|
|
if (sd_card > 0) |
|
|
|
|
{ |
|
|
|
|
File sysex; |
|
|
|
|
char filename[FILENAME_LEN]; |
|
|
|
|
File json; |
|
|
|
|
|
|
|
|
|
sprintf(filename, "/%s/%s%d.syx", FX_CONFIG_PATH, FX_CONFIG_NAME, fx); |
|
|
|
|
sprintf(filename, "/%s/%s%d.json", FX_CONFIG_PATH, FX_CONFIG_NAME, fx); |
|
|
|
|
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.print(F("Saving fx config ")); |
|
|
|
@ -578,143 +684,63 @@ bool save_sd_fx(uint8_t fx) |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
AudioNoInterrupts(); |
|
|
|
|
sysex = SD.open(filename, FILE_WRITE); |
|
|
|
|
if (sysex) |
|
|
|
|
{ |
|
|
|
|
if (write_sd_data(sysex, 0x43, (uint8_t*)&configuration.fx, sizeof(configuration.fx))) |
|
|
|
|
{ |
|
|
|
|
sysex.close(); |
|
|
|
|
AudioInterrupts(); |
|
|
|
|
return (true); |
|
|
|
|
} |
|
|
|
|
sysex.close(); |
|
|
|
|
AudioInterrupts(); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.print(F("E : Cannot open ")); |
|
|
|
|
Serial.print(filename); |
|
|
|
|
Serial.println(F(" on SD.")); |
|
|
|
|
#endif |
|
|
|
|
return (false); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return (false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
|
SD PERFORMANCE |
|
|
|
|
******************************************************************************/ |
|
|
|
|
bool load_sd_performance(int8_t p) |
|
|
|
|
{ |
|
|
|
|
if (p < 0) |
|
|
|
|
return (false); |
|
|
|
|
|
|
|
|
|
p = constrain(p, 0, MAX_PERFORMANCE); |
|
|
|
|
|
|
|
|
|
if (sd_card > 0) |
|
|
|
|
{ |
|
|
|
|
File sysex; |
|
|
|
|
char filename[FILENAME_LEN]; |
|
|
|
|
|
|
|
|
|
sprintf(filename, "/%s/%s%d.syx", PERFORMANCE_CONFIG_PATH, PERFORMANCE_CONFIG_NAME, p); |
|
|
|
|
|
|
|
|
|
// first check if file exists...
|
|
|
|
|
AudioNoInterrupts(); |
|
|
|
|
if (SD.exists(filename)) |
|
|
|
|
json = SD.open(filename, FILE_WRITE); |
|
|
|
|
if (json) |
|
|
|
|
{ |
|
|
|
|
// ... and if: load
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.print(F("Found performance configuration [")); |
|
|
|
|
Serial.print(filename); |
|
|
|
|
Serial.println(F("]... loading...")); |
|
|
|
|
#endif |
|
|
|
|
sysex = SD.open(filename); |
|
|
|
|
if (sysex) |
|
|
|
|
{ |
|
|
|
|
get_sd_data(sysex, 0x44, (uint8_t*)&configuration.performance); |
|
|
|
|
sysex.close(); |
|
|
|
|
AudioInterrupts(); |
|
|
|
|
|
|
|
|
|
for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) |
|
|
|
|
{ |
|
|
|
|
load_sd_voice(configuration.performance.bank[instance_id], configuration.performance.voice[instance_id], instance_id); |
|
|
|
|
load_sd_voiceconfig(configuration.performance.voiceconfig_number[instance_id], instance_id); |
|
|
|
|
|
|
|
|
|
MicroDexed[instance_id]->ControllersRefresh(); |
|
|
|
|
MicroDexed[instance_id]->panic(); |
|
|
|
|
} |
|
|
|
|
load_sd_fx(configuration.performance.fx_number); |
|
|
|
|
StaticJsonDocument<JSON_BUFFER> data_json; |
|
|
|
|
|
|
|
|
|
return (true); |
|
|
|
|
} |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
else |
|
|
|
|
for (uint8_t i = 0; i < MAX_DEXED; i++) |
|
|
|
|
{ |
|
|
|
|
Serial.print(F("E : Cannot open ")); |
|
|
|
|
Serial.print(filename); |
|
|
|
|
Serial.println(F(" on SD.")); |
|
|
|
|
data_json["filter_cutoff"][i] = configuration.fx.filter_cutoff[i]; |
|
|
|
|
data_json["filter_resonance"][i] = configuration.fx.filter_resonance[i]; |
|
|
|
|
data_json["chorus_frequency"][i] = configuration.fx.chorus_frequency[i]; |
|
|
|
|
data_json["chorus_waveform"][i] = configuration.fx.chorus_waveform[i]; |
|
|
|
|
data_json["chorus_depth"][i] = configuration.fx.chorus_depth[i]; |
|
|
|
|
data_json["chorus_level"][i] = configuration.fx.chorus_level[i]; |
|
|
|
|
data_json["delay_time"][i] = configuration.fx.delay_time[i]; |
|
|
|
|
data_json["delay_feedback"][i] = configuration.fx.delay_feedback[i]; |
|
|
|
|
data_json["delay_level"][i] = configuration.fx.delay_level[i]; |
|
|
|
|
data_json["delay_sync"][i] = configuration.fx.delay_sync[i]; |
|
|
|
|
data_json["reverb_send"][i] = configuration.fx.reverb_send[i]; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.print(F("No ")); |
|
|
|
|
Serial.print(filename); |
|
|
|
|
Serial.println(F(" available.")); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return (false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool save_sd_performance(uint8_t p) |
|
|
|
|
{ |
|
|
|
|
p = constrain(p, 0, MAX_PERFORMANCE); |
|
|
|
|
|
|
|
|
|
if (sd_card > 0) |
|
|
|
|
{ |
|
|
|
|
File sysex; |
|
|
|
|
char filename[FILENAME_LEN]; |
|
|
|
|
|
|
|
|
|
sprintf(filename, "/%s/%s%d.syx", PERFORMANCE_CONFIG_PATH, PERFORMANCE_CONFIG_NAME, p); |
|
|
|
|
data_json["reverb_roomsize"] = configuration.fx.reverb_roomsize; |
|
|
|
|
data_json["reverb_damping"] = configuration.fx.reverb_damping; |
|
|
|
|
data_json["reverb_lowpass"] = configuration.fx.reverb_lowpass; |
|
|
|
|
data_json["reverb_lodamp"] = configuration.fx.reverb_lodamp; |
|
|
|
|
data_json["reverb_hidamp"] = configuration.fx.reverb_hidamp; |
|
|
|
|
data_json["reverb_diffusion"] = configuration.fx.reverb_diffusion; |
|
|
|
|
data_json["reverb_level"] = configuration.fx.reverb_level; |
|
|
|
|
data_json["eq_bass"] = configuration.fx.eq_bass; |
|
|
|
|
data_json["eq_treble"] = configuration.fx.eq_treble; |
|
|
|
|
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.print(F("Saving performance config ")); |
|
|
|
|
Serial.print(p); |
|
|
|
|
Serial.print(F(" to ")); |
|
|
|
|
Serial.println(filename); |
|
|
|
|
Serial.println(F("Write JSON data:")); |
|
|
|
|
serializeJsonPretty(data_json, Serial); |
|
|
|
|
Serial.println(); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
AudioNoInterrupts(); |
|
|
|
|
sysex = SD.open(filename, FILE_WRITE); |
|
|
|
|
if (sysex) |
|
|
|
|
{ |
|
|
|
|
if (write_sd_data(sysex, 0x44, (uint8_t*)&configuration.performance, sizeof(configuration.performance))) |
|
|
|
|
{ |
|
|
|
|
sysex.close(); |
|
|
|
|
AudioInterrupts(); |
|
|
|
|
return (true); |
|
|
|
|
} |
|
|
|
|
sysex.close(); |
|
|
|
|
serializeJsonPretty(data_json, json); |
|
|
|
|
json.close(); |
|
|
|
|
AudioInterrupts(); |
|
|
|
|
return (true); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
json.close(); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.print(F("E : Cannot open ")); |
|
|
|
|
Serial.print(filename); |
|
|
|
|
Serial.println(F(" on SD.")); |
|
|
|
|
Serial.print(F("E : Cannot open ")); |
|
|
|
|
Serial.print(filename); |
|
|
|
|
Serial.println(F(" on SD.")); |
|
|
|
|
#endif |
|
|
|
|
return (false); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
AudioInterrupts(); |
|
|
|
|
return (false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
|
SD PERFORMANCE |
|
|
|
|
******************************************************************************/ |
|
|
|
|
bool load_sd_performance_json(int8_t p) |
|
|
|
|
{ |
|
|
|
|
if (p < 0) |
|
|
|
@ -742,14 +768,15 @@ bool load_sd_performance_json(int8_t p) |
|
|
|
|
json = SD.open(filename); |
|
|
|
|
if (json) |
|
|
|
|
{ |
|
|
|
|
StaticJsonDocument<256> data_json; |
|
|
|
|
|
|
|
|
|
StaticJsonDocument<JSON_BUFFER> data_json; |
|
|
|
|
deserializeJson(data_json, json); |
|
|
|
|
|
|
|
|
|
json.close(); |
|
|
|
|
AudioInterrupts(); |
|
|
|
|
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.println(F("Read JSON data:")); |
|
|
|
|
serializeJsonPretty(data_json, Serial); |
|
|
|
|
Serial.println(); |
|
|
|
|
Serial.println(F("Read JSON data:")); |
|
|
|
|
serializeJsonPretty(data_json, Serial); |
|
|
|
|
Serial.println(); |
|
|
|
|
#endif |
|
|
|
|
for (uint8_t i = 0; i < MAX_DEXED; i++) |
|
|
|
|
{ |
|
|
|
@ -759,17 +786,15 @@ bool load_sd_performance_json(int8_t p) |
|
|
|
|
} |
|
|
|
|
configuration.performance.fx_number = data_json["fx_number"]; |
|
|
|
|
|
|
|
|
|
json.close(); |
|
|
|
|
AudioInterrupts(); |
|
|
|
|
|
|
|
|
|
for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) |
|
|
|
|
{ |
|
|
|
|
load_sd_voiceconfig(configuration.performance.voiceconfig_number[instance_id], instance_id); |
|
|
|
|
|
|
|
|
|
load_sd_voice(configuration.performance.bank[instance_id], configuration.performance.voice[instance_id], instance_id); |
|
|
|
|
load_sd_voiceconfig_json(configuration.performance.voiceconfig_number[instance_id], instance_id); |
|
|
|
|
MicroDexed[instance_id]->ControllersRefresh(); |
|
|
|
|
MicroDexed[instance_id]->panic(); |
|
|
|
|
} |
|
|
|
|
load_sd_fx(configuration.performance.fx_number); |
|
|
|
|
load_sd_fx_json(configuration.performance.fx_number); |
|
|
|
|
|
|
|
|
|
return (true); |
|
|
|
|
} |
|
|
|
@ -780,17 +805,17 @@ bool load_sd_performance_json(int8_t p) |
|
|
|
|
Serial.print(filename); |
|
|
|
|
Serial.println(F(" on SD.")); |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.print(F("No ")); |
|
|
|
|
Serial.print(filename); |
|
|
|
|
Serial.println(F(" available.")); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
AudioInterrupts(); |
|
|
|
|
return (false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -817,7 +842,7 @@ bool save_sd_performance_json(uint8_t p) |
|
|
|
|
json = SD.open(filename, FILE_WRITE); |
|
|
|
|
if (json) |
|
|
|
|
{ |
|
|
|
|
StaticJsonDocument<256> data_json; |
|
|
|
|
StaticJsonDocument<JSON_BUFFER> data_json; |
|
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < MAX_DEXED; i++) |
|
|
|
|
{ |
|
|
|
|