Several additions for storing configuration data.

pull/32/head
Holger Wirtz 4 years ago
parent 19b6fa95c4
commit 724f2908f0
  1. 3
      MicroDexed.ino
  2. 320
      UI.hpp
  3. 98
      UI_1_FX.h
  4. 5
      config.h
  5. 83
      dexed.cpp
  6. 3
      dexed.h
  7. 138
      dexed_sysex.cpp
  8. 10
      dexed_sysex.h
  9. 6
      doc/sysex-format_dexed-setup.txt
  10. 14
      third-party/LCDMenuLib2/src/LCDMenuLib2.cpp
  11. 2
      third-party/LCDMenuLib2/src/LCDMenuLib2.h

@ -676,7 +676,6 @@ void loop()
show_cpu_and_mem_usage();
}
#endif
//}
}
/******************************************************************************
@ -1046,7 +1045,7 @@ void handleSystemExclusive(byte * sysex, uint len)
#ifdef DEBUG
else
{
Serial.println(F("E: Unknown SysEx voce or function."));
Serial.println(F("E: Unknown SysEx voice or function."));
}
#endif
}

320
UI.hpp

@ -202,12 +202,18 @@ void UI_func_OP6(uint8_t param);
void UI_handle_OP(uint8_t param, uint8_t op, uint8_t instance_id);
void UI_func_information(uint8_t param);
void UI_func_volume(uint8_t param);
void UI_func_load(uint8_t param);
void UI_func_save(uint8_t param);
void UI_func_load_performance(uint8_t param);
void UI_func_save_performance(uint8_t param);
void UI_func_save_config(uint8_t param);
void UI_func_midi_soft_thru(uint8_t param);
void UI_func_velocity_level(uint8_t param);
void UI_func_firmware_reset(uint8_t param);
void UI_func_eeprom_reset(uint8_t param);
void UI_func_voice_select(uint8_t param);
void UI_func_sysex_send_voice(uint8_t param);
void UI_func_sysex_receive_voice(uint8_t param);
void UI_func_save_voice(uint8_t param);
void UI_func_sysex_receive_bank(uint8_t param);
void UI_func_sysex_send_bank(uint8_t param);
void UI_function_not_enabled(void);
void UI_function_not_implemented(uint8_t param);
void lcd_display_int(int16_t var, uint8_t size, bool zeros, bool brackets, bool sign);
@ -649,10 +655,12 @@ void lcdml_menu_control(void)
Serial.println(F("ENC-L short"));
#endif
encoderDir[ENC_L].ButtonShort(true);
menu_init = false;
if (LCDML.MENU_getLastActivFunctionID() == 0xff && LCDML.MENU_getLastCursorPositionID() == 0)
if ((LCDML.MENU_getLastActivFunctionID() == 0xff && LCDML.MENU_getLastCursorPositionID() == 0) || menu_init == true)
{
LCDML.MENU_goRoot();
menu_init = false;
}
else
LCDML.BT_quit();
}
@ -2933,7 +2941,7 @@ void UI_func_velocity_level(uint8_t param)
}
}
void UI_func_firmware_reset(uint8_t param)
void UI_func_eeprom_reset(uint8_t param)
{
static bool yesno = false;
@ -2998,12 +3006,6 @@ void UI_func_voice_select(uint8_t param)
{
encoderDir[ENC_R].reset();
if (menu_init == true)
{
LCDML.FUNC_setGBAToLastFunc(0xff);
LCDML.FUNC_setGBAToLastCursorPos(0);
}
strip_extension(bank_names[instance_id][configuration.dexed[instance_id].bank], bank_name[instance_id]);
lcd.show(0, 0, 2, configuration.dexed[instance_id].bank);
@ -3202,14 +3204,16 @@ void UI_func_volume(uint8_t param)
}
}
void UI_func_load(uint8_t param)
void UI_func_load_performance(uint8_t param)
{
if (LCDML.FUNC_setup()) // ****** SETUP *********
{
encoderDir[ENC_R].reset();
lcd.setCursor(0, 0);
lcd.print(F("Load setup"));
lcd.print(F("Load Perf. SD"));
lcd.setCursor(0, 1);
lcd.print(F("Not implemented."));
}
if (LCDML.FUNC_loop()) // ****** LOOP *********
@ -3218,24 +3222,213 @@ void UI_func_load(uint8_t param)
{
if (LCDML.BT_checkDown())
{
if (dexed_setup_number < 100)
{
dexed_setup_number++;
}
;
}
else if (LCDML.BT_checkUp())
{
if (dexed_setup_number > 1)
;
}
}
}
if (LCDML.FUNC_close()) // ****** STABLE END *********
{
eeprom_write();
encoderDir[ENC_R].reset();
}
}
void UI_func_save_performance(uint8_t param)
{
if (LCDML.FUNC_setup()) // ****** SETUP *********
{
encoderDir[ENC_R].reset();
lcd.setCursor(0, 0);
lcd.print(F("Save Perf. SD"));
lcd.setCursor(0, 1);
lcd.print(F("Not implemented."));
}
if (LCDML.FUNC_loop()) // ****** LOOP *********
{
if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()))
{
if (LCDML.BT_checkDown())
{
;
}
else if (LCDML.BT_checkUp())
{
;
}
}
}
if (LCDML.FUNC_close()) // ****** STABLE END *********
{
eeprom_write();
encoderDir[ENC_R].reset();
}
}
void UI_func_save_config(uint8_t param)
{
#if NUMDEXED > 1
static int8_t instance_id;
static uint8_t chosen;
#else
uint8_t instance_id = 0;
#endif
static bool yesno;
if (LCDML.FUNC_setup()) // ****** SETUP *********
{
encoderDir[ENC_R].reset();
lcd.setCursor(0, 0);
lcd.print(F("Save Config SD"));
#if NUMDEXED > 1
instance_id = -1;
chosen = 0;
lcd.setCursor(0, 1);
lcd.print(F("Instance [1]"));
#else
int8_t instance_id = 0;
lcd.setCursor(0, 1);
lcd.print(F("[NO ]"));
#endif
yesno = false;
}
if (LCDML.FUNC_loop()) // ****** LOOP *********
{
if ((LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort()) || (LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()))
{
#if NUMDEXED > 1
if ((LCDML.BT_checkDown() || LCDML.BT_checkUp()) && instance_id < 0)
{
chosen = (chosen + 1) % 2;
}
else if (LCDML.BT_checkEnter() && instance_id < 0)
{
instance_id = chosen;
lcd.setCursor(0, 1);
lcd.print(F("[NO ] "));
}
else if ((LCDML.BT_checkDown() || LCDML.BT_checkUp()) && instance_id >= 0)
#else
if ((LCDML.BT_checkDown() || LCDML.BT_checkUp()))
#endif
{
yesno = !yesno;
}
#if NUMDEXED > 1
if (instance_id < 0)
{
lcd.setCursor(10, 1);
lcd.print(chosen + 1);
}
else
{
#endif
if (yesno == true)
{
lcd.setCursor(1, 1);
lcd.print(F("YES"));
}
else
{
dexed_setup_number--;
lcd.setCursor(1, 1);
lcd.print(F("NO "));
}
#if NUMDEXED > 1
}
#endif
//encoderDir[ENC_R].reset();
}
}
if (LCDML.FUNC_close()) // ****** STABLE END *********
{
if (yesno == true)
{
LCDML.DISP_clear();
lcd.print(F("Storing config"));
save_sysex_config(configuration.dexed[instance_id].bank, configuration.dexed[instance_id].voice, instance_id);
lcd.setCursor(0, 1);
lcd.print(F("Done."));
delay(500);
}
encoderDir[ENC_R].reset();
}
}
void UI_func_sysex_send_voice(uint8_t param)
{
if (LCDML.FUNC_setup()) // ****** SETUP *********
{
encoderDir[ENC_R].reset();
lcd.setCursor(0, 0);
lcd.print(F("Send Voice"));
lcd.setCursor(0, 1);
lcd.print(F("Not implemented."));
}
//LOAD SYSEX FILE
if (LCDML.FUNC_loop()) // ****** LOOP *********
{
if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()))
{
if (LCDML.BT_checkDown())
{
;
}
else if (LCDML.BT_checkUp())
{
;
}
}
}
if (LCDML.FUNC_close()) // ****** STABLE END *********
{
eeprom_write();
encoderDir[ENC_R].reset();
}
}
void UI_func_sysex_receive_voice(uint8_t param)
{
if (LCDML.FUNC_setup()) // ****** SETUP *********
{
encoderDir[ENC_R].reset();
lcd.setCursor(0, 0);
lcd.print(F("Receive Voice"));
lcd.setCursor(0, 1);
lcd_display_int(dexed_setup_number, 2, false, true, false);
lcd.print(F("Not implemented."));
}
if (LCDML.FUNC_loop()) // ****** LOOP *********
{
if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()))
{
if (LCDML.BT_checkDown())
{
;
}
else if (LCDML.BT_checkUp())
{
;
}
}
}
if (LCDML.FUNC_close()) // ****** STABLE END *********
@ -3245,14 +3438,16 @@ void UI_func_load(uint8_t param)
}
}
void UI_func_save(uint8_t param)
void UI_func_save_voice(uint8_t param)
{
if (LCDML.FUNC_setup()) // ****** SETUP *********
{
encoderDir[ENC_R].reset();
lcd.setCursor(0, 0);
lcd.print(F("Save setup"));
lcd.print(F("Save Voice SD"));
lcd.setCursor(0, 1);
lcd.print(F("Not implemented."));
}
if (LCDML.FUNC_loop()) // ****** LOOP *********
@ -3261,24 +3456,81 @@ void UI_func_save(uint8_t param)
{
if (LCDML.BT_checkDown())
{
if (dexed_setup_number < 100)
{
dexed_setup_number++;
}
;
}
else if (LCDML.BT_checkUp())
{
if (dexed_setup_number > 1)
{
dexed_setup_number--;
}
;
}
}
}
//SAVE SYSEX FILE
if (LCDML.FUNC_close()) // ****** STABLE END *********
{
eeprom_write();
encoderDir[ENC_R].reset();
}
}
void UI_func_sysex_receive_bank(uint8_t param)
{
if (LCDML.FUNC_setup()) // ****** SETUP *********
{
encoderDir[ENC_R].reset();
lcd.setCursor(0, 0);
lcd.print(F("MIDI Recv Bank"));
lcd.setCursor(0, 1);
lcd.print(F("Not implemented."));
}
if (LCDML.FUNC_loop()) // ****** LOOP *********
{
if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()))
{
if (LCDML.BT_checkDown())
{
;
}
else if (LCDML.BT_checkUp())
{
;
}
}
}
if (LCDML.FUNC_close()) // ****** STABLE END *********
{
eeprom_write();
encoderDir[ENC_R].reset();
}
}
void UI_func_sysex_send_bank(uint8_t param)
{
if (LCDML.FUNC_setup()) // ****** SETUP *********
{
encoderDir[ENC_R].reset();
lcd.setCursor(0, 0);
lcd.print(F("MIDI Send Bank"));
lcd.setCursor(0, 1);
lcd_display_int(dexed_setup_number, 2, false, true, false);
lcd.print(F("Not implemented."));
}
if (LCDML.FUNC_loop()) // ****** LOOP *********
{
if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()))
{
if (LCDML.BT_checkDown())
{
;
}
else if (LCDML.BT_checkUp())
{
;
}
}
}
if (LCDML.FUNC_close()) // ****** STABLE END *********

@ -61,50 +61,56 @@ LCDML_add(32, LCDML_0_1, 4, "MIDI", NULL);
LCDML_add(33, LCDML_0_1_4, 1, "MIDI Channel", UI_func_midi_channel);
LCDML_add(34, LCDML_0_1_4, 2, "Lowest Note", UI_func_lowest_note);
LCDML_add(35, LCDML_0_1_4, 3, "Highest Note", UI_func_highest_note);
LCDML_add(36, LCDML_0_1, 5, "Setup", NULL);
LCDML_add(37, LCDML_0_1_5, 1, "Portamento", NULL);
LCDML_add(38, LCDML_0_1_5_1, 1, "Port. Mode", UI_func_portamento_mode);
LCDML_add(39, LCDML_0_1_5_1, 2, "Port. Gliss", UI_func_portamento_glissando);
LCDML_add(40, LCDML_0_1_5_1, 3, "Port. Time", UI_func_portamento_time);
LCDML_add(41, LCDML_0_1_5, 2, "Polyphony", UI_func_polyphony);
LCDML_add(42, LCDML_0_1_5, 3, "Transpose", UI_func_transpose);
LCDML_add(43, LCDML_0_1_5, 4, "Fine Tune", UI_func_tune);
LCDML_add(44, LCDML_0_1_5, 5, "Mono/Poly", UI_func_mono_poly);
LCDML_add(45, LCDML_0_1, 6, "Internal", NULL);
LCDML_add(46, LCDML_0_1_6, 1, "Note Refresh", UI_func_note_refresh);
LCDML_add(47, LCDML_0_1_6, 2, "Velocity Lvl", UI_func_velocity_level);
LCDML_add(48, LCDML_0_1_6, 3, "Engine", UI_func_engine);
LCDML_add(49, LCDML_0_1, 7, "Operator", NULL);
LCDML_add(50, LCDML_0_1_7, 1, "OP1", UI_func_OP1);
LCDML_add(51, LCDML_0_1_7, 2, "OP2", UI_func_OP2);
LCDML_add(52, LCDML_0_1_7, 3, "OP3", UI_func_OP3);
LCDML_add(53, LCDML_0_1_7, 4, "OP4", UI_func_OP4);
LCDML_add(54, LCDML_0_1_7, 5, "OP5", UI_func_OP5);
LCDML_add(55, LCDML_0_1_7, 6, "OP6", UI_func_OP6);
LCDML_add(56, LCDML_0, 2, "Effect", NULL);
LCDML_add(57, LCDML_0_2, 1, "Chorus", NULL);
LCDML_add(58, LCDML_0_2_1, 1, "Frequency", UI_func_chorus_frequency);
LCDML_add(59, LCDML_0_2_1, 2, "Waveform", UI_func_chorus_waveform);
LCDML_add(60, LCDML_0_2_1, 3, "Depth", UI_func_chorus_depth);
LCDML_add(61, LCDML_0_2_1, 4, "Level", UI_func_chorus_level);
LCDML_add(62, LCDML_0_2, 2, "Delay", NULL);
LCDML_add(63, LCDML_0_2_2, 1, "Time", UI_func_delay_time);
LCDML_add(64, LCDML_0_2_2, 2, "Feedback", UI_func_delay_feedback);
LCDML_add(65, LCDML_0_2_2, 3, "Level", UI_func_delay_level);
LCDML_add(66, LCDML_0_2, 3, "Reverb", NULL);
LCDML_add(67, LCDML_0_2_3, 1, "Roomsize", UI_func_reverb_roomsize);
LCDML_add(68, LCDML_0_2_3, 2, "Damping", UI_func_reverb_damping);
LCDML_add(69, LCDML_0_2_3, 3, "Level", UI_func_reverb_level);
LCDML_add(70, LCDML_0, 3, "Load/Save", NULL);
LCDML_add(71, LCDML_0_3, 1, "Load", UI_func_load);
LCDML_add(72, LCDML_0_3, 2, "Save", UI_func_save);
LCDML_add(73, LCDML_0_3, 3, "Firmware Reset", UI_func_firmware_reset);
LCDML_add(74, LCDML_0, 4, "System", NULL);
LCDML_add(75, LCDML_0_4, 3, "Volume", UI_func_volume);
LCDML_add(76, LCDML_0_4, 1, "Stereo/Mono", UI_func_stereo_mono);
LCDML_add(77, LCDML_0_4, 2, "MIDI Soft THRU", UI_func_midi_soft_thru);
LCDML_add(78, LCDML_0, 6, "Info", UI_func_information);
#define _LCDML_DISP_cnt 78
#define MENU_ID_OF_INSTANCE_2 56
#define VOLUME_MENU_ID 75
LCDML_add(36, LCDML_0_1_4, 4, "Send Voice", UI_func_sysex_send_voice);
LCDML_add(37, LCDML_0_1_4, 5, "Receive Voice", UI_func_sysex_receive_voice);
LCDML_add(38, LCDML_0_1, 5, "Setup", NULL);
LCDML_add(39, LCDML_0_1_5, 1, "Portamento", NULL);
LCDML_add(40, LCDML_0_1_5_1, 1, "Port. Mode", UI_func_portamento_mode);
LCDML_add(41, LCDML_0_1_5_1, 2, "Port. Gliss", UI_func_portamento_glissando);
LCDML_add(42, LCDML_0_1_5_1, 3, "Port. Time", UI_func_portamento_time);
LCDML_add(43, LCDML_0_1_5, 2, "Polyphony", UI_func_polyphony);
LCDML_add(44, LCDML_0_1_5, 3, "Transpose", UI_func_transpose);
LCDML_add(45, LCDML_0_1_5, 4, "Fine Tune", UI_func_tune);
LCDML_add(46, LCDML_0_1_5, 5, "Mono/Poly", UI_func_mono_poly);
LCDML_add(47, LCDML_0_1, 6, "Internal", NULL);
LCDML_add(48, LCDML_0_1_6, 1, "Note Refresh", UI_func_note_refresh);
LCDML_add(49, LCDML_0_1_6, 2, "Velocity Lvl", UI_func_velocity_level);
LCDML_add(50, LCDML_0_1_6, 3, "Engine", UI_func_engine);
LCDML_add(51, LCDML_0_1, 7, "Operator", NULL);
LCDML_add(52, LCDML_0_1_7, 1, "OP1", UI_func_OP1);
LCDML_add(53, LCDML_0_1_7, 2, "OP2", UI_func_OP2);
LCDML_add(54, LCDML_0_1_7, 3, "OP3", UI_func_OP3);
LCDML_add(55, LCDML_0_1_7, 4, "OP4", UI_func_OP4);
LCDML_add(56, LCDML_0_1_7, 5, "OP5", UI_func_OP5);
LCDML_add(57, LCDML_0_1_7, 6, "OP6", UI_func_OP6);
LCDML_add(58, LCDML_0, 2, "Effect", NULL);
LCDML_add(59, LCDML_0_2, 1, "Chorus", NULL);
LCDML_add(60, LCDML_0_2_1, 1, "Frequency", UI_func_chorus_frequency);
LCDML_add(61, LCDML_0_2_1, 2, "Waveform", UI_func_chorus_waveform);
LCDML_add(62, LCDML_0_2_1, 3, "Depth", UI_func_chorus_depth);
LCDML_add(63, LCDML_0_2_1, 4, "Level", UI_func_chorus_level);
LCDML_add(64, LCDML_0_2, 2, "Delay", NULL);
LCDML_add(65, LCDML_0_2_2, 1, "Time", UI_func_delay_time);
LCDML_add(66, LCDML_0_2_2, 2, "Feedback", UI_func_delay_feedback);
LCDML_add(67, LCDML_0_2_2, 3, "Level", UI_func_delay_level);
LCDML_add(68, LCDML_0_2, 3, "Reverb", NULL);
LCDML_add(69, LCDML_0_2_3, 1, "Roomsize", UI_func_reverb_roomsize);
LCDML_add(70, LCDML_0_2_3, 2, "Damping", UI_func_reverb_damping);
LCDML_add(71, LCDML_0_2_3, 3, "Level", UI_func_reverb_level);
LCDML_add(72, LCDML_0, 3, "Load/Save", NULL);
//LCDML_add(74, LCDML_0_3, 2, "Load Perf. SD", UI_func_load_performance);
//LCDML_add(74, LCDML_0_3, 2, "Save Perf. SD", UI_func_save_performance);
LCDML_add(73, LCDML_0_3, 1, "Save Config SD", UI_func_save_config);
LCDML_add(74, LCDML_0_3, 3, "Save Voice SD", UI_func_save_voice);
LCDML_add(75, LCDML_0_3, 4, "MIDI Recv Bank", UI_func_sysex_receive_bank);
LCDML_add(76, LCDML_0_3, 5, "MIDI Send Bank", UI_func_sysex_send_bank);
LCDML_add(77, LCDML_0_3, 6, "EEPROM Reset", UI_func_eeprom_reset);
LCDML_add(78, LCDML_0, 4, "System", NULL);
LCDML_add(79, LCDML_0_4, 3, "Volume", UI_func_volume);
LCDML_add(80, LCDML_0_4, 1, "Stereo/Mono", UI_func_stereo_mono);
LCDML_add(81, LCDML_0_4, 2, "MIDI Soft THRU", UI_func_midi_soft_thru);
LCDML_add(82, LCDML_0, 6, "Info", UI_func_information);
#define _LCDML_DISP_cnt 82
#define MENU_ID_OF_INSTANCE_2 58
#define VOLUME_MENU_ID 79
#endif

@ -223,6 +223,7 @@
#define MAX_VOICES 32 // voices per bank
#define BANK_NAME_LEN 13 // FAT12 filenames (plus '\0')
#define VOICE_NAME_LEN 11 // 10 (plus '\0')
#define FILENAME_LEN BANK_NAME_LEN + VOICE_NAME_LEN
//*************************************************************************************************
//* DO NO CHANGE ANYTHING BEYOND IF YOU DON'T KNOW WHAT YOU ARE DOING !!!
@ -233,7 +234,7 @@
#define CPU_OVERLOAD_THROTTLE_TIMER 100 // timer (in ms) when next throttling is possible
enum { DEXED, CHORUS, DELAY, REVERB};
#define CONTROL_RATE_MS 30
#define CONTROL_RATE_MS 100
// MIDI
#ifdef MIDI_DEVICE_USB
@ -425,7 +426,7 @@ enum { DEXED, CHORUS, DELAY, REVERB};
#define MW_MODE_MIN 0
#define MW_MODE_MAX MIDI_CONTROLLER_MODE_MAX
#define MW_MODE_DEFAULT 1
#define MW_MODE_DEFAULT 0
#define FC_RANGE_MIN 0
#define FC_RANGE_MAX 99

@ -464,7 +464,7 @@ uint8_t Dexed::getNumNotesPlaying(void)
return (count_playing_voices);
}
bool Dexed::loadPackedVoiceParameters(uint8_t* new_data)
bool Dexed::decodeVoice(uint8_t* encoded_data)
{
uint8_t* p_data = data;
uint8_t op;
@ -486,21 +486,21 @@ bool Dexed::loadPackedVoiceParameters(uint8_t* new_data)
// DEXED_OP_LEV_SCL_BRK_PT, // 8
// DEXED_OP_SCL_LEFT_DEPTH, // 9
// DEXED_OP_SCL_RGHT_DEPTH, // 10
memcpy(&data[op * 21], &new_data[op * 17], 11);
tmp = new_data[(op * 17) + 11];
*(p_data + DEXED_OP_SCL_LEFT_CURVE + (op * 21)) = (tmp & 0x3);
memcpy(&data[op * 21], &encoded_data[op * 17], 11);
tmp = encoded_data[(op * 17) + 11];
*(p_data + DEXED_OP_SCL_LEFT_CURVE + (op * 21)) = (tmp & 0x03);
*(p_data + DEXED_OP_SCL_RGHT_CURVE + (op * 21)) = (tmp & 0x0c) >> 2;
tmp = new_data[(op * 17) + 12];
tmp = encoded_data[(op * 17) + 12];
*(p_data + DEXED_OP_OSC_DETUNE + (op * 21)) = (tmp & 0x78) >> 3;
*(p_data + DEXED_OP_OSC_RATE_SCALE + (op * 21)) = (tmp & 0x07);
tmp = new_data[(op * 17) + 13];
tmp = encoded_data[(op * 17) + 13];
*(p_data + DEXED_OP_KEY_VEL_SENS + (op * 21)) = (tmp & 0x1c) >> 2;
*(p_data + DEXED_OP_AMP_MOD_SENS + (op * 21)) = (tmp & 0x03);
*(p_data + DEXED_OP_OUTPUT_LEV + (op * 21)) = new_data[(op * 17) + 14];
tmp = new_data[(op * 17) + 15];
*(p_data + DEXED_OP_OUTPUT_LEV + (op * 21)) = encoded_data[(op * 17) + 14];
tmp = encoded_data[(op * 17) + 15];
*(p_data + DEXED_OP_FREQ_COARSE + (op * 21)) = (tmp & 0x3e) >> 1;
*(p_data + DEXED_OP_OSC_MODE + (op * 21)) = (tmp & 0x01);
*(p_data + DEXED_OP_FREQ_FINE + (op * 21)) = new_data[(op * 17) + 16];
*(p_data + DEXED_OP_FREQ_FINE + (op * 21)) = encoded_data[(op * 17) + 16];
}
// DEXED_PITCH_EG_R1, // 0
// DEXED_PITCH_EG_R2, // 1
@ -510,29 +510,29 @@ bool Dexed::loadPackedVoiceParameters(uint8_t* new_data)
// DEXED_PITCH_EG_L2, // 5
// DEXED_PITCH_EG_L3, // 6
// DEXED_PITCH_EG_L4, // 7
memcpy(&data[DEXED_VOICE_OFFSET], &new_data[102], 8);
tmp = new_data[110];
memcpy(&data[DEXED_VOICE_OFFSET], &encoded_data[102], 8);
tmp = encoded_data[110];
*(p_data + DEXED_VOICE_OFFSET + DEXED_ALGORITHM) = (tmp & 0x1f);
tmp = new_data[111];
tmp = encoded_data[111];
*(p_data + DEXED_VOICE_OFFSET + DEXED_OSC_KEY_SYNC) = (tmp & 0x08) >> 3;
*(p_data + DEXED_VOICE_OFFSET + DEXED_FEEDBACK) = (tmp & 0x07);
// DEXED_LFO_SPEED, // 11
// DEXED_LFO_DELAY, // 12
// DEXED_LFO_PITCH_MOD_DEP, // 13
// DEXED_LFO_AMP_MOD_DEP, // 14
memcpy(&data[DEXED_VOICE_OFFSET + DEXED_LFO_SPEED], &new_data[112], 4);
tmp = new_data[116];
memcpy(&data[DEXED_VOICE_OFFSET + DEXED_LFO_SPEED], &encoded_data[112], 4);
tmp = encoded_data[116];
*(p_data + DEXED_VOICE_OFFSET + DEXED_LFO_PITCH_MOD_SENS) = (tmp & 0x30) >> 4;
*(p_data + DEXED_VOICE_OFFSET + DEXED_LFO_WAVE) = (tmp & 0x0e) >> 1;
*(p_data + DEXED_VOICE_OFFSET + DEXED_LFO_SYNC) = (tmp & 0x01);
*(p_data + DEXED_VOICE_OFFSET + DEXED_TRANSPOSE) = new_data[117];
memcpy(&data[DEXED_VOICE_OFFSET + DEXED_NAME], &new_data[118], 10);
*(p_data + DEXED_VOICE_OFFSET + DEXED_TRANSPOSE) = encoded_data[117];
memcpy(&data[DEXED_VOICE_OFFSET + DEXED_NAME], &encoded_data[118], 10);
panic();
doRefreshVoice();
//activate();
strncpy(dexed_voice_name, (char *)&new_data[118], sizeof(dexed_voice_name) - 1);
strncpy(dexed_voice_name, (char *)&encoded_data[118], sizeof(dexed_voice_name) - 1);
dexed_voice_name[10] = '\0';
#ifdef DEBUG
Serial.print(F("Voice ["));
@ -543,6 +543,55 @@ bool Dexed::loadPackedVoiceParameters(uint8_t* new_data)
return (true);
}
bool Dexed::encodeVoice(uint8_t* encoded_data)
{
uint8_t* p_data = data;
uint8_t op;
for (op = 0; op < 6; op++)
{
// DEXED_OP_EG_R1, // 0
// DEXED_OP_EG_R2, // 1
// DEXED_OP_EG_R3, // 2
// DEXED_OP_EG_R4, // 3
// DEXED_OP_EG_L1, // 4
// DEXED_OP_EG_L2, // 5
// DEXED_OP_EG_L3, // 6
// DEXED_OP_EG_L4, // 7
// DEXED_OP_LEV_SCL_BRK_PT, // 8
// DEXED_OP_SCL_LEFT_DEPTH, // 9
// DEXED_OP_SCL_RGHT_DEPTH, // 10
memcpy(&encoded_data[op * 17], &data[op * 21], 11);
encoded_data[(op * 17) + 11] = ((*(p_data + DEXED_OP_SCL_RGHT_CURVE + (op * 21)) & 0x0c) << 2) & (*(p_data + DEXED_OP_SCL_LEFT_CURVE + (op * 21)) & 0x03);
encoded_data[(op * 17) + 12] = ((*(p_data + DEXED_OP_OSC_DETUNE + (op * 21)) & 0x78) << 3) & (*(p_data + DEXED_OP_OSC_RATE_SCALE + (op * 21)) & 0x07);
encoded_data[(op * 17) + 13] = ((*(p_data + DEXED_OP_KEY_VEL_SENS + (op * 21)) & 0x1c) << 2) & (*(p_data + DEXED_OP_AMP_MOD_SENS + (op * 21)) & 0x03);
encoded_data[(op * 17) + 14] = *(p_data + DEXED_OP_OUTPUT_LEV + (op * 21));
encoded_data[(op * 17) + 15] = ((*(p_data + DEXED_OP_FREQ_COARSE + (op * 21)) & 0x3e) << 1) & (*(p_data + DEXED_OP_OSC_MODE + (op * 21)) & 0x01);
encoded_data[(op * 17) + 16] = *(p_data + DEXED_OP_FREQ_FINE + (op * 21));
}
// DEXED_PITCH_EG_R1, // 0
// DEXED_PITCH_EG_R2, // 1
// DEXED_PITCH_EG_R3, // 2
// DEXED_PITCH_EG_R4, // 3
// DEXED_PITCH_EG_L1, // 4
// DEXED_PITCH_EG_L2, // 5
// DEXED_PITCH_EG_L3, // 6
// DEXED_PITCH_EG_L4, // 7
memcpy(&encoded_data[102], &data[DEXED_VOICE_OFFSET], 8);
encoded_data[110] = (*(p_data + DEXED_VOICE_OFFSET + DEXED_ALGORITHM) & 0x1f);
encoded_data[111] = ((*(p_data + DEXED_VOICE_OFFSET + DEXED_OSC_KEY_SYNC) & 0x08) << 3) & (*(p_data + DEXED_VOICE_OFFSET + DEXED_FEEDBACK) & 0x07);
// DEXED_LFO_SPEED, // 11
// DEXED_LFO_DELAY, // 12
// DEXED_LFO_PITCH_MOD_DEP, // 13
// DEXED_LFO_AMP_MOD_DEP, // 14
memcpy(&encoded_data[112], &data[DEXED_VOICE_OFFSET + DEXED_LFO_SPEED], 4);
encoded_data[116] = ((*(p_data + DEXED_VOICE_OFFSET + DEXED_LFO_PITCH_MOD_SENS) & 0x30) << 4) & ((*(p_data + DEXED_VOICE_OFFSET + DEXED_LFO_WAVE) & 0x0e) << 1) & (*(p_data + DEXED_VOICE_OFFSET + DEXED_LFO_SYNC) & 0x01);
encoded_data[117] = *(p_data + DEXED_VOICE_OFFSET + DEXED_TRANSPOSE);
memcpy(&encoded_data[118], &data[DEXED_VOICE_OFFSET + DEXED_NAME], 10);
return (true);
}
bool Dexed::loadVoiceParameters(uint8_t* new_data)
{
char dexed_voice_name[11];

@ -158,7 +158,8 @@ class Dexed
uint8_t getMaxNotes(void);
void doRefreshVoice(void);
void setOPs(uint8_t ops);
bool loadPackedVoiceParameters(uint8_t* data);
bool decodeVoice(uint8_t* encoded_data);
bool encodeVoice(uint8_t* encoded_data);
bool loadVoiceParameters(uint8_t* data);
bool loadGlobalParameters(uint8_t* data);
bool initGlobalParameters(void);

@ -33,15 +33,16 @@
extern AudioSourceMicroDexed * MicroDexed[NUM_DEXED];
extern void show_patch(uint8_t instance_id);
void create_sysex_filename(uint8_t b, char* sysex_file_name, uint8_t instance_id)
{
/*
void create_sysex_filename(uint8_t b, char* sysex_file_name, uint8_t instance_id)
{
// init and set name for actual bank
memset(sysex_file_name, 0, 4 + VOICE_NAME_LEN);
sysex_file_name[0] = '/';
itoa(b, &sysex_file_name[1], 10);
strcat(sysex_file_name, "/");
strcat(sysex_file_name, bank_names[instance_id][b]);
#ifdef DEBUG
#ifdef DEBUG
Serial.print(F("Created sysex_filename from bank "));
Serial.print(b, DEC);
Serial.print(F(" and name "));
@ -49,6 +50,23 @@ void create_sysex_filename(uint8_t b, char* sysex_file_name, uint8_t instance_id
Serial.print(F(": ["));
Serial.print(sysex_file_name);
Serial.println(F("]"));
#endif
}
*/
void create_sysex_bankfilename(char* filename, uint8_t b, uint8_t instance_id)
{
// init and set name for actual bank
memset(filename, 0, FILENAME_LEN);
sprintf(filename, "/%d/%s", b, bank_names[instance_id][b]);
#ifdef DEBUG
Serial.print(F("Created sysex_filename from bank "));
Serial.print(b, DEC);
Serial.print(F(" and name "));
Serial.print(bank_names[instance_id][b]);
Serial.print(F(": ["));
Serial.print(filename);
Serial.println(F("]"));
#endif
}
@ -79,10 +97,10 @@ bool get_voice_names_from_bank(uint8_t b, uint8_t instance_id)
if (sd_card > 0)
{
char sysex_file_name[4 + VOICE_NAME_LEN];
char sysex_file_name[FILENAME_LEN];
// init and set name for actual bank
create_sysex_filename(b, sysex_file_name, instance_id);
create_sysex_bankfilename(sysex_file_name, b, instance_id);
#ifdef DEBUG
Serial.print(F("Reading voice names for bank ["));
@ -229,10 +247,10 @@ bool load_sysex(uint8_t b, uint8_t v, uint8_t instance_id)
if (sd_card > 0)
{
File sysex;
char sysex_file_name[10 + VOICE_NAME_LEN];
char sysex_file_name[FILENAME_LEN];
uint8_t data[128];
create_sysex_filename(b, sysex_file_name, instance_id);
create_sysex_bankfilename(sysex_file_name, b, instance_id);
sysex = SD.open(sysex_file_name);
if (!sysex)
@ -254,7 +272,7 @@ bool load_sysex(uint8_t b, uint8_t v, uint8_t instance_id)
Serial.print(voice_names[instance_id][v]);
Serial.println(F("]"));
#endif
bool ret = MicroDexed[instance_id]->loadPackedVoiceParameters(data);
bool ret = MicroDexed[instance_id]->decodeVoice(data);
#ifdef DEBUG
show_patch(instance_id);
#endif
@ -356,27 +374,29 @@ bool get_sysex_voice(File sysex, uint8_t voice_number, uint8_t* data)
return (true);
}
void create_sysex_setup_filename(uint8_t b, uint8_t v, char* sysex_setup_file_name)
bool write_sysex_config(File sysex, config_t configuration)
{
// init and set name for actual bank
memset(sysex_setup_file_name, 0, SYSEXFILENAME_LEN);
sysex_setup_file_name[0] = '/';
itoa(b, &sysex_setup_file_name[1], 10);
strcat(sysex_setup_file_name, "/");
itoa(v, &sysex_setup_file_name[3], 10);
strcat(sysex_setup_file_name, ".syx");
#ifdef DEBUG
Serial.print(F("Created sysex_setup_file_name from bank "));
Serial.print(b, DEC);
Serial.print(F(" and voice "));
Serial.print(v, DEC);
Serial.print(F(": ["));
Serial.print(sysex_setup_file_name);
Serial.println(F("]"));
#endif
uint16_t n;
char* c = (char*)&configuration;
// write sysex start
sysex.write(0xf0);
// write sysex vendor is unofficial SYSEX-ID for MicroDexed
sysex.write(0x67);
// write sysex format number (f=66..69; 1..4 MicroDexed setup(s))
sysex.write(0x66);
// write configuration data
for (n = 0; n < sizeof(configuration); n++)
sysex.write(c + n);
// write sysex end
sysex.write(0xf7);
return (true);
}
bool get_sysex_setup(File sysex, config_t configuration)
bool read_sysex_config(File sysex, config_t configuration)
{
uint16_t n;
int32_t bulk_checksum_calc = 0;
@ -473,41 +493,43 @@ bool get_sysex_setup(File sysex, config_t configuration)
return (true);
}
bool load_sysex_setup(uint8_t b, uint8_t v, uint8_t instance_id)
bool save_sysex_config(uint8_t b, uint8_t v, uint8_t instance_id)
{
#if DEBUG
bool found = false;
#endif
v = constrain(v, 0, MAX_VOICES - 1);
b = constrain(b, 0, MAX_BANKS - 1);
if (sd_card > 0)
{
File sysex;
char sysex_setup_file_name[SYSEXFILENAME_LEN];
char sysex_config_filename[FILENAME_LEN];
create_sysex_setup_filename(b, v, sysex_setup_file_name);
sprintf(sysex_config_filename, "/%d/config%d.syx", b, v);
sysex = SD.open(sysex_setup_file_name);
#ifdef DEBUG
Serial.print(F("saving config "));
Serial.print(b);
Serial.print(F("/"));
Serial.print(v);
Serial.print(F("["));
Serial.print(instance_id);
Serial.print(F("]"));
Serial.print(F(" to "));
Serial.println(sysex_config_filename);
#endif
sysex = SD.open(sysex_config_filename, FILE_WRITE);
if (!sysex)
{
#ifdef DEBUG
Serial.print(F("E : Cannot open "));
Serial.print(sysex_setup_file_name);
Serial.println(F("from SD."));
Serial.print(sysex_config_filename);
Serial.println(F(" on SD."));
#endif
return (false);
}
if (get_sysex_setup(sysex, configuration))
if (write_sysex_config(sysex, configuration))
{
#ifdef DEBUG
Serial.print(F("Loading sysex setup "));
Serial.print(sysex_setup_file_name);
Serial.print(F(" ["));
Serial.print(voice_names[instance_id][v]);
Serial.println(F("]"));
#endif
return (true);
}
#ifdef DEBUG
@ -515,36 +537,6 @@ bool load_sysex_setup(uint8_t b, uint8_t v, uint8_t instance_id)
Serial.println(F("E : Cannot load setup data"));
#endif
}
#ifdef DEBUG
if (found == false)
Serial.println(F("E : File not found."));
#endif
return (false);
}
bool save_sysex_setup(uint8_t b, uint8_t v, config_t configuration)
{
const char* sysex_filename = "config.syx";
if (sd_card > 0)
{
File sysex;
char sysex_file_name[20];
create_sysex_filename(b, sysex_file_name, v);
sysex = SD.open(sysex_file_name);
if (!sysex)
{
#ifdef DEBUG
Serial.print(F("E : Cannot create "));
Serial.print(sysex_file_name);
Serial.println(F("on SD."));
#endif
return (false);
}
}
return (false);
}

@ -29,8 +29,6 @@
#ifndef DEXED_SYSEX_H_INCLUDED
#define DEXED_SYSEX_H_INCLUDED
#define SYSEXFILENAME_LEN 10
extern uint8_t sd_card;
extern Dexed* dexed;
extern AudioSourceMicroDexed * MicroDexed[NUM_DEXED];
@ -46,7 +44,7 @@ extern uint8_t ui_main_state;
extern config_t configuration;
extern uint32_t crc32(byte * calc_start, uint16_t calc_bytes);
void create_sysex_filename(uint8_t b, char* sysex_file_name);
void create_sysex_bankfilename(char* filename, uint8_t b, uint8_t instance_id);
void strip_extension(char* s, char *target);
bool get_voice_names_from_bank(uint8_t b, uint8_t i);
uint8_t get_bank_names(uint8_t instance_id);
@ -54,8 +52,8 @@ bool get_bank_voice_name(uint8_t b, uint8_t v);
bool load_sysex(uint8_t b, uint8_t v, uint8_t instance_id);
bool get_sysex_voice(File sysex, uint8_t voice_number, uint8_t* data);
void create_sysex_setup_filename(uint8_t b, uint8_t v, char* sysex_setup_file_name);
bool get_sysex_setup(File sysex, uint8_t voice_number, uint8_t* data);
bool load_sysex_setup(uint8_t b, uint8_t v, uint8_t instance_id);
bool save_sysex_setup(uint8_t b, uint8_t v, config_t configuration);
bool write_sysex_config(File sysex, config_t configuration);
bool load_sysex_config(uint8_t b, uint8_t v, uint8_t instance_id);
bool save_sysex_config(uint8_t b, uint8_t v, uint8_t instance_id);
#endif

@ -6,13 +6,7 @@ SYSEX Message Controller-Set
11110000 F0 Status byte - start sysex
0iiiiiii 67 ID # (i=103; unofficial SYSEX-ID for MicroDexed)
0sssnnnn 00 Sub-status (s=0) & channel number (n=0; ch 1)
0fffffff ** format number (f=66..69; 1..4 MicroDexed setup(s))
0bbbbbbb ** byte count MS byte
0bbbbbbb ** byte count LS byte (b=44; 1 instance
b=75; 2 instances
b=106; 3 instances
b=137; 4 instances)
0ddddddd ** data byte 1 setup config
| | |

@ -1928,13 +1928,6 @@ void LCDMenuLib2::FUNC_disableScreensaver(void)
bitSet(REG_special, _LCDML_REG_special_disable_screensaver);
}
/* ******************************************************************** */
void LCDMenuLib2::FUNC_setGBAToLastCursorPos(uint8_t p)
/* ******************************************************************** */
{
actMenu_lastCursorPositionID=p;
}
/* ******************************************************************** */
void LCDMenuLib2::FUNC_setGBAToLastCursorPos(void)
/* ******************************************************************** */
@ -1949,13 +1942,6 @@ void LCDMenuLib2::FUNC_setGBAToLastCursorPos(void)
bitSet(REG_MenuFunction, _LCDML_REG_MenuFunction_setCursorToID);
}
/* ******************************************************************** */
void LCDMenuLib2::FUNC_setGBAToLastFunc(uint8_t p)
/* ******************************************************************** */
{
actMenu_lastFuncID=p;
}
/* ******************************************************************** */
void LCDMenuLib2::FUNC_setGBAToLastFunc(void)
/* ******************************************************************** */

@ -368,9 +368,7 @@
void FUNC_setLoopInterval(unsigned long p_t); // set a loop intervall for the current menu function the default loop intervall is 100000000 ms
void FUNC_disableScreensaver(void); // disable the screensaver for the current menu function
void FUNC_setGBAToLastCursorPos(void); // set a special "go back handling"
void FUNC_setGBAToLastCursorPos(uint8_t p); // set a special "go back handling"
void FUNC_setGBAToLastFunc(void); // set a special "go back handling"
void FUNC_setGBAToLastFunc(uint8_t p); // set a special "go back handling"
void FUNC_setGBA(void); // set a special "go back handling" which decide between the two function above
// timer methods

Loading…
Cancel
Save