|
|
|
@ -138,10 +138,10 @@ void create_audio_connections(AudioSourceMicroDexed &d) |
|
|
|
|
|
|
|
|
|
bool sd_card_available = false; |
|
|
|
|
uint8_t max_loaded_banks = 0; |
|
|
|
|
char bank_name[BANK_NAME_LEN]; |
|
|
|
|
char voice_name[VOICE_NAME_LEN]; |
|
|
|
|
char bank_names[MAX_BANKS][BANK_NAME_LEN]; |
|
|
|
|
char voice_names[MAX_VOICES][VOICE_NAME_LEN]; |
|
|
|
|
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]; |
|
|
|
|
elapsedMillis autostore; |
|
|
|
|
uint8_t midi_timing_counter = 0; // 24 per qarter
|
|
|
|
|
elapsedMillis midi_timing_timestep; |
|
|
|
@ -279,41 +279,47 @@ void setup() |
|
|
|
|
if (!SD.begin(SDCARD_CS_PIN)) |
|
|
|
|
{ |
|
|
|
|
Serial.println(F("SD card not accessable.")); |
|
|
|
|
strcpy(bank_name, "Default"); |
|
|
|
|
strcpy(voice_name, "Default"); |
|
|
|
|
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 |
|
|
|
|
{ |
|
|
|
|
Serial.println(F("SD card found.")); |
|
|
|
|
sd_card_available = true; |
|
|
|
|
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.bank[instance_id]], bank_name[instance_id]); |
|
|
|
|
|
|
|
|
|
// read all bank names
|
|
|
|
|
max_loaded_banks = get_bank_names(); |
|
|
|
|
strip_extension(bank_names[configuration.bank[0]], bank_name); |
|
|
|
|
|
|
|
|
|
// read all voice name for actual bank
|
|
|
|
|
get_voice_names_from_bank(configuration.bank[0]); |
|
|
|
|
// read all voice name for actual bank
|
|
|
|
|
get_voice_names_from_bank(configuration.bank[instance_id], instance_id); |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.print(F("Bank [")); |
|
|
|
|
Serial.print(bank_names[configuration.bank[0]]); |
|
|
|
|
Serial.print(F("/")); |
|
|
|
|
Serial.print(bank_name); |
|
|
|
|
Serial.println(F("]")); |
|
|
|
|
for (uint8_t n = 0; n < MAX_VOICES; n++) |
|
|
|
|
{ |
|
|
|
|
if (n < 10) |
|
|
|
|
Serial.print(F(" ")); |
|
|
|
|
Serial.print(F(" ")); |
|
|
|
|
Serial.print(n, DEC); |
|
|
|
|
Serial.print(F("[")); |
|
|
|
|
Serial.print(voice_names[n]); |
|
|
|
|
Serial.print(F("Bank [")); |
|
|
|
|
Serial.print(bank_names[instance_id][configuration.bank[instance_id]]); |
|
|
|
|
Serial.print(F("/")); |
|
|
|
|
Serial.print(bank_name[instance_id]); |
|
|
|
|
Serial.println(F("]")); |
|
|
|
|
} |
|
|
|
|
for (uint8_t n = 0; n < MAX_VOICES; 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_sysex(configuration.bank[0], configuration.voice[0]); |
|
|
|
|
// load default SYSEX data
|
|
|
|
|
load_sysex(configuration.bank[0], configuration.voice[0], instance_id); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef DISPLAY_LCD_SPI |
|
|
|
|
change_disp_sd(true); |
|
|
|
|
#endif |
|
|
|
@ -399,14 +405,17 @@ void setup() |
|
|
|
|
AudioMemoryUsageMaxReset(); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) |
|
|
|
|
{ |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.print(F("Bank/Voice from EEPROM [")); |
|
|
|
|
Serial.print(configuration.bank[0], DEC); |
|
|
|
|
Serial.print(F("/")); |
|
|
|
|
Serial.print(configuration.voice[0], DEC); |
|
|
|
|
Serial.println(F("]")); |
|
|
|
|
show_patch(); |
|
|
|
|
Serial.print(F("Bank/Voice from EEPROM [")); |
|
|
|
|
Serial.print(configuration.bank[instance_id], DEC); |
|
|
|
|
Serial.print(F("/")); |
|
|
|
|
Serial.print(configuration.voice[instance_id], DEC); |
|
|
|
|
Serial.println(F("]")); |
|
|
|
|
show_patch(instance_id); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Serial.print(F("AUDIO_BLOCK_SAMPLES=")); |
|
|
|
|
Serial.print(AUDIO_BLOCK_SAMPLES); |
|
|
|
@ -556,173 +565,163 @@ void loop() |
|
|
|
|
******************************************************************************/ |
|
|
|
|
void handleNoteOn(byte inChannel, byte inNumber, byte inVelocity) |
|
|
|
|
{ |
|
|
|
|
if (checkMidiChannel(inChannel)) |
|
|
|
|
for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) |
|
|
|
|
{ |
|
|
|
|
MicroDexed[0]->keydown(inNumber, inVelocity); |
|
|
|
|
if (checkMidiChannel(inChannel, instance_id)) |
|
|
|
|
{ |
|
|
|
|
MicroDexed[instance_id]->keydown(inNumber, inVelocity); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void handleNoteOff(byte inChannel, byte inNumber, byte inVelocity) |
|
|
|
|
{ |
|
|
|
|
if (checkMidiChannel(inChannel)) |
|
|
|
|
for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) |
|
|
|
|
{ |
|
|
|
|
MicroDexed[0]->keyup(inNumber); |
|
|
|
|
if (checkMidiChannel(inChannel, instance_id)) |
|
|
|
|
{ |
|
|
|
|
MicroDexed[instance_id]->keyup(inNumber); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void handleControlChange(byte inChannel, byte inCtrl, byte inValue) |
|
|
|
|
{ |
|
|
|
|
if (checkMidiChannel(inChannel)) |
|
|
|
|
for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) |
|
|
|
|
{ |
|
|
|
|
if (checkMidiChannel(inChannel, instance_id)) |
|
|
|
|
{ |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.print(F("CC#")); |
|
|
|
|
Serial.print(inCtrl, DEC); |
|
|
|
|
Serial.print(F(":")); |
|
|
|
|
Serial.println(inValue, DEC); |
|
|
|
|
Serial.print(F("INSTANCE ")); |
|
|
|
|
Serial.print(instance_id, DEC); |
|
|
|
|
Serial.print(F(": CC#")); |
|
|
|
|
Serial.print(inCtrl, DEC); |
|
|
|
|
Serial.print(F(":")); |
|
|
|
|
Serial.println(inValue, DEC); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
switch (inCtrl) { |
|
|
|
|
case 0: |
|
|
|
|
if (inValue < MAX_BANKS) |
|
|
|
|
{ |
|
|
|
|
configuration.bank[0] = inValue; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case 1: |
|
|
|
|
for (uint8_t i = 0; i < NUM_DEXED; i++) |
|
|
|
|
{ |
|
|
|
|
MicroDexed[i]->controllers.modwheel_cc = inValue; |
|
|
|
|
MicroDexed[i]->controllers.refresh(); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case 2: |
|
|
|
|
for (uint8_t i = 0; i < NUM_DEXED; i++) |
|
|
|
|
{ |
|
|
|
|
MicroDexed[i]->controllers.breath_cc = inValue; |
|
|
|
|
MicroDexed[i]->controllers.refresh(); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case 4: |
|
|
|
|
for (uint8_t i = 0; i < NUM_DEXED; i++) |
|
|
|
|
{ |
|
|
|
|
MicroDexed[i]->controllers.foot_cc = inValue; |
|
|
|
|
MicroDexed[i]->controllers.refresh(); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case 7: // Volume
|
|
|
|
|
configuration.vol = map(inValue, 0, 0x7f, VOLUME_MIN, VOLUME_MAX); |
|
|
|
|
soften_volume.update(configuration.vol, SOFTEN_VALUE_CHANGE_STEPS); |
|
|
|
|
break; |
|
|
|
|
case 10: // Pan
|
|
|
|
|
configuration.pan[0] = map(inValue, 0, 0x7f, PANORAMA_MIN, PANORAMA_MAX); |
|
|
|
|
set_volume(configuration.vol, configuration.pan[0], configuration.mono); |
|
|
|
|
break; |
|
|
|
|
case 32: // BankSelect LSB
|
|
|
|
|
configuration.bank[0] = inValue; |
|
|
|
|
break; |
|
|
|
|
case 64: |
|
|
|
|
for (uint8_t i = 0; i < NUM_DEXED; i++) |
|
|
|
|
{ |
|
|
|
|
MicroDexed[i]->setSustain(inValue > 63); |
|
|
|
|
if (!MicroDexed[i]->getSustain()) { |
|
|
|
|
for (uint8_t note = 0; note < MicroDexed[0]->getMaxNotes(); note++) { |
|
|
|
|
if (MicroDexed[i]->voices[note].sustained && !MicroDexed[i]->voices[note].keydown) { |
|
|
|
|
MicroDexed[i]->voices[note].dx7_note->keyup(); |
|
|
|
|
MicroDexed[i]->voices[note].sustained = false; |
|
|
|
|
switch (inCtrl) { |
|
|
|
|
case 0: |
|
|
|
|
if (inValue < MAX_BANKS) |
|
|
|
|
{ |
|
|
|
|
configuration.bank[instance_id] = inValue; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case 1: |
|
|
|
|
MicroDexed[instance_id]->controllers.modwheel_cc = inValue; |
|
|
|
|
MicroDexed[instance_id]->controllers.refresh(); |
|
|
|
|
break; |
|
|
|
|
case 2: |
|
|
|
|
MicroDexed[instance_id]->controllers.breath_cc = inValue; |
|
|
|
|
MicroDexed[instance_id]->controllers.refresh(); |
|
|
|
|
break; |
|
|
|
|
case 4: |
|
|
|
|
MicroDexed[instance_id]->controllers.foot_cc = inValue; |
|
|
|
|
MicroDexed[instance_id]->controllers.refresh(); |
|
|
|
|
break; |
|
|
|
|
case 7: // Volume
|
|
|
|
|
configuration.vol = map(inValue, 0, 0x7f, VOLUME_MIN, VOLUME_MAX); |
|
|
|
|
soften_volume.update(configuration.vol, SOFTEN_VALUE_CHANGE_STEPS); |
|
|
|
|
break; |
|
|
|
|
case 10: // Pan
|
|
|
|
|
configuration.pan[instance_id] = map(inValue, 0, 0x7f, PANORAMA_MIN, PANORAMA_MAX); |
|
|
|
|
set_volume(configuration.vol, configuration.pan[instance_id], configuration.mono); |
|
|
|
|
break; |
|
|
|
|
case 32: // BankSelect LSB
|
|
|
|
|
configuration.bank[instance_id] = inValue; |
|
|
|
|
break; |
|
|
|
|
case 64: |
|
|
|
|
MicroDexed[instance_id]->setSustain(inValue > 63); |
|
|
|
|
if (!MicroDexed[instance_id]->getSustain()) { |
|
|
|
|
for (uint8_t note = 0; note < MicroDexed[instance_id]->getMaxNotes(); note++) { |
|
|
|
|
if (MicroDexed[instance_id]->voices[note].sustained && !MicroDexed[instance_id]->voices[note].keydown) { |
|
|
|
|
MicroDexed[instance_id]->voices[note].dx7_note->keyup(); |
|
|
|
|
MicroDexed[instance_id]->voices[note].sustained = false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case 103: // CC 103: filter resonance
|
|
|
|
|
configuration.filter_resonance[0] = map(inValue, 0, 0x7f, FILTER_RESONANCE_MIN, FILTER_RESONANCE_MAX); |
|
|
|
|
for (uint8_t i = 0; i < NUM_DEXED; i++) |
|
|
|
|
{ |
|
|
|
|
MicroDexed[i]->fx.Reso = configuration.filter_resonance[i] / 100.0; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case 104: // CC 104: filter cutoff
|
|
|
|
|
configuration.filter_cutoff[0] = map(inValue, 0, 0x7f, FILTER_CUTOFF_MIN, FILTER_CUTOFF_MAX); |
|
|
|
|
for (uint8_t i = 0; i < NUM_DEXED; i++) |
|
|
|
|
{ |
|
|
|
|
MicroDexed[i]->fx.Cutoff = configuration.filter_cutoff[i] / 100.0; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case 105: // CC 105: delay time
|
|
|
|
|
configuration.delay_time = map(inValue, 0, 0x7f, DELAY_TIME_MIN, DELAY_TIME_MAX); |
|
|
|
|
delay1.delay(0, configuration.delay_time * 10); |
|
|
|
|
case 106: // CC 106: delay feedback
|
|
|
|
|
configuration.delay_feedback = map(inValue, 0, 0x7f, DELAY_FEEDBACK_MIN , DELAY_FEEDBACK_MAX); |
|
|
|
|
delay_fb_mixer.gain(1, configuration.delay_feedback / 100.0 ); // amount of feedback
|
|
|
|
|
delay_fb_mixer.gain(0, 1.0 - configuration.delay_feedback / 100.0); // original signalbreak;
|
|
|
|
|
break; |
|
|
|
|
case 107: // CC 107: delay volume
|
|
|
|
|
configuration.delay_level[0] = map(inValue, 0, 0x7f, DELAY_LEVEL_MIN, DELAY_LEVEL_MAX); |
|
|
|
|
master_mixer_r.gain(DELAY, configuration.delay_level[0] / 100.0); |
|
|
|
|
master_mixer_l.gain(2, configuration.delay_level[0] / 100.0); |
|
|
|
|
break; |
|
|
|
|
case 120: |
|
|
|
|
for (uint8_t i = 0; i < NUM_DEXED; i++) |
|
|
|
|
{ |
|
|
|
|
MicroDexed[i]->panic(); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case 121: |
|
|
|
|
for (uint8_t i = 0; i < NUM_DEXED; i++) |
|
|
|
|
{ |
|
|
|
|
MicroDexed[i]->resetControllers(); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case 123: |
|
|
|
|
for (uint8_t i = 0; i < NUM_DEXED; i++) |
|
|
|
|
{ |
|
|
|
|
MicroDexed[i]->notesOff(); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case 126: |
|
|
|
|
for (uint8_t i = 0; i < NUM_DEXED; i++) |
|
|
|
|
{ |
|
|
|
|
MicroDexed[i]->setMonoMode(true); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case 127: |
|
|
|
|
for (uint8_t i = 0; i < NUM_DEXED; i++) |
|
|
|
|
{ |
|
|
|
|
MicroDexed[i]->setMonoMode(false); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
break; |
|
|
|
|
case 103: // CC 103: filter resonance
|
|
|
|
|
configuration.filter_resonance[instance_id] = map(inValue, 0, 0x7f, FILTER_RESONANCE_MIN, FILTER_RESONANCE_MAX); |
|
|
|
|
MicroDexed[instance_id]->fx.Reso = configuration.filter_resonance[instance_id] / 100.0; |
|
|
|
|
break; |
|
|
|
|
case 104: // CC 104: filter cutoff
|
|
|
|
|
configuration.filter_cutoff[instance_id] = map(inValue, 0, 0x7f, FILTER_CUTOFF_MIN, FILTER_CUTOFF_MAX); |
|
|
|
|
MicroDexed[instance_id]->fx.Cutoff = configuration.filter_cutoff[instance_id] / 100.0; |
|
|
|
|
break; |
|
|
|
|
case 105: // CC 105: delay time
|
|
|
|
|
configuration.delay_time = map(inValue, 0, 0x7f, DELAY_TIME_MIN, DELAY_TIME_MAX); |
|
|
|
|
delay1.delay(0, configuration.delay_time * 10); |
|
|
|
|
case 106: // CC 106: delay feedback
|
|
|
|
|
configuration.delay_feedback = map(inValue, 0, 0x7f, DELAY_FEEDBACK_MIN , DELAY_FEEDBACK_MAX); |
|
|
|
|
delay_fb_mixer.gain(1, configuration.delay_feedback / 100.0 ); // amount of feedback
|
|
|
|
|
delay_fb_mixer.gain(0, 1.0 - configuration.delay_feedback / 100.0); // original signalbreak;
|
|
|
|
|
break; |
|
|
|
|
case 107: // CC 107: delay volume
|
|
|
|
|
configuration.delay_level[instance_id] = map(inValue, 0, 0x7f, DELAY_LEVEL_MIN, DELAY_LEVEL_MAX); |
|
|
|
|
master_mixer_r.gain(DELAY, configuration.delay_level[instance_id] / 100.0); |
|
|
|
|
master_mixer_l.gain(2, configuration.delay_level[instance_id] / 100.0); |
|
|
|
|
break; |
|
|
|
|
case 120: |
|
|
|
|
MicroDexed[instance_id]->panic(); |
|
|
|
|
break; |
|
|
|
|
case 121: |
|
|
|
|
MicroDexed[instance_id]->resetControllers(); |
|
|
|
|
break; |
|
|
|
|
case 123: |
|
|
|
|
MicroDexed[instance_id]->notesOff(); |
|
|
|
|
break; |
|
|
|
|
case 126: |
|
|
|
|
MicroDexed[instance_id]->setMonoMode(true); |
|
|
|
|
break; |
|
|
|
|
case 127: |
|
|
|
|
MicroDexed[instance_id]->setMonoMode(false); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void handleAfterTouch(byte inChannel, byte inPressure) |
|
|
|
|
{ |
|
|
|
|
for (uint8_t i = 0; i < NUM_DEXED; i++) |
|
|
|
|
for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) |
|
|
|
|
{ |
|
|
|
|
MicroDexed[i]->controllers.aftertouch_cc = inPressure; |
|
|
|
|
MicroDexed[i]->controllers.refresh(); |
|
|
|
|
if (checkMidiChannel(inChannel, instance_id)) |
|
|
|
|
{ |
|
|
|
|
MicroDexed[instance_id]->controllers.aftertouch_cc = inPressure; |
|
|
|
|
MicroDexed[instance_id]->controllers.refresh(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void handlePitchBend(byte inChannel, int inPitch) |
|
|
|
|
{ |
|
|
|
|
for (uint8_t i = 0; i < NUM_DEXED; i++) |
|
|
|
|
for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) |
|
|
|
|
{ |
|
|
|
|
MicroDexed[i]->controllers.values_[kControllerPitch] = inPitch + 0x2000; // -8192 to +8191 --> 0 to 16383
|
|
|
|
|
if (checkMidiChannel(inChannel, instance_id)) |
|
|
|
|
{ |
|
|
|
|
MicroDexed[instance_id]->controllers.values_[kControllerPitch] = inPitch + 0x2000; // -8192 to +8191 --> 0 to 16383
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void handleProgramChange(byte inChannel, byte inProgram) |
|
|
|
|
{ |
|
|
|
|
if (inProgram < MAX_VOICES) |
|
|
|
|
for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) |
|
|
|
|
{ |
|
|
|
|
if (checkMidiChannel(inChannel, instance_id)) |
|
|
|
|
{ |
|
|
|
|
if (inProgram < MAX_VOICES) |
|
|
|
|
{ |
|
|
|
|
#ifdef DISPLAY_LCD_SPI |
|
|
|
|
change_disp_sd(false); |
|
|
|
|
change_disp_sd(false); |
|
|
|
|
#endif |
|
|
|
|
load_sysex(configuration.bank[0], inProgram); |
|
|
|
|
load_sysex(configuration.bank[instance_id], inProgram, instance_id); |
|
|
|
|
#ifdef DISPLAY_LCD_SPI |
|
|
|
|
change_disp_sd(true); |
|
|
|
|
change_disp_sd(true); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -746,166 +745,172 @@ void handleSystemExclusive(byte * sysex, uint len) |
|
|
|
|
11110111 F7 Status - end sysex |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.print(F("SYSEX-Data[")); |
|
|
|
|
Serial.print(len, DEC); |
|
|
|
|
Serial.print(F("]")); |
|
|
|
|
for (uint8_t i = 0; i < len; i++) |
|
|
|
|
for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) |
|
|
|
|
{ |
|
|
|
|
Serial.print(F(" ")); |
|
|
|
|
Serial.print(sysex[i], DEC); |
|
|
|
|
} |
|
|
|
|
Serial.println(); |
|
|
|
|
if (!checkMidiChannel((sysex[2] & 0x0f) + 1 , instance_id)) |
|
|
|
|
{ |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.print(F("INSTANCE ")); |
|
|
|
|
Serial.print(instance_id, DEC); |
|
|
|
|
Serial.println(F(": SYSEX-MIDI-Channel mismatch")); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
if (!checkMidiChannel((sysex[2] & 0x0f) + 1 )) |
|
|
|
|
{ |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.println(F("SYSEX-MIDI-Channel mismatch")); |
|
|
|
|
Serial.print(F("INSTANCE ")); |
|
|
|
|
Serial.print(instance_id, DEC); |
|
|
|
|
Serial.print(F(": SYSEX-Data[")); |
|
|
|
|
Serial.print(len, DEC); |
|
|
|
|
Serial.print(F("]")); |
|
|
|
|
for (uint8_t i = 0; i < len; i++) |
|
|
|
|
{ |
|
|
|
|
Serial.print(F(" ")); |
|
|
|
|
Serial.print(sysex[i], DEC); |
|
|
|
|
} |
|
|
|
|
Serial.println(); |
|
|
|
|
#endif |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (sysex[1] != 0x43) // check for Yamaha sysex
|
|
|
|
|
{ |
|
|
|
|
if (sysex[1] != 0x43) // check for Yamaha sysex
|
|
|
|
|
{ |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.println(F("E: SysEx vendor not Yamaha.")); |
|
|
|
|
Serial.println(F("E: SysEx vendor not Yamaha.")); |
|
|
|
|
#endif |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.print(F("Substatus: [")); |
|
|
|
|
Serial.print((sysex[2] & 0x70) >> 4); |
|
|
|
|
Serial.println(F("]")); |
|
|
|
|
Serial.print(F("Substatus: [")); |
|
|
|
|
Serial.print((sysex[2] & 0x70) >> 4); |
|
|
|
|
Serial.println(F("]")); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
// parse parameter change
|
|
|
|
|
if (len == 7) |
|
|
|
|
{ |
|
|
|
|
if (((sysex[3] & 0x7c) >> 2) != 0 && ((sysex[3] & 0x7c) >> 2) != 2) |
|
|
|
|
// parse parameter change
|
|
|
|
|
if (len == 7) |
|
|
|
|
{ |
|
|
|
|
if (((sysex[3] & 0x7c) >> 2) != 0 && ((sysex[3] & 0x7c) >> 2) != 2) |
|
|
|
|
{ |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.println(F("E: Not a SysEx parameter or function parameter change.")); |
|
|
|
|
Serial.println(F("E: Not a SysEx parameter or function parameter change.")); |
|
|
|
|
#endif |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
if (sysex[6] != 0xf7) |
|
|
|
|
{ |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
if (sysex[6] != 0xf7) |
|
|
|
|
{ |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.println(F("E: SysEx end status byte not detected.")); |
|
|
|
|
Serial.println(F("E: SysEx end status byte not detected.")); |
|
|
|
|
#endif |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
sysex[4] &= 0x7f; |
|
|
|
|
sysex[5] &= 0x7f; |
|
|
|
|
sysex[4] &= 0x7f; |
|
|
|
|
sysex[5] &= 0x7f; |
|
|
|
|
|
|
|
|
|
uint8_t data_index; |
|
|
|
|
uint8_t data_index; |
|
|
|
|
|
|
|
|
|
if (((sysex[3] & 0x7c) >> 2) == 0) |
|
|
|
|
{ |
|
|
|
|
MicroDexed[0]->notesOff(); |
|
|
|
|
MicroDexed[0]->data[sysex[4] + ((sysex[3] & 0x03) * 128)] = sysex[5]; // set parameter
|
|
|
|
|
MicroDexed[0]->doRefreshVoice(); |
|
|
|
|
data_index = sysex[4] + ((sysex[3] & 0x03) * 128); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
MicroDexed[0]->data[DEXED_GLOBAL_PARAMETER_OFFSET - 63 + sysex[4]] = sysex[5]; // set function parameter
|
|
|
|
|
MicroDexed[0]->controllers.values_[kControllerPitchRange] = MicroDexed[0]->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_PITCHBEND_RANGE]; |
|
|
|
|
MicroDexed[0]->controllers.values_[kControllerPitchStep] = MicroDexed[0]->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_PITCHBEND_STEP]; |
|
|
|
|
MicroDexed[0]->controllers.wheel.setRange(MicroDexed[0]->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_MODWHEEL_RANGE]); |
|
|
|
|
MicroDexed[0]->controllers.wheel.setTarget(MicroDexed[0]->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_MODWHEEL_ASSIGN]); |
|
|
|
|
MicroDexed[0]->controllers.foot.setRange(MicroDexed[0]->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_FOOTCTRL_RANGE]); |
|
|
|
|
MicroDexed[0]->controllers.foot.setTarget(MicroDexed[0]->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_FOOTCTRL_ASSIGN]); |
|
|
|
|
MicroDexed[0]->controllers.breath.setRange(MicroDexed[0]->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_BREATHCTRL_RANGE]); |
|
|
|
|
MicroDexed[0]->controllers.breath.setTarget(MicroDexed[0]->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_BREATHCTRL_ASSIGN]); |
|
|
|
|
MicroDexed[0]->controllers.at.setRange(MicroDexed[0]->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_AT_RANGE]); |
|
|
|
|
MicroDexed[0]->controllers.at.setTarget(MicroDexed[0]->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_AT_ASSIGN]); |
|
|
|
|
MicroDexed[0]->controllers.masterTune = (MicroDexed[0]->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_MASTER_TUNE] * 0x4000 << 11) * (1.0 / 12); |
|
|
|
|
MicroDexed[0]->controllers.refresh(); |
|
|
|
|
data_index = DEXED_GLOBAL_PARAMETER_OFFSET - 63 + sysex[4]; |
|
|
|
|
} |
|
|
|
|
if (((sysex[3] & 0x7c) >> 2) == 0) |
|
|
|
|
{ |
|
|
|
|
MicroDexed[instance_id]->notesOff(); |
|
|
|
|
MicroDexed[instance_id]->data[sysex[4] + ((sysex[3] & 0x03) * 128)] = sysex[5]; // set parameter
|
|
|
|
|
MicroDexed[instance_id]->doRefreshVoice(); |
|
|
|
|
data_index = sysex[4] + ((sysex[3] & 0x03) * 128); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
MicroDexed[instance_id]->data[DEXED_GLOBAL_PARAMETER_OFFSET - 63 + sysex[4]] = sysex[5]; // set function parameter
|
|
|
|
|
MicroDexed[instance_id]->controllers.values_[kControllerPitchRange] = MicroDexed[instance_id]->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_PITCHBEND_RANGE]; |
|
|
|
|
MicroDexed[instance_id]->controllers.values_[kControllerPitchStep] = MicroDexed[instance_id]->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_PITCHBEND_STEP]; |
|
|
|
|
MicroDexed[instance_id]->controllers.wheel.setRange(MicroDexed[instance_id]->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_MODWHEEL_RANGE]); |
|
|
|
|
MicroDexed[instance_id]->controllers.wheel.setTarget(MicroDexed[instance_id]->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_MODWHEEL_ASSIGN]); |
|
|
|
|
MicroDexed[instance_id]->controllers.foot.setRange(MicroDexed[instance_id]->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_FOOTCTRL_RANGE]); |
|
|
|
|
MicroDexed[instance_id]->controllers.foot.setTarget(MicroDexed[instance_id]->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_FOOTCTRL_ASSIGN]); |
|
|
|
|
MicroDexed[instance_id]->controllers.breath.setRange(MicroDexed[instance_id]->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_BREATHCTRL_RANGE]); |
|
|
|
|
MicroDexed[instance_id]->controllers.breath.setTarget(MicroDexed[instance_id]->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_BREATHCTRL_ASSIGN]); |
|
|
|
|
MicroDexed[instance_id]->controllers.at.setRange(MicroDexed[instance_id]->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_AT_RANGE]); |
|
|
|
|
MicroDexed[instance_id]->controllers.at.setTarget(MicroDexed[instance_id]->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_AT_ASSIGN]); |
|
|
|
|
MicroDexed[instance_id]->controllers.masterTune = (MicroDexed[instance_id]->data[DEXED_GLOBAL_PARAMETER_OFFSET + DEXED_MASTER_TUNE] * 0x4000 << 11) * (1.0 / 12); |
|
|
|
|
MicroDexed[instance_id]->controllers.refresh(); |
|
|
|
|
data_index = DEXED_GLOBAL_PARAMETER_OFFSET - 63 + sysex[4]; |
|
|
|
|
} |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.print(F("SysEx")); |
|
|
|
|
if (((sysex[3] & 0x7c) >> 2) == 0) |
|
|
|
|
Serial.print(F(" function")); |
|
|
|
|
Serial.print(F(" parameter ")); |
|
|
|
|
Serial.print(sysex[4], DEC); |
|
|
|
|
Serial.print(F(" = ")); |
|
|
|
|
Serial.print(sysex[5], DEC); |
|
|
|
|
Serial.print(F(", data_index = ")); |
|
|
|
|
Serial.println(data_index, DEC); |
|
|
|
|
Serial.print(F("SysEx")); |
|
|
|
|
if (((sysex[3] & 0x7c) >> 2) == 0) |
|
|
|
|
Serial.print(F(" function")); |
|
|
|
|
Serial.print(F(" parameter ")); |
|
|
|
|
Serial.print(sysex[4], DEC); |
|
|
|
|
Serial.print(F(" = ")); |
|
|
|
|
Serial.print(sysex[5], DEC); |
|
|
|
|
Serial.print(F(", data_index = ")); |
|
|
|
|
Serial.println(data_index, DEC); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
else if (len == 163) |
|
|
|
|
{ |
|
|
|
|
int32_t bulk_checksum_calc = 0; |
|
|
|
|
int8_t bulk_checksum = sysex[161]; |
|
|
|
|
} |
|
|
|
|
else if (len == 163) |
|
|
|
|
{ |
|
|
|
|
int32_t bulk_checksum_calc = 0; |
|
|
|
|
int8_t bulk_checksum = sysex[161]; |
|
|
|
|
|
|
|
|
|
// 1 Voice bulk upload
|
|
|
|
|
// 1 Voice bulk upload
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.println(F("One Voice bulk upload")); |
|
|
|
|
Serial.println(F("One Voice bulk upload")); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
if (sysex[162] != 0xf7) |
|
|
|
|
{ |
|
|
|
|
if (sysex[162] != 0xf7) |
|
|
|
|
{ |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.println(F("E: Found no SysEx end marker.")); |
|
|
|
|
Serial.println(F("E: Found no SysEx end marker.")); |
|
|
|
|
#endif |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if ((sysex[3] & 0x7f) != 0) |
|
|
|
|
{ |
|
|
|
|
if ((sysex[3] & 0x7f) != 0) |
|
|
|
|
{ |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.println(F("E: Not a SysEx voice bulk upload.")); |
|
|
|
|
Serial.println(F("E: Not a SysEx voice bulk upload.")); |
|
|
|
|
#endif |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (((sysex[4] << 7) | sysex[5]) != 0x9b) |
|
|
|
|
{ |
|
|
|
|
if (((sysex[4] << 7) | sysex[5]) != 0x9b) |
|
|
|
|
{ |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.println(F("E: Wrong length for SysEx voice bulk upload (not 155).")); |
|
|
|
|
Serial.println(F("E: Wrong length for SysEx voice bulk upload (not 155).")); |
|
|
|
|
#endif |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// checksum calculation
|
|
|
|
|
for (uint8_t i = 0; i < 155 ; i++) |
|
|
|
|
{ |
|
|
|
|
bulk_checksum_calc -= sysex[i + 6]; |
|
|
|
|
} |
|
|
|
|
bulk_checksum_calc &= 0x7f; |
|
|
|
|
// 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) |
|
|
|
|
{ |
|
|
|
|
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("]")); |
|
|
|
|
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; |
|
|
|
|
} |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// load sysex-data into voice memory
|
|
|
|
|
MicroDexed[0]->loadVoiceParameters(&sysex[6]); |
|
|
|
|
//MicroDexed[0]->initGlobalParameters();
|
|
|
|
|
// load sysex-data into voice memory
|
|
|
|
|
MicroDexed[instance_id]->loadVoiceParameters(&sysex[6]); |
|
|
|
|
//MicroDexed[instance_id]->initGlobalParameters();
|
|
|
|
|
|
|
|
|
|
// manipulate UI names and numbers
|
|
|
|
|
strncpy(voice_name, (char *)&sysex[151], sizeof(voice_name) - 1); |
|
|
|
|
Serial.print(F("Got voice [")); |
|
|
|
|
Serial.print(voice_name); |
|
|
|
|
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 |
|
|
|
|
Serial.println(F("E: SysEx parameter length wrong.")); |
|
|
|
|
else |
|
|
|
|
Serial.println(F("E: SysEx parameter length wrong.")); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void handleTimeCodeQuarterFrame(byte data) |
|
|
|
@ -969,31 +974,36 @@ void handleActiveSensing(void) |
|
|
|
|
|
|
|
|
|
void handleSystemReset(void) |
|
|
|
|
{ |
|
|
|
|
for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) |
|
|
|
|
{ |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.println(F("MIDI SYSEX RESET")); |
|
|
|
|
Serial.println(F("MIDI SYSEX RESET")); |
|
|
|
|
#endif |
|
|
|
|
MicroDexed[0]->notesOff(); |
|
|
|
|
MicroDexed[0]->panic(); |
|
|
|
|
MicroDexed[0]->resetControllers(); |
|
|
|
|
MicroDexed[instance_id]->notesOff(); |
|
|
|
|
MicroDexed[instance_id]->panic(); |
|
|
|
|
MicroDexed[instance_id]->resetControllers(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
|
MIDI HELPER |
|
|
|
|
******************************************************************************/ |
|
|
|
|
bool checkMidiChannel(byte inChannel) |
|
|
|
|
bool checkMidiChannel(byte inChannel, uint8_t instance_id) |
|
|
|
|
{ |
|
|
|
|
// check for MIDI channel
|
|
|
|
|
if (configuration.midi_channel[0] == MIDI_CHANNEL_OMNI) |
|
|
|
|
if (configuration.midi_channel[instance_id] == MIDI_CHANNEL_OMNI) |
|
|
|
|
{ |
|
|
|
|
return (true); |
|
|
|
|
} |
|
|
|
|
else if (inChannel != configuration.midi_channel[0]) |
|
|
|
|
else if (inChannel != configuration.midi_channel[instance_id]) |
|
|
|
|
{ |
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.print(F("Ignoring MIDI data on channel ")); |
|
|
|
|
Serial.print(F("INSTANCE ")); |
|
|
|
|
Serial.print(instance_id, DEC); |
|
|
|
|
Serial.print(F(": Ignoring MIDI data on channel ")); |
|
|
|
|
Serial.print(inChannel); |
|
|
|
|
Serial.print(F("(listening on ")); |
|
|
|
|
Serial.print(configuration.midi_channel[0]); |
|
|
|
|
Serial.print(configuration.midi_channel[instance_id]); |
|
|
|
|
Serial.println(F(")")); |
|
|
|
|
#endif |
|
|
|
|
return (false); |
|
|
|
@ -1132,13 +1142,56 @@ void initial_values_from_eeprom(void) |
|
|
|
|
configuration.at_assign[i] = AT_ASSIGN_DEFAULT; |
|
|
|
|
configuration.op_enabled[i] = OP_ENABLED_DEFAULT; |
|
|
|
|
} |
|
|
|
|
eeprom_update(); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
EEPROM_readAnything(EEPROM_START_ADDRESS, configuration); |
|
|
|
|
|
|
|
|
|
configuration.instances %= INSTANCES_MAX; |
|
|
|
|
configuration.instance_mode %= INSTANCE_MODE_MAX; |
|
|
|
|
configuration.instance_splitpoint %= INSTANCE_SPLITPOINT_MAX; |
|
|
|
|
configuration.vol %= VOLUME_MAX; |
|
|
|
|
configuration.mono %= MONO_MAX; |
|
|
|
|
configuration.reverb_roomsize %= REVERB_ROOMSIZE_MAX; |
|
|
|
|
configuration.reverb_damping %= REVERB_DAMPING_MAX; |
|
|
|
|
configuration.chorus_frequency %= CHORUS_FREQUENCY_MAX; |
|
|
|
|
configuration.chorus_waveform %= CHORUS_WAVEFORM_MAX; |
|
|
|
|
configuration.chorus_depth %= CHORUS_DEPTH_MAX; |
|
|
|
|
configuration.delay_time %= DELAY_TIME_MAX; |
|
|
|
|
configuration.delay_feedback %= DELAY_FEEDBACK_MAX; |
|
|
|
|
for (uint8_t i = 0; i < NUM_DEXED; i++) |
|
|
|
|
{ |
|
|
|
|
configuration.midi_channel[i] %= MIDI_CHANNEL_MAX; |
|
|
|
|
configuration.bank[i] %= MAX_BANKS; |
|
|
|
|
configuration.voice[i] %= MAX_VOICES; |
|
|
|
|
configuration.pan[i] %= PANORAMA_MAX; |
|
|
|
|
configuration.reverb_level[i] %= REVERB_LEVEL_MAX; |
|
|
|
|
configuration.chorus_level[i] %= CHORUS_LEVEL_MAX; |
|
|
|
|
configuration.delay_level[i] %= DELAY_LEVEL_MAX; |
|
|
|
|
configuration.filter_cutoff[i] %= FILTER_CUTOFF_MAX; |
|
|
|
|
configuration.filter_resonance[i] %= FILTER_RESONANCE_MAX; |
|
|
|
|
configuration.loudness[i] %= LOUDNESS_MAX; |
|
|
|
|
configuration.polyphony[i] %= POLYPHONY_MAX; |
|
|
|
|
configuration.engine[i] %= ENGINE_MAX; |
|
|
|
|
configuration.monopoly[i] %= MONOPOLY_MAX; |
|
|
|
|
configuration.pb_range[i] %= PB_RANGE_MAX; |
|
|
|
|
configuration.pb_step[i] %= PB_STEP_MAX; |
|
|
|
|
configuration.mw_range[i] %= MW_RANGE_MAX; |
|
|
|
|
configuration.mw_assign[i] %= MW_ASSIGN_MAX; |
|
|
|
|
configuration.fc_range[i] %= FC_RANGE_MAX; |
|
|
|
|
configuration.fc_assign[i] %= FC_ASSIGN_MAX; |
|
|
|
|
configuration.bc_range[i] %= BC_RANGE_MAX; |
|
|
|
|
configuration.bc_assign[i] %= BC_ASSIGN_MAX; |
|
|
|
|
configuration.at_range[i] %= AT_RANGE_MAX; |
|
|
|
|
configuration.at_assign[i] %= AT_ASSIGN_MAX; |
|
|
|
|
configuration.op_enabled[i] %= 0x3f; |
|
|
|
|
|
|
|
|
|
//MicroDexed[i]->setControllers(configuration.pb_range[i], configuration.pb_step[i], configuration.mw_range[i], configuration.mw_assign[i], configuration.fc_range[i], configuration.fc_assign[i], configuration.bc_range[i], configuration.bc_assign[i], configuration.at_range[i], configuration.at_assign[i]);
|
|
|
|
|
} |
|
|
|
|
Serial.print(F(" - OK, loading!")); |
|
|
|
|
} |
|
|
|
|
eeprom_update(); |
|
|
|
|
|
|
|
|
|
#ifdef DEBUG |
|
|
|
|
Serial.println(); |
|
|
|
|
show_configuration(); |
|
|
|
@ -1190,6 +1243,17 @@ uint32_t crc32(byte * calc_start, uint16_t calc_bytes) // base code from https:/ |
|
|
|
|
#if defined (DEBUG) && defined (SHOW_CPU_LOAD_MSEC) |
|
|
|
|
void show_cpu_and_mem_usage(void) |
|
|
|
|
{ |
|
|
|
|
uint32_t sum_xrun = 0; |
|
|
|
|
uint16_t sum_render_time_max = 0; |
|
|
|
|
uint32_t sum_overload = 0; |
|
|
|
|
|
|
|
|
|
for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) |
|
|
|
|
{ |
|
|
|
|
sum_xrun += MicroDexed[instance_id]->xrun; |
|
|
|
|
sum_render_time_max += MicroDexed[instance_id]->render_time_max; |
|
|
|
|
sum_overload += MicroDexed[instance_id]->overload; |
|
|
|
|
MicroDexed[instance_id]->render_time_max = 0; |
|
|
|
|
} |
|
|
|
|
Serial.print(F("CPU: ")); |
|
|
|
|
Serial.print(AudioProcessorUsage(), 2); |
|
|
|
|
Serial.print(F("% CPU MAX: ")); |
|
|
|
@ -1199,11 +1263,11 @@ void show_cpu_and_mem_usage(void) |
|
|
|
|
Serial.print(F(" MEM MAX: ")); |
|
|
|
|
Serial.print(AudioMemoryUsageMax(), DEC); |
|
|
|
|
Serial.print(F(" RENDER_TIME_MAX: ")); |
|
|
|
|
Serial.print(MicroDexed[0]->render_time_max, DEC); |
|
|
|
|
Serial.print(sum_render_time_max, DEC); |
|
|
|
|
Serial.print(F(" XRUN: ")); |
|
|
|
|
Serial.print(MicroDexed[0]->xrun, DEC); |
|
|
|
|
Serial.print(sum_xrun, DEC); |
|
|
|
|
Serial.print(F(" OVERLOAD: ")); |
|
|
|
|
Serial.print(MicroDexed[0]->overload, DEC); |
|
|
|
|
Serial.print(sum_overload, DEC); |
|
|
|
|
Serial.print(F(" PEAK: ")); |
|
|
|
|
Serial.print(peak, DEC); |
|
|
|
|
Serial.print(F(" BLOCKSIZE: ")); |
|
|
|
@ -1213,7 +1277,6 @@ void show_cpu_and_mem_usage(void) |
|
|
|
|
Serial.println(); |
|
|
|
|
AudioProcessorUsageMaxReset(); |
|
|
|
|
AudioMemoryUsageMaxReset(); |
|
|
|
|
MicroDexed[0]->render_time_max = 0; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
@ -1237,7 +1300,7 @@ void show_configuration(void) |
|
|
|
|
Serial.print(F("Delay Feedback ")); Serial.println(configuration.delay_feedback, DEC); |
|
|
|
|
for (uint8_t i = 0; i < NUM_DEXED; i++) |
|
|
|
|
{ |
|
|
|
|
Serial.print(F("=== DEXED Instance ")); |
|
|
|
|
Serial.print(F("=== DEXED INSTANCE ")); |
|
|
|
|
Serial.print(i, DEC); |
|
|
|
|
Serial.println(" ==="); |
|
|
|
|
Serial.print(F(" MIDI-Channel ")); Serial.println(configuration.midi_channel[i], DEC); |
|
|
|
@ -1268,11 +1331,14 @@ void show_configuration(void) |
|
|
|
|
Serial.println(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void show_patch(void) |
|
|
|
|
void show_patch(uint8_t instance_id) |
|
|
|
|
{ |
|
|
|
|
uint8_t i; |
|
|
|
|
char voicename[VOICE_NAME_LEN]; |
|
|
|
|
|
|
|
|
|
Serial.print(F("INSTANCE ")); |
|
|
|
|
Serial.println(instance_id, DEC); |
|
|
|
|
|
|
|
|
|
memset(voicename, 0, sizeof(voicename)); |
|
|
|
|
for (i = 0; i < 6; i++) |
|
|
|
|
{ |
|
|
|
@ -1280,81 +1346,81 @@ void show_patch(void) |
|
|
|
|
Serial.print(6 - i, DEC); |
|
|
|
|
Serial.println(F(": ")); |
|
|
|
|
Serial.println(F("R1 | R2 | R3 | R4 | L1 | L2 | L3 | L4 LEV_SCL_BRK_PT | SCL_LEFT_DEPTH | SCL_RGHT_DEPTH")); |
|
|
|
|
Serial.print(MicroDexed[0]->data[(i * 21) + DEXED_OP_EG_R1], DEC); |
|
|
|
|
Serial.print(MicroDexed[instance_id]->data[(i * 21) + DEXED_OP_EG_R1], DEC); |
|
|
|
|
Serial.print(F(" ")); |
|
|
|
|
Serial.print(MicroDexed[0]->data[(i * 21) + DEXED_OP_EG_R2], DEC); |
|
|
|
|
Serial.print(MicroDexed[instance_id]->data[(i * 21) + DEXED_OP_EG_R2], DEC); |
|
|
|
|
Serial.print(F(" ")); |
|
|
|
|
Serial.print(MicroDexed[0]->data[(i * 21) + DEXED_OP_EG_R3], DEC); |
|
|
|
|
Serial.print(MicroDexed[instance_id]->data[(i * 21) + DEXED_OP_EG_R3], DEC); |
|
|
|
|
Serial.print(F(" ")); |
|
|
|
|
Serial.print(MicroDexed[0]->data[(i * 21) + DEXED_OP_EG_R4], DEC); |
|
|
|
|
Serial.print(MicroDexed[instance_id]->data[(i * 21) + DEXED_OP_EG_R4], DEC); |
|
|
|
|
Serial.print(F(" ")); |
|
|
|
|
Serial.print(MicroDexed[0]->data[(i * 21) + DEXED_OP_EG_L1], DEC); |
|
|
|
|
Serial.print(MicroDexed[instance_id]->data[(i * 21) + DEXED_OP_EG_L1], DEC); |
|
|
|
|
Serial.print(F(" ")); |
|
|
|
|
Serial.print(MicroDexed[0]->data[(i * 21) + DEXED_OP_EG_L2], DEC); |
|
|
|
|
Serial.print(MicroDexed[instance_id]->data[(i * 21) + DEXED_OP_EG_L2], DEC); |
|
|
|
|
Serial.print(F(" ")); |
|
|
|
|
Serial.print(MicroDexed[0]->data[(i * 21) + DEXED_OP_EG_L3], DEC); |
|
|
|
|
Serial.print(MicroDexed[instance_id]->data[(i * 21) + DEXED_OP_EG_L3], DEC); |
|
|
|
|
Serial.print(F(" ")); |
|
|
|
|
Serial.print(MicroDexed[0]->data[(i * 21) + DEXED_OP_EG_L4], DEC); |
|
|
|
|
Serial.print(MicroDexed[instance_id]->data[(i * 21) + DEXED_OP_EG_L4], DEC); |
|
|
|
|
Serial.print(F(" ")); |
|
|
|
|
Serial.print(MicroDexed[0]->data[(i * 21) + DEXED_OP_LEV_SCL_BRK_PT], DEC); |
|
|
|
|
Serial.print(MicroDexed[instance_id]->data[(i * 21) + DEXED_OP_LEV_SCL_BRK_PT], DEC); |
|
|
|
|
Serial.print(F(" ")); |
|
|
|
|
Serial.print(MicroDexed[0]->data[(i * 21) + DEXED_OP_SCL_LEFT_DEPTH], DEC); |
|
|
|
|
Serial.print(MicroDexed[instance_id]->data[(i * 21) + DEXED_OP_SCL_LEFT_DEPTH], DEC); |
|
|
|
|
Serial.print(F(" ")); |
|
|
|
|
Serial.println(MicroDexed[0]->data[(i * 21) + DEXED_OP_SCL_RGHT_DEPTH], DEC); |
|
|
|
|
Serial.println(MicroDexed[instance_id]->data[(i * 21) + DEXED_OP_SCL_RGHT_DEPTH], DEC); |
|
|
|
|
Serial.println(F("SCL_L_CURVE | SCL_R_CURVE | RT_SCALE | AMS | KVS | OUT_LEV | OP_MOD | FRQ_C | FRQ_F | DETUNE")); |
|
|
|
|
Serial.print(F(" ")); |
|
|
|
|
Serial.print(MicroDexed[0]->data[(i * 21) + DEXED_OP_SCL_LEFT_CURVE], DEC); |
|
|
|
|
Serial.print(MicroDexed[instance_id]->data[(i * 21) + DEXED_OP_SCL_LEFT_CURVE], DEC); |
|
|
|
|
Serial.print(F(" ")); |
|
|
|
|
Serial.print(MicroDexed[0]->data[(i * 21) + DEXED_OP_SCL_RGHT_CURVE], DEC); |
|
|
|
|
Serial.print(MicroDexed[instance_id]->data[(i * 21) + DEXED_OP_SCL_RGHT_CURVE], DEC); |
|
|
|
|
Serial.print(F(" ")); |
|
|
|
|
Serial.print(MicroDexed[0]->data[(i * 21) + DEXED_OP_OSC_RATE_SCALE], DEC); |
|
|
|
|
Serial.print(MicroDexed[instance_id]->data[(i * 21) + DEXED_OP_OSC_RATE_SCALE], DEC); |
|
|
|
|
Serial.print(F(" ")); |
|
|
|
|
Serial.print(MicroDexed[0]->data[(i * 21) + DEXED_OP_AMP_MOD_SENS], DEC); |
|
|
|
|
Serial.print(MicroDexed[instance_id]->data[(i * 21) + DEXED_OP_AMP_MOD_SENS], DEC); |
|
|
|
|
Serial.print(F(" ")); |
|
|
|
|
Serial.print(MicroDexed[0]->data[(i * 21) + DEXED_OP_KEY_VEL_SENS], DEC); |
|
|
|
|
Serial.print(MicroDexed[instance_id]->data[(i * 21) + DEXED_OP_KEY_VEL_SENS], DEC); |
|
|
|
|
Serial.print(F(" ")); |
|
|
|
|
Serial.print(MicroDexed[0]->data[(i * 21) + DEXED_OP_OUTPUT_LEV], DEC); |
|
|
|
|
Serial.print(MicroDexed[instance_id]->data[(i * 21) + DEXED_OP_OUTPUT_LEV], DEC); |
|
|
|
|
Serial.print(F(" ")); |
|
|
|
|
Serial.print(MicroDexed[0]->data[(i * 21) + DEXED_OP_OSC_MODE], DEC); |
|
|
|
|
Serial.print(MicroDexed[instance_id]->data[(i * 21) + DEXED_OP_OSC_MODE], DEC); |
|
|
|
|
Serial.print(F(" ")); |
|
|
|
|
Serial.print(MicroDexed[0]->data[(i * 21) + DEXED_OP_FREQ_COARSE], DEC); |
|
|
|
|
Serial.print(MicroDexed[instance_id]->data[(i * 21) + DEXED_OP_FREQ_COARSE], DEC); |
|
|
|
|
Serial.print(F(" ")); |
|
|
|
|
Serial.print(MicroDexed[0]->data[(i * 21) + DEXED_OP_FREQ_FINE], DEC); |
|
|
|
|
Serial.print(MicroDexed[instance_id]->data[(i * 21) + DEXED_OP_FREQ_FINE], DEC); |
|
|
|
|
Serial.print(F(" ")); |
|
|
|
|
Serial.println(MicroDexed[0]->data[(i * 21) + DEXED_OP_OSC_DETUNE], DEC); |
|
|
|
|
Serial.println(MicroDexed[instance_id]->data[(i * 21) + DEXED_OP_OSC_DETUNE], DEC); |
|
|
|
|
} |
|
|
|
|
Serial.println(F("PR1 | PR2 | PR3 | PR4 | PL1 | PL2 | PL3 | PL4")); |
|
|
|
|
Serial.print(F(" ")); |
|
|
|
|
for (i = 0; i < 8; i++) |
|
|
|
|
{ |
|
|
|
|
Serial.print(MicroDexed[0]->data[DEXED_VOICE_OFFSET + i], DEC); |
|
|
|
|
Serial.print(MicroDexed[instance_id]->data[DEXED_VOICE_OFFSET + i], DEC); |
|
|
|
|
Serial.print(F(" ")); |
|
|
|
|
} |
|
|
|
|
Serial.println(); |
|
|
|
|
Serial.print(F("ALG: ")); |
|
|
|
|
Serial.println(MicroDexed[0]->data[DEXED_VOICE_OFFSET + DEXED_ALGORITHM], DEC); |
|
|
|
|
Serial.println(MicroDexed[instance_id]->data[DEXED_VOICE_OFFSET + DEXED_ALGORITHM], DEC); |
|
|
|
|
Serial.print(F("FB: ")); |
|
|
|
|
Serial.println(MicroDexed[0]->data[DEXED_VOICE_OFFSET + DEXED_FEEDBACK], DEC); |
|
|
|
|
Serial.println(MicroDexed[instance_id]->data[DEXED_VOICE_OFFSET + DEXED_FEEDBACK], DEC); |
|
|
|
|
Serial.print(F("OKS: ")); |
|
|
|
|
Serial.println(MicroDexed[0]->data[DEXED_VOICE_OFFSET + DEXED_OSC_KEY_SYNC], DEC); |
|
|
|
|
Serial.println(MicroDexed[instance_id]->data[DEXED_VOICE_OFFSET + DEXED_OSC_KEY_SYNC], DEC); |
|
|
|
|
Serial.print(F("LFO SPD: ")); |
|
|
|
|
Serial.println(MicroDexed[0]->data[DEXED_VOICE_OFFSET + DEXED_LFO_SPEED], DEC); |
|
|
|
|
Serial.println(MicroDexed[instance_id]->data[DEXED_VOICE_OFFSET + DEXED_LFO_SPEED], DEC); |
|
|
|
|
Serial.print(F("LFO_DLY: ")); |
|
|
|
|
Serial.println(MicroDexed[0]->data[DEXED_VOICE_OFFSET + DEXED_LFO_DELAY], DEC); |
|
|
|
|
Serial.println(MicroDexed[instance_id]->data[DEXED_VOICE_OFFSET + DEXED_LFO_DELAY], DEC); |
|
|
|
|
Serial.print(F("LFO PMD: ")); |
|
|
|
|
Serial.println(MicroDexed[0]->data[DEXED_VOICE_OFFSET + DEXED_LFO_PITCH_MOD_DEP], DEC); |
|
|
|
|
Serial.println(MicroDexed[instance_id]->data[DEXED_VOICE_OFFSET + DEXED_LFO_PITCH_MOD_DEP], DEC); |
|
|
|
|
Serial.print(F("LFO_AMD: ")); |
|
|
|
|
Serial.println(MicroDexed[0]->data[DEXED_VOICE_OFFSET + DEXED_LFO_AMP_MOD_DEP], DEC); |
|
|
|
|
Serial.println(MicroDexed[instance_id]->data[DEXED_VOICE_OFFSET + DEXED_LFO_AMP_MOD_DEP], DEC); |
|
|
|
|
Serial.print(F("LFO_SYNC: ")); |
|
|
|
|
Serial.println(MicroDexed[0]->data[DEXED_VOICE_OFFSET + DEXED_LFO_SYNC], DEC); |
|
|
|
|
Serial.println(MicroDexed[instance_id]->data[DEXED_VOICE_OFFSET + DEXED_LFO_SYNC], DEC); |
|
|
|
|
Serial.print(F("LFO_WAVEFRM: ")); |
|
|
|
|
Serial.println(MicroDexed[0]->data[DEXED_VOICE_OFFSET + DEXED_LFO_WAVE], DEC); |
|
|
|
|
Serial.println(MicroDexed[instance_id]->data[DEXED_VOICE_OFFSET + DEXED_LFO_WAVE], DEC); |
|
|
|
|
Serial.print(F("LFO_PMS: ")); |
|
|
|
|
Serial.println(MicroDexed[0]->data[DEXED_VOICE_OFFSET + DEXED_LFO_PITCH_MOD_SENS], DEC); |
|
|
|
|
Serial.println(MicroDexed[instance_id]->data[DEXED_VOICE_OFFSET + DEXED_LFO_PITCH_MOD_SENS], DEC); |
|
|
|
|
Serial.print(F("TRNSPSE: ")); |
|
|
|
|
Serial.println(MicroDexed[0]->data[DEXED_VOICE_OFFSET + DEXED_TRANSPOSE], DEC); |
|
|
|
|
Serial.println(MicroDexed[instance_id]->data[DEXED_VOICE_OFFSET + DEXED_TRANSPOSE], DEC); |
|
|
|
|
Serial.print(F("NAME: ")); |
|
|
|
|
strncpy(voicename, (char *)&MicroDexed[0]->data[DEXED_VOICE_OFFSET + DEXED_NAME], sizeof(voicename) - 1); |
|
|
|
|
strncpy(voicename, (char *)&MicroDexed[instance_id]->data[DEXED_VOICE_OFFSET + DEXED_NAME], sizeof(voicename) - 1); |
|
|
|
|
Serial.print(F("[")); |
|
|
|
|
Serial.print(voicename); |
|
|
|
|
Serial.println(F("]")); |
|
|
|
@ -1362,7 +1428,7 @@ void show_patch(void) |
|
|
|
|
{ |
|
|
|
|
Serial.print(i, DEC); |
|
|
|
|
Serial.print(F(": ")); |
|
|
|
|
Serial.println(MicroDexed[0]->data[i]); |
|
|
|
|
Serial.println(MicroDexed[instance_id]->data[i]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Serial.println(); |
|
|
|
|