diff --git a/MicroDexed.ino b/MicroDexed.ino index 0603bb6..d996c9d 100644 --- a/MicroDexed.ino +++ b/MicroDexed.ino @@ -194,12 +194,6 @@ void create_audio_connections(AudioSourceMicroDexed &dexed, AudioEffectMonoStere uint8_t sd_card = 0; Sd2Card card; SdVolume volume; -uint8_t max_loaded_banks = 0; -char bank_name[NUM_DEXED][BANK_NAME_LEN]; -char voice_name[NUM_DEXED][VOICE_NAME_LEN]; -char bank_names[NUM_DEXED][MAX_BANKS][BANK_NAME_LEN]; -char voice_names[NUM_DEXED][MAX_VOICES][VOICE_NAME_LEN]; -uint8_t dexed_setup_number = 1; uint8_t midi_timing_counter = 0; // 24 per qarter elapsedMillis midi_timing_timestep; uint16_t midi_timing_quarter = 0; @@ -375,11 +369,6 @@ void setup() #ifdef DEBUG Serial.println(F("SD card not accessable.")); #endif - for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) - { - strcpy(bank_name[instance_id], "Default"); - strcpy(voice_name[instance_id], "Default"); - } } else { @@ -387,30 +376,6 @@ void setup() for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) { - // read all bank names - max_loaded_banks = get_bank_names(instance_id); - strip_extension(bank_names[instance_id][configuration.performance.bank[instance_id]], bank_name[instance_id]); - - // read all voice name for actual bank - get_voice_names_from_bank(configuration.performance.bank[instance_id], instance_id); -#ifdef DEBUG - Serial.print(F("Bank [")); - Serial.print(bank_names[instance_id][configuration.performance.bank[instance_id]]); - Serial.print(F("/")); - Serial.print(bank_name[instance_id]); - Serial.println(F("]")); - for (uint8_t n = 0; n < MAX_VOICES - 1; n++) - { - if (n < 10) - Serial.print(F(" ")); - Serial.print(F(" ")); - Serial.print(n, DEC); - Serial.print(F("[")); - Serial.print(voice_names[instance_id][n]); - Serial.println(F("]")); - } -#endif - // load default SYSEX data load_sd_voice(configuration.performance.bank[instance_id], configuration.performance.voice[instance_id], instance_id); } @@ -986,13 +951,13 @@ void handleSystemExclusive(byte * sysex, uint len) // load sysex-data into voice memory MicroDexed[instance_id]->loadVoiceParameters(&sysex[6]); - //MicroDexed[instance_id]->initGlobalParameters(); - // manipulate UI names and numbers - strncpy(voice_name[instance_id], (char *)&sysex[151], sizeof(voice_name[instance_id]) - 1); - Serial.print(F("Got voice [")); - Serial.print(voice_name[instance_id]); - Serial.println(F("].")); + /* + // manipulate UI names and numbers + strncpy(voice_name[instance_id], (char *)&sysex[151], sizeof(voice_name[instance_id]) - 1); + Serial.print(F("Got voice [")); + Serial.print(voice_name[instance_id]); + Serial.println(F("]."));*/ } #ifdef DEBUG else @@ -1245,7 +1210,7 @@ void check_configuration(void) configuration.sys.mono = constrain(configuration.sys.mono, MONO_MIN, MONO_MAX); configuration.sys.soft_midi_thru = constrain(configuration.sys.soft_midi_thru, SOFT_MIDI_THRU_MIN, SOFT_MIDI_THRU_MAX); configuration.sys.performance_number = constrain(configuration.sys.performance_number, PERFORMANCE_NUM_MIN, PERFORMANCE_NUM_MAX); - + configuration.performance.fx_number = constrain(configuration.performance.fx_number, FX_NUM_MIN, FX_NUM_MAX); configuration.fx.reverb_roomsize = constrain(configuration.fx.reverb_roomsize, REVERB_ROOMSIZE_MIN, REVERB_ROOMSIZE_MAX); @@ -1337,10 +1302,9 @@ void init_configuration(void) configuration.fx.delay_feedback = DELAY_FEEDBACK_DEFAULT; configuration.fx.delay_level = DELAY_LEVEL_DEFAULT; - //configuration.performance.checksum = 0xffff; configuration.performance.fx_number = FX_NUM_DEFAULT; - for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) + for (uint8_t instance_id = 0; instance_id < MAX_DEXED; instance_id++) { configuration.performance.bank[instance_id] = SYSEXBANK_DEFAULT; configuration.performance.voice[instance_id] = SYSEXSOUND_DEFAULT; @@ -1828,8 +1792,8 @@ void check_and_create_directories(void) } } #ifdef DEBUG -#else - Serial.println(F("No SD card for directory check available.")); + else + Serial.println(F("No SD card for directory check available.")); #endif } diff --git a/UI.hpp b/UI.hpp index 023443f..727ac88 100644 --- a/UI.hpp +++ b/UI.hpp @@ -47,15 +47,7 @@ #define _LCDML_DISP_cfg_scrollbar 1 // enable a scrollbar extern config_t configuration; -extern uint8_t dexed_setup_number; extern void set_volume(uint8_t v, uint8_t m); -extern char bank_names[NUM_DEXED][MAX_BANKS][BANK_NAME_LEN]; -extern char bank_name[NUM_DEXED][BANK_NAME_LEN]; -extern char voice_name[NUM_DEXED][VOICE_NAME_LEN]; -extern char voice_names[NUM_DEXED][MAX_VOICES][VOICE_NAME_LEN]; -extern void strip_extension(char* s, char *target); -//extern void eeprom_write(void); -extern bool get_voice_names_from_bank(uint8_t b, uint8_t instance_id); extern bool load_sysex(uint8_t b, uint8_t v); extern void generate_version_string(char* buffer, uint8_t len); extern void initial_values_from_eeprom(bool init); @@ -3197,7 +3189,7 @@ void UI_func_eeprom_reset(uint8_t param) void UI_func_voice_select(uint8_t param) { uint8_t instance_id = 0; - static uint8_t menu_voice_select = MENU_VOICE_SOUND; + static uint8_t menu_voice_select = MENU_VOICE_SOUND; if (LCDML.FUNC_getID() > MENU_ID_OF_INSTANCE_2) instance_id = 1; @@ -3206,12 +3198,18 @@ void UI_func_voice_select(uint8_t param) { encoderDir[ENC_R].reset(); - strip_extension(bank_names[instance_id][configuration.performance.bank[instance_id]], bank_name[instance_id]); + char bank_name[BANK_NAME_LEN]; + char voice_name[VOICE_NAME_LEN]; + + if (!get_bank_name(configuration.performance.bank[instance_id], bank_name, sizeof(bank_name))) + strncpy(bank_name, "*ERROR*", sizeof(bank_name)); + if (!get_voice_by_bank_name(configuration.performance.bank[instance_id], bank_name, configuration.performance.voice[instance_id], voice_name, sizeof(voice_name))) + strncpy(voice_name, "*ERROR*", sizeof(voice_name)); lcd.show(0, 0, 2, configuration.performance.bank[instance_id]); lcd.show(1, 0, 2, configuration.performance.voice[instance_id] + 1); - lcd.show(0, 4, 10, bank_name[instance_id]); - lcd.show(1, 4, 10, voice_names[instance_id][configuration.performance.voice[instance_id]]); + lcd.show(0, 4, 10, bank_name); + lcd.show(1, 4, 10, voice_name); switch (menu_voice_select) { @@ -3232,12 +3230,16 @@ void UI_func_voice_select(uint8_t param) if (LCDML.FUNC_loop()) // ****** LOOP ********* { + char bank_name[BANK_NAME_LEN]; + char voice_name[VOICE_NAME_LEN]; + if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up()) || (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort())) { uint8_t bank_tmp; int8_t voice_tmp; if (LCDML.BT_checkUp()) + { switch (menu_voice_select) { case MENU_VOICE_BANK: @@ -3247,7 +3249,6 @@ void UI_func_voice_select(uint8_t param) change_disp_sd(false); #endif load_sd_voice(configuration.performance.bank[instance_id], configuration.performance.voice[instance_id], instance_id); - get_voice_names_from_bank(configuration.performance.bank[instance_id], instance_id); #ifdef DISPLAY_LCD_SPI change_disp_sd(true); #endif @@ -3265,18 +3266,18 @@ void UI_func_voice_select(uint8_t param) } if (voice_tmp < 0) voice_tmp = MAX_VOICES + voice_tmp; - configuration.performance.voice[instance_id] = voice_tmp; + configuration.performance.voice[instance_id] = constrain(voice_tmp, 0, MAX_VOICES - 1); #ifdef DISPLAY_LCD_SPI change_disp_sd(false); #endif load_sd_voice(configuration.performance.bank[instance_id], configuration.performance.voice[instance_id], instance_id); - get_voice_names_from_bank(configuration.performance.bank[instance_id], instance_id); #ifdef DISPLAY_LCD_SPI change_disp_sd(true); #endif break; } + } else if (LCDML.BT_checkDown()) { switch (menu_voice_select) @@ -3288,7 +3289,6 @@ void UI_func_voice_select(uint8_t param) change_disp_sd(false); #endif load_sd_voice(configuration.performance.bank[instance_id], configuration.performance.voice[instance_id], instance_id); - get_voice_names_from_bank(configuration.performance.bank[instance_id], instance_id); #ifdef DISPLAY_LCD_SPI change_disp_sd(true); #endif @@ -3305,18 +3305,16 @@ void UI_func_voice_select(uint8_t param) { voice_tmp = MAX_VOICES - 1; } - configuration.performance.voice[instance_id] = voice_tmp; + configuration.performance.voice[instance_id] = constrain(voice_tmp, 0, MAX_VOICES - 1); #ifdef DISPLAY_LCD_SPI change_disp_sd(false); #endif load_sd_voice(configuration.performance.bank[instance_id], configuration.performance.voice[instance_id], instance_id); - get_voice_names_from_bank(configuration.performance.bank[instance_id], instance_id); #ifdef DISPLAY_LCD_SPI change_disp_sd(true); #endif break; - } } else if (LCDML.BT_checkEnter()) @@ -3326,29 +3324,32 @@ void UI_func_voice_select(uint8_t param) else menu_voice_select = MENU_VOICE_BANK; } + } - strip_extension(bank_names[instance_id][configuration.performance.bank[instance_id]], bank_name[instance_id]); + if (!get_bank_name(configuration.performance.bank[instance_id], bank_name, sizeof(bank_name))) + strncpy(bank_name, "*ERROR*", sizeof(bank_name)); + if (!get_voice_by_bank_name(configuration.performance.bank[instance_id], bank_name, configuration.performance.voice[instance_id], voice_name, sizeof(voice_name))) + strncpy(voice_name, "*ERROR*", sizeof(voice_name)); - lcd.show(0, 0, 2, configuration.performance.bank[instance_id]); - lcd.show(1, 0, 2, configuration.performance.voice[instance_id] + 1); - lcd.show(0, 4, 10, bank_name[instance_id]); - lcd.show(1, 4, 10, voice_names[instance_id][configuration.performance.voice[instance_id]]); + lcd.show(0, 0, 2, configuration.performance.bank[instance_id]); + lcd.show(1, 0, 2, configuration.performance.voice[instance_id] + 1); + lcd.show(0, 4, 10, bank_name); + lcd.show(1, 4, 10, voice_name); - switch (menu_voice_select) - { - case MENU_VOICE_BANK: - lcd.show(0, 2, 2, " ["); - lcd.show(0, 14, 1, "]"); - lcd.show(1, 2, 2, " "); - lcd.show(1, 14, 1, " "); - break; - case MENU_VOICE_SOUND: - lcd.show(0, 2, 2, " "); - lcd.show(0, 14, 1, " "); - lcd.show(1, 2, 2, " ["); - lcd.show(1, 14, 1, "]"); - break; - } + switch (menu_voice_select) + { + case MENU_VOICE_BANK: + lcd.show(0, 2, 2, " ["); + lcd.show(0, 14, 1, "]"); + lcd.show(1, 2, 2, " "); + lcd.show(1, 14, 1, " "); + break; + case MENU_VOICE_SOUND: + lcd.show(0, 2, 2, " "); + lcd.show(0, 14, 1, " "); + lcd.show(1, 2, 2, " ["); + lcd.show(1, 14, 1, "]"); + break; } } diff --git a/config.h b/config.h index b871419..9b3c6ee 100644 --- a/config.h +++ b/config.h @@ -224,7 +224,7 @@ #define MAX_FX 99 #define MAX_PERFORMANCE 99 #define MAX_VOICECONFIG 99 -#define BANK_NAME_LEN 13 // FAT12 filenames (plus '\0') +#define BANK_NAME_LEN 11 // 10 (plus '\0') #define VOICE_NAME_LEN 11 // 10 (plus '\0') #define FILENAME_LEN BANK_NAME_LEN + VOICE_NAME_LEN diff --git a/dexed_sd.cpp b/dexed_sd.cpp index fd984ce..aaa7926 100644 --- a/dexed_sd.cpp +++ b/dexed_sd.cpp @@ -46,9 +46,11 @@ bool load_sd_voice(uint8_t b, uint8_t v, uint8_t instance_id) { File sysex; char filename[FILENAME_LEN]; + char bank_name[BANK_NAME_LEN]; uint8_t data[128]; - sprintf(filename, "/%d/%s", b, bank_names[instance_id][b]); + get_bank_name(b, bank_name, sizeof(bank_name)); + sprintf(filename, "/%d/%s.syx", b, bank_name); sysex = SD.open(filename); if (!sysex) @@ -64,10 +66,12 @@ bool load_sd_voice(uint8_t b, uint8_t v, uint8_t instance_id) if (get_sd_voice(sysex, v, data)) { #ifdef DEBUG + char voice_name[VOICE_NAME_LEN]; + get_voice_name(b, v, voice_name, sizeof(voice_name)); Serial.print(F("Loading voice from ")); Serial.print(filename); Serial.print(F(" [")); - Serial.print(voice_names[instance_id][v]); + Serial.print(voice_name); Serial.println(F("]")); #endif bool ret = MicroDexed[instance_id]->decodeVoice(data); @@ -83,6 +87,7 @@ bool load_sd_voice(uint8_t b, uint8_t v, uint8_t instance_id) else Serial.println(F("E : Cannot load voice data")); #endif + sysex.close(); } #ifdef DEBUG if (found == false) @@ -615,25 +620,9 @@ uint8_t calc_checksum(uint8_t* data, uint16_t len) return (bulk_checksum_calc & 0x7f); } -void create_sd_voiceconfig_filename(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 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 -} - void strip_extension(char* s, char* target) { - char tmp[BANK_NAME_LEN]; + char tmp[FILENAME_LEN]; char* token; strcpy(tmp, s); @@ -644,152 +633,136 @@ void strip_extension(char* s, char* target) strcpy(target, token); } -bool get_voice_names_from_bank(uint8_t b, uint8_t instance_id) +bool get_bank_name(uint8_t b, char* name, uint8_t len) { File sysex; - uint8_t voice_counter = 0; - int32_t bulk_checksum_calc = 0; - int8_t bulk_checksum; - - b = constrain(b, 0, MAX_BANKS - 1); - - // erase all data for voice names - memset(voice_names[instance_id], 0, MAX_VOICES * VOICE_NAME_LEN); if (sd_card > 0) { - char filename[FILENAME_LEN]; + char bankdir[4]; + File entry; - sprintf(filename, "/%d/%s", b, bank_names[instance_id][b]); + memset(name, 0, len); -#ifdef DEBUG - Serial.print(F("Reading voice names for bank [")); - Serial.print(filename); - Serial.println(F("]")); -#endif + sprintf(bankdir, "/%d", b); - // try to open bank directory - sysex = SD.open(filename); + // try to open directory + sysex = SD.open(bankdir); if (!sysex) return (false); - if (sysex.size() != 4104) // 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() != 0x43) // check sysex vendor is Yamaha - { -#ifdef DEBUG - Serial.println(F("E : SysEx vendor not Yamaha.")); -#endif - return (false); - } - sysex.seek(4103); - if (sysex.read() != 0xf7) // check sysex end-byte + do { -#ifdef DEBUG - Serial.println(F("E : SysEx end byte not found.")); -#endif + entry = sysex.openNextFile(); + } while (entry.isDirectory()); + + if (entry.isDirectory()) return (false); - } - sysex.seek(3); - if (sysex.read() != 0x09) // check for sysex type (0x09=32 voices) - { + + strip_extension(entry.name(), name); #ifdef DEBUG - Serial.println(F("E : SysEx type not 32 voices.")); + Serial.print(F("Found bank-name [")); + Serial.print(name); + Serial.print(F("] for bank [")); + Serial.print(b); + Serial.println(F("]")); #endif - return (false); - } - sysex.seek(4102); // Bulk checksum - bulk_checksum = sysex.read(); - sysex.seek(6); // start of bulk data + sysex.close(); - for (uint16_t n = 0; n < 4096; n++) - { - uint8_t d = sysex.read(); + return (true); + } - if ((n % 128) >= 118 && (n % 128) < 128) // found the start of the voicename - { - voice_names[instance_id][voice_counter][(n % 128) - 118] = d; - } - if (n % 128 == 127) - voice_counter++; - bulk_checksum_calc -= d; - } - bulk_checksum_calc &= 0x7f; + return (false); +} + +bool get_voice_name(uint8_t b, uint8_t v, char* name, uint8_t len) +{ + File sysex; + + if (sd_card > 0) + { + char bank_name[BANK_NAME_LEN]; + char filename[FILENAME_LEN]; + b = constrain(b, 0, MAX_BANKS - 1); + v = constrain(v, 0, MAX_VOICES - 1); + + get_bank_name(b, bank_name, sizeof(bank_name)); + sprintf(filename, "/%d/%s.syx", b, bank_name); #ifdef DEBUG - Serial.print(F("Bulk checksum : 0x")); - Serial.print(bulk_checksum_calc, HEX); - Serial.print(F(" [0x")); - Serial.print(bulk_checksum, HEX); + Serial.print(F("Reading voice-name from [")); + Serial.print(filename); Serial.println(F("]")); #endif - if (bulk_checksum_calc != bulk_checksum) - { + // try to open directory + sysex = SD.open(filename); + if (!sysex) + return (false); + + memset(name, 0, len); + sysex.seek(124 + (v * 128)); + sysex.read(name, min(len, 10)); + #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); + Serial.print(F("Found voice-name [")); + Serial.print(name); + Serial.print(F("] for bank [")); + Serial.print(b); + Serial.print(F("] and voice [")); + Serial.print(v); + Serial.println(F("]")); #endif - return (false); - } + + sysex.close(); + + return (true); } return (false); } -uint8_t get_bank_names(uint8_t instance_id) +bool get_voice_by_bank_name(uint8_t b, const char* bank_name, uint8_t v, char* voice_name, uint8_t len) { - File root; - uint8_t bank_counter = 0; - - // erase all data for bank names - memset(bank_names[instance_id], 0, MAX_BANKS * BANK_NAME_LEN); + File sysex; if (sd_card > 0) { - char bankdir[4]; + char filename[FILENAME_LEN]; - do - { - // init and set name for actual bank directory - sprintf(bankdir, "/%d", bank_counter); + sprintf(filename, "/%d/%s.syx", b, bank_name); +#ifdef DEBUG + Serial.print(F("Reading voice-name from [")); + Serial.print(filename); + Serial.println(F("]")); +#endif - // try to open directory - root = SD.open(bankdir); - if (!root) - break; + // try to open directory + sysex = SD.open(filename); + if (!sysex) + return (false); + + memset(voice_name, 0, len); + sysex.seek(124 + (v * 128)); + sysex.read(voice_name, min(len, 10)); - // read filenames - File entry = root.openNextFile(); - if (!entry.isDirectory()) - { - strcpy(bank_names[instance_id][bank_counter], entry.name()); #ifdef DEBUG - Serial.print(F("Found bank [")); - Serial.print(bank_names[instance_id][bank_counter]); - Serial.println(F("]")); + Serial.print(F("Found voice-name [")); + Serial.print(voice_name); + Serial.print(F("] for bank [")); + Serial.print(b); + Serial.print(F("|")); + Serial.print(bank_name); + Serial.print(F("] and voice [")); + Serial.print(v); + Serial.println(F("]")); #endif - bank_counter++; - } - } while (root); - return (bank_counter); + sysex.close(); + + return (true); } - else - return (0); + + return (false); } diff --git a/dexed_sd.h b/dexed_sd.h index 1879711..1e9d666 100644 --- a/dexed_sd.h +++ b/dexed_sd.h @@ -36,10 +36,6 @@ extern void show_patch(uint8_t instance_id); extern uint8_t bank; extern uint8_t voice; -extern char bank_name[NUM_DEXED][BANK_NAME_LEN]; -extern char voice_name[NUM_DEXED][VOICE_NAME_LEN]; -extern char bank_names[NUM_DEXED][MAX_BANKS][BANK_NAME_LEN]; -extern char voice_names[NUM_DEXED][MAX_VOICES][VOICE_NAME_LEN]; extern uint8_t ui_state; extern uint8_t ui_main_state; extern config_t configuration; @@ -66,7 +62,9 @@ bool save_sd_performance(uint8_t p); bool get_sd_data(File sysex, uint8_t format, uint8_t* conf); bool write_sd_data(File sysex, uint8_t format, uint8_t* data, uint16_t len); uint8_t calc_checksum(uint8_t* data, uint16_t len); -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); +void strip_extension(char* s, char* target); + +bool get_bank_name(uint8_t b, char* name, uint8_t len); +bool get_voice_name(uint8_t b, uint8_t v, char* name, uint8_t len); +bool get_voice_by_bank_name(uint8_t b, const char* bank_name, uint8_t v, char* voice_name, uint8_t len); #endif