Added direct voice/bankname reading from SD instead of caching.

Fixes.
pull/32/head
Holger Wirtz 5 years ago
parent 161f77c3e2
commit 11b2afb949
  1. 44
      MicroDexed.ino
  2. 45
      UI.hpp
  3. 2
      config.h
  4. 213
      dexed_sd.cpp
  5. 10
      dexed_sd.h

@ -194,12 +194,6 @@ void create_audio_connections(AudioSourceMicroDexed &dexed, AudioEffectMonoStere
uint8_t sd_card = 0; uint8_t sd_card = 0;
Sd2Card card; Sd2Card card;
SdVolume volume; 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 uint8_t midi_timing_counter = 0; // 24 per qarter
elapsedMillis midi_timing_timestep; elapsedMillis midi_timing_timestep;
uint16_t midi_timing_quarter = 0; uint16_t midi_timing_quarter = 0;
@ -375,11 +369,6 @@ void setup()
#ifdef DEBUG #ifdef DEBUG
Serial.println(F("SD card not accessable.")); Serial.println(F("SD card not accessable."));
#endif #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 else
{ {
@ -387,30 +376,6 @@ void setup()
for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) 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 default SYSEX data
load_sd_voice(configuration.performance.bank[instance_id], configuration.performance.voice[instance_id], instance_id); 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 // load sysex-data into voice memory
MicroDexed[instance_id]->loadVoiceParameters(&sysex[6]); MicroDexed[instance_id]->loadVoiceParameters(&sysex[6]);
//MicroDexed[instance_id]->initGlobalParameters();
/*
// manipulate UI names and numbers // manipulate UI names and numbers
strncpy(voice_name[instance_id], (char *)&sysex[151], sizeof(voice_name[instance_id]) - 1); strncpy(voice_name[instance_id], (char *)&sysex[151], sizeof(voice_name[instance_id]) - 1);
Serial.print(F("Got voice [")); Serial.print(F("Got voice ["));
Serial.print(voice_name[instance_id]); Serial.print(voice_name[instance_id]);
Serial.println(F("].")); Serial.println(F("]."));*/
} }
#ifdef DEBUG #ifdef DEBUG
else else
@ -1337,10 +1302,9 @@ void init_configuration(void)
configuration.fx.delay_feedback = DELAY_FEEDBACK_DEFAULT; configuration.fx.delay_feedback = DELAY_FEEDBACK_DEFAULT;
configuration.fx.delay_level = DELAY_LEVEL_DEFAULT; configuration.fx.delay_level = DELAY_LEVEL_DEFAULT;
//configuration.performance.checksum = 0xffff;
configuration.performance.fx_number = FX_NUM_DEFAULT; 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.bank[instance_id] = SYSEXBANK_DEFAULT;
configuration.performance.voice[instance_id] = SYSEXSOUND_DEFAULT; configuration.performance.voice[instance_id] = SYSEXSOUND_DEFAULT;
@ -1828,7 +1792,7 @@ void check_and_create_directories(void)
} }
} }
#ifdef DEBUG #ifdef DEBUG
#else else
Serial.println(F("No SD card for directory check available.")); Serial.println(F("No SD card for directory check available."));
#endif #endif
} }

