|
|
@ -93,6 +93,8 @@ extern char sd_string[LCD_cols + 1]; |
|
|
|
extern char g_voice_name[NUM_DEXED][VOICE_NAME_LEN]; |
|
|
|
extern char g_voice_name[NUM_DEXED][VOICE_NAME_LEN]; |
|
|
|
extern char g_bank_name[NUM_DEXED][BANK_NAME_LEN]; |
|
|
|
extern char g_bank_name[NUM_DEXED][BANK_NAME_LEN]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
extern void send_sysex_voice(uint8_t midi_channel, uint8_t* data); |
|
|
|
|
|
|
|
|
|
|
|
/***********************************************************************
|
|
|
|
/***********************************************************************
|
|
|
|
GLOBAL |
|
|
|
GLOBAL |
|
|
|
************************************************************************/ |
|
|
|
************************************************************************/ |
|
|
@ -248,7 +250,6 @@ void UI_func_velocity_level(uint8_t param); |
|
|
|
void UI_func_voice_select(uint8_t param); |
|
|
|
void UI_func_voice_select(uint8_t param); |
|
|
|
void UI_func_sysex_send_voice(uint8_t param); |
|
|
|
void UI_func_sysex_send_voice(uint8_t param); |
|
|
|
void UI_func_sysex_receive_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_receive_bank(uint8_t param); |
|
|
|
void UI_func_sysex_send_bank(uint8_t param); |
|
|
|
void UI_func_sysex_send_bank(uint8_t param); |
|
|
|
void UI_func_eq_bass(uint8_t param); |
|
|
|
void UI_func_eq_bass(uint8_t param); |
|
|
@ -4935,7 +4936,7 @@ void UI_func_sysex_send_bank(uint8_t param) |
|
|
|
{ |
|
|
|
{ |
|
|
|
encoderDir[ENC_R].reset(); |
|
|
|
encoderDir[ENC_R].reset(); |
|
|
|
|
|
|
|
|
|
|
|
if (bank_number != 0xff) |
|
|
|
if (bank_number < 0xff) |
|
|
|
{ |
|
|
|
{ |
|
|
|
lcd.setCursor(0, 1); |
|
|
|
lcd.setCursor(0, 1); |
|
|
|
lcd.print(F("Canceled. ")); |
|
|
|
lcd.print(F("Canceled. ")); |
|
|
@ -4946,33 +4947,144 @@ void UI_func_sysex_send_bank(uint8_t param) |
|
|
|
|
|
|
|
|
|
|
|
void UI_func_sysex_send_voice(uint8_t param) |
|
|
|
void UI_func_sysex_send_voice(uint8_t param) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
static uint8_t mode; |
|
|
|
|
|
|
|
static uint8_t bank_number; |
|
|
|
|
|
|
|
static uint8_t voice_number; |
|
|
|
|
|
|
|
|
|
|
|
if (LCDML.FUNC_setup()) // ****** SETUP *********
|
|
|
|
if (LCDML.FUNC_setup()) // ****** SETUP *********
|
|
|
|
{ |
|
|
|
{ |
|
|
|
encoderDir[ENC_R].reset(); |
|
|
|
encoderDir[ENC_R].reset(); |
|
|
|
|
|
|
|
mode = 0; |
|
|
|
|
|
|
|
bank_number = configuration.performance.bank[selected_instance_id]; |
|
|
|
|
|
|
|
voice_number = configuration.performance.voice[selected_instance_id]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
char bank_name[BANK_NAME_LEN]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!get_bank_name(bank_number, bank_name, sizeof(bank_name))) |
|
|
|
|
|
|
|
strcpy(bank_name, "*ERROR*"); |
|
|
|
|
|
|
|
|
|
|
|
lcd.setCursor(0, 0); |
|
|
|
lcd.setCursor(0, 0); |
|
|
|
lcd.print(F("MIDI Send Voice")); |
|
|
|
lcd.print(F("MIDI Send Voice")); |
|
|
|
lcd.setCursor(0, 1); |
|
|
|
lcd.show(1, 0, 2, bank_number); |
|
|
|
lcd.print(F("Not implemented.")); |
|
|
|
lcd.show(1, 4, 10, bank_name); |
|
|
|
|
|
|
|
lcd.show(1, 2, 2, " ["); |
|
|
|
|
|
|
|
lcd.show(1, 14, 1, "]"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
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())) |
|
|
|
if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) |
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
switch (mode) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
case 0: // Bank selection
|
|
|
|
if (LCDML.BT_checkDown()) |
|
|
|
if (LCDML.BT_checkDown()) |
|
|
|
|
|
|
|
bank_number = constrain(bank_number + ENCODER[ENC_R].speed(), 0, MAX_BANKS - 1); |
|
|
|
|
|
|
|
else if (LCDML.BT_checkUp() && bank_number > 0) |
|
|
|
|
|
|
|
bank_number = constrain(bank_number - ENCODER[ENC_R].speed(), 0, MAX_BANKS - 1); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!get_bank_name(bank_number, bank_name, sizeof(bank_name))) |
|
|
|
|
|
|
|
strcpy(bank_name, "*ERROR*"); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lcd.show(1, 0, 2, bank_number); |
|
|
|
|
|
|
|
lcd.show(1, 4, 10, bank_name); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case 1: // Voice selection
|
|
|
|
|
|
|
|
if (LCDML.BT_checkDown() && voice_number < MAX_VOICES - 1) |
|
|
|
|
|
|
|
voice_number = constrain(voice_number + ENCODER[ENC_R].speed(), 0, MAX_VOICES - 1); |
|
|
|
|
|
|
|
else if (LCDML.BT_checkUp() && voice_number > 0) |
|
|
|
|
|
|
|
voice_number = constrain(voice_number - ENCODER[ENC_R].speed(), 0, MAX_VOICES - 1); |
|
|
|
|
|
|
|
if (!get_bank_name(bank_number, bank_name, sizeof(bank_name))) |
|
|
|
|
|
|
|
strncpy(bank_name, "*ERROR*", sizeof(bank_name)); |
|
|
|
|
|
|
|
if (!get_voice_by_bank_name(bank_number, bank_name, voice_number, voice_name, sizeof(voice_name))) |
|
|
|
|
|
|
|
strncpy(voice_name, "*ERROR*", sizeof(voice_name)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lcd.show(1, 0, 2, voice_number + 1); |
|
|
|
|
|
|
|
lcd.show(1, 4, 10, voice_name); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (LCDML.BT_checkEnter()) |
|
|
|
{ |
|
|
|
{ |
|
|
|
; |
|
|
|
if (encoderDir[ENC_R].ButtonShort()) |
|
|
|
|
|
|
|
mode++; |
|
|
|
|
|
|
|
switch (mode) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
case 1: |
|
|
|
|
|
|
|
if (!get_bank_name(bank_number, bank_name, sizeof(bank_name))) |
|
|
|
|
|
|
|
strncpy(bank_name, "*ERROR*", sizeof(bank_name)); |
|
|
|
|
|
|
|
if (!get_voice_by_bank_name(bank_number, bank_name, voice_number, voice_name, sizeof(voice_name))) |
|
|
|
|
|
|
|
strncpy(voice_name, "*ERROR*", sizeof(voice_name)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lcd.show(1, 0, 2, voice_number + 1); |
|
|
|
|
|
|
|
lcd.show(1, 4, 10, voice_name); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case 2: |
|
|
|
|
|
|
|
File sysex; |
|
|
|
|
|
|
|
char filename[FILENAME_LEN]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (get_bank_name(bank_number, bank_name, sizeof(bank_name))) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
sprintf(filename, "/%d/%s.syx", bank_number, bank_name); |
|
|
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
|
|
|
Serial.print(F("Send voice ")); |
|
|
|
|
|
|
|
Serial.print(voice_number); |
|
|
|
|
|
|
|
Serial.print(F(" of ")); |
|
|
|
|
|
|
|
Serial.print(filename); |
|
|
|
|
|
|
|
Serial.println(F(" from SD.")); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
sysex = SD.open(filename); |
|
|
|
|
|
|
|
if (!sysex) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
|
|
|
Serial.println(F("Connot read from SD.")); |
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
lcd.show(1, 0, 16, "Read error."); |
|
|
|
|
|
|
|
bank_number = 0xff; |
|
|
|
} |
|
|
|
} |
|
|
|
else if (LCDML.BT_checkUp()) |
|
|
|
else |
|
|
|
{ |
|
|
|
{ |
|
|
|
; |
|
|
|
uint8_t voice_data[155]; |
|
|
|
|
|
|
|
uint8_t encoded_voice_data[128]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sysex.seek(6 + (voice_number * 128)); |
|
|
|
|
|
|
|
sysex.read(encoded_voice_data, 128); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MicroDexed[selected_instance_id]->decodeVoice(encoded_voice_data, voice_data); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lcd.show(1, 0, 16, "Sending..."); |
|
|
|
|
|
|
|
send_sysex_voice(configuration.dexed[selected_instance_id].midi_channel, voice_data); |
|
|
|
|
|
|
|
lcd.show(1, 0, 16, "Done."); |
|
|
|
|
|
|
|
sysex.close(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bank_number = 0xff; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
lcd.show(1, 0, 16, "No voice."); |
|
|
|
|
|
|
|
bank_number = 0xff; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mode = 0xff; |
|
|
|
|
|
|
|
delay(MESSAGE_WAIT_TIME); |
|
|
|
|
|
|
|
LCDML.FUNC_goBackToMenu(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (LCDML.FUNC_close()) // ****** STABLE END *********
|
|
|
|
if (LCDML.FUNC_close()) // ****** STABLE END *********
|
|
|
|
{ |
|
|
|
{ |
|
|
|
|
|
|
|
if (mode < 0xff) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
lcd.show(1, 0, 16, "Canceled."); |
|
|
|
|
|
|
|
delay(MESSAGE_WAIT_TIME); |
|
|
|
|
|
|
|
} |
|
|
|
encoderDir[ENC_R].reset(); |
|
|
|
encoderDir[ENC_R].reset(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|