|
|
|
@ -45,11 +45,11 @@ extern void sequencer(); |
|
|
|
|
extern float drums_volume; |
|
|
|
|
//extern StaticJsonDocument<JSON_BUFFER> data_json;
|
|
|
|
|
extern uint8_t seq_chain_lenght; |
|
|
|
|
extern uint8_t seq_data[10][16]; |
|
|
|
|
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 uint8_t seq_data[NUM_SEQ_PATTERN][16]; |
|
|
|
|
extern uint8_t seq_vel[NUM_SEQ_PATTERN][16]; |
|
|
|
|
extern uint8_t seq_patternchain[NUM_SEQ_TRACKS][4]; |
|
|
|
|
extern uint8_t seq_content_type[NUM_SEQ_PATTERN]; |
|
|
|
|
extern uint8_t seq_track_type[NUM_SEQ_TRACKS]; |
|
|
|
|
extern uint8_t seq_chord_key_ammount; |
|
|
|
|
extern uint8_t seq_element_shift; |
|
|
|
|
extern int seq_oct_shift; |
|
|
|
@ -63,7 +63,7 @@ extern uint8_t arp_lenght; |
|
|
|
|
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 uint8_t seq_inst_dexed[NUM_SEQ_TRACKS]; |
|
|
|
|
extern char seq_name[FILENAME_LEN]; |
|
|
|
|
extern char seq_name_temp[FILENAME_LEN]; |
|
|
|
|
extern PeriodicTimer timer1; |
|
|
|
@ -945,24 +945,132 @@ bool save_sd_fx_json(uint8_t fx, uint8_t target) |
|
|
|
|
return (false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool save_sd_seq_sub_vel_json(uint8_t seq_number) |
|
|
|
|
{ |
|
|
|
|
char filename[FILENAME_LEN]; |
|
|
|
|
int count = 0; |
|
|
|
|
seq_number = constrain(seq_number, 0, 99); |
|
|
|
|
if (sd_card > 0) |
|
|
|
|
{ |
|
|
|
|
File json; |
|
|
|
|
StaticJsonDocument<JSON_BUFFER_SIZE> data_json; |
|
|
|
|
sprintf(filename, "/%s/%d-vel.json", SEQ_CONFIG_PATH, seq_number); |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.print(F("Saving sequencer velocity ")); |
|
|
|
|
Serial.print(seq_number); |
|
|
|
|
Serial.print(F(" to ")); |
|
|
|
|
Serial.println(filename); |
|
|
|
|
#endif |
|
|
|
|
int total = sizeof(seq_vel); |
|
|
|
|
int columns = sizeof(seq_vel[0]); |
|
|
|
|
int rows = total / columns; |
|
|
|
|
AudioNoInterrupts(); |
|
|
|
|
SD.begin(); |
|
|
|
|
SD.remove(filename); |
|
|
|
|
json = SD.open(filename, FILE_WRITE); |
|
|
|
|
if (json) |
|
|
|
|
{ |
|
|
|
|
for (uint8_t i = 0; i < rows; i++) |
|
|
|
|
{ |
|
|
|
|
for (uint8_t j = 0; j < columns; j++) { |
|
|
|
|
data_json["seq_velocity"][count] = seq_vel[i][j]; |
|
|
|
|
count++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
#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 |
|
|
|
|
} |
|
|
|
|
return (false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool save_sd_seq_sub_patterns_json(uint8_t seq_number) |
|
|
|
|
{ |
|
|
|
|
char filename[FILENAME_LEN]; |
|
|
|
|
int count = 0; |
|
|
|
|
seq_number = constrain(seq_number, 0, 99); |
|
|
|
|
if (sd_card > 0) |
|
|
|
|
{ |
|
|
|
|
File json; |
|
|
|
|
StaticJsonDocument<JSON_BUFFER_SIZE> data_json; |
|
|
|
|
sprintf(filename, "/%s/%d-pat.json", SEQ_CONFIG_PATH, seq_number); |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.print(F("Saving sequencer patterns ")); |
|
|
|
|
Serial.print(seq_number); |
|
|
|
|
Serial.print(F(" to ")); |
|
|
|
|
Serial.println(filename); |
|
|
|
|
#endif |
|
|
|
|
int total = sizeof(seq_data); |
|
|
|
|
int columns = sizeof(seq_data[0]); |
|
|
|
|
int rows = total / columns; |
|
|
|
|
AudioNoInterrupts(); |
|
|
|
|
SD.begin(); |
|
|
|
|
SD.remove(filename); |
|
|
|
|
json = SD.open(filename, FILE_WRITE); |
|
|
|
|
if (json) |
|
|
|
|
{ |
|
|
|
|
for (uint8_t i = 0; i < rows; i++) |
|
|
|
|
{ |
|
|
|
|
for (uint8_t j = 0; j < columns; j++) { |
|
|
|
|
data_json["seq_data"][count] = seq_data[i][j]; |
|
|
|
|
count++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
#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 |
|
|
|
|
} |
|
|
|
|
return (false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool save_sd_seq_json(uint8_t seq_number) |
|
|
|
|
{ |
|
|
|
|
char filename[FILENAME_LEN]; |
|
|
|
|
int count = 0; |
|
|
|
|
seq_number = constrain(seq_number, 0, 99); |
|
|
|
|
save_sd_seq_sub_vel_json(seq_number); |
|
|
|
|
save_sd_seq_sub_patterns_json(seq_number); |
|
|
|
|
sprintf(filename, "/%s/%d-fx.json", SEQ_CONFIG_PATH, seq_number); |
|
|
|
|
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.print(F("write SEQ-FX-Config ")); |
|
|
|
|
Serial.print(seq_number); |
|
|
|
|
Serial.print(F(" ")); |
|
|
|
|
#endif |
|
|
|
|
save_sd_fx_json(seq_number, 1); |
|
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < MAX_DEXED; i++) |
|
|
|
|
{ sprintf(filename, "/%s/%d-v%d.json", SEQ_CONFIG_PATH, seq_number, i); |
|
|
|
|
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.print(F("Write Voice-Config for sequencer")); |
|
|
|
|
Serial.print(filename); |
|
|
|
@ -989,32 +1097,15 @@ bool save_sd_seq_json(uint8_t seq_number) |
|
|
|
|
Serial.print(" Columns: "); |
|
|
|
|
Serial.print(columns); |
|
|
|
|
Serial.print(F(" ")); |
|
|
|
|
|
|
|
|
|
AudioNoInterrupts(); |
|
|
|
|
SD.begin(); |
|
|
|
|
SD.remove(filename); |
|
|
|
|
json = SD.open(filename, FILE_WRITE); |
|
|
|
|
if (json) |
|
|
|
|
{ |
|
|
|
|
for (uint8_t i = 0; i < rows; i++) |
|
|
|
|
{ |
|
|
|
|
for (uint8_t j = 0; j < columns; j++) { |
|
|
|
|
data_json["seq_data"][count] = seq_data[i][j]; |
|
|
|
|
count++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
count = 0; |
|
|
|
|
for (uint8_t i = 0; i < rows; i++) |
|
|
|
|
{ |
|
|
|
|
for (uint8_t j = 0; j < columns; j++) { |
|
|
|
|
data_json["seq_velocity"][count] = seq_vel[i][j]; |
|
|
|
|
count++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
total = sizeof(seq_patternchain); |
|
|
|
|
columns = sizeof(seq_patternchain[0]); |
|
|
|
|
rows = total / columns; |
|
|
|
|
|
|
|
|
|
Serial.print(F("Chain Rows: ")); |
|
|
|
|
Serial.print(rows); |
|
|
|
|
Serial.print(" Chain Columns: "); |
|
|
|
@ -1042,13 +1133,11 @@ bool save_sd_seq_json(uint8_t seq_number) |
|
|
|
|
data_json["chord_key_ammount"] = seq_chord_key_ammount; |
|
|
|
|
data_json["seq_oct_shift"] = seq_oct_shift; |
|
|
|
|
data_json["seq_element_shift"] = seq_element_shift; |
|
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < MAX_DEXED; i++) |
|
|
|
|
{ |
|
|
|
|
data_json["bank"][i] = configuration.performance.bank[i]; |
|
|
|
|
data_json["voice"][i] = configuration.performance.voice[i]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (uint8_t i = 0; i < sizeof(seq_track_type); i++) { |
|
|
|
|
data_json["track_type"][i] = seq_track_type[i]; |
|
|
|
|
} |
|
|
|
@ -1061,8 +1150,6 @@ bool save_sd_seq_json(uint8_t seq_number) |
|
|
|
|
for (uint8_t i = 0; i < FILENAME_LEN; i++) { |
|
|
|
|
data_json["seq_name"][i] = seq_name[i]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.println(F("Write JSON data:")); |
|
|
|
|
serializeJsonPretty(data_json, Serial); |
|
|
|
@ -1074,7 +1161,6 @@ bool save_sd_seq_json(uint8_t seq_number) |
|
|
|
|
return (true); |
|
|
|
|
} |
|
|
|
|
json.close(); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
@ -1123,14 +1209,82 @@ void get_sd_seq_name_json(uint8_t seq_number) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool load_sd_seq_json(uint8_t seq_number) |
|
|
|
|
bool load_sd_seq_sub_vel_json(uint8_t seq_number) |
|
|
|
|
{ |
|
|
|
|
if (seq_number < 0) |
|
|
|
|
return (false); |
|
|
|
|
|
|
|
|
|
seq_number = constrain(seq_number, 0, 99); |
|
|
|
|
|
|
|
|
|
load_sd_fx_json(seq_number, 1); |
|
|
|
|
if (sd_card > 0) |
|
|
|
|
{ |
|
|
|
|
File json; |
|
|
|
|
StaticJsonDocument<JSON_BUFFER_SIZE> data_json; |
|
|
|
|
char filename[FILENAME_LEN]; |
|
|
|
|
|
|
|
|
|
sprintf(filename, "/%s/%d-vel.json", SEQ_CONFIG_PATH, seq_number); |
|
|
|
|
|
|
|
|
|
// first check if file exists...
|
|
|
|
|
AudioNoInterrupts(); |
|
|
|
|
if (SD.exists(filename)) |
|
|
|
|
{ |
|
|
|
|
// ... and if: load
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.print(F("Found velocity data [")); |
|
|
|
|
Serial.print(filename); |
|
|
|
|
Serial.println(F("]... loading...")); |
|
|
|
|
Serial.println(F(" ")); |
|
|
|
|
#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 |
|
|
|
|
int total = sizeof(seq_vel); |
|
|
|
|
int columns = sizeof(seq_vel[0]); |
|
|
|
|
int rows = total / columns; |
|
|
|
|
int count = 0; |
|
|
|
|
for (uint8_t i = 0; i < rows; i++) |
|
|
|
|
{ |
|
|
|
|
for (uint8_t j = 0; j < columns; j++) { |
|
|
|
|
seq_vel[i][j] = data_json["seq_velocity"][count]; |
|
|
|
|
count++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
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 |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return (false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool load_sd_seq_sub_patterns_json(uint8_t seq_number) |
|
|
|
|
{ |
|
|
|
|
if (seq_number < 0) |
|
|
|
|
return (false); |
|
|
|
|
|
|
|
|
|
seq_number = constrain(seq_number, 0, 99); |
|
|
|
|
|
|
|
|
|
if (sd_card > 0) |
|
|
|
|
{ |
|
|
|
@ -1138,7 +1292,7 @@ bool load_sd_seq_json(uint8_t seq_number) |
|
|
|
|
StaticJsonDocument<JSON_BUFFER_SIZE> data_json; |
|
|
|
|
char filename[FILENAME_LEN]; |
|
|
|
|
|
|
|
|
|
sprintf(filename, "/%s/%d-S.json", SEQ_CONFIG_PATH, seq_number); |
|
|
|
|
sprintf(filename, "/%s/%d-pat.json", SEQ_CONFIG_PATH, seq_number); |
|
|
|
|
|
|
|
|
|
// first check if file exists...
|
|
|
|
|
AudioNoInterrupts(); |
|
|
|
@ -1146,7 +1300,7 @@ bool load_sd_seq_json(uint8_t seq_number) |
|
|
|
|
{ |
|
|
|
|
// ... and if: load
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.print(F("Found Sequencer configuration [")); |
|
|
|
|
Serial.print(F("Found pattern data [")); |
|
|
|
|
Serial.print(filename); |
|
|
|
|
Serial.println(F("]... loading...")); |
|
|
|
|
Serial.println(F(" ")); |
|
|
|
@ -1176,18 +1330,75 @@ bool load_sd_seq_json(uint8_t seq_number) |
|
|
|
|
count++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
count = 0; |
|
|
|
|
for (uint8_t i = 0; i < rows; i++) |
|
|
|
|
return (true); |
|
|
|
|
} |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
for (uint8_t j = 0; j < columns; j++) { |
|
|
|
|
seq_vel[i][j] = data_json["seq_velocity"][count]; |
|
|
|
|
count++; |
|
|
|
|
Serial.print(F("E : Cannot open ")); |
|
|
|
|
Serial.print(filename); |
|
|
|
|
Serial.println(F(" on SD.")); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
total = sizeof(seq_patternchain); |
|
|
|
|
columns = sizeof(seq_patternchain[0]); |
|
|
|
|
rows = total / columns; |
|
|
|
|
count = 0; |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
Serial.print(F("No ")); |
|
|
|
|
Serial.print(filename); |
|
|
|
|
Serial.println(F(" available.")); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return (false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bool load_sd_seq_json(uint8_t seq_number) |
|
|
|
|
{ |
|
|
|
|
if (seq_number < 0) |
|
|
|
|
return (false); |
|
|
|
|
|
|
|
|
|
seq_number = constrain(seq_number, 0, 99); |
|
|
|
|
|
|
|
|
|
load_sd_seq_sub_patterns_json(seq_number); |
|
|
|
|
load_sd_seq_sub_vel_json(seq_number); |
|
|
|
|
|
|
|
|
|
load_sd_fx_json(seq_number, 1); |
|
|
|
|
|
|
|
|
|
if (sd_card > 0) |
|
|
|
|
{ |
|
|
|
|
File json; |
|
|
|
|
StaticJsonDocument<JSON_BUFFER_SIZE> data_json; |
|
|
|
|
char filename[FILENAME_LEN]; |
|
|
|
|
|
|
|
|
|
sprintf(filename, "/%s/%d-S.json", SEQ_CONFIG_PATH, seq_number); |
|
|
|
|
|
|
|
|
|
// first check if file exists...
|
|
|
|
|
AudioNoInterrupts(); |
|
|
|
|
if (SD.exists(filename)) |
|
|
|
|
{ |
|
|
|
|
// ... and if: load
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.print(F("Found Sequencer configuration [")); |
|
|
|
|
Serial.print(filename); |
|
|
|
|
Serial.println(F("]... loading...")); |
|
|
|
|
Serial.println(F(" ")); |
|
|
|
|
#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 |
|
|
|
|
int total = sizeof(seq_patternchain); |
|
|
|
|
int columns = sizeof(seq_patternchain[0]); |
|
|
|
|
int rows = total / columns; |
|
|
|
|
int count = 0; |
|
|
|
|
for (uint8_t i = 0; i < rows; i++) |
|
|
|
|
{ |
|
|
|
|
for (uint8_t j = 0; j < columns; j++) { |
|
|
|
@ -1210,7 +1421,6 @@ bool load_sd_seq_json(uint8_t seq_number) |
|
|
|
|
seq_name[i] = data_json["seq_name"][i]; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
count = 0; |
|
|
|
|
seq_tempo_ms = data_json["seq_tempo_ms"] ; |
|
|
|
|
seq_bpm = data_json["seq_bpm"]; |
|
|
|
@ -1225,17 +1435,12 @@ bool load_sd_seq_json(uint8_t seq_number) |
|
|
|
|
seq_chord_key_ammount = data_json["chord_key_ammount"]; |
|
|
|
|
seq_oct_shift = data_json["seq_oct_shift"]; |
|
|
|
|
seq_element_shift = data_json["seq_element_shift"]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) |
|
|
|
|
{ |
|
|
|
|
configuration.performance.bank[instance_id] = data_json["bank"][instance_id]; |
|
|
|
|
configuration.performance.voice[instance_id] = data_json["voice"][instance_id]; |
|
|
|
|
load_sd_voice(configuration.performance.bank[instance_id], configuration.performance.voice[instance_id], instance_id); |
|
|
|
|
load_sd_voiceconfig_json(seq_number, instance_id, 1); |
|
|
|
|
//check_configuration_dexed(instance_id);
|
|
|
|
|
//set_voiceconfig_params(instance_id);
|
|
|
|
|
//MicroDexed[instance_id]->ControllersRefresh();
|
|
|
|
|
MicroDexed[instance_id]->setGain(midi_volume_transform(map(configuration.dexed[instance_id].sound_intensity, SOUND_INTENSITY_MIN, SOUND_INTENSITY_MAX, 0, 127))); |
|
|
|
|
MicroDexed[instance_id]->panic(); |
|
|
|
|
#ifdef DEBUG |
|
|
|
@ -1245,16 +1450,13 @@ bool load_sd_seq_json(uint8_t seq_number) |
|
|
|
|
Serial.print(F(" ")); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) |
|
|
|
|
set_voiceconfig_params(instance_id); |
|
|
|
|
set_fx_params(); |
|
|
|
|
|
|
|
|
|
if (seq_running) |
|
|
|
|
timer1.begin(sequencer, seq_tempo_ms / 2); |
|
|
|
|
else |
|
|
|
|
timer1.begin(sequencer, seq_tempo_ms / 2, false); |
|
|
|
|
|
|
|
|
|
return (true); |
|
|
|
|
} |
|
|
|
|
#ifdef DEBUG |
|
|
|
|