@ -47,15 +47,7 @@
#define _LCDML_DISP_cfg_scrollbar 1 // enable a scrollbar #define _LCDML_DISP_cfg_scrollbar 1 // enable a scrollbar
extern config_t configuration; extern config_t configuration;
extern uint8_t dexed_setup_number;
extern void set_volume(uint8_t v, uint8_t m); 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 bool load_sysex(uint8_t b, uint8_t v);
extern void generate_version_string(char* buffer, uint8_t len); extern void generate_version_string(char* buffer, uint8_t len);
extern void initial_values_from_eeprom(bool init); extern void initial_values_from_eeprom(bool init);
@ -3206,12 +3198,18 @@ void UI_func_voice_select(uint8_t param)
{ {
encoderDir[ENC_R].reset(); 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(0, 0, 2, configuration.performance.bank[instance_id]);
lcd.show(1, 0, 2, configuration.performance.voice[instance_id] + 1); lcd.show(1, 0, 2, configuration.performance.voice[instance_id] + 1);
lcd.show(0, 4, 10, bank_name[instance_id]); lcd.show(0, 4, 10, bank_name);
lcd.show(1, 4, 10, voice_names[instance_id][configuration.performance.voice[instance_id]]); lcd.show(1, 4, 10, voice_name);
switch (menu_voice_select) switch (menu_voice_select)
{ {
@ -3232,12 +3230,16 @@ void UI_func_voice_select(uint8_t param)
if (LCDML.FUNC_loop()) // ****** LOOP ********* 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())) 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; uint8_t bank_tmp;
int8_t voice_tmp; int8_t voice_tmp;
if (LCDML.BT_checkUp()) if (LCDML.BT_checkUp())
{
switch (menu_voice_select) switch (menu_voice_select)
{ {
case MENU_VOICE_BANK: case MENU_VOICE_BANK:
@ -3247,7 +3249,6 @@ void UI_func_voice_select(uint8_t param)
change_disp_sd(false); change_disp_sd(false);
#endif #endif
load_sd_voice(configuration.performance.bank[instance_id], configuration.performance.voice[instance_id], instance_id); 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 #ifdef DISPLAY_LCD_SPI
change_disp_sd(true); change_disp_sd(true);
#endif #endif
@ -3265,18 +3266,18 @@ void UI_func_voice_select(uint8_t param)
} }
if (voice_tmp < 0) if (voice_tmp < 0)
voice_tmp = MAX_VOICES + voice_tmp; 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 #ifdef DISPLAY_LCD_SPI
change_disp_sd(false); change_disp_sd(false);
#endif #endif
load_sd_voice(configuration.performance.bank[instance_id], configuration.performance.voice[instance_id], instance_id); 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 #ifdef DISPLAY_LCD_SPI
change_disp_sd(true); change_disp_sd(true);
#endif #endif
break; break;
} }
}
else if (LCDML.BT_checkDown()) else if (LCDML.BT_checkDown())
{ {
switch (menu_voice_select) switch (menu_voice_select)
@ -3288,7 +3289,6 @@ void UI_func_voice_select(uint8_t param)
change_disp_sd(false); change_disp_sd(false);
#endif #endif
load_sd_voice(configuration.performance.bank[instance_id], configuration.performance.voice[instance_id], instance_id); 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 #ifdef DISPLAY_LCD_SPI
change_disp_sd(true); change_disp_sd(true);
#endif #endif
@ -3305,18 +3305,16 @@ void UI_func_voice_select(uint8_t param)
{ {
voice_tmp = MAX_VOICES - 1; 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 #ifdef DISPLAY_LCD_SPI
change_disp_sd(false); change_disp_sd(false);
#endif #endif
load_sd_voice(configuration.performance.bank[instance_id], configuration.performance.voice[instance_id], instance_id); 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 #ifdef DISPLAY_LCD_SPI
change_disp_sd(true); change_disp_sd(true);
#endif #endif
break; break;
} }
} }
else if (LCDML.BT_checkEnter()) else if (LCDML.BT_checkEnter())
@ -3326,13 +3324,17 @@ void UI_func_voice_select(uint8_t param)
else else
menu_voice_select = MENU_VOICE_BANK; 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(0, 0, 2, configuration.performance.bank[instance_id]);
lcd.show(1, 0, 2, configuration.performance.voice[instance_id] + 1); lcd.show(1, 0, 2, configuration.performance.voice[instance_id] + 1);
lcd.show(0, 4, 10, bank_name[instance_id]); lcd.show(0, 4, 10, bank_name);
lcd.show(1, 4, 10, voice_names[instance_id][configuration.performance.voice[instance_id]]); lcd.show(1, 4, 10, voice_name);
switch (menu_voice_select) switch (menu_voice_select)
{ {
@ -3350,7 +3352,6 @@ void UI_func_voice_select(uint8_t param)
break; break;
} }
} }
}
if (LCDML.FUNC_close()) // ****** STABLE END ********* if (LCDML.FUNC_close()) // ****** STABLE END *********
{ {

@ -224,7 +224,7 @@
#define MAX_FX 99 #define MAX_FX 99
#define MAX_PERFORMANCE 99 #define MAX_PERFORMANCE 99
#define MAX_VOICECONFIG 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 VOICE_NAME_LEN 11 // 10 (plus '\0')
#define FILENAME_LEN BANK_NAME_LEN + VOICE_NAME_LEN #define FILENAME_LEN BANK_NAME_LEN + VOICE_NAME_LEN

@ -46,9 +46,11 @@ bool load_sd_voice(uint8_t b, uint8_t v, uint8_t instance_id)
{ {
File sysex; File sysex;
char filename[FILENAME_LEN]; char filename[FILENAME_LEN];
char bank_name[BANK_NAME_LEN];
uint8_t data[128]; 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); sysex = SD.open(filename);
if (!sysex) 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)) if (get_sd_voice(sysex, v, data))
{ {
#ifdef DEBUG #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(F("Loading voice from "));
Serial.print(filename); Serial.print(filename);
Serial.print(F(" [")); Serial.print(F(" ["));
Serial.print(voice_names[instance_id][v]); Serial.print(voice_name);
Serial.println(F("]")); Serial.println(F("]"));
#endif #endif
bool ret = MicroDexed[instance_id]->decodeVoice(data); 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 else
Serial.println(F("E : Cannot load voice data")); Serial.println(F("E : Cannot load voice data"));
#endif #endif
sysex.close();
} }
#ifdef DEBUG #ifdef DEBUG
if (found == false) if (found == false)
@ -615,25 +620,9 @@ uint8_t calc_checksum(uint8_t* data, uint16_t len)
return (bulk_checksum_calc & 0x7f); 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) void strip_extension(char* s, char* target)
{ {
char tmp[BANK_NAME_LEN]; char tmp[FILENAME_LEN];
char* token; char* token;
strcpy(tmp, s); strcpy(tmp, s);
@ -644,152 +633,136 @@ void strip_extension(char* s, char* target)
strcpy(target, token); 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; 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) 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 sprintf(bankdir, "/%d", b);
Serial.print(F("Reading voice names for bank ["));
Serial.print(filename);
Serial.println(F("]"));
#endif
// try to open bank directory // try to open directory
sysex = SD.open(filename); sysex = SD.open(bankdir);
if (!sysex) if (!sysex)
return (false); return (false);
if (sysex.size() != 4104) // check sysex size do
{
#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 entry = sysex.openNextFile();
Serial.println(F("E : SysEx vendor not Yamaha.")); } while (entry.isDirectory());
#endif
if (entry.isDirectory())
return (false); return (false);
}
sysex.seek(4103); strip_extension(entry.name(), name);
if (sysex.read() != 0xf7) // check sysex end-byte
{
#ifdef DEBUG #ifdef DEBUG
Serial.println(F("E : SysEx end byte not found.")); Serial.print(F("Found bank-name ["));
Serial.print(name);
Serial.print(F("] for bank ["));
Serial.print(b);
Serial.println(F("]"));
#endif #endif
return (false);
sysex.close();
return (true);
} }
sysex.seek(3);
if (sysex.read() != 0x09) // check for sysex type (0x09=32 voices)
{
#ifdef DEBUG
Serial.println(F("E : SysEx type not 32 voices."));
#endif
return (false); return (false);
} }
sysex.seek(4102); // Bulk checksum
bulk_checksum = sysex.read();
sysex.seek(6); // start of bulk data
for (uint16_t n = 0; n < 4096; n++) bool get_voice_name(uint8_t b, uint8_t v, char* name, uint8_t len)
{ {
uint8_t d = sysex.read(); File sysex;
if ((n % 128) >= 118 && (n % 128) < 128) // found the start of the voicename if (sd_card > 0)
{ {
voice_names[instance_id][voice_counter][(n % 128) - 118] = d; char bank_name[BANK_NAME_LEN];
} char filename[FILENAME_LEN];
if (n % 128 == 127)
voice_counter++;
bulk_checksum_calc -= d;
}
bulk_checksum_calc &= 0x7f;
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 #ifdef DEBUG
Serial.print(F("Bulk checksum : 0x")); Serial.print(F("Reading voice-name from ["));
Serial.print(bulk_checksum_calc, HEX); Serial.print(filename);
Serial.print(F(" [0x"));
Serial.print(bulk_checksum, HEX);
Serial.println(F("]")); Serial.println(F("]"));
#endif #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 #ifdef DEBUG
Serial.print(F("E : Bulk checksum mismatch : 0x")); Serial.print(F("Found voice-name ["));
Serial.print(bulk_checksum_calc, HEX); Serial.print(name);
Serial.print(F(" != 0x")); Serial.print(F("] for bank ["));
Serial.println(bulk_checksum, HEX); Serial.print(b);
Serial.print(F("] and voice ["));
Serial.print(v);
Serial.println(F("]"));
#endif #endif
return (false);
} sysex.close();
return (true);
} }
return (false); 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; File sysex;
uint8_t bank_counter = 0;
// erase all data for bank names
memset(bank_names[instance_id], 0, MAX_BANKS * BANK_NAME_LEN);
if (sd_card > 0) if (sd_card > 0)
{ {
char bankdir[4]; char filename[FILENAME_LEN];
do sprintf(filename, "/%d/%s.syx", b, bank_name);
{ #ifdef DEBUG
// init and set name for actual bank directory Serial.print(F("Reading voice-name from ["));
sprintf(bankdir, "/%d", bank_counter); Serial.print(filename);
Serial.println(F("]"));
#endif
// try to open directory // try to open directory
root = SD.open(bankdir); sysex = SD.open(filename);
if (!root) if (!sysex)
break; 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 #ifdef DEBUG
Serial.print(F("Found bank [")); Serial.print(F("Found voice-name ["));
Serial.print(bank_names[instance_id][bank_counter]); 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("]")); Serial.println(F("]"));
#endif #endif
bank_counter++;
}
} while (root);
return (bank_counter); sysex.close();
return (true);
} }
else
return (0); return (false);
} }

@ -36,10 +36,6 @@ extern void show_patch(uint8_t instance_id);
extern uint8_t bank; extern uint8_t bank;
extern uint8_t voice; 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_state;
extern uint8_t ui_main_state; extern uint8_t ui_main_state;
extern config_t configuration; extern config_t configuration;
@ -67,6 +63,8 @@ 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); 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); uint8_t calc_checksum(uint8_t* data, uint16_t len);
void strip_extension(char* s, char* target); 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); 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 #endif

Loading…
Cancel
Save