Merge pull request 'Much improved Chord and Arp functions. Started with proper load/save functions for sequencer state' (#75) from positionhigh/MicroDexed:dev into dev

Reviewed-on: https://codeberg.org/dcoredump/MicroDexed/pulls/75
pull/76/head
Holger Wirtz 3 years ago
commit 4af597461e
  1. 2
      MicroDexed.ino
  2. 350
      UI.hpp
  3. 35
      UI_FX.h
  4. 36
      UI_FX_T4.h
  5. 52
      UI_NO_FX.h
  6. 2
      config.h
  7. 451
      dexed_sd.cpp
  8. 75
      sequencer.cpp
  9. 24
      sequencer.h

@ -609,6 +609,8 @@ void setup()
#if NUM_DRUMS > 0
master_mixer_r.gain(2, VOL_MAX_FLOAT);
master_mixer_l.gain(2, VOL_MAX_FLOAT);
drums_volume = VOL_MAX_FLOAT;
#else
master_mixer_r.gain(2, 0.0);
master_mixer_l.gain(2, 0.0);

350
UI.hpp

@ -53,6 +53,7 @@
extern PeriodicTimer timer1;
extern void sequencer(void);
extern bool check_sd_seq_exists(uint8_t);
extern config_t configuration;
extern void set_volume(uint8_t v, uint8_t m);
@ -78,6 +79,7 @@ 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_step;
extern uint8_t seq_chord_key_ammount;
extern int seq_tempo_ms;
extern uint8_t seq_bpm;
extern uint8_t seq_chain_lenght;
@ -92,15 +94,19 @@ extern uint8_t seq_temp_active_menu;
extern uint8_t seq_chain_active_chainstep; //for editor
extern uint8_t seq_chain_active_step;
extern int seq_transpose;
extern uint8_t seq_inst_dexed[4];
extern uint8_t arp_step;
extern uint8_t arp_note;
extern uint8_t arp_chord;
extern uint8_t arp_octave;
extern uint8_t arp_oct_usersetting;
extern uint8_t arp_lenght;
extern uint8_t arp_style;
extern uint8_t arp_speed;
extern uint8_t seq_element_shift;
extern int seq_oct_shift;
extern char arp_style_names[4][3];
extern char seq_chord_names[7][4];
extern float drums_volume;
#endif
#ifdef DISPLAY_LCD_SPI
@ -282,14 +288,17 @@ void UI_func_information(uint8_t param);
void UI_func_sequencer(uint8_t param);
void UI_func_seq_vel_editor(uint8_t param);
void UI_func_seq_live_transpose_oct(uint8_t param);
void UI_func_arp_shift(uint8_t param);
void UI_func_seq_chord_keys_ammount(uint8_t param);
void UI_func_seq_lenght(uint8_t param);
void UI_func_seq_tempo(uint8_t param);
void UI_func_seq_pat_chain(uint8_t param);
void UI_func_arpeggio(uint8_t param);
void UI_func_seq_track_setup(uint8_t param);
void UI_func_dexed_assign(uint8_t param);
void UI_func_seq_display_style(uint8_t param);
void UI_func_seq_pattern_load(uint8_t param);
void UI_func_seq_pattern_save(uint8_t param);
void UI_func_seq_state_load(uint8_t param);
void UI_func_seq_state_save(uint8_t param);
void UI_func_volume(uint8_t param);
void UI_func_load_performance(uint8_t param);
void UI_func_save_performance(uint8_t param);
@ -337,7 +346,7 @@ void locate_previous_favorite();
void locate_next_favorite();
void locate_next_non_favorite();
void locate_random_non_favorite();
void UI_func_drum_main_volume(uint8_t param);
void UI_func_drums_main_volume(uint8_t param);
void UI_func_drum_volume(uint8_t param);
void UI_func_drum_pan(uint8_t param);
@ -3600,6 +3609,10 @@ void UI_func_drum_reverb_send(uint8_t param)
encoderDir[ENC_R].reset();
lcd.setCursor(0, 0);
lcd.print("Drum Rev. Send");
lcd.setCursor(1, 1);
sprintf(displayname, "%02d", activesample);
lcd.print(displayname);
lcd.show(4, 5, 6, basename(drum_config[activesample].name));
}
if (LCDML.FUNC_loop()) // ****** LOOP *********
{
@ -3674,9 +3687,42 @@ void UI_func_drum_reverb_send(uint8_t param)
}
}
void UI_func_drum_main_volume(uint8_t param)
void UI_func_drums_main_volume(uint8_t param)
{
;
char displayname[4] = {0, 0, 0, 0};
if (LCDML.FUNC_setup()) // ****** SETUP *********
{
encoderDir[ENC_R].reset();
temp_int = mapfloat(drums_volume, 0.0, VOL_MAX_FLOAT, 0, 100);
lcd.setCursor(0, 0);
lcd.print(" Drums M.Volume ");
}
if (LCDML.FUNC_loop()) // ****** LOOP *********
{
if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()) || (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort()))
{
if (LCDML.BT_checkDown())
{
temp_int = constrain(temp_int + ENCODER[ENC_R].speed(), 0, 100);
}
else if (LCDML.BT_checkUp())
{
temp_int = constrain(temp_int - ENCODER[ENC_R].speed(), 0, 100);
}
}
lcd.setCursor(5, 1);
sprintf(displayname, "%03d", temp_int);
lcd.print(displayname);
lcd.setCursor(8, 1);
lcd.print("/100");
master_mixer_r.gain (2, mapfloat(temp_int, 0, 100, 0.0, VOL_MAX_FLOAT));
master_mixer_l.gain (2, mapfloat(temp_int, 0, 100, 0.0, VOL_MAX_FLOAT));
drums_volume = mapfloat(temp_int, 0, 100, 0.0, VOL_MAX_FLOAT);
}
if (LCDML.FUNC_close()) // ****** STABLE END *********
{
encoderDir[ENC_R].reset();
}
}
void UI_func_drum_volume(uint8_t param)
@ -3687,6 +3733,12 @@ void UI_func_drum_volume(uint8_t param)
encoderDir[ENC_R].reset();
lcd.setCursor(0, 0);
lcd.print("DrumSmp. Volume");
lcd.setCursor(1, 1);
lcd.setCursor(1, 1);
sprintf(displayname, "%02d", activesample);
lcd.print(displayname);
lcd.show(1, 4, 7, basename(drum_config[activesample].name));
}
if (LCDML.FUNC_loop()) // ****** LOOP *********
{
@ -3762,6 +3814,88 @@ void UI_func_drum_volume(uint8_t param)
}
}
void UI_func_arp_shift(uint8_t param)
{
char displayname[4] = {0, 0, 0, 0};
if (LCDML.FUNC_setup()) // ****** SETUP *********
{
encoderDir[ENC_R].reset();
lcd.setCursor(0, 0);
lcd.print("Arp/Chord Transp");
lcd.setCursor(0, 1);
lcd.print("Oct");
lcd.setCursor(4, 1);
sprintf(displayname, "%02d", seq_oct_shift);
lcd.print(displayname);
lcd.setCursor(8, 1);
lcd.print("Shift");
lcd.setCursor(14, 1);
lcd.print(seq_element_shift);
}
if (LCDML.FUNC_loop()) // ****** LOOP *********
{
if (menu_select_toggle == false) {
if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()) || (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort()))
{
if (LCDML.BT_checkDown())
{
seq_oct_shift = constrain(seq_oct_shift + ENCODER[ENC_R].speed(), -2, 2);
}
else if (LCDML.BT_checkUp())
{
seq_oct_shift = constrain(seq_oct_shift - ENCODER[ENC_R].speed(), -2, 2);
}
}
} else {
if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()) || (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort()))
{
if (LCDML.BT_checkDown())
{
seq_element_shift = constrain(seq_element_shift + ENCODER[ENC_R].speed(), 0, 6);
}
else if (LCDML.BT_checkUp())
{
seq_element_shift = constrain(seq_element_shift - ENCODER[ENC_R].speed(), 0, 6);
}
}
}
if (LCDML.BT_checkEnter())
{
menu_select_toggle = !menu_select_toggle;
}
if (menu_select_toggle == false)
{ lcd.setCursor(13, 1);
lcd.print(" ");
lcd.setCursor(15, 1);
lcd.print(" ");
lcd.setCursor(3, 1);
lcd.print("[");
lcd.setCursor(6, 1);
lcd.print("]");
lcd.setCursor(4, 1);
sprintf(displayname, "%02d", seq_oct_shift);
lcd.print(displayname);
} else {
lcd.setCursor(3, 1);
lcd.print(" ");
lcd.setCursor(6, 1);
lcd.print(" ");
lcd.setCursor(13, 1);
lcd.print("[");
lcd.setCursor(15, 1);
lcd.print("]");
lcd.setCursor(14, 1);
lcd.print(seq_element_shift);
}
}
if (LCDML.FUNC_close()) // ****** STABLE END *********
{
encoderDir[ENC_R].reset();
}
}
void UI_func_drum_pan(uint8_t param)
{
char displayname[8] = {0, 0, 0, 0, 0, 0, 0};
@ -3770,6 +3904,10 @@ void UI_func_drum_pan(uint8_t param)
encoderDir[ENC_R].reset();
lcd.setCursor(0, 0);
lcd.print("DrmSmp. Panorama");
lcd.setCursor(1, 1);
sprintf(displayname, "%02d", activesample);
lcd.print(displayname);
lcd.show(1, 4, 6, basename(drum_config[activesample].name));
}
if (LCDML.FUNC_loop()) // ****** LOOP *********
{
@ -3843,7 +3981,7 @@ void UI_func_drum_pan(uint8_t param)
else {
lcd.print("C");
}
sprintf(displayname, "%02d", temp_int);
sprintf(displayname, "%02d", abs(temp_int));
lcd.setCursor(13, 1);
lcd.print( displayname);
}
@ -4042,6 +4180,38 @@ void UI_func_seq_live_transpose_oct(uint8_t param)
}
}
void UI_func_seq_chord_keys_ammount(uint8_t param)
{
char displayname[4] = {0, 0, 0, 0};
if (LCDML.FUNC_setup()) // ****** SETUP *********
{
encoderDir[ENC_R].reset();
lcd.setCursor(0, 0);
lcd.print("ChordTrack Keys:");
lcd.setCursor(8, 1);
lcd.print("Keys");
}
if (LCDML.FUNC_loop()) // ****** LOOP *********
{
if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()) || (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort()))
{
if (LCDML.BT_checkDown())
seq_chord_key_ammount = constrain(seq_chord_key_ammount + ENCODER[ENC_R].speed(), 1, 7);
else if (LCDML.BT_checkUp())
seq_chord_key_ammount = constrain(seq_chord_key_ammount - ENCODER[ENC_R].speed(), 1, 7);
}
lcd.setCursor(4, 1);
lcd.print("[");
sprintf(displayname, "%02d", seq_chord_key_ammount);
lcd.print(displayname);
lcd.print("]");
}
if (LCDML.FUNC_close()) // ****** STABLE END *********
{
encoderDir[ENC_R].reset();
}
}
void UI_func_seq_lenght(uint8_t param)
{
if (LCDML.FUNC_setup()) // ****** SETUP *********
@ -4411,7 +4581,7 @@ void UI_func_sequencer(uint8_t param)
seq_active_track = constrain(seq_active_track - 1, 0, 9);
lcd.setCursor(1, 0);
if (seq_content_type[seq_active_track] == 0) lcd.print("Drum "); else lcd.print("Inst "); //else lcd.print("[ ]");
if (seq_content_type[seq_active_track] == 0) lcd.print("Drum "); else if (seq_content_type[seq_active_track] == 1) lcd.print("Instr "); else if (seq_content_type[seq_active_track] == 2) lcd.print("Chord "); else lcd.print("Arp ");
}
}
if (LCDML.BT_checkEnter()) //handle button presses during menu >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
@ -4483,7 +4653,7 @@ void UI_func_sequencer(uint8_t param)
seq_active_function = 0;
} else if ( seq_menu == 0 && seq_active_function == 0)
{
if ( (seq_content_type[seq_active_track] == 0 && activesample == NUM_DRUMSET_CONFIG + 4) || (seq_content_type[seq_active_track] == 1 && temp_int == 114) )
if ( (seq_content_type[seq_active_track] == 0 && activesample == NUM_DRUMSET_CONFIG + 4) || (seq_content_type[seq_active_track] > 0 && temp_int == 114) )
{ //fill patterns
lcd.setCursor(0, 0);
lcd.print("Fill Pattern:");
@ -4493,25 +4663,25 @@ void UI_func_sequencer(uint8_t param)
seq_temp_select_menu = 0;
seq_temp_active_menu = 0;
}
else if ( (seq_content_type[seq_active_track] == 0 && activesample == NUM_DRUMSET_CONFIG + 3) || (seq_content_type[seq_active_track] == 1 && temp_int == 113) )
else if ( (seq_content_type[seq_active_track] == 0 && activesample == NUM_DRUMSET_CONFIG + 3) || (seq_content_type[seq_active_track] > 0 && temp_int == 113) )
{ //swap patterns: Active pattern <-> destination pattern
lcd.setCursor(0, 0);
lcd.print("Swap Pattern:");
temp_int = seq_active_track + 1;
if (temp_int > 9)temp_int = 0;
seq_menu = 30;
} else if ( (seq_content_type[seq_active_track] == 0 && activesample == NUM_DRUMSET_CONFIG + 2) || (seq_content_type[seq_active_track] == 1 && temp_int == 112) )
} else if ( (seq_content_type[seq_active_track] == 0 && activesample == NUM_DRUMSET_CONFIG + 2) || (seq_content_type[seq_active_track] > 0 && temp_int == 112) )
{ //copy pattern
lcd.setCursor(0, 0);
lcd.print("Copy Pattern:");
temp_int = seq_active_track + 1;
if (temp_int > 9)temp_int = 0;
seq_menu = 31;
} else if ( (seq_content_type[seq_active_track] == 0 && activesample == NUM_DRUMSET_CONFIG + 1) || (seq_content_type[seq_active_track] == 1 && temp_int == 111) )
} else if ( (seq_content_type[seq_active_track] == 0 && activesample == NUM_DRUMSET_CONFIG + 1) || (seq_content_type[seq_active_track] > 0 && temp_int == 111) )
{ //clear all patterns
seq_clear_all_patterns();
seq_printAllSeqSteps();
} else if ( (seq_content_type[seq_active_track] == 0 && activesample == NUM_DRUMSET_CONFIG) || (seq_content_type[seq_active_track] == 1 && temp_int == 110) )
} else if ( (seq_content_type[seq_active_track] == 0 && activesample == NUM_DRUMSET_CONFIG) || (seq_content_type[seq_active_track] > 0 && temp_int == 110) )
{ //clear pattern
seq_clear_active_pattern();
seq_printAllSeqSteps();
@ -4600,7 +4770,7 @@ void UI_func_sequencer(uint8_t param)
} else if (seq_menu == 32 ) { //fill pattern
if (seq_content_type[seq_active_track] == 0) { //inst
if (seq_content_type[seq_active_track] == 0) { //drum
lcd.setCursor(0, 1);
lcd.print("with");
lcd.setCursor(4, 1);
@ -4784,10 +4954,10 @@ void UI_func_arpeggio(uint8_t param)
if (LCDML.FUNC_setup()) // ****** SETUP *********
{
encoderDir[ENC_R].reset();
seq_temp_select_menu=0;
seq_temp_active_menu=0;
seq_temp_select_menu = 0;
seq_temp_active_menu = 0;
lcd.setCursor( 0, 0);
lcd.print("Oct");
lcd.print("Len");
lcd.setCursor(7, 0);
lcd.print( seq_chord_names[arp_chord][0]);
lcd.print( seq_chord_names[arp_chord][1]);
@ -4809,12 +4979,13 @@ void UI_func_arpeggio(uint8_t param)
seq_temp_select_menu = constrain(seq_temp_select_menu + ENCODER[ENC_R].speed(), 0, 3);
else if (LCDML.BT_checkUp())
seq_temp_select_menu = constrain(seq_temp_select_menu - ENCODER[ENC_R].speed(), 0, 3);
} else if (seq_temp_active_menu == 1) // Octave setting
}
else if (seq_temp_active_menu == 1) // Octave setting
{
if (LCDML.BT_checkDown())
arp_oct_usersetting = constrain(arp_oct_usersetting + ENCODER[ENC_R].speed(), 0, 3);
arp_lenght = constrain(arp_lenght + ENCODER[ENC_R].speed(), 0, 9);
else if (LCDML.BT_checkUp())
arp_oct_usersetting = constrain(arp_oct_usersetting - ENCODER[ENC_R].speed(), 0, 3);
arp_lenght = constrain(arp_lenght - ENCODER[ENC_R].speed(), 0, 9);
}
else if (seq_temp_active_menu == 2) // Style setting
{
@ -4880,10 +5051,8 @@ void UI_func_arpeggio(uint8_t param)
}
}
}
lcd.setCursor( 4, 0);
lcd.print(arp_oct_usersetting);
lcd.print(arp_lenght);
lcd.setCursor( 6, 1);
lcd.print( arp_style_names[arp_style][0] );
lcd.print( arp_style_names[arp_style][1] );
@ -4904,11 +5073,9 @@ void UI_func_arpeggio(uint8_t param)
lcd.print(" ");
lcd.setCursor( 15, 1);
lcd.print(" ");
}
else if (seq_temp_select_menu == 1)
{
lcd.setCursor( 5, 1);
lcd.print("[");
lcd.setCursor( 9, 1);
@ -4952,7 +5119,6 @@ void UI_func_arpeggio(uint8_t param)
lcd.setCursor( 5, 0);
lcd.print(" ");
}
}
if (LCDML.FUNC_close()) // ****** STABLE END *********
{
@ -5265,7 +5431,122 @@ void UI_func_seq_track_setup(uint8_t param)
}
}
void UI_func_seq_pattern_load(uint8_t param)
void UI_func_dexed_assign(uint8_t param)
{
if (LCDML.FUNC_setup()) // ****** SETUP *********
{
// setup function
seq_temp_active_menu = 99;
lcd.setCursor(0 , 0);
lcd.print("T1");
lcd.setCursor(0 , 1);
lcd.print("T2");
lcd.setCursor(9 , 0);
lcd.print("T3");
lcd.setCursor(9 , 1);
lcd.print("T4");
lcd.setCursor(3 , 0);
if (seq_inst_dexed[0] == 0 ) lcd.print("D1"); else lcd.print("D2");
lcd.setCursor(3 , 1);
if (seq_inst_dexed[1] == 0 ) lcd.print("D1"); else lcd.print("D2");
lcd.setCursor(12 , 0);
if (seq_inst_dexed[2] == 0 ) lcd.print("D1"); else lcd.print("D2");
lcd.setCursor(12 , 1);
if (seq_inst_dexed[3] == 0 ) lcd.print("D1"); else lcd.print("D2");
}
if (LCDML.FUNC_loop()) // ****** LOOP *********
{
if (seq_temp_active_menu == 99) {
if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()))
{
if (LCDML.BT_checkDown())
seq_temp_select_menu = constrain(seq_temp_select_menu + 1, 0, 3);
else if (LCDML.BT_checkUp())
seq_temp_select_menu = constrain(seq_temp_select_menu - 1, 0, 3);
}
} else {
if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()))
{
if (LCDML.BT_checkDown())
seq_inst_dexed[seq_temp_active_menu] = constrain(seq_inst_dexed[seq_temp_active_menu] + 1, 0, 1);
else if (LCDML.BT_checkUp())
seq_inst_dexed[seq_temp_active_menu] = constrain(seq_inst_dexed[seq_temp_active_menu] - 1, 0, 1);
}
}
if (LCDML.BT_checkEnter()) //handle button presses during menu >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
{
if (seq_temp_active_menu == 99) {
seq_temp_active_menu = seq_temp_select_menu;
} else
{
seq_temp_active_menu = 99;
}
}
if (seq_temp_select_menu == 0)
{
lcd.setCursor(2 , 0);
lcd.print("[");
lcd.setCursor(6 , 0);
lcd.print("]");
lcd.setCursor(2 , 1);
lcd.print(" ");
lcd.setCursor(6 , 1);
lcd.print(" ");
lcd.setCursor(3 , 0);
if (seq_inst_dexed[0] == 0 ) lcd.print("D1"); else lcd.print("D2");
} else if (seq_temp_select_menu == 1)
{
lcd.setCursor(2 , 0);
lcd.print(" ");
lcd.setCursor(6 , 0);
lcd.print(" ");
lcd.setCursor(2 , 1);
lcd.print("[");
lcd.setCursor(6 , 1);
lcd.print("]");
lcd.setCursor(11 , 0);
lcd.print(" ");
lcd.setCursor(15 , 0);
lcd.print(" ");
lcd.setCursor(3 , 1);
if (seq_inst_dexed[1] == 0 ) lcd.print("D1"); else lcd.print("D2");
} else if (seq_temp_select_menu == 2)
{
lcd.setCursor(2 , 1);
lcd.print(" ");
lcd.setCursor(6 , 1);
lcd.print(" ");
lcd.setCursor(11 , 0);
lcd.print("[");
lcd.setCursor(15 , 0);
lcd.print("]");
lcd.setCursor(11 , 1);
lcd.print(" ");
lcd.setCursor(15 , 1);
lcd.print(" ");
lcd.setCursor(12 , 0);
if (seq_inst_dexed[2] == 0 ) lcd.print("D1"); else lcd.print("D2");
} else if (seq_temp_select_menu == 3)
{
lcd.setCursor(11 , 0);
lcd.print(" ");
lcd.setCursor(15 , 0);
lcd.print(" ");
lcd.setCursor(11 , 1);
lcd.print("[");
lcd.setCursor(15 , 1);
lcd.print("]");
lcd.setCursor(12 , 1);
if (seq_inst_dexed[3] == 0 ) lcd.print("D1"); else lcd.print("D2");
}
}
if (LCDML.FUNC_close()) // ****** STABLE END *********
{
encoderDir[ENC_R].reset();
}
}
void UI_func_seq_state_load(uint8_t param)
{
static uint8_t mode;
if (LCDML.FUNC_setup()) // ****** SETUP *********
@ -5275,7 +5556,7 @@ void UI_func_seq_pattern_load(uint8_t param)
mode = 0;
encoderDir[ENC_R].reset();
lcd.setCursor(0, 0);
lcd.print(F("Load Patterns"));
lcd.print(F("Load Seq. state "));
lcd.setCursor(0, 1);
sprintf(tmp, "[%2d]", param);
lcd.print(tmp);
@ -5306,11 +5587,18 @@ void UI_func_seq_pattern_load(uint8_t param)
delay(MESSAGE_WAIT_TIME);
LCDML.FUNC_goBackToMenu();
}
}
lcd.setCursor(0, 1);
char tmp[10];
sprintf(tmp, "[%2d]", temp_int);
lcd.print(tmp);
lcd.setCursor(5, 1);
if (check_sd_seq_exists(temp_int))
{
lcd.print("-- DATA --");
}
else lcd.print(" ");
}
if (LCDML.FUNC_close()) // ****** STABLE END *********
{
@ -5324,7 +5612,7 @@ void UI_func_seq_pattern_load(uint8_t param)
}
}
void UI_func_seq_pattern_save(uint8_t param)
void UI_func_seq_state_save(uint8_t param)
{
static bool overwrite;
static bool yesno;
@ -5337,7 +5625,7 @@ void UI_func_seq_pattern_save(uint8_t param)
mode = 0;
encoderDir[ENC_R].reset();
lcd.setCursor(0, 0);
lcd.print(F("Save Patterns to:"));
lcd.print(F("Save Seq. state:"));
lcd.setCursor(0, 1);
sprintf(tmp, "[%2d]", temp_int);
lcd.print(tmp);
@ -5412,6 +5700,8 @@ void UI_func_seq_pattern_save(uint8_t param)
lcd.setCursor(0, 1);
sprintf(tmp, "[%2d]", temp_int);
lcd.print(tmp);
lcd.setCursor(5, 1);
if (overwrite == false)lcd.print("-- empty --"); else lcd.print(" ");
}
else
{

@ -122,20 +122,23 @@ LCDML_add(88, LCDML_0_5, 1, "Sequencer", UI_func_sequencer);
LCDML_add(89, LCDML_0_5, 2, "Vel./Chrd Edit", UI_func_seq_vel_editor);
LCDML_add(90, LCDML_0_5, 3, "Pattern Chain", UI_func_seq_pat_chain);
LCDML_add(91, LCDML_0_5, 4, "Arpeggio", UI_func_arpeggio);
LCDML_add(92, LCDML_0_5, 5, "Seq. Length", UI_func_seq_lenght);
LCDML_add(93, LCDML_0_5, 6, "Tempo", UI_func_seq_tempo);
LCDML_add(94, LCDML_0_5, 7, "L.Transp.Key", UI_func_seq_live_transpose_oct);
LCDML_add(95, LCDML_0_5, 8, "L.Trp.Offset", NULL);
LCDML_add(96, LCDML_0_5, 9, "Track Setup", UI_func_seq_track_setup);
LCDML_add(97, LCDML_0_5, 10, "Seq.Disp.Style", UI_func_seq_display_style);
LCDML_add(98, LCDML_0_5, 11, "LOAD Patterns", UI_func_seq_pattern_load);
LCDML_add(99, LCDML_0_5, 12, "SAVE Patterns", UI_func_seq_pattern_save);
LCDML_add(100, LCDML_0, 6, "System", NULL);
LCDML_add(101, LCDML_0_6, 1, "Stereo/Mono", UI_func_stereo_mono);
LCDML_add(102, LCDML_0_6, 2, "MIDI Soft THRU", UI_func_midi_soft_thru);
LCDML_add(103, LCDML_0_6, 3, "Favorites", UI_func_favorites);
LCDML_add(104, LCDML_0_6, 4, "EEPROM Reset", UI_func_eeprom_reset);
LCDML_add(105, LCDML_0, 7, "Info", UI_func_information);
LCDML_addAdvanced(106, LCDML_0, 8, COND_hide, "Volume", UI_func_volume, 0, _LCDML_TYPE_default);
#define _LCDML_DISP_cnt 106
LCDML_add(92, LCDML_0_5, 5, "Seq. Settings", NULL);
LCDML_add(93, LCDML_0_5_5, 1, "Tempo", UI_func_seq_tempo);
LCDML_add(94, LCDML_0_5_5, 2, "Seq. Length", UI_func_seq_lenght);
LCDML_add(95, LCDML_0_5_5, 3, "Track Setup", UI_func_seq_track_setup);
LCDML_add(96, LCDML_0_5_5, 4, "Seq.Disp.Style", UI_func_seq_display_style);
LCDML_add(97, LCDML_0_5_5, 5, "dexed assign", UI_func_dexed_assign);
LCDML_add(98, LCDML_0_5_5, 6, "shift&transp.", UI_func_arp_shift);
LCDML_add(99, LCDML_0_5_5, 8, "ChordTrack Keys", UI_func_seq_chord_keys_ammount);
LCDML_add(100, LCDML_0_5_5, 6, "L.Transp.Key", UI_func_seq_live_transpose_oct);
LCDML_add(101, LCDML_0_5, 6, "LOAD Seq.Data", UI_func_seq_state_load);
LCDML_add(102, LCDML_0_5, 7, "SAVE Seq.Data", UI_func_seq_state_save);
LCDML_add(103, LCDML_0, 6, "System", NULL);
LCDML_add(104, LCDML_0_6, 1, "Stereo/Mono", UI_func_stereo_mono);
LCDML_add(105, LCDML_0_6, 2, "MIDI Soft THRU", UI_func_midi_soft_thru);
LCDML_add(106, LCDML_0_6, 3, "Favorites", UI_func_favorites);
LCDML_add(107, LCDML_0_6, 4, "EEPROM Reset", UI_func_eeprom_reset);
LCDML_add(108, LCDML_0, 7, "Info", UI_func_information);
LCDML_addAdvanced(109, LCDML_0, 8, COND_hide, "Volume", UI_func_volume, 0, _LCDML_TYPE_default);
#define _LCDML_DISP_cnt 109
#endif

@ -116,7 +116,7 @@ LCDML_add(82, LCDML_0_3_5, 1, "MIDI Recv Bank", UI_func_sysex_receive_bank);
LCDML_add(83, LCDML_0_3_5, 2, "MIDI Snd Bank", UI_func_sysex_send_bank);
LCDML_add(84, LCDML_0_3_5, 3, "MIDI Snd Voice", UI_func_sysex_send_voice);
LCDML_add(85, LCDML_0, 4, "Drums", NULL);
LCDML_add(86, LCDML_0_4, 1, "Drums Main Vol", UI_func_drum_main_volume);
LCDML_add(86, LCDML_0_4, 1, "Drums Main Vol", UI_func_drums_main_volume);
LCDML_add(87, LCDML_0_4, 2, "Drum Volumes", UI_func_drum_volume);
LCDML_add(88, LCDML_0_4, 3, "Drum Pan", UI_func_drum_pan);
LCDML_add(89, LCDML_0_4, 4, "Drum Rev.Send", UI_func_drum_reverb_send);
@ -125,19 +125,23 @@ LCDML_add(91, LCDML_0_5, 1, "Sequencer", UI_func_sequencer);
LCDML_add(92, LCDML_0_5, 2, "Vel./Chrd Edit", UI_func_seq_vel_editor);
LCDML_add(93, LCDML_0_5, 3, "Pattern Chain", UI_func_seq_pat_chain);
LCDML_add(94, LCDML_0_5, 4, "Arpeggio", UI_func_arpeggio);
LCDML_add(95, LCDML_0_5, 5, "Seq. Length", UI_func_seq_lenght);
LCDML_add(96, LCDML_0_5, 6, "Tempo", UI_func_seq_tempo);
LCDML_add(97, LCDML_0_5, 7, "L.Transp.Key", UI_func_seq_live_transpose_oct);
LCDML_add(98, LCDML_0_5, 8, "Track Setup", UI_func_seq_track_setup);
LCDML_add(99, LCDML_0_5, 9, "Seq.Disp.Style", UI_func_seq_display_style);
LCDML_add(100, LCDML_0_5, 10, "LOAD Patterns", UI_func_seq_pattern_load);
LCDML_add(101, LCDML_0_5, 11, "SAVE Patterns", UI_func_seq_pattern_save);
LCDML_add(102, LCDML_0, 6, "System", NULL);
LCDML_add(103, LCDML_0_6, 1, "Stereo/Mono", UI_func_stereo_mono);
LCDML_add(104, LCDML_0_6, 2, "MIDI Soft THRU", UI_func_midi_soft_thru);
LCDML_add(105, LCDML_0_6, 3, "Favorites", UI_func_favorites);
LCDML_add(106, LCDML_0_6, 4, "EEPROM Reset", UI_func_eeprom_reset);
LCDML_add(107, LCDML_0, 7, "Info", UI_func_information);
LCDML_addAdvanced(108, LCDML_0, 8, COND_hide, "Volume", UI_func_volume, 0, _LCDML_TYPE_default);
#define _LCDML_DISP_cnt 108
LCDML_add(95, LCDML_0_5, 5, "Seq. Settings", NULL);
LCDML_add(96, LCDML_0_5_5, 1, "Tempo", UI_func_seq_tempo);
LCDML_add(97, LCDML_0_5_5, 2, "Seq. Length", UI_func_seq_lenght);
LCDML_add(98, LCDML_0_5_5, 3, "Track Setup", UI_func_seq_track_setup);
LCDML_add(99, LCDML_0_5_5, 4, "Seq.Disp.Style", UI_func_seq_display_style);
LCDML_add(100, LCDML_0_5_5, 5, "dexed assign", UI_func_dexed_assign);
LCDML_add(101, LCDML_0_5_5, 6, "shift&transp.", UI_func_arp_shift);
LCDML_add(102, LCDML_0_5_5, 7, "L.Transp.Key", UI_func_seq_live_transpose_oct);
LCDML_add(103, LCDML_0_5_5, 8, "ChordTrack Keys", UI_func_seq_chord_keys_ammount);
LCDML_add(104, LCDML_0_5, 6, "LOAD Seq.Data", UI_func_seq_state_load);
LCDML_add(105, LCDML_0_5, 7, "SAVE Seq.Data", UI_func_seq_state_save);
LCDML_add(106, LCDML_0, 6, "System", NULL);
LCDML_add(107, LCDML_0_6, 1, "Stereo/Mono", UI_func_stereo_mono);
LCDML_add(108, LCDML_0_6, 2, "MIDI Soft THRU", UI_func_midi_soft_thru);
LCDML_add(109, LCDML_0_6, 3, "Favorites", UI_func_favorites);
LCDML_add(110, LCDML_0_6, 4, "EEPROM Reset", UI_func_eeprom_reset);
LCDML_add(111, LCDML_0, 7, "Info", UI_func_information);
LCDML_addAdvanced(112, LCDML_0, 8, COND_hide, "Volume", UI_func_volume, 0, _LCDML_TYPE_default);
#define _LCDML_DISP_cnt 112
#endif

@ -85,29 +85,33 @@ LCDML_add(51, LCDML_0_2, 4, "MIDI", NULL);
LCDML_add(52, LCDML_0_2_4, 1, "MIDI Recv Bank", UI_func_sysex_receive_bank);
LCDML_add(53, LCDML_0_2_4, 2, "MIDI Snd Bank", UI_func_sysex_send_bank);
LCDML_add(54, LCDML_0_2_4, 3, "MIDI Snd Voice", UI_func_sysex_send_voice);
LCDML_add(55, LCDML_0, 3, "Drum", NULL);
LCDML_add(56, LCDML_0_3, 1, "Drums Main Vol", UI_func_drum_main_volume);
LCDML_add(57, LCDML_0_3, 2, "Drum Volumes", UI_func_drum_volume);
LCDML_add(58, LCDML_0_3, 3, "Drum Pan", UI_func_drum_pan);
LCDML_add(59, LCDML_0, 4, "Sequencer", NULL);
LCDML_add(60, LCDML_0_4, 1, "Sequencer", UI_func_sequencer);
LCDML_add(61, LCDML_0_5, 2, "Vel./Chrd Edit", UI_func_seq_vel_editor);
LCDML_add(62, LCDML_0_4, 3, "Pattern Chain", UI_func_seq_pat_chain);
LCDML_add(63, LCDML_0_5, 4, "Arpeggio", UI_func_arpeggio);
LCDML_add(64, LCDML_0_4, 5, "Seq. Length", UI_func_seq_lenght);
LCDML_add(65, LCDML_0_4, 6, "Tempo", UI_func_seq_tempo);
LCDML_add(66, LCDML_0_4, 7, "L.Transp.Key", UI_func_seq_live_transpose_oct);
LCDML_add(67, LCDML_0_5, 8, "Track Setup", UI_func_seq_track_setup);
LCDML_add(68, LCDML_0_5, 9, "Seq.Disp.Style", UI_func_seq_display_style);
LCDML_add(69, LCDML_0_4, 10, "LOAD Patterns", UI_func_seq_pattern_load);
LCDML_add(70, LCDML_0_4, 11, "SAVE Patterns", UI_func_seq_pattern_save);
LCDML_add(71, LCDML_0, 5, "System", NULL);
LCDML_add(72, LCDML_0_5, 1, "Stereo/Mono", UI_func_stereo_mono);
LCDML_add(73, LCDML_0_5, 2, "MIDI Soft THRU", UI_func_midi_soft_thru);
LCDML_add(74, LCDML_0_5, 3, "Favorites", UI_func_favorites);
LCDML_add(75, LCDML_0_5, 4, "EEPROM Reset", UI_func_eeprom_reset);
LCDML_add(76, LCDML_0, 6, "Info", UI_func_information);
LCDML_addAdvanced(77, LCDML_0, 5, COND_hide, "Volume", UI_func_volume, 0, _LCDML_TYPE_default);
#define _LCDML_DISP_cnt 77
LCDML_add(55, LCDML_0, 4, "Drums", NULL);
LCDML_add(56, LCDML_0_4, 1, "Drums Main Vol", UI_func_drums_main_volume);
LCDML_add(57, LCDML_0_4, 2, "Drum Volumes", UI_func_drum_volume);
LCDML_add(58, LCDML_0_4, 3, "Drum Pan", UI_func_drum_pan);
LCDML_add(59, LCDML_0_4, 4, "Drum Rev.Send", UI_func_drum_reverb_send);
LCDML_add(60, LCDML_0, 5, "Sequencer", NULL);
LCDML_add(61, LCDML_0_5, 1, "Sequencer", UI_func_sequencer);
LCDML_add(62, LCDML_0_5, 2, "Vel./Chrd Edit", UI_func_seq_vel_editor);
LCDML_add(63, LCDML_0_5, 3, "Pattern Chain", UI_func_seq_pat_chain);
LCDML_add(64, LCDML_0_5, 4, "Arpeggio", UI_func_arpeggio);
LCDML_add(65, LCDML_0_5, 5, "Seq. Settings", NULL);
LCDML_add(66, LCDML_0_5_5, 1, "Tempo", UI_func_seq_tempo);
LCDML_add(67, LCDML_0_5_5, 2, "Seq. Length", UI_func_seq_lenght);
LCDML_add(68, LCDML_0_5_5, 3, "Track Setup", UI_func_seq_track_setup);
LCDML_add(69, LCDML_0_5_5, 4, "Seq.Disp.Style", UI_func_seq_display_style);
LCDML_add(70, LCDML_0_5_5, 5, "dexed assign", UI_func_dexed_assign);
LCDML_add(71, LCDML_0_5_5, 6, "L.Transp.Key", UI_func_seq_live_transpose_oct);
LCDML_add(72, LCDML_0_5_5, 8, "ChordTrack Keys", UI_func_seq_chord_keys_ammount);
LCDML_add(73, LCDML_0_5, 6, "LOAD Seq.Data", UI_func_seq_state_load);
LCDML_add(74, LCDML_0_5, 7, "SAVE Seq.Data", UI_func_seq_state_save);
LCDML_add(75, LCDML_0, 5, "System", NULL);
LCDML_add(76, LCDML_0_5, 1, "Stereo/Mono", UI_func_stereo_mono);
LCDML_add(77, LCDML_0_5, 2, "MIDI Soft THRU", UI_func_midi_soft_thru);
LCDML_add(78, LCDML_0_5, 3, "Favorites", UI_func_favorites);
LCDML_add(79, LCDML_0_5, 4, "EEPROM Reset", UI_func_eeprom_reset);
LCDML_add(80, LCDML_0, 6, "Info", UI_func_information);
LCDML_addAdvanced(81, LCDML_0, 5, COND_hide, "Volume", UI_func_volume, 0, _LCDML_TYPE_default);
#define _LCDML_DISP_cnt 81
#endif

@ -627,7 +627,7 @@
// Buffer for load/save configuration as JSON
#define JSON_BUFFER 6144
#define JSON_BUFFER 8192
// Internal configuration structure
typedef struct dexed_s {

@ -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,21 @@ 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 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_bpm;
extern bool arp_play_basenote;
extern uint8_t arp_speed;
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 PeriodicTimer timer1;
/******************************************************************************
SD BANK/VOICE LOADING
@ -747,14 +762,316 @@ bool save_sd_fx_json(uint8_t fx)
return (false);
}
bool load_sd_seq_drumsettings_json(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-d.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 load_sd_seq_voicesettings_json(uint8_t number)
{
uint8_t bank[MAX_DEXED];
uint8_t voice[MAX_DEXED];
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-v.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 Sequencer configuration ["));
Serial.print(filename);
Serial.println(F("]... loading..."));
#endif
json = SD.open(filename);
if (json)
{
deserializeJson(data_json, json);
json.close();
AudioInterrupts();
//check_configuration_fx();
#ifdef DEBUG
Serial.println(F("Read JSON data:"));
serializeJsonPretty(data_json, Serial);
Serial.println();
#endif
for (uint8_t i = 0; i < MAX_DEXED; i++)
{
bank[i] = data_json["bank"][i];
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["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(bank[i], 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);
}
#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_json(uint8_t number)
{
char filename[FILENAME_LEN];
number = constrain(number, 0, 99);
if (sd_card > 0)
{
File json;
sprintf(filename, "/%s/%s%d-d.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_voicesettings_json(uint8_t number)
{
char filename[FILENAME_LEN];
number = constrain(number, 0, 99);
if (sd_card > 0)
{
File json;
sprintf(filename, "/%s/%s%d-v.json", SEQ_CONFIG_PATH, SEQ_CONFIG_NAME, number);
#ifdef DEBUG
Serial.print(F("Saving sequencer voice config "));
Serial.print(number);
Serial.print(F(" to "));
Serial.println(filename);
#endif
AudioNoInterrupts();
json = SD.open(filename, FILE_WRITE);
if (json)
{
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];
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["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;
#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];
int count = 0;
seq_number = constrain(seq_number, 0, 99);
save_sd_seq_drumsettings_json(seq_number);
save_sd_seq_voicesettings_json(seq_number);
if (sd_card > 0)
{
sprintf(filename, "/%s/%s%d.json", SEQ_CONFIG_PATH, SEQ_CONFIG_NAME, seq_number);
AudioNoInterrupts();
if (SD.exists(filename)) {
Serial.println("Remove");
Serial.print(filename);
SD.remove(filename);
}
AudioInterrupts();
File json;
sprintf(filename, "/%s/%s%d.json", SEQ_CONFIG_PATH, SEQ_CONFIG_NAME, seq_number);
@ -774,22 +1091,12 @@ bool save_sd_seq_json(uint8_t seq_number)
Serial.print(" Columns: ");
Serial.print(columns);
Serial.print(F(" "));
AudioNoInterrupts();
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 +1112,6 @@ bool save_sd_seq_json(uint8_t seq_number)
count++;
}
}
total = sizeof(seq_patternchain);
columns = sizeof(seq_patternchain[0]);
rows = total / columns;
@ -826,21 +1132,29 @@ bool save_sd_seq_json(uint8_t seq_number)
}
count = 0;
// 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["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_lenght"] = arp_lenght;
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;
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;
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;
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];
}
#ifdef DEBUG
Serial.println(F("Write JSON data:"));
@ -849,10 +1163,11 @@ bool save_sd_seq_json(uint8_t seq_number)
#endif
serializeJsonPretty(data_json, json);
json.close();
AudioInterrupts();
return (true);
}
json.close();
AudioInterrupts();
}
else
{
@ -862,11 +1177,11 @@ bool save_sd_seq_json(uint8_t seq_number)
Serial.println(F(" on SD."));
#endif
}
AudioInterrupts();
return (false);
}
bool load_sd_seq_json(uint8_t seq_number)
{
if (seq_number < 0)
@ -874,6 +1189,9 @@ bool load_sd_seq_json(uint8_t seq_number)
seq_number = constrain(seq_number, 0, 99);
load_sd_seq_drumsettings_json(seq_number);
load_sd_seq_voicesettings_json(seq_number);
if (sd_card > 0)
{
File json;
@ -910,15 +1228,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,23 +1255,30 @@ bool load_sd_seq_json(uint8_t seq_number)
count++;
}
}
count = 0;
// 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];
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];
}
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"];
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_lenght = data_json["arp_lenght"];
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_chain_lenght = data_json["seq_chain_lenght"];
seq_transpose = data_json["seq_transpose"];
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"];
set_fx_params();
@ -988,6 +1304,29 @@ bool load_sd_seq_json(uint8_t seq_number)
AudioInterrupts();
return (false);
}
bool check_sd_seq_exists(uint8_t number)
{
if (number < 0)
return (false);
number = constrain(number, 0, 99);
if (sd_card > 0)
{
char filename[FILENAME_LEN];
sprintf(filename, "/%s/%s%d.json", SEQ_CONFIG_PATH, SEQ_CONFIG_NAME, number);
// check if file exists...
AudioNoInterrupts();
if (SD.exists(filename))
{
return (true);
} else return (false);
} else
return (false);
AudioInterrupts();
}
/******************************************************************************
SD PERFORMANCE

@ -36,56 +36,58 @@ void sequencer_part1(void)
for (uint8_t d = 0; d < 4; d++)
{
if ( seq_track_type[d] == 0) { // drum track
if (seq_data[ seq_patternchain[seq_chain_active_step][d] ][seq_step] > 0 && seq_vel[ seq_patternchain[seq_chain_active_step][d] ][seq_step] > 0)
if (seq_data[ seq_patternchain[seq_chain_active_step][d] ][seq_step] > 0 )
{
handleNoteOn(DRUM_MIDI_CHANNEL, seq_data[ seq_patternchain[seq_chain_active_step][d] ][seq_step] , seq_vel[ seq_patternchain[seq_chain_active_step][d] ][seq_step]);
}
}
else {
if (seq_data[ seq_patternchain[seq_chain_active_step][d] ][seq_step] > 0 && seq_vel[ seq_patternchain[seq_chain_active_step][d] ][seq_step] > 0) // instrument track
if (seq_data[seq_patternchain[seq_chain_active_step][d]][seq_step] > 0 ) // instrument track
{
if (seq_track_type[d] == 1 || (seq_track_type[d] == 3 && arp_play_basenote) )
{
handleNoteOn(configuration.dexed[seq_inst_dexed[d]].midi_channel, seq_data[ seq_patternchain[seq_chain_active_step][d] ][seq_step] + seq_transpose , seq_vel[ seq_patternchain[seq_chain_active_step][d] ][seq_step]);
}
seq_prev_note[d] = seq_data[ seq_patternchain[seq_chain_active_step][d] ][seq_step] + seq_transpose;
handleNoteOn(configuration.dexed[seq_inst_dexed[d]].midi_channel, seq_data[ seq_patternchain[seq_chain_active_step][d] ][seq_step], seq_vel[ seq_patternchain[seq_chain_active_step][d] ][seq_step]);
seq_prev_note[d] = seq_data[ seq_patternchain[seq_chain_active_step][d] ][seq_step];
seq_prev_vel[d] = seq_vel[ seq_patternchain[seq_chain_active_step][d] ][seq_step];
if (seq_track_type[d] == 2) { //Chords
if (seq_vel[ seq_patternchain[seq_chain_active_step][d] ][seq_step] > 199)
}
else if (seq_track_type[d] == 2 ) //Chords
{
if (seq_vel[ seq_patternchain[seq_chain_active_step][d]][seq_step] > 199)
{
//handleNoteOn(configuration.dexed[seq_inst_dexed[d]].midi_channel, seq_data[ seq_patternchain[seq_chain_active_step][d] ][seq_step], seq_chord_velocity); // basenote
for (uint8_t x = seq_element_shift; x < seq_element_shift + seq_chord_key_ammount; x++) //play chord notes
{
handleNoteOn(configuration.dexed[seq_chord_dexed_inst].midi_channel, seq_data[ seq_patternchain[seq_chain_active_step][d] ][seq_step] + seq_transpose + seq_chords[seq_vel[ seq_patternchain[seq_chain_active_step][d] ][seq_step] - 200][0], seq_chord_velocity);
handleNoteOn(configuration.dexed[seq_chord_dexed_inst].midi_channel, seq_data[ seq_patternchain[seq_chain_active_step][d] ][seq_step] + seq_transpose + seq_chords[seq_vel[ seq_patternchain[seq_chain_active_step][d] ][seq_step] - 200][1], seq_chord_velocity);
handleNoteOn(configuration.dexed[seq_chord_dexed_inst].midi_channel, seq_data[ seq_patternchain[seq_chain_active_step][d] ][seq_step] + seq_transpose + seq_chords[seq_vel[ seq_patternchain[seq_chain_active_step][d] ][seq_step] - 200][2], seq_chord_velocity);
handleNoteOn(configuration.dexed[seq_chord_dexed_inst].midi_channel, seq_data[ seq_patternchain[seq_chain_active_step][d] ][seq_step] + seq_transpose + seq_chords[seq_vel[ seq_patternchain[seq_chain_active_step][d] ][seq_step] - 200][3], seq_chord_velocity);
handleNoteOn(configuration.dexed[seq_chord_dexed_inst].midi_channel, seq_data[ seq_patternchain[seq_chain_active_step][d] ][seq_step] + (seq_oct_shift * 12) + seq_arps[seq_vel[ seq_patternchain[seq_chain_active_step][d] ][seq_step] - 200][x], seq_chord_velocity);
}
seq_prev_note[d] = seq_data[ seq_patternchain[seq_chain_active_step][d] ][seq_step] + (seq_oct_shift * 12);
seq_prev_vel[d] = seq_vel[ seq_patternchain[seq_chain_active_step][d] ][seq_step];
}
else if (seq_track_type[d] == 3) { //Arp
}
if (seq_track_type[d] == 3) { //Arp
arp_step = 0;
arp_counter = 0;
arp_note = seq_data[ seq_patternchain[seq_chain_active_step][d] ][seq_step] + seq_transpose;
if (seq_vel[ seq_patternchain[seq_chain_active_step][d] ][seq_step] - 200 >= 0)
arp_chord = seq_vel[ seq_patternchain[seq_chain_active_step][d] ][seq_step] - 200;
}
arp_note = seq_data[ seq_patternchain[seq_chain_active_step][d] ][seq_step] + (seq_oct_shift * 12);
if (seq_vel[seq_patternchain[seq_chain_active_step][d] ][seq_step] - 200 >= 0)
arp_chord = seq_vel[seq_patternchain[seq_chain_active_step][d] ][seq_step] - 200;
}
}
// after here not triggered by a key input - arp only
if (seq_track_type[d] == 3)
{ //Arp
if (arp_speed == 0 || (arp_speed == 1 && arp_counter == 0) ) {
if (arp_step % 8 == 0 ) {
handleNoteOn(configuration.dexed[seq_chord_dexed_inst].midi_channel, arp_note + arp_octave * 12 , seq_chord_velocity);
arp_note_prev = arp_note + arp_octave * 12;
}
else
{ if (arp_style == 0) { //arp up
handleNoteOn(configuration.dexed[seq_chord_dexed_inst].midi_channel, arp_note + seq_chords[arp_chord][arp_step] + arp_octave * 12, seq_chord_velocity);
arp_note_prev = arp_note + seq_chords[arp_chord][arp_step] + arp_octave * 12;
handleNoteOn(configuration.dexed[seq_chord_dexed_inst].midi_channel, arp_note + seq_arps[arp_chord][arp_step + seq_element_shift] , seq_chord_velocity);
arp_note_prev = arp_note + seq_arps[arp_chord][arp_step + seq_element_shift] ;
}
else if (arp_style == 3) { //arp random
uint8_t rnd1 = random(4);
uint8_t rnd2 = random(arp_oct_usersetting + 1) * 12;
handleNoteOn(configuration.dexed[seq_chord_dexed_inst].midi_channel, arp_note + seq_chords[arp_chord][rnd1] + rnd2, seq_chord_velocity);
arp_note_prev = arp_note + seq_chords[arp_chord][rnd1] + rnd2;
uint8_t rnd1 = random(5);
handleNoteOn(configuration.dexed[seq_chord_dexed_inst].midi_channel, arp_note + seq_chords[arp_chord][rnd1] + (seq_oct_shift * 12), seq_chord_velocity);
arp_note_prev = arp_note + seq_chords[arp_chord][rnd1] + (seq_oct_shift * 12);
}
}
}
}
@ -106,16 +108,14 @@ void sequencer_part1(void)
arp_counter = 0;
arp_step++;
}
}
}
//if (arp_step > 3 || seq_chords[arp_chord][arp_step] == 0 ) {
if (arp_step > 3 || seq_chords[arp_chord][arp_step] == 0 ) {
if ( (arp_step > 1 && seq_arps[arp_chord][arp_step] == 0) || arp_step == arp_lenght)
{
arp_step = 0;
arp_octave++;
if (arp_octave >= arp_oct_usersetting) arp_octave = 0;
}
if (seq_step > 15) {
if (seq_step > 15)
{
seq_step = 0;
if (seq_chain_lenght > 0) {
seq_chain_active_step++;
@ -137,10 +137,10 @@ void sequencer_part2(void)
handleNoteOff(configuration.dexed[seq_inst_dexed[d]].midi_channel, seq_prev_note[d] , 0);
if (seq_track_type[d] == 2) { //Chords
if ( seq_prev_vel[d] > 199) {
handleNoteOff(configuration.dexed[seq_chord_dexed_inst].midi_channel, seq_prev_note[d] + seq_chords[seq_prev_vel[d] - 200][0], 0);
handleNoteOff(configuration.dexed[seq_chord_dexed_inst].midi_channel, seq_prev_note[d] + seq_chords[seq_prev_vel[d] - 200][1] , 0);
handleNoteOff(configuration.dexed[seq_chord_dexed_inst].midi_channel, seq_prev_note[d] + seq_chords[seq_prev_vel[d] - 200][2] , 0);
handleNoteOff(configuration.dexed[seq_chord_dexed_inst].midi_channel, seq_prev_note[d] + seq_chords[seq_prev_vel[d] - 200][3] , 0);
for (uint8_t x = seq_element_shift; x < seq_element_shift + seq_chord_key_ammount; x++) //play chord notes
{
handleNoteOff(configuration.dexed[seq_chord_dexed_inst].midi_channel, seq_prev_note[d] + seq_arps[seq_prev_vel[d] - 200][x], 0);
}
}
}
else if (seq_track_type[d] == 3)
@ -153,7 +153,6 @@ void sequencer_part2(void)
}
}
void sequencer(void)
{ // Runs in Interrupt Timer. Switches between the Noteon and Noteoff Task, each cycle

@ -1,4 +1,5 @@
float drums_volume;
uint8_t seq_active_track = 0;
uint8_t seq_menu;
bool seq_button_r = false;
@ -11,7 +12,10 @@ uint8_t seq_note_in_velocity;
int seq_transpose;
uint8_t seq_inst_dexed[4] = { 0, 0, 1, 1 };
uint8_t seq_chord_dexed_inst = 0;
uint8_t seq_chord_velocity = 50;
uint8_t seq_chord_velocity = 60;
uint8_t seq_chord_key_ammount = 4;
uint8_t seq_element_shift=0;
int seq_oct_shift=0;
uint8_t arp_style = 0; // up, down, up&down, random
uint8_t seq_chords[7][4] = { 4, 7, 0, 0, //major
3, 7, 0, 0, //minor
@ -21,6 +25,16 @@ uint8_t seq_chords[7][4] = { 4, 7, 0, 0, //major
4, 7, 11, 0, //maj7,
0, 0, 0 , 0 //no Chord
};
uint8_t seq_arps[7][22] = { //up
0, 4, 7, 12, 16, 19, 24, 28, 31, 36, 40, 43, 48, 52, 55, 60 ,99,0,0,0,0,0,//major
0, 3, 7, 12, 15, 19, 24, 27, 31, 36, 39, 43, 48, 51, 55, 60 ,99,0,0,0,0,0,//minor
0, 4, 7, 10, 12, 16, 19, 22, 24, 28, 31, 34, 36, 40, 43, 46, 48, 52, 55, 58, 60 ,99,//seventh
0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60 ,99,0,0,0,0,0,//augmented
0, 3, 6, 12, 15, 18, 24, 27, 30, 36, 39, 42, 48, 51, 54, 60 ,99,0,0,0,0,0,//dim
0, 4, 7, 11, 12, 16, 19, 23, 24, 28, 31, 35, 36, 40, 43, 47, 48, 52, 55, 59, 60 ,99//maj7
};
char seq_chord_names[7][4] = { 'M', 'a', 'j', ' ' , //major
'M', 'i', 'n', ' ' ,
's', 'e', 'v', ' ' ,
@ -41,20 +55,20 @@ int seq_bpm = 102;
uint8_t seq_temp_select_menu;
uint8_t seq_temp_active_menu = 99;
uint8_t seq_chain_active_chainstep;
uint8_t seq_chain_lenght = 0; // 0 = 16 steps, 1 = 32 Steps, 2 = 46 Steps, 3 = 64 Steps
uint8_t seq_chain_lenght = 3; // 0 = 16 steps, 1 = 32 Steps, 2 = 46 Steps, 3 = 64 Steps
uint8_t seq_chain_active_step = 0;
uint8_t seq_prev_note[4]; // note_offs for every (instr.) track
uint8_t seq_prev_vel[4];
uint8_t arp_step;
uint8_t arp_note;
uint8_t arp_chord = 6;
bool arp_play_basenote=true;
bool arp_play_basenote = true;
uint8_t arp_note_prev;
uint8_t arp_octave;
uint8_t arp_prev_oct;
uint8_t arp_speed = 0;
uint8_t arp_counter = 0;
uint8_t arp_oct_usersetting = 1;
uint8_t arp_lenght = 8;
uint8_t seq_data[10][16] = {72 , 0 , 0 , 0 , 72 , 0 , 0 , 0 , 72 , 0 , 0 , 0 , 72 , 0 , 0 , 0 ,
78 , 78 , 78 , 78 , 78 , 78 , 78 , 78 , 78 , 78 , 78 , 78 , 78 , 78 , 78 , 78 ,
72 , 0 , 0 , 0 , 72 , 0 , 0 , 0 , 72 , 0 , 0 , 75 , 72 , 0 , 0 , 0 ,
@ -81,7 +95,7 @@ uint8_t seq_vel[10][16] = {120, 0, 0, 0, 120, 0, 0, 0, 120, 0, 0, 0, 120, 0, 0,
uint8_t seq_patternchain[4][4] = { 0 , 1 , 6 , 9 , 0 , 1 , 5 , 8 , 0 , 1 , 6 , 9 , 2 , 1 , 5 , 7
};
uint8_t seq_content_type[10] = { 0, 0, 0, 0 , 1, 1, 1 , 1 , 1 , 1 }; // 0 = track is Drumtrack, 1= Instrumenttrack, 2= Chord or Arpeggio
uint8_t seq_track_type[4] = { 0, 0, 0, 1 }; // 0 = track is Drumtrack, 1 = Instrumenttrack, 2 = Chord, 3 = Arp
uint8_t seq_track_type[4] = { 0, 0, 2, 1 }; // 0 = track is Drumtrack, 1 = Instrumenttrack, 2 = Chord, 3 = Arp
//uint8_t seq_reverb[4][16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
// 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0,

Loading…
Cancel
Save