Fixes for handling SYSEX.

dev
Holger Wirtz 3 years ago
parent 42ec36b607
commit b55e7afb56
  1. 346
      MicroDexed.ino
  2. 1128
      drumset.h

@ -1394,8 +1394,8 @@ void handleControlChange(byte inChannel, byte inCtrl, byte inValue)
case 64: case 64:
MicroDexed[instance_id]->setSustain(inValue > 63); MicroDexed[instance_id]->setSustain(inValue > 63);
/* /*
if (!MicroDexed[instance_id]->getSustain()) if (!MicroDexed[instance_id]->getSustain())
{ {
for (uint8_t note = 0; note < MicroDexed[instance_id]->getMaxNotes(); note++) for (uint8_t note = 0; note < MicroDexed[instance_id]->getMaxNotes(); note++)
{ {
if (MicroDexed[instance_id]->voices[note].sustained && !MicroDexed[instance_id]->voices[note].keydown) if (MicroDexed[instance_id]->voices[note].sustained && !MicroDexed[instance_id]->voices[note].keydown)
@ -1404,7 +1404,7 @@ void handleControlChange(byte inChannel, byte inCtrl, byte inValue)
MicroDexed[instance_id]->voices[note].sustained = false; MicroDexed[instance_id]->voices[note].sustained = false;
} }
} }
} }
*/ */
break; break;
case 65: case 65:
@ -1584,8 +1584,10 @@ void handleProgramChange(byte inChannel, byte inProgram)
} }
} }
void handleSystemExclusive(byte * sysex, uint len) void handleSystemExclusive(byte* sysex, unsigned int len)
{ {
int16_t sysex_return;
for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++)
{ {
if (!checkMidiChannel((sysex[2] & 0x0f) + 1 , instance_id)) if (!checkMidiChannel((sysex[2] & 0x0f) + 1 , instance_id))
@ -1624,61 +1626,97 @@ void handleSystemExclusive(byte * sysex, uint len)
Serial.println(); Serial.println();
#endif #endif
// Check for SYSEX end byte sysex_return = MicroDexed[instance_id]->handleSystemExclusive(sysex, len);
if (sysex[len - 1] != 0xf7)
{
#ifdef DEBUG #ifdef DEBUG
Serial.println(F("E: SysEx end status byte not detected.")); Serial.print(F("SYSEX handler return value:"));
Serial.print(sysex_return, DEC);
Serial.println();
#endif #endif
return;
}
if (sysex[1] != 0x43) // check for Yamaha sysex switch (sysex_return)
{ {
case -1:
#ifdef DEBUG #ifdef DEBUG
Serial.println(F("E: SysEx vendor not Yamaha.")); Serial.println(F("E: SysEx end status byte not detected."));
#endif #endif
return; break;
} case -2:
#ifdef DEBUG #ifdef DEBUG
Serial.print(F("Substatus: [")); Serial.println(F("E: SysEx vendor not Yamaha."));
Serial.print((sysex[2] & 0x70) >> 4);
Serial.println(F("]"));
#endif #endif
break;
// parse parameter change case -3:
if (len == 7)
{
if (((sysex[3] & 0x7c) >> 2) != 0 && ((sysex[3] & 0x7c) >> 2) != 2)
{
#ifdef DEBUG #ifdef DEBUG
Serial.println(F("E: Not a SysEx parameter or function parameter change.")); Serial.println(F("E: Unknown SysEx parameter change."));
#endif #endif
return; break;
} case -4:
sysex[4] &= 0x7f;
sysex[5] &= 0x7f;
if ((sysex[3] & 0x7c) >> 2 == 0)
{
#ifdef DEBUG #ifdef DEBUG
Serial.println(F("SysEx Voice parameter:")); Serial.println(F("E: Unknown SysEx voice or function."));
Serial.print("Parameter #");
Serial.print(sysex[4] + ((sysex[3] & 0x03) * 128), DEC);
Serial.print(" Value: ");
Serial.println(sysex[5], DEC);
#endif #endif
MicroDexed[instance_id]->setVoiceDataElement(sysex[4] + ((sysex[3] & 0x03) * 128), sysex[5]); break;
} case -5:
else if ((sysex[3] & 0x7c) >> 2 == 2)
{
#ifdef DEBUG #ifdef DEBUG
Serial.println(F("SysEx Function parameter:")); Serial.println(F("E: Not a SysEx voice bulk upload."));
Serial.print("Parameter #"); #endif
break;
case -6:
#ifdef DEBUG
Serial.println(F("E: Wrong length for SysEx voice bulk upload (not 155)."));
#endif
break;
case -7:
#ifdef DEBUG
Serial.println(F("E: Checksum error for one voice."));
#endif
break;
case -8:
#ifdef DEBUG
Serial.println(F("E: Not a SysEx bank bulk upload."));
#endif
display.setCursor(0, 1);
display.print(F("Error (TYPE) "));
delay(MESSAGE_WAIT_TIME);
LCDML.FUNC_goBackToMenu();
break;
case -9:
#ifdef DEBUG
Serial.println(F("E: Wrong length for SysEx bank bulk upload (not 4096)."));
#endif
display.setCursor(0, 1);
display.print(F("Error (SIZE) "));
delay(MESSAGE_WAIT_TIME);
LCDML.FUNC_goBackToMenu();
break;
case -10:
#ifdef DEBUG
Serial.println(F("E: Checksum error for bank."));
#endif
break;
case -11:
#ifdef DEBUG
Serial.println(F("E: Unknown SysEx message."));
#endif
break;
case 64:
case 65:
case 66:
case 67:
case 68:
case 69:
case 70:
case 71:
case 72:
case 73:
case 74:
case 75:
case 76:
case 77:
#ifdef DEBUG
Serial.println(F("SysEx Function parameter change : "));
Serial.print(F("Parameter #"));
Serial.print(sysex[4], DEC); Serial.print(sysex[4], DEC);
Serial.print(" Value: "); Serial.print(F(" Value : "));
Serial.println(sysex[5], DEC); Serial.println(sysex[5], DEC);
#endif #endif
switch (sysex[4]) switch (sysex[4])
@ -1800,189 +1838,87 @@ void handleSystemExclusive(byte * sysex, uint len)
LCDML.loop_menu(); LCDML.loop_menu();
} }
break; break;
default:
MicroDexed[instance_id]->setVoiceDataElement(sysex[4], sysex[5]); // set function parameter
break;
} }
MicroDexed[instance_id]->ControllersRefresh(); break;
} case 100:
#ifdef DEBUG // fix voice name
else for (uint8_t i = 0; i < 10; i++)
{
Serial.println(F("E: Unknown SysEx voice or function."));
}
#endif
}
else if (len == 163)
{
int32_t bulk_checksum_calc = 0;
int8_t bulk_checksum = sysex[161];
// 1 Voice bulk upload
#ifdef DEBUG
Serial.println(F("One Voice bulk upload"));
#endif
if ((sysex[3] & 0x7f) != 0)
{
#ifdef DEBUG
Serial.println(F("E: Not a SysEx voice bulk upload."));
#endif
return;
}
if (((sysex[4] << 7) | sysex[5]) != 0x9b)
{
#ifdef DEBUG
Serial.println(F("E: Wrong length for SysEx voice bulk upload (not 155)."));
#endif
return;
}
// checksum calculation
for (uint8_t i = 0; i < 155 ; i++)
{
bulk_checksum_calc -= sysex[i + 6];
}
bulk_checksum_calc &= 0x7f;
if (bulk_checksum_calc != bulk_checksum)
{
#ifdef DEBUG
Serial.print(F("E: Checksum error for one voice [0x"));
Serial.print(bulk_checksum, HEX);
Serial.print(F("/0x"));
Serial.print(bulk_checksum_calc, HEX);
Serial.println(F("]"));
#endif
return;
}
// fix voice name
for (uint8_t i = 0; i < 10; i++)
{
if (sysex[151 + i] > 126) // filter characters
sysex[151 + i] = 32;
}
// load sysex-data into voice memory
MicroDexed[instance_id]->loadVoiceParameters(&sysex[6]);
#ifdef DEBUG
show_patch(instance_id);
#endif
// show voice name
strncpy(g_voice_name[instance_id], (char*)&sysex[151], VOICE_NAME_LEN - 1);
if (LCDML.FUNC_getID() == LCDML.OTHER_getIDFromFunction(UI_func_voice_select))
{
LCDML.OTHER_updateFunc();
LCDML.loop_menu();
}
}
else if (len == 4104)
{
if (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 Bank bulk upload
if ((sysex[3] & 0x7f) != 9)
{ {
#ifdef DEBUG if (sysex[151 + i] > 126) // filter characters
Serial.println(F("E: Not a SysEx bank bulk upload.")); sysex[151 + i] = 32;
#endif
display.setCursor(0, 1);
display.print(F("Error (TYPE) "));
delay(MESSAGE_WAIT_TIME);
LCDML.FUNC_goBackToMenu();
return;
} }
#ifdef DEBUG // load sysex-data into voice memory
Serial.println(F("Bank bulk upload.")); MicroDexed[instance_id]->loadVoiceParameters(&sysex[6]);
#endif
if (((sysex[4] << 7) | sysex[5]) != 0x1000)
{
#ifdef DEBUG #ifdef DEBUG
Serial.println(F("E: Wrong length for SysEx bank bulk upload (not 4096).")); Serial.println(F("One Voice bulk upload"));
show_patch(instance_id);
#endif #endif
display.setCursor(0, 1); strncpy(g_voice_name[instance_id], (char*)&sysex[151], VOICE_NAME_LEN - 1);
display.print(F("Error (SIZE) "));
delay(MESSAGE_WAIT_TIME);
LCDML.FUNC_goBackToMenu();
return;
}
#ifdef DEBUG if (LCDML.FUNC_getID() == LCDML.OTHER_getIDFromFunction(UI_func_voice_select))
Serial.println(F("Bank type ok"));
#endif
// checksum calculation
for (uint16_t i = 0; i < 4096 ; i++)
{ {
bulk_checksum_calc -= sysex[i + 6]; LCDML.OTHER_updateFunc();
LCDML.loop_menu();
} }
bulk_checksum_calc &= 0x7f; break;
case 200:
if (bulk_checksum_calc != bulk_checksum) if (strlen(receive_bank_filename) > 0 && LCDML.FUNC_getID() == LCDML.OTHER_getIDFromFunction(UI_func_sysex_receive_bank))
{ {
#ifdef DEBUG #ifdef DEBUG
Serial.print(F("E: Checksum error for bank [0x")); Serial.println(F("Bank bulk upload."));
Serial.print(bulk_checksum, HEX); #endif
Serial.print(F("/0x")); if (save_sd_bank(receive_bank_filename, sysex))
Serial.print(bulk_checksum_calc, HEX); {
Serial.println(F("]"));
#endif
display.setCursor(0, 1);
display.print(F("Error (CHECKSUM)"));
delay(MESSAGE_WAIT_TIME);
LCDML.FUNC_goBackToMenu();
return;
}
#ifdef DEBUG #ifdef DEBUG
Serial.println(F("Bank checksum ok")); Serial.print(F("Bank saved as ["));
Serial.print(receive_bank_filename);
Serial.println(F("]"));
#endif #endif
display.setCursor(0, 1);
if (save_sd_bank(receive_bank_filename, sysex)) display.print(F("Done. "));
{ delay(MESSAGE_WAIT_TIME);
LCDML.FUNC_goBackToMenu();
}
else
{
#ifdef DEBUG #ifdef DEBUG
Serial.print(F("Bank saved as [")); Serial.println(F("Error during saving bank as ["));
Serial.print(receive_bank_filename); Serial.print(receive_bank_filename);
Serial.println(F("]")); Serial.println(F("]"));
#endif #endif
display.setCursor(0, 1); display.setCursor(0, 1);
display.print(F("Done. ")); display.print(F("Error. "));
delay(MESSAGE_WAIT_TIME); delay(MESSAGE_WAIT_TIME);
LCDML.FUNC_goBackToMenu(); LCDML.FUNC_goBackToMenu();
}
memset(receive_bank_filename, 0, FILENAME_LEN);
} }
else
{
#ifdef DEBUG #ifdef DEBUG
Serial.println(F("Error during saving bank as [")); else
Serial.print(receive_bank_filename); Serial.println(F("E : Not in MIDI receive bank mode."));
Serial.println(F("]"));
#endif #endif
display.setCursor(0, 1); break;
display.print(F("Error. ")); case 300:
delay(MESSAGE_WAIT_TIME);
LCDML.FUNC_goBackToMenu();
}
memset(receive_bank_filename, 0, FILENAME_LEN);
}
#ifdef DEBUG #ifdef DEBUG
else Serial.println(F("SysEx Voice parameter:"));
Serial.println(F("E: Not in MIDI receive bank mode.")); Serial.print(F("Parameter #"));
Serial.print(sysex[4] + ((sysex[3] & 0x03) * 128), DEC);
Serial.print(F(" Value: "));
Serial.println(sysex[5], DEC);
#endif #endif
} break;
default:
#ifdef DEBUG #ifdef DEBUG
else Serial.println(F("SysEx Voice parameter change : "));
Serial.println(F("E: SysEx parameter length wrong.")); Serial.print(F("Parameter #"));
Serial.print(sysex_return);
Serial.print(F(" Value : "));
Serial.println(sysex[5], DEC);
#endif #endif
break;
}
} }
} }

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save