|
|
|
@ -30,11 +30,14 @@ |
|
|
|
|
#include <ArduinoJson.h> |
|
|
|
|
#include "synth_dexed.h" |
|
|
|
|
#include "dexed_sd.h" |
|
|
|
|
#include "TeensyTimerTool.h" |
|
|
|
|
using namespace TeensyTimerTool; |
|
|
|
|
|
|
|
|
|
extern void init_MIDI_send_CC(void); |
|
|
|
|
extern void check_configuration_dexed(uint8_t instance_id); |
|
|
|
|
extern void check_configuration_performance(void); |
|
|
|
|
extern void check_configuration_fx(void); |
|
|
|
|
extern void sequencer(); |
|
|
|
|
extern StaticJsonDocument<JSON_BUFFER> data_json; |
|
|
|
|
extern uint8_t seq_chain_lenght; |
|
|
|
|
extern uint8_t seq_data[10][16]; |
|
|
|
@ -42,9 +45,18 @@ extern uint8_t seq_vel[10][16]; |
|
|
|
|
extern uint8_t seq_patternchain[4][4]; |
|
|
|
|
extern uint8_t seq_content_type[10]; |
|
|
|
|
extern uint8_t seq_track_type[4]; |
|
|
|
|
extern int perform_attack_mod[NUM_DEXED]; |
|
|
|
|
extern int perform_release_mod[NUM_DEXED]; |
|
|
|
|
extern int seq_transpose; |
|
|
|
|
extern int seq_tempo_ms ; |
|
|
|
|
extern int seq_bpm; |
|
|
|
|
extern bool arp_play_basenote; |
|
|
|
|
extern uint8_t arp_speed; |
|
|
|
|
extern uint8_t arp_oct_usersetting; |
|
|
|
|
extern uint8_t arp_style; |
|
|
|
|
extern uint8_t seq_chord_velocity; |
|
|
|
|
extern uint8_t seq_chord_dexed_inst; |
|
|
|
|
extern uint8_t seq_inst_dexed[4]; |
|
|
|
|
extern PeriodicTimer timer1; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
|
SD BANK/VOICE LOADING |
|
|
|
@ -747,6 +759,131 @@ bool save_sd_fx_json(uint8_t fx) |
|
|
|
|
return (false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool load_sd_seq_drumsettings(uint8_t number) |
|
|
|
|
{ |
|
|
|
|
if (number < 0) |
|
|
|
|
return (false); |
|
|
|
|
|
|
|
|
|
number = constrain(number, 0, 99); |
|
|
|
|
|
|
|
|
|
if (sd_card > 0) |
|
|
|
|
{ |
|
|
|
|
File json; |
|
|
|
|
char filename[FILENAME_LEN]; |
|
|
|
|
|
|
|
|
|
sprintf(filename, "/%s/%s%d-drums.json", SEQ_CONFIG_PATH, SEQ_CONFIG_NAME, number); |
|
|
|
|
|
|
|
|
|
// first check if file exists...
|
|
|
|
|
AudioNoInterrupts(); |
|
|
|
|
if (SD.exists(filename)) |
|
|
|
|
{ |
|
|
|
|
// ... and if: load
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.print(F("Found drums configuration [")); |
|
|
|
|
Serial.print(filename); |
|
|
|
|
Serial.println(F("]... loading...")); |
|
|
|
|
#endif |
|
|
|
|
json = SD.open(filename); |
|
|
|
|
if (json) |
|
|
|
|
{ |
|
|
|
|
deserializeJson(data_json, json); |
|
|
|
|
json.close(); |
|
|
|
|
AudioInterrupts(); |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.println(F("Read JSON data:")); |
|
|
|
|
serializeJsonPretty(data_json, Serial); |
|
|
|
|
Serial.println(); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
// drums_volume = data_json["drums_volume"];
|
|
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < 20; i++) // needs to replaced by NUM_DRUMSET_CONFIG but does not work
|
|
|
|
|
{ |
|
|
|
|
drum_config[i].pan = data_json["pan"][i] ; |
|
|
|
|
drum_config[i].vol_max = data_json["vol_max"][i] ; |
|
|
|
|
drum_config[i].vol_min = data_json["vol_min"][i] ; |
|
|
|
|
drum_config[i].reverb_send = data_json["reverb_send"][i]; |
|
|
|
|
} |
|
|
|
|
set_fx_params(); |
|
|
|
|
|
|
|
|
|
return (true); |
|
|
|
|
} |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
Serial.print(F("E : Cannot open ")); |
|
|
|
|
Serial.print(filename); |
|
|
|
|
Serial.println(F(" on SD.")); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
Serial.print(F("No ")); |
|
|
|
|
Serial.print(filename); |
|
|
|
|
Serial.println(F(" available.")); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
AudioInterrupts(); |
|
|
|
|
return (false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool save_sd_seq_drumsettings(uint8_t number) |
|
|
|
|
{ |
|
|
|
|
char filename[FILENAME_LEN]; |
|
|
|
|
number = constrain(number, 0, 99); |
|
|
|
|
|
|
|
|
|
if (sd_card > 0) |
|
|
|
|
{ |
|
|
|
|
File json; |
|
|
|
|
|
|
|
|
|
sprintf(filename, "/%s/%s%d-drums.json", SEQ_CONFIG_PATH, SEQ_CONFIG_NAME, number); |
|
|
|
|
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.print(F("Saving drums config ")); |
|
|
|
|
Serial.print(number); |
|
|
|
|
Serial.print(F(" to ")); |
|
|
|
|
Serial.println(filename); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
AudioNoInterrupts(); |
|
|
|
|
json = SD.open(filename, FILE_WRITE); |
|
|
|
|
if (json) |
|
|
|
|
{ |
|
|
|
|
// data_json["drums_volume"] = drums_volume;
|
|
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < 20; i++) // needs to be replaced by NUM_DRUMSET_CONFIG
|
|
|
|
|
{ |
|
|
|
|
data_json["pan"][i] = drum_config[i].pan; |
|
|
|
|
data_json["vol_max"][i] = drum_config[i].vol_max; |
|
|
|
|
data_json["vol_min"][i] = drum_config[i].vol_min; |
|
|
|
|
data_json["reverb_send"][i] = drum_config[i].reverb_send; |
|
|
|
|
} |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.println(F("Write JSON data:")); |
|
|
|
|
serializeJsonPretty(data_json, Serial); |
|
|
|
|
Serial.println(); |
|
|
|
|
#endif |
|
|
|
|
serializeJsonPretty(data_json, json); |
|
|
|
|
json.close(); |
|
|
|
|
AudioInterrupts(); |
|
|
|
|
return (true); |
|
|
|
|
} |
|
|
|
|
json.close(); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.print(F("E : Cannot open ")); |
|
|
|
|
Serial.print(filename); |
|
|
|
|
Serial.println(F(" on SD.")); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
AudioInterrupts(); |
|
|
|
|
return (false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool save_sd_seq_json(uint8_t seq_number) |
|
|
|
|
{ |
|
|
|
|
char filename[FILENAME_LEN]; |
|
|
|
@ -778,18 +915,6 @@ bool save_sd_seq_json(uint8_t seq_number) |
|
|
|
|
json = SD.open(filename, FILE_WRITE); |
|
|
|
|
if (json) |
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
data_json["seq_chain_lenght"] = seq_chain_lenght; |
|
|
|
|
data_json["seq_transpose"] = seq_transpose; |
|
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < sizeof(seq_track_type); i++) { |
|
|
|
|
data_json["track_type"][i] = seq_track_type[i]; |
|
|
|
|
} |
|
|
|
|
for (uint8_t i = 0; i < sizeof(seq_content_type); i++) { |
|
|
|
|
data_json["content_type"][i] = seq_content_type[i]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < rows; i++) |
|
|
|
|
{ |
|
|
|
|
for (uint8_t j = 0; j < columns; j++) { |
|
|
|
@ -805,7 +930,6 @@ bool save_sd_seq_json(uint8_t seq_number) |
|
|
|
|
count++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
total = sizeof(seq_patternchain); |
|
|
|
|
columns = sizeof(seq_patternchain[0]); |
|
|
|
|
rows = total / columns; |
|
|
|
@ -826,19 +950,45 @@ bool save_sd_seq_json(uint8_t seq_number) |
|
|
|
|
} |
|
|
|
|
count = 0; |
|
|
|
|
|
|
|
|
|
data_json["seq_tempo_ms"] = seq_tempo_ms ; |
|
|
|
|
data_json["seq_bpm"] = seq_bpm; |
|
|
|
|
data_json["arp_play_basenote"] = arp_play_basenote; |
|
|
|
|
data_json["arp_speed"] = arp_speed; |
|
|
|
|
data_json["arp_oct_usersetting"] = arp_oct_usersetting; |
|
|
|
|
data_json["arp_style"] = arp_style; |
|
|
|
|
data_json["seq_chord_velocity"] = seq_chord_velocity; |
|
|
|
|
data_json["seq_chord_dexed_inst"] = seq_chord_dexed_inst; |
|
|
|
|
data_json["seq_chain_lenght"] = seq_chain_lenght; |
|
|
|
|
data_json["seq_transpose"] = seq_transpose; |
|
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < sizeof(seq_track_type); i++) { |
|
|
|
|
data_json["track_type"][i] = seq_track_type[i]; |
|
|
|
|
} |
|
|
|
|
for (uint8_t i = 0; i < sizeof(seq_content_type); i++) { |
|
|
|
|
data_json["content_type"][i] = seq_content_type[i]; |
|
|
|
|
} |
|
|
|
|
for (uint8_t i = 0; i < sizeof(seq_inst_dexed); i++) { |
|
|
|
|
data_json["seq_inst_dexed"][i] = seq_inst_dexed[i]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// following data maybe useful to be included in sequencer store and OPTIONAL to be loaded
|
|
|
|
|
for (uint8_t i = 0; i < MAX_DEXED; i++) |
|
|
|
|
{ |
|
|
|
|
data_json["reverb_send"][i] = configuration.fx.reverb_send[i]; |
|
|
|
|
data_json["bank"][i] = configuration.performance.bank[i]; |
|
|
|
|
data_json["voice"][i] = configuration.performance.voice[i]; |
|
|
|
|
data_json["rev_send"][i] = configuration.fx.reverb_send[i]; |
|
|
|
|
data_json["midi_ch"][i] = configuration.dexed[i].midi_channel; |
|
|
|
|
data_json["vol"][i] = configuration.dexed[i].sound_intensity; |
|
|
|
|
data_json["v_trans"][i] = configuration.dexed[i].transpose; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
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["rev_roomsize"] = configuration.fx.reverb_roomsize; |
|
|
|
|
data_json["rev_damping"] = configuration.fx.reverb_damping; |
|
|
|
|
data_json["rev_lowpass"] = configuration.fx.reverb_lowpass; |
|
|
|
|
data_json["rev_lodamp"] = configuration.fx.reverb_lodamp; |
|
|
|
|
data_json["rev_hidamp"] = configuration.fx.reverb_hidamp; |
|
|
|
|
data_json["rev_diffusion"] = configuration.fx.reverb_diffusion; |
|
|
|
|
data_json["rev_level"] = configuration.fx.reverb_level; |
|
|
|
|
data_json["eq_bass"] = configuration.fx.eq_bass; |
|
|
|
|
data_json["eq_treble"] = configuration.fx.eq_treble; |
|
|
|
|
|
|
|
|
@ -862,7 +1012,7 @@ bool save_sd_seq_json(uint8_t seq_number) |
|
|
|
|
Serial.println(F(" on SD.")); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//save_sd_seq_drumsettings(seq_number);
|
|
|
|
|
AudioInterrupts(); |
|
|
|
|
return (false); |
|
|
|
|
} |
|
|
|
@ -910,15 +1060,6 @@ bool load_sd_seq_json(uint8_t seq_number) |
|
|
|
|
int columns = sizeof(seq_data[0]); |
|
|
|
|
int rows = total / columns; |
|
|
|
|
int count = 0; |
|
|
|
|
seq_transpose = data_json["seq_transpose"]; |
|
|
|
|
seq_chain_lenght = data_json["seq_chain_lenght"]; |
|
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < sizeof(seq_track_type); i++) { |
|
|
|
|
seq_track_type[i] = data_json["track_type"][i]; |
|
|
|
|
} |
|
|
|
|
for (uint8_t i = 0; i < sizeof(seq_content_type); i++) { |
|
|
|
|
seq_content_type[i] = data_json["content_type"][i]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < rows; i++) |
|
|
|
|
{ |
|
|
|
@ -946,24 +1087,59 @@ bool load_sd_seq_json(uint8_t seq_number) |
|
|
|
|
count++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
count = 0; |
|
|
|
|
for (uint8_t i = 0; i < sizeof(seq_track_type); i++) { |
|
|
|
|
seq_track_type[i] = data_json["track_type"][i]; |
|
|
|
|
} |
|
|
|
|
for (uint8_t i = 0; i < sizeof(seq_content_type); i++) { |
|
|
|
|
seq_content_type[i] = data_json["content_type"][i]; |
|
|
|
|
} |
|
|
|
|
for (uint8_t i = 0; i < sizeof(seq_inst_dexed); i++) { |
|
|
|
|
seq_inst_dexed[i] = data_json["seq_inst_dexed"][i]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
count = 0; |
|
|
|
|
seq_tempo_ms = data_json["seq_tempo_ms"] ; |
|
|
|
|
seq_bpm = data_json["seq_bpm"]; |
|
|
|
|
arp_play_basenote = data_json["arp_play_basenote"]; |
|
|
|
|
arp_speed = data_json["arp_speed"] ; |
|
|
|
|
arp_oct_usersetting = data_json["arp_oct_usersetting"]; |
|
|
|
|
arp_style = data_json["arp_style"]; |
|
|
|
|
seq_chord_velocity = data_json["seq_chord_velocity"]; |
|
|
|
|
seq_chord_dexed_inst = data_json["seq_chord_dexed_inst"] ; |
|
|
|
|
seq_transpose = data_json["seq_transpose"]; |
|
|
|
|
seq_chain_lenght = data_json["seq_chain_lenght"]; |
|
|
|
|
// following data maybe useful to be included in sequencer store and OPTIONAL to be loaded back
|
|
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < MAX_DEXED; i++) |
|
|
|
|
{ |
|
|
|
|
configuration.fx.reverb_send[i] = data_json["reverb_send"][i]; |
|
|
|
|
configuration.performance.bank[i] = data_json["bank"][i]; |
|
|
|
|
configuration.performance.voice[i] = data_json["voice"][i]; |
|
|
|
|
configuration.fx.reverb_send[i] = data_json["rev_send"][i]; |
|
|
|
|
configuration.dexed[i].midi_channel = data_json["midi_ch"][i]; |
|
|
|
|
configuration.dexed[i].sound_intensity = data_json["vol"][i]; |
|
|
|
|
configuration.dexed[i].transpose = data_json["v_trans"][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.reverb_roomsize = data_json["rev_roomsize"]; |
|
|
|
|
configuration.fx.reverb_damping = data_json["rev_damping"]; |
|
|
|
|
configuration.fx.reverb_lowpass = data_json["rev_lowpass"]; |
|
|
|
|
configuration.fx.reverb_lodamp = data_json["rev_lodamp"]; |
|
|
|
|
configuration.fx.reverb_hidamp = data_json["rev_hidamp"]; |
|
|
|
|
configuration.fx.reverb_diffusion = data_json["rev_diffusion"]; |
|
|
|
|
configuration.fx.reverb_level = data_json["rev_level"]; |
|
|
|
|
configuration.fx.eq_bass = data_json["eq_bass"]; |
|
|
|
|
configuration.fx.eq_treble = data_json["eq_treble"]; |
|
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < NUM_DEXED; i++) |
|
|
|
|
{ |
|
|
|
|
load_sd_voice(configuration.performance.bank[i], configuration.performance.voice[i], i); |
|
|
|
|
MicroDexed[i]->doRefreshVoice(); |
|
|
|
|
MicroDexed[i]->panic(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
seq_tempo_ms = 60000000 / seq_bpm / 4; |
|
|
|
|
timer1.begin(sequencer, seq_tempo_ms / 2, false); |
|
|
|
|
|
|
|
|
|
set_fx_params(); |
|
|
|
|
|
|
|
|
|
return (true); |
|
|
|
@ -984,7 +1160,7 @@ bool load_sd_seq_json(uint8_t seq_number) |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//load_sd_seq_drumsettings(seq_number);
|
|
|
|
|
AudioInterrupts(); |
|
|
|
|
return (false); |
|
|
|
|
} |
|
|
|
|