diff --git a/MicroDexed.ino b/MicroDexed.ino index f7cd558..4c851ad 100644 --- a/MicroDexed.ino +++ b/MicroDexed.ino @@ -374,6 +374,8 @@ void setup() { #ifdef DEBUG Serial.begin(SERIAL_SPEED); +#else + delay(50); // seems to be needed when no serial debugging is enabled #endif #ifdef DISPLAY_LCD_SPI @@ -1676,11 +1678,29 @@ void handleClock(void) midi_bpm_counter++; } +void dac_mute(void) +{ + sgtl5000.lineOutLevel(0.0); + sgtl5000.dacVolume(0.0); + sgtl5000.volume(0.0, 0.0); // Headphone volume +} + +void dac_unmute(void) +{ + sgtl5000.lineOutLevel(SGTL5000_LINEOUT_LEVEL); + sgtl5000.dacVolume(1.0); + sgtl5000.volume(SGTL5000_HEADPHONE_VOLUME, SGTL5000_HEADPHONE_VOLUME); // Headphone volume +} void handleStart(void) { midi_bpm_timer = 0; midi_bpm_counter = 0; _midi_bpm = -1; + seq_step = 0; + seq_chain_active_step = 0; + seq_running = true; + timer1.start(); + } void handleContinue(void) @@ -1690,7 +1710,17 @@ void handleContinue(void) void handleStop(void) { - ; + timer1.stop(); + seq_running = false; + seq_recording = false; + seq_note_in = 0; + seq_step = 0; + seq_chain_active_step = 0; + + MicroDexed[0]->panic(); +#if NUM_DEXED > 1 + MicroDexed[1]->panic(); +#endif } void handleActiveSensing(void) diff --git a/UI.hpp b/UI.hpp index 1cf95cd..ecd2b41 100644 --- a/UI.hpp +++ b/UI.hpp @@ -5211,8 +5211,7 @@ void UI_func_seq_pattern_editor(uint8_t param) { if (seq_running == false && seq_recording == false) { - seq_running = true; - timer1.start(); + handleStart(); } else if (seq_running == true && seq_recording == false) { seq_running = true; @@ -5220,13 +5219,7 @@ void UI_func_seq_pattern_editor(uint8_t param) seq_note_in = 0; } else if (seq_running == true && seq_recording == true) { - seq_running = false; - seq_recording = false; - seq_note_in = 0; - seq_step = 0; - seq_chain_active_step = 0; - timer1.stop(); - MicroDexed[0]->panic(); + handleStop(); } } else if ( seq_menu == 2 && seq_active_function != 40) { @@ -5710,11 +5703,7 @@ void UI_func_arpeggio(uint8_t param) if (seq_running) { seq_running = !seq_running; - timer1.stop(); - MicroDexed[0]->panic(); -#if NUM_DEXED > 1 - MicroDexed[1]->panic(); -#endif + handleStop(); arp_refresh_display_play_status(); seq_step = 0; arp_octave = 0; @@ -5724,7 +5713,7 @@ void UI_func_arpeggio(uint8_t param) { seq_running = !seq_running; arp_refresh_display_play_status(); - timer1.start(); + handleStart(); } } else if ( seq_temp_select_menu == 3 && seq_temp_active_menu == 0 ) diff --git a/config.h b/config.h index 61a5851..b4a2095 100644 --- a/config.h +++ b/config.h @@ -119,15 +119,15 @@ #define DRUM_MIDI_CHANNEL 10 // NUMBER OF SAMPLES IN DRUMSET -#if defined(ARDUINO_TEENSY41) +#if defined(ARDUINO_TEENSY41) #define NUM_DRUMSET_CONFIG 71 #elif defined(TEENSY4) -#define NUM_DRUMSET_CONFIG 47 +#define NUM_DRUMSET_CONFIG 47 #else -#define NUM_DRUMSET_CONFIG 22 +#define NUM_DRUMSET_CONFIG 22 #endif -// SEQUENCER +// SEQUENCER #ifdef TEENSY4 #define NUM_SEQ_PATTERN 24 @@ -666,7 +666,7 @@ // Buffer-size define for load/save configuration as JSON -#define JSON_BUFFER_SIZE 7168 +#define JSON_BUFFER_SIZE 8192 // Internal configuration structure typedef struct dexed_s { diff --git a/dexed_sd.cpp b/dexed_sd.cpp index 32bd4ae..8161d22 100644 --- a/dexed_sd.cpp +++ b/dexed_sd.cpp @@ -54,7 +54,7 @@ extern uint8_t seq_chord_key_ammount; extern uint8_t seq_element_shift; extern int seq_oct_shift; extern int seq_transpose; -extern int seq_tempo_ms ; +extern int seq_tempo_ms; extern int seq_bpm; extern bool arp_play_basenote; extern bool seq_running; @@ -64,6 +64,8 @@ extern uint8_t arp_style; extern uint8_t seq_chord_velocity; extern uint8_t seq_chord_dexed_inst; extern uint8_t seq_inst_dexed[NUM_SEQ_TRACKS]; +extern uint8_t seq_step; +extern uint8_t seq_chain_active_step; extern char seq_name[FILENAME_LEN]; extern char seq_name_temp[FILENAME_LEN]; extern PeriodicTimer timer1; @@ -75,6 +77,10 @@ extern void set_sample_pan(uint8_t sample, float s_pan); extern void set_sample_vol_max(uint8_t sample, float s_max); extern void set_sample_vol_min(uint8_t sample, float s_min); extern void set_sample_reverb_send(uint8_t sample, float s_reverb); +extern void handleStop(void); +extern void handleStart(void); +extern void dac_mute(void); +extern void dac_unmute(void); extern uint8_t get_sample_note(uint8_t sample); extern float get_sample_pitch(uint8_t sample); extern float get_sample_p_offset(uint8_t sample); @@ -492,7 +498,7 @@ bool load_sd_drumsettings_json(uint8_t number, uint8_t target) uint8_t drumnumber = 0; drumnumber = find_drum_number_from_note( data_json["note"][i] ); if ( ( (int)data_json["note"][i] > 0 && find_drum_number_from_note( data_json["note"][i] ) > 0 ) || - ( i == 0 && (int)data_json["note"][i] == 210) ) + ( i == 0 && (int)data_json["note"][i] == 210) ) { set_sample_pitch( drumnumber, data_json["pitch"][i] ); set_sample_p_offset ( drumnumber, data_json["p_offset"][i] ); @@ -1072,7 +1078,14 @@ bool save_sd_seq_json(uint8_t seq_number) { char filename[FILENAME_LEN]; int count = 0; + bool seq_was_running = false; seq_number = constrain(seq_number, 0, 99); + if (seq_running == true ) { + seq_was_running = true; + handleStop(); + } + dac_mute(); + AudioNoInterrupts(); 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); @@ -1106,7 +1119,6 @@ bool save_sd_seq_json(uint8_t seq_number) int columns = sizeof(seq_patternchain[0]); int rows = total / columns; Serial.print(F(" ")); - AudioNoInterrupts(); SD.begin(); SD.remove(filename); json = SD.open(filename, FILE_WRITE); @@ -1164,6 +1176,9 @@ bool save_sd_seq_json(uint8_t seq_number) serializeJsonPretty(data_json, json); json.close(); AudioInterrupts(); + dac_unmute(); + if (seq_was_running == true ) + handleStart(); return (true); } json.close(); @@ -1219,9 +1234,7 @@ bool load_sd_seq_sub_vel_json(uint8_t seq_number) { if (seq_number < 0) return (false); - seq_number = constrain(seq_number, 0, 99); - if (sd_card > 0) { File json; @@ -1289,9 +1302,7 @@ 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) { File json; @@ -1359,14 +1370,20 @@ bool load_sd_seq_sub_patterns_json(uint8_t seq_number) bool load_sd_seq_json(uint8_t seq_number) { + bool seq_was_running = false; if (seq_number < 0) return (false); - + if (seq_running) + { + seq_was_running = true; + seq_running = false; + } + dac_mute(); + handleStop(); + AudioNoInterrupts(); 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) @@ -1374,11 +1391,8 @@ bool load_sd_seq_json(uint8_t seq_number) File json; StaticJsonDocument 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 @@ -1392,10 +1406,8 @@ bool load_sd_seq_json(uint8_t seq_number) if (json) { deserializeJson(data_json, json); - json.close(); AudioInterrupts(); - #ifdef DEBUG Serial.println(F("Read JSON data:")); serializeJsonPretty(data_json, Serial); @@ -1465,8 +1477,14 @@ bool load_sd_seq_json(uint8_t seq_number) for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) set_voiceconfig_params(instance_id); set_fx_params(); - if (seq_running) + dac_unmute(); + seq_step = 0; + seq_chain_active_step = 0; + if (seq_was_running) + { timer1.begin(sequencer, seq_tempo_ms / 2); + seq_running = true; + } else timer1.begin(sequencer, seq_tempo_ms / 2, false); return (true);