Added MIDI bank receive and storing - but does not work yet.

pull/32/head
Holger Wirtz 4 years ago
parent a43b6ace1e
commit 1ff6ea3d5f
  1. 21
      MicroDexed.ino
  2. 210
      UI.hpp
  3. 9
      config.h
  4. 8
      midi_devices.hpp

@ -1151,12 +1151,12 @@ void handleSystemExclusive(byte * sysex, uint len)
LCDML.loop_menu();
}
}
else if (len == 4104 && strlen(receive_bank_filename) > 0)
else if (len == 4104 && strlen(receive_bank_filename) > 0 && LCDML.FUNC_getID() == LCDML.OTHER_getIDFromFunction(UI_func_sysex_receive_bank))
{
int32_t bulk_checksum_calc = 0;
int8_t bulk_checksum = sysex[4102];
// 1 Voice bulk upload
// 1 Bank bulk upload
#ifdef DEBUG
Serial.println(F("Bank bulk upload"));
#endif
@ -1196,23 +1196,30 @@ void handleSystemExclusive(byte * sysex, uint len)
return;
}
#ifdef DEBUG
if (save_sd_bank(receive_bank_filename, sysex))
{
#ifdef DEBUG
Serial.print(F("Bank saved as ["));
Serial.print(receive_bank_filename);
Serial.println(F("]"));
#endif
lcd.setCursor(0, 1);
lcd.print(F("Done. "));
delay(MESSAGE_WAIT_TIME);
LCDML.FUNC_goBackToMenu();
}
else
{
#ifdef DEBUG
Serial.println(F("Error during saving bank as ["));
Serial.print(receive_bank_filename);
Serial.println(F("]"));
}
#else
save_sd_bank(receive_bank_filename, sysex);
#endif
lcd.setCursor(0, 1);
lcd.print(F("Error. "));
delay(MESSAGE_WAIT_TIME);
LCDML.FUNC_goBackToMenu();
}
memset(receive_bank_filename, 0, FILENAME_LEN);
}
#ifdef DEBUG

210
UI.hpp

