Started reading/writing sysex-setup data.

Menu extended for setup data.
pull/11/head
Holger Wirtz 5 years ago
parent ca563505ea
commit 0acde384fc
  1. 138
      UI.hpp
  2. 156
      dexed_sysex.cpp
  3. 4
      dexed_sysex.h

138
UI.hpp

@ -148,6 +148,7 @@ void UI_func_information(uint8_t param);
void UI_func_voice_selection(uint8_t param); void UI_func_voice_selection(uint8_t param);
void UI_func_volume(uint8_t param); void UI_func_volume(uint8_t param);
void UI_function_not_enabled(void); void UI_function_not_enabled(void);
void UI_function_not_implemented(void);
void lcd_display_int(int16_t var, uint8_t size, bool zeros, bool brackets, bool sign); void lcd_display_int(int16_t var, uint8_t size, bool zeros, bool brackets, bool sign);
void lcd_display_float(float var, uint8_t size_number, uint8_t size_fraction, bool zeros, bool brackets, bool sign); void lcd_display_float(float var, uint8_t size_number, uint8_t size_fraction, bool zeros, bool brackets, bool sign);
@ -156,34 +157,91 @@ LCDMenuLib2_menu LCDML_0(255, 0, 0, NULL, NULL); // normal root menu element (do
LCDMenuLib2 LCDML(LCDML_0, _LCDML_DISP_rows, _LCDML_DISP_cols, lcdml_menu_display, lcdml_menu_clear, lcdml_menu_control); LCDMenuLib2 LCDML(LCDML_0, _LCDML_DISP_rows, _LCDML_DISP_cols, lcdml_menu_display, lcdml_menu_clear, lcdml_menu_control);
// LCDML_add(id, prev_layer, new_num, lang_char_array, callback_function) // LCDML_add(id, prev_layer, new_num, lang_char_array, callback_function)
LCDML_add(0, LCDML_0, 1, "Sound", UI_func_sound); LCDML_add(0, LCDML_0, 1, "Setup", NULL);
LCDML_add(1, LCDML_0, 2, "Effect", NULL); LCDML_add(1, LCDML_0_1, 1, "Instances", UI_function_not_implemented);
LCDML_add(2, LCDML_0_2, 1, "Reverb", NULL); LCDML_add(2, LCDML_0_1, 2, "Instance 1", NULL);
LCDML_add(3, LCDML_0_2_1, 1, "Roomsize", UI_func_reverb_roomsize); LCDML_add(3, LCDML_0_1_2, 1, "Mono/Poly 1", UI_function_not_implemented);
LCDML_add(4, LCDML_0_2_1, 2, "Damping", UI_func_reverb_damping); LCDML_add(4, LCDML_0_1_2, 2, "Pitchbend 1", NULL);
LCDML_add(5, LCDML_0_2_1, 3, "Level", UI_func_reverb_level); LCDML_add(5, LCDML_0_1_2_2, 1, "PB Range 1", UI_function_not_implemented);
LCDML_add(6, LCDML_0_2, 2, "Chorus", NULL); LCDML_add(6, LCDML_0_1_2_2, 2, "PB Step 1", UI_function_not_implemented);
LCDML_add(7, LCDML_0_2_2, 1, "Frequency", UI_func_chorus_frequency); LCDML_add(7, LCDML_0_1_2, 3, "Mod Wheel 1", NULL);
LCDML_add(8, LCDML_0_2_2, 2, "Waveform", UI_func_chorus_waveform); LCDML_add(8, LCDML_0_1_2_3, 1, "MW Range 1", UI_function_not_implemented);
LCDML_add(9, LCDML_0_2_2, 3, "Depth", UI_func_chorus_depth); LCDML_add(9, LCDML_0_1_2_3, 2, "MW Assign 1", UI_function_not_implemented);
LCDML_add(10, LCDML_0_2_2, 4, "Level", UI_func_chorus_level); LCDML_add(10, LCDML_0_1_2, 4, "Foot Ctrl 1", NULL);
LCDML_add(11, LCDML_0_2, 3, "Delay", NULL); LCDML_add(11, LCDML_0_1_2_4, 1, "FC Range 1", UI_function_not_implemented);
LCDML_add(12, LCDML_0_2_3, 1, "Time", UI_func_delay_time); LCDML_add(12, LCDML_0_1_2_4, 2, "FC Assign 1", UI_function_not_implemented);
LCDML_add(13, LCDML_0_2_3, 2, "Feedback", UI_func_delay_feedback); LCDML_add(13, LCDML_0_1_2, 5, "Breath Ctrl 1", NULL);
LCDML_add(14, LCDML_0_2_3, 3, "Level", UI_func_delay_level); LCDML_add(14, LCDML_0_1_2_5, 1, "BC Range 1", UI_function_not_implemented);
LCDML_add(15, LCDML_0_2, 4, "Filter", NULL); LCDML_add(15, LCDML_0_1_2_5, 2, "BC Assign 1", UI_function_not_implemented);
LCDML_add(16, LCDML_0_2_4, 1, "Cutoff", UI_func_filter_cutoff); LCDML_add(16, LCDML_0_1_2, 6, "Aftertouch 1", NULL);
LCDML_add(17, LCDML_0_2_4, 2, "Resonance", UI_func_filter_resonance); LCDML_add(17, LCDML_0_1_2_6, 1, "AT Range 1", UI_function_not_implemented);
LCDML_add(18, LCDML_0, 3, "Store", NULL); LCDML_add(18, LCDML_0_1_2_6, 2, "AT Assign 1", UI_function_not_implemented);
LCDML_add(19, LCDML_0, 4, "System", NULL); LCDML_add(19, LCDML_0_1_2, 7, "Portamento 1", NULL);
LCDML_add(20, LCDML_0_4, 1, "MIDI Channel", UI_func_midi_channel); LCDML_add(20, LCDML_0_1_2_7, 1, "Port. Mode 1", UI_function_not_enabled);
LCDML_add(21, LCDML_0_4, 2, "Loudness", UI_func_loudness); LCDML_add(21, LCDML_0_1_2_7, 2, "Port. Gliss 1", UI_function_not_enabled);
LCDML_add(22, LCDML_0_4, 3, "Panorama", UI_func_panorama); LCDML_add(22, LCDML_0_1_2_7, 3, "Port. Time 1", UI_function_not_enabled);
LCDML_add(23, LCDML_0_4, 4, "Stereo/Mono", UI_func_stereo_mono); LCDML_add(23, LCDML_0_1_2, 8, "Operator 1", NULL);
LCDML_add(24, LCDML_0_4, 5, "Polyphony", UI_func_polyphony); LCDML_add(24, LCDML_0_1_2_8, 1, "OP1 1", UI_function_not_implemented);
LCDML_add(25, LCDML_0_4, 6, "Engine", UI_func_engine); LCDML_add(25, LCDML_0_1_2_8, 2, "OP2 1", UI_function_not_implemented);
LCDML_add(26, LCDML_0, 5, "Info", UI_func_information); LCDML_add(26, LCDML_0_1_2_8, 3, "OP3 1", UI_function_not_implemented);
#define _LCDML_DISP_cnt 26 LCDML_add(27, LCDML_0_1_2_8, 4, "OP4 1", UI_function_not_implemented);
LCDML_add(28, LCDML_0_1_2_8, 5, "OP5 1", UI_function_not_implemented);
LCDML_add(29, LCDML_0_1_2_8, 6, "OP6 1", UI_function_not_implemented);
LCDML_add(30, LCDML_0_1, 3, "Instance 2", NULL);
LCDML_add(31, LCDML_0_1_3, 1, "Mono/Poly 2", UI_function_not_implemented);
LCDML_add(32, LCDML_0_1_3, 2, "Pitchbend 2", NULL);
LCDML_add(33, LCDML_0_1_3_2, 1, "PB Range 2", UI_function_not_implemented);
LCDML_add(34, LCDML_0_1_3_2, 2, "PB Step 2", UI_function_not_implemented);
LCDML_add(35, LCDML_0_1_3, 3, "Mod Wheel 2", NULL);
LCDML_add(36, LCDML_0_1_3_3, 1, "MW Range 2", UI_function_not_implemented);
LCDML_add(37, LCDML_0_1_3_3, 2, "MW Assign 2", UI_function_not_implemented);
LCDML_add(38, LCDML_0_1_3, 4, "Foot Ctrl 2", NULL);
LCDML_add(39, LCDML_0_1_3_4, 1, "FC Range 2", UI_function_not_implemented);
LCDML_add(40, LCDML_0_1_3_4, 2, "FC Assign 2", UI_function_not_implemented);
LCDML_add(41, LCDML_0_1_3, 5, "Breat Ctrl 2", NULL);
LCDML_add(42, LCDML_0_1_3_5, 1, "BC Range 2", UI_function_not_implemented);
LCDML_add(43, LCDML_0_1_3_5, 2, "BC Assign 2", UI_function_not_implemented);
LCDML_add(44, LCDML_0_1_3, 6, "Aftertouch 2", NULL);
LCDML_add(45, LCDML_0_1_3_6, 1, "AT Range 2", UI_function_not_implemented);
LCDML_add(46, LCDML_0_1_3_6, 2, "AT Assign 2", UI_function_not_implemented);
LCDML_add(47, LCDML_0_1_3, 7, "Portamento 2", NULL);
LCDML_add(48, LCDML_0_1_3_7, 1, "Port. Mode 2", UI_function_not_enabled);
LCDML_add(49, LCDML_0_1_3_7, 2, "Port. Gliss 2", UI_function_not_enabled);
LCDML_add(50, LCDML_0_1_3_7, 3, "Port. Time 2", UI_function_not_enabled);
LCDML_add(51, LCDML_0_1_3, 8, "Operator 2", NULL);
LCDML_add(52, LCDML_0_1_3_8, 1, "OP1 2", UI_function_not_implemented);
LCDML_add(53, LCDML_0_1_3_8, 2, "OP2 2", UI_function_not_implemented);
LCDML_add(54, LCDML_0_1_3_8, 3, "OP3 2", UI_function_not_implemented);
LCDML_add(55, LCDML_0_1_3_8, 4, "OP4 2", UI_function_not_implemented);
LCDML_add(56, LCDML_0_1_3_8, 5, "OP5 2", UI_function_not_implemented);
LCDML_add(57, LCDML_0_1_3_8, 6, "OP6 2", UI_function_not_implemented);
LCDML_add(58, LCDML_0, 2, "Effect", NULL);
LCDML_add(59, LCDML_0_2, 1, "Reverb", NULL);
LCDML_add(60, LCDML_0_2_1, 1, "Roomsize", UI_func_reverb_roomsize);
LCDML_add(61, LCDML_0_2_1, 2, "Damping", UI_func_reverb_damping);
LCDML_add(62, LCDML_0_2_1, 3, "Level", UI_func_reverb_level);
LCDML_add(63, LCDML_0_2, 2, "Chorus", NULL);
LCDML_add(64, LCDML_0_2_2, 1, "Frequency", UI_func_chorus_frequency);
LCDML_add(65, LCDML_0_2_2, 2, "Waveform", UI_func_chorus_waveform);
LCDML_add(66, LCDML_0_2_2, 3, "Depth", UI_func_chorus_depth);
LCDML_add(67, LCDML_0_2_2, 4, "Level", UI_func_chorus_level);
LCDML_add(68, LCDML_0_2, 3, "Delay", NULL);
LCDML_add(69, LCDML_0_2_3, 1, "Time", UI_func_delay_time);
LCDML_add(70, LCDML_0_2_3, 2, "Feedback", UI_func_delay_feedback);
LCDML_add(71, LCDML_0_2_3, 3, "Level", UI_func_delay_level);
LCDML_add(72, LCDML_0_2, 4, "Filter", NULL);
LCDML_add(73, LCDML_0_2_4, 1, "Cutoff", UI_func_filter_cutoff);
LCDML_add(74, LCDML_0_2_4, 2, "Resonance", UI_func_filter_resonance);
LCDML_add(75, LCDML_0, 3, "Store", NULL);
LCDML_add(76, LCDML_0, 4, "System", NULL);
LCDML_add(77, LCDML_0_4, 1, "MIDI Channel", UI_func_midi_channel);
LCDML_add(78, LCDML_0_4, 2, "Loudness", UI_func_loudness);
LCDML_add(79, LCDML_0_4, 3, "Panorama", UI_func_panorama);
LCDML_add(80, LCDML_0_4, 4, "Stereo/Mono", UI_func_stereo_mono);
LCDML_add(81, LCDML_0_4, 5, "Polyphony", UI_func_polyphony);
LCDML_add(82, LCDML_0_4, 6, "Engine", UI_func_engine);
LCDML_add(83, LCDML_0, 5, "Info", UI_func_information);
#define _LCDML_DISP_cnt 83
// create menu // create menu
LCDML_createMenu(_LCDML_DISP_cnt); LCDML_createMenu(_LCDML_DISP_cnt);
@ -1778,6 +1836,30 @@ void UI_function_not_enabled(void)
} }
} }
void UI_function_not_implemented(void)
{
if (LCDML.FUNC_setup()) // ****** SETUP *********
{
// setup function
lcd.setCursor(0, 0);
lcd.print(F("Function not"));
lcd.setCursor(0, 1);
lcd.print(F("implemented!"));
}
if (LCDML.FUNC_loop()) // ****** LOOP *********
{
if (LCDML.BT_checkEnter())
{
LCDML.FUNC_goBackToMenu();
}
}
if (LCDML.FUNC_close()) // ****** STABLE END *********
{
// you can here reset some global vars or do nothing
}
}
void lcd_display_int(int16_t var, uint8_t size, bool zeros, bool brackets, bool sign) void lcd_display_int(int16_t var, uint8_t size, bool zeros, bool brackets, bool sign)
{ {
int16_t tmp = 0; int16_t tmp = 0;

@ -248,10 +248,7 @@ bool load_sysex(uint8_t b, uint8_t v)
if (get_sysex_voice(sysex, v, data)) if (get_sysex_voice(sysex, v, data))
{ {
#ifdef DEBUG #ifdef DEBUG
//char n[11]; Serial.print(F("Loading sysex "));
//strncpy(n, (char*)&data[118], 10);
Serial.print("Loading sysex ");
Serial.print(sysex_file_name); Serial.print(sysex_file_name);
Serial.print(F(" [")); Serial.print(F(" ["));
Serial.print(voice_names[v]); Serial.print(voice_names[v]);
@ -353,3 +350,154 @@ bool get_sysex_voice(File sysex, uint8_t voice_number, uint8_t* data)
return (true); return (true);
} }
void create_sysex_setup_filename(uint8_t b, uint8_t v, char* sysex_setup_file_name)
{
// init and set name for actual bank
memset(sysex_setup_file_name, 0, sizeof(sysex_setup_file_name));
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
}
bool get_sysex_setup(File sysex, config_t configuration)
{
uint16_t n;
int32_t bulk_checksum_calc = 0;
int8_t bulk_checksum;
if (sysex.size() != 47 || sysex.size() != 78) // check sysex size
{
#ifdef DEBUG
Serial.println(F("E : SysEx file size wrong."));
#endif
return (false);
}
if (sysex.read() != 0xf0) // check sysex start-byte
{
#ifdef DEBUG
Serial.println(F("E : SysEx start byte not found."));
#endif
return (false);
}
if (sysex.read() != 0x67) // check sysex vendor is unofficial SYSEX-ID for MicroDexed
{
#ifdef DEBUG
Serial.println(F("E : SysEx vendor not unofficial SYSEX-ID for MicroDexed."));
#endif
return (false);
}
sysex.seek(sysex.size());
if (sysex.read() != 0xf7) // check sysex end-byte
{
#ifdef DEBUG
Serial.println(F("E : SysEx end byte not found."));
#endif
return (false);
}
sysex.seek(3);
if (sysex.read() != 0x4b) // check for sysex type (0x75=MicroDexed setup)
{
#ifdef DEBUG
Serial.println(F("E : SysEx type not MicroDexed setup."));
#endif
return (false);
}
sysex.seek(sysex.size() - 1); // Bulk checksum
bulk_checksum = sysex.read();
sysex.seek(6); // start of bulk data
for (n = 0; n < sysex.size() - 2; n++)
{
uint8_t d = sysex.read();
#ifdef DEBUG
Serial.print(n + 6, DEC);
Serial.print(F("="));
Serial.println(d);
#endif
bulk_checksum_calc -= d;
}
bulk_checksum_calc &= 0x7f;
#ifdef DEBUG
Serial.print(F("Bulk checksum : 0x"));
Serial.print(bulk_checksum_calc, HEX);
Serial.print(F(" [0x"));
Serial.print(bulk_checksum, HEX);
Serial.println(F("]"));
#endif
if (bulk_checksum_calc != bulk_checksum)
{
#ifdef DEBUG
Serial.print(F("E : Bulk checksum mismatch : 0x"));
Serial.print(bulk_checksum_calc, HEX);
Serial.print(F(" != 0x"));
Serial.println(bulk_checksum, HEX);
#endif
return (false);
}
return (true);
}
bool load_sysex_setup(uint8_t b, uint8_t v)
{
#if DEBUG
bool found = false;
#endif
v %= MAX_VOICES;
b %= MAX_BANKS;
if (sd_card_available)
{
File sysex;
char sysex_setup_file_name[10];
create_sysex_setup_filename(b, v, sysex_setup_file_name);
sysex = SD.open(sysex_setup_file_name);
if (!sysex)
{
#ifdef DEBUG
Serial.print(F("E : Cannot open "));
Serial.print(sysex_setup_file_name);
Serial.println(F("from SD."));
#endif
return (false);
}
if (get_sysex_setup(sysex, configuration))
{
#ifdef DEBUG
Serial.print(F("Loading sysex setup "));
Serial.print(sysex_setup_file_name);
Serial.print(F(" ["));
Serial.print(voice_names[v]);
Serial.println(F("]"));
#endif
return (true);
}
#ifdef DEBUG
else
Serial.println(F("E : Cannot load setup data"));
#endif
}
#ifdef DEBUG
if (found == false)
Serial.println(F("E : File not found."));
#endif
return (false);
}

@ -41,6 +41,7 @@ extern char bank_names[MAX_BANKS][BANK_NAME_LEN];
extern char voice_names[MAX_VOICES][VOICE_NAME_LEN]; extern char voice_names[MAX_VOICES][VOICE_NAME_LEN];
extern uint8_t ui_state; extern uint8_t ui_state;
extern uint8_t ui_main_state; extern uint8_t ui_main_state;
extern config_t configuration;
void create_sysex_filename(uint8_t b, char* sysex_file_name); void create_sysex_filename(uint8_t b, char* sysex_file_name);
void strip_extension(char* s, char *target); void strip_extension(char* s, char *target);
@ -49,5 +50,8 @@ uint8_t get_bank_names(void);
bool get_bank_voice_name(uint8_t b, uint8_t v); bool get_bank_voice_name(uint8_t b, uint8_t v);
bool load_sysex(uint8_t b, uint8_t v); bool load_sysex(uint8_t b, uint8_t v);
bool get_sysex_voice(File sysex, uint8_t voice_number, uint8_t* data); 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);
#endif #endif

Loading…
Cancel
Save