@ -58,6 +58,7 @@ extern void eeprom_update_fx(void);
extern void eeprom_update_dexed(uint8_t instance_id);
extern float pseudo_log_curve(float value);
extern uint8_t selected_instance_id;
extern char receive_bank_filename[FILENAME_LEN];
#ifdef DISPLAY_LCD_SPI
extern void change_disp_sd(bool d);
@ -97,6 +98,7 @@ extern char g_bank_name[NUM_DEXED][BANK_NAME_LEN];
************************************************************************/
elapsedMillis back_from_volume;
uint8_t instance_num[8][8];
char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
#ifdef I2C_DISPLAY
#include <LiquidCrystal_I2C.h>
@ -253,6 +255,7 @@ void UI_func_eq_bass(uint8_t param);
void UI_func_eq_treble(uint8_t param);
void UI_function_not_enabled(void);
void UI_function_not_implemented(uint8_t param);
bool UI_select_name(uint8_t y, uint8_t x, char* edit_string, uint8_t len, bool init);
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_bar_int(const char* title, uint32_t value, float factor, int32_t min_value, int32_t max_value, uint8_t size, bool zeros, bool sign, bool init);
@ -4678,14 +4681,27 @@ void UI_func_save_voice(uint8_t param)
void UI_func_sysex_receive_bank(uint8_t param)
{
static bool yesno;
static uint8_t mode;
static uint8_t bank_number;
static uint8_t ui_select_name_state;
if (LCDML.FUNC_setup()) // ****** SETUP *********
{
encoderDir[ENC_R].reset();
yesno = false;
mode = 0;
bank_number = configuration.performance.bank[selected_instance_id];
lcd.setCursor(0, 0);
lcd.print(F("MIDI Recv Bank"));
lcd.setCursor(0, 1);
lcd.print(F("Not implemented."));
lcd.print(F("[ ]"));
if (!get_bank_name(configuration.performance.bank[selected_instance_id], receive_bank_filename, sizeof(receive_bank_filename)))
strncpy(receive_bank_filename, "*ERROR*", sizeof(receive_bank_filename));
lcd.show(1, 1, 2, bank_number);
lcd.show(1, 5, 10, receive_bank_filename);
}
if (LCDML.FUNC_loop()) // ****** LOOP *********
@ -4694,18 +4710,121 @@ void UI_func_sysex_receive_bank(uint8_t param)
{
if (LCDML.BT_checkDown())
{
;
switch (mode)
{
case 0:
bank_number = constrain(bank_number + ENCODER[ENC_R].speed(), 0, MAX_BANKS - 1);
if (!get_bank_name(bank_number, receive_bank_filename, sizeof(receive_bank_filename)))
strncpy(receive_bank_filename, "*ERROR*", sizeof(receive_bank_filename));
lcd.show(1, 1, 2, bank_number);
lcd.show(1, 5, 10, receive_bank_filename);
break;
case 1:
yesno = !yesno;
if (yesno)
lcd.show(1, 12, 3, "YES");
else
lcd.show(1, 12, 3, "NO");
break;
case 2:
ui_select_name_state = UI_select_name(1, 1, receive_bank_filename, BANK_NAME_LEN - 1, false);
break;
}
}
else if (LCDML.BT_checkUp())
{
;
switch (mode)
{
case 0:
bank_number = constrain(bank_number - ENCODER[ENC_R].speed(), 0, MAX_BANKS - 1);
if (!get_bank_name(bank_number, receive_bank_filename, sizeof(receive_bank_filename)))
strncpy(receive_bank_filename, "*ERROR*", sizeof(receive_bank_filename));
lcd.show(1, 1, 2, bank_number);
lcd.show(1, 5, 10, receive_bank_filename);
break;
case 1:
yesno = !yesno;
if (yesno)
lcd.show(1, 12, 3, "YES");
else
lcd.show(1, 12, 3, "NO");
break;
case 2:
ui_select_name_state = UI_select_name(1, 1, receive_bank_filename, BANK_NAME_LEN - 1, false);
break;
}
}
}
else if (LCDML.BT_checkEnter() && encoderDir[ENC_R].ButtonShort())
{
if (mode == 0)
{
if (!strncmp(receive_bank_filename, "*ERROR*", sizeof(receive_bank_filename)))
{
yesno = true;
strncpy(receive_bank_filename, "EMPTY", BANK_NAME_LEN);
mode += 2;
lcd.blink();
}
else
{
mode = 1;
lcd.setCursor(0, 1);
lcd.print(F("Overwrite: [NO ]"));
}
}
else if (mode == 1 && yesno == true)
{
mode = 2;
lcd.setCursor(0, 1);
lcd.print(F("[ ] "));
lcd.blink();
ui_select_name_state = UI_select_name(1, 1, receive_bank_filename, BANK_NAME_LEN - 1, true);
}
else if (mode == 2)
{
ui_select_name_state = UI_select_name(1, 1, receive_bank_filename, BANK_NAME_LEN - 1, false);
if (ui_select_name_state == true)
{
if (yesno == true)
{
mode = 0xff;
lcd.noBlink();
lcd.setCursor(0, 1);
lcd.print(F("Waiting... "));
/// Storing is done in SYSEX code
}
}
}
else if (mode >= 1 && yesno == false)
{
Serial.println(mode, DEC);
memset(receive_bank_filename, 0, sizeof(receive_bank_filename));
mode = 0xff;
lcd.noBlink();
lcd.setCursor(0, 1);
lcd.print(F("Canceled. "));
delay(MESSAGE_WAIT_TIME);
LCDML.FUNC_goBackToMenu();
}
}
encoderDir[ENC_R].reset();
}
if (LCDML.FUNC_close()) // ****** STABLE END *********
{
encoderDir[ENC_R].reset();
memset(receive_bank_filename, 0, sizeof(receive_bank_filename));
lcd.noBlink();
if (mode < 0xff)
{
lcd.setCursor(0, 1);
lcd.print(F("Canceled. "));
delay(MESSAGE_WAIT_TIME);
}
}
}
@ -4942,6 +5061,91 @@ void UI_function_not_implemented(uint8_t param)
}
}
bool UI_select_name(uint8_t y, uint8_t x, char* edit_string, uint8_t len, bool init)
{
static int8_t edit_pos;
static bool edit_mode;
if (init == true)
{
lcd.setCursor(x, y);
lcd.print(edit_string);
edit_mode = false;
edit_pos = 0;
lcd.setCursor(x, y);
return (false);
}
if (LCDML.BT_checkDown() || LCDML.BT_checkUp())
{
if (LCDML.BT_checkDown())
{
if (edit_mode == true)
{
edit_string[edit_pos] = constrain(edit_string[edit_pos] + 1, 32, 126);
lcd.setCursor(x + edit_pos, y);
lcd.print(edit_string[edit_pos]);
}
else
{
edit_pos = constrain(edit_pos + 1, 0, len);
if (edit_pos == len)
{
lcd.noBlink();
lcd.setCursor(x - 1, y);
lcd.print(F(" "));
lcd.setCursor(x + len, y);
lcd.print(F(" "));
lcd.setCursor(x + len + 1, y);
lcd.print(F("[OK]"));
}
}
}
else if (LCDML.BT_checkUp())
{
if (edit_mode == true)
{
edit_string[edit_pos] = constrain(edit_string[edit_pos] - 1, 32, 126);
lcd.setCursor(x + edit_pos, y);
lcd.print(edit_string[edit_pos]);
}
else
{
edit_pos = constrain(edit_pos - 1, 0, len - 1);
if (edit_pos == len - 1)
{
lcd.setCursor(x - 1, y);
lcd.print(F("["));
lcd.setCursor(x + len, y);
lcd.print(F("]"));
lcd.setCursor(x + len + 1, y);
lcd.print(F(" "));
lcd.blink();
}
}
}
}
else if (LCDML.BT_checkEnter())
{
if (edit_pos >= len)
{
edit_pos = 0;
edit_mode = false;
return (true);
}
else
{
edit_mode = !edit_mode;
}
}
lcd.setCursor(x + edit_pos, y);
encoderDir[ENC_R].reset();
return (false);
}
void lcd_display_int(int16_t var, uint8_t size, bool zeros, bool brackets, bool sign)
{
lcd_display_float(float(var), size, 0, zeros, brackets, sign);

@ -43,13 +43,18 @@
// Tools for testing MIDI: https://github.com/gbevin/SendMIDI
// https://github.com/gbevin/ReceiveMIDI
//
// e.g. sendmidi dev "MicroDexed MIDI" on 80 127 && sleep 1.0 && sendmidi dev "MicroDexed MIDI" off 80 0
// e.g.:
// * sendmidi dev "MicroDexed MIDI" on 80 127 && sleep 1.0 && sendmidi dev "MicroDexed MIDI" off 80 0
// * sendmidi dev "MicroDexed MIDI" syx syf addon/SD/90/RitCh1.syx
//
// Receiving and storing MIDI SYSEX with Linux:
// amidi -p hw:2,0,0 -d -r /tmp/bkup1.syx
//
// For SYSEX Bank upload via USB:
// sed -i.orig 's/SYSEX_MAX_LEN = 290/SYSEX_MAX_LEN = 4104/' /usr/local/arduino-teensy-1.8.12/hardware/teensy/avr/libraries/USBHost_t36/USBHost_t36.h
// sed -i.orig 's/^#define USB_MIDI_SYSEX_MAX 290/#define USB_MIDI_SYSEX_MAX 4104/' /usr/local/arduino-teensy-1.8.12/hardware/teensy/avr/cores/teensy3/usb_midi.h
#define VERSION "0.9.9j"
#define VERSION "0.9.9k"
//*************************************************************************************************
//* DEVICE SETTINGS

@ -35,8 +35,14 @@ extern config_t configuration;
#include <USBHost_t36.h>
#endif
// override default sysex size settings
struct MicroDexedSettings : public midi::DefaultSettings
{
static const unsigned SysExMaxSize = 4104; // Accept SysEx messages up to 1024 bytes long.
};
#ifdef MIDI_DEVICE_DIN
MIDI_CREATE_INSTANCE(HardwareSerial, MIDI_DEVICE_DIN, midi_serial);
MIDI_CREATE_CUSTOM_INSTANCE(HardwareSerial, MIDI_DEVICE_DIN, midi_serial, MicroDexedSettings);
#endif
#ifdef MIDI_DEVICE_USB_HOST
USBHost usb_host;

Loading…
Cancel
Save