From a34ee7d50df35eab0df849e0b336688c4549efe4 Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Fri, 9 Dec 2022 19:12:09 +0100 Subject: [PATCH] Several adds for handling drums and drum mapping. Small fixes for performance files. --- MicroDexed.ino | 392 +++++----- addon/SD/PERFORMANCE/0/drmmap.json | 174 ++--- addon/SD/PERFORMANCE/0/drums.json | 972 ++++++++++++------------ addon/SD/PERFORMANCE/0/epiano.json | 40 +- addon/SD/PERFORMANCE/0/fx.json | 128 ++-- addon/SD/PERFORMANCE/0/performance.json | 52 +- addon/SD/PERFORMANCE/0/voice1.json | 66 +- addon/SD/PERFORMANCE/0/voice2.json | 66 +- config.h | 2 +- dexed_sd.cpp | 583 +++++++------- dexed_sd.h | 10 +- 11 files changed, 1182 insertions(+), 1303 deletions(-) diff --git a/MicroDexed.ino b/MicroDexed.ino index 0830aff..b705706 100644 --- a/MicroDexed.ino +++ b/MicroDexed.ino @@ -407,6 +407,7 @@ int16_t* ep_delayline_l; extern drum_config_t drum_config[NUM_DRUMSET_CONFIG]; uint8_t drum_counter; uint8_t drum_type[NUM_DRUMS]; +int8_t drum_map[NUM_DRUMSET_CONFIG]; uint8_t drum_midi_channel = DRUM_MIDI_CHANNEL; #endif @@ -416,7 +417,6 @@ extern LCDMenuLib2 LCDML; extern void getNoteName(char* noteName, uint8_t noteNumber); - /*********************************************************************** SETUP ***********************************************************************/ @@ -568,6 +568,7 @@ void setup() { configuration.drums.drum_reverb_send[i] = mapfloat(drum_config[i].reverb_send, 0.0, 1.0, DRUMS_REVERB_SEND_MIN, DRUMS_REVERB_SEND_MAX); configuration.drums.drum_pitch[i] = mapfloat(drum_config[i].pitch, -1.0, 1.0, DRUMS_PITCH_MIN, DRUMS_PITCH_MAX); configuration.drums.drum_midi_note[i] = constrain(drum_config[i].midinote, DRUMS_MIDI_NOTE_MIN, DRUMS_MIDI_NOTE_MAX); + drum_map[i] = -1; } #endif @@ -918,7 +919,7 @@ void handleNoteOn(byte inChannel, byte inNumber, byte inVelocity) { // Play Notes // - // Check for MicroDexed + // MicroDexed for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) { if (checkMidiChannel(inChannel, instance_id)) { if (inNumber >= configuration.dexed[instance_id].lowest_note && inNumber <= configuration.dexed[instance_id].highest_note) { @@ -947,8 +948,27 @@ void handleNoteOn(byte inChannel, byte inNumber, byte inVelocity) { } } + // E-Piano +#if defined(USE_EPIANO) + if (configuration.epiano.midi_channel == MIDI_CHANNEL_OMNI || configuration.epiano.midi_channel == inChannel) { + if (inNumber >= configuration.epiano.lowest_note && inNumber <= configuration.epiano.highest_note) { + ep.noteOn(inNumber + configuration.epiano.transpose - 24, inVelocity); +#ifdef DEBUG + char note_name[4]; + getNoteName(note_name, inNumber); + Serial.print(F("KeyDown ")); + Serial.print(note_name); + Serial.print(F(" EPIANO ")); + Serial.print(F(" MIDI-channel ")); + Serial.print(inChannel, DEC); + Serial.println(); +#endif + } + } +#endif + + // Drums #if NUM_DRUMS > 0 - // Check for Drum if (inChannel == drum_midi_channel || drum_midi_channel == MIDI_CHANNEL_OMNI) { if (drum_counter >= NUM_DRUMS) drum_counter = 0; @@ -956,14 +976,25 @@ void handleNoteOn(byte inChannel, byte inNumber, byte inVelocity) { #ifdef DEBUG char note_name[4]; getNoteName(note_name, inNumber); - Serial.print(F("=> Drum[")); + Serial.print(F("Triggring Drum[")); Serial.print(drum_counter, DEC); - Serial.print(F("]: ")); + Serial.print(F("]: with note ")); Serial.println(note_name); #endif + int8_t mapped_note = -1; for (uint8_t d = 0; d < NUM_DRUMSET_CONFIG; d++) { - if (inNumber == drum_config[d].midinote) { + if (drum_map[inNumber] != -1) { + mapped_note = drum_map[inNumber]; +#ifdef DEBUG + Serial.print("MIDI drum-note mapping ["); + Serial.print(inNumber); + Serial.print("] -> ["); + Serial.print(mapped_note); + Serial.println("]"); +#endif + } + if (mapped_note == drum_config[d].midinote) { uint8_t slot = drum_get_slot(drum_config[d].drum_class); float pan = mapfloat(drum_config[d].pan, -1.0, 1.0, 0.0, 1.0); @@ -974,8 +1005,6 @@ void handleNoteOn(byte inChannel, byte inNumber, byte inVelocity) { drum_reverb_send_mixer_l.gain(slot, pan * volume_transform(drum_config[d].reverb_send)); #endif if (drum_config[d].drum_data != NULL && drum_config[d].len > 0) { - //Drum[slot]->play(drum_config[d].drum_data); - if (drum_config[d].pitch != 0.0) { Drum[slot]->enableInterpolation(true); Drum[slot]->setPlaybackRate(drum_config[d].pitch); @@ -988,15 +1017,13 @@ void handleNoteOn(byte inChannel, byte inNumber, byte inVelocity) { Serial.print(drum_config[d].shortname); Serial.print(F(" [")); Serial.print(drum_config[d].name); - Serial.print(F("], Slot ")); + Serial.print(F("], Slot [")); Serial.print(slot); - Serial.print(F(": V")); + Serial.print(F("]: Velocity=")); Serial.print(mapfloat(inVelocity, 0, 127, drum_config[d].vol_min, drum_config[d].vol_max), 2); - Serial.print(F(" P")); - Serial.print(drum_config[d].pan, 2); - Serial.print(F(" PAN")); + Serial.print(F(" Pan=")); Serial.print(pan, 2); - Serial.print(F(" RS")); + Serial.print(F(" ReverbSend=")); Serial.println(drum_config[d].reverb_send, 2); #endif break; @@ -1004,135 +1031,6 @@ void handleNoteOn(byte inChannel, byte inNumber, byte inVelocity) { } } #endif - -#if defined(USE_EPIANO) - // - // E-Piano - // - if (configuration.epiano.midi_channel == MIDI_CHANNEL_OMNI || configuration.epiano.midi_channel == inChannel) { - if (inNumber >= configuration.epiano.lowest_note && inNumber <= configuration.epiano.highest_note) { - ep.noteOn(inNumber + configuration.epiano.transpose - 24, inVelocity); -#ifdef DEBUG - char note_name[4]; - getNoteName(note_name, inNumber); - Serial.print(F("KeyDown ")); - Serial.print(note_name); - Serial.print(F(" EPIANO ")); - Serial.print(F(" MIDI-channel ")); - Serial.print(inChannel, DEC); - Serial.println(); -#endif - } - } -#endif -} - -#if NUM_DRUMS > 0 -uint8_t drum_get_slot(uint8_t dt) { - for (uint8_t i = 0; i < NUM_DRUMS; i++) { - if (!Drum[i]->isPlaying()) { - drum_type[i] = DRUM_NONE; - Drum[i]->enableInterpolation(false); - Drum[i]->setPlaybackRate(1.0); - } - // else - // { - // if (drum_type[i] == dt) - // { - //#ifdef DEBUG - // Serial.print(F("Stopping Drum ")); - // Serial.print(i); - // Serial.print(F(" type ")); - // Serial.println(dt); - //#endif - // Drum[i]->stop(); - // - // return (i); - // } - // } - } -#ifdef DEBUG - Serial.print(F("Using next free Drum slot ")); - Serial.println(drum_counter % NUM_DRUMS); -#endif - drum_type[drum_counter % NUM_DRUMS] = dt; - drum_counter++; - return (drum_counter - 1 % NUM_DRUMS); -} -#endif - -int8_t handle_midi_learn(int8_t note) { - int8_t ret_channel = -1; - -#ifdef DEBUG - Serial.print("MIDI learning for "); - Serial.println(note); -#endif - - if (LCDML.FUNC_getID() == LCDML.OTHER_getIDFromFunction(UI_func_drum_midi_note)) { - ret_channel = configuration.drums.drum_midi_channel; - //LCDML.OTHER_jumpToFunc(UI_func_drum_midi_note); - } else if (LCDML.FUNC_getID() == LCDML.OTHER_getIDFromFunction(UI_func_epiano_lowest_note)) { - if (note > configuration.epiano.highest_note) - configuration.epiano.lowest_note = configuration.epiano.highest_note; - else - configuration.epiano.lowest_note = note; - ret_channel = configuration.epiano.midi_channel; -#ifdef DEBUG - Serial.print("MIDI learned lowest note: "); - Serial.print(note); - Serial.print(" for EPiano, ghosting MIDI channel "); - Serial.println(ret_channel); -#endif - } else if (LCDML.FUNC_getID() == LCDML.OTHER_getIDFromFunction(UI_func_epiano_highest_note)) { - if (note < configuration.epiano.lowest_note) - configuration.epiano.highest_note = configuration.epiano.lowest_note; - else - configuration.epiano.highest_note = note; - ret_channel = configuration.epiano.midi_channel; -#ifdef DEBUG - Serial.print("MIDI learned highest note: "); - Serial.print(note); - Serial.print(" for EPiano, ghosting MIDI channel "); - Serial.println(ret_channel); -#endif - } - - // Check for Dexed - for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) { - if (LCDML.FUNC_getID() == LCDML.OTHER_getIDFromFunction(UI_func_lowest_note)) { - if (note > configuration.dexed[selected_instance_id].highest_note) - configuration.dexed[selected_instance_id].lowest_note = configuration.dexed[selected_instance_id].highest_note; - else - configuration.dexed[selected_instance_id].lowest_note = note; - ret_channel = configuration.dexed[selected_instance_id].midi_channel; -#ifdef DEBUG - Serial.print("MIDI learned lowest note: "); - Serial.print(note); - Serial.print(" for instance: "); - Serial.print(selected_instance_id); - Serial.print(", ghosting MIDI channel "); - Serial.println(ret_channel); -#endif - } else if (LCDML.FUNC_getID() == LCDML.OTHER_getIDFromFunction(UI_func_highest_note)) { - if (note < configuration.dexed[selected_instance_id].lowest_note) - configuration.dexed[selected_instance_id].highest_note = configuration.dexed[selected_instance_id].lowest_note; - else - configuration.dexed[selected_instance_id].highest_note = note; - ret_channel = configuration.dexed[selected_instance_id].midi_channel; -#ifdef DEBUG - Serial.print("MIDI learned highest note: "); - Serial.print(note); - Serial.print(" for instance: "); - Serial.print(selected_instance_id); - Serial.print(", ghosting MIDI channel "); - Serial.println(ret_channel); -#endif - } - LCDML.OTHER_updateFunc(); - } - - return (ret_channel); } void handleNoteOff(byte inChannel, byte inNumber, byte inVelocity) { @@ -1145,6 +1043,7 @@ void handleNoteOff(byte inChannel, byte inNumber, byte inVelocity) { inChannel = tmp_channel; } + // Dexed for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) { if (checkMidiChannel(inChannel, instance_id)) { if (inNumber >= configuration.dexed[instance_id].lowest_note && inNumber <= configuration.dexed[instance_id].highest_note) { @@ -1167,6 +1066,7 @@ void handleNoteOff(byte inChannel, byte inNumber, byte inVelocity) { } } +// EPiano #if defined(USE_EPIANO) if (configuration.epiano.midi_channel == MIDI_CHANNEL_OMNI || configuration.epiano.midi_channel == inChannel) { if (inNumber >= configuration.epiano.lowest_note && inNumber <= configuration.epiano.highest_note) { @@ -1190,6 +1090,13 @@ void handleControlChange(byte inChannel, byte inCtrl, byte inValue) { inCtrl = constrain(inCtrl, 0, 127); inValue = constrain(inValue, 0, 127); +// EPiano +#if defined(USE_EPIANO) + if (configuration.epiano.midi_channel == MIDI_CHANNEL_OMNI || configuration.epiano.midi_channel == inChannel) + ep.processMidiController(inCtrl, inValue); +#endif + + // Dexed for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) { if (checkMidiChannel(inChannel, instance_id)) { #ifdef DEBUG @@ -1389,11 +1296,6 @@ void handleControlChange(byte inChannel, byte inCtrl, byte inValue) { } } } - -#if defined(USE_EPIANO) - if (configuration.epiano.midi_channel == MIDI_CHANNEL_OMNI || configuration.epiano.midi_channel == inChannel) - ep.processMidiController(inCtrl, inValue); -#endif } void handleAfterTouch(byte inChannel, byte inPressure) { @@ -1856,6 +1758,7 @@ void set_drums_volume(float vol) { master_mixer_r.gain(MASTER_MIX_CH_DRUMS, vol); master_mixer_l.gain(MASTER_MIX_CH_DRUMS, vol); } + void set_volume(uint8_t v, uint8_t m) { float tmp_v; @@ -2073,6 +1976,26 @@ void check_configuration_epiano(void) { configuration.epiano.midi_channel = constrain(configuration.epiano.midi_channel, EP_MIDI_CHANNEL_MIN, EP_MIDI_CHANNEL_MAX); } +void check_configuration_drum_config(void) { + configuration.drums.drum_main_vol = constrain(configuration.drums.drum_main_vol, DRUMS_MAIN_VOL_MIN, DRUMS_MAIN_VOL_MAX); + for (uint8_t i = 0; i < NUM_DRUMSET_CONFIG - 1; i++) { + drum_config[i].midinote = constrain(drum_config[i].midinote, DRUMS_MIDI_NOTE_MIN, DRUMS_MIDI_NOTE_MAX); + drum_config[i].pitch = constrain(drum_config[i].pitch, DRUMS_PITCH_MIN, DRUMS_PITCH_MAX); + drum_config[i].pan = constrain(drum_config[i].pan, DRUMS_PANORAMA_MIN, DRUMS_PANORAMA_MAX); + drum_config[i].vol_max = constrain(drum_config[i].vol_max, DRUMS_VOL_MIN, DRUMS_VOL_MAX); + drum_config[i].vol_min = constrain(drum_config[i].vol_min, DRUMS_VOL_MIN, DRUMS_VOL_MAX); + drum_config[i].reverb_send = constrain(drum_config[i].reverb_send, DRUMS_REVERB_SEND_MIN, DRUMS_REVERB_SEND_MAX); + } +} + +void check_configuration_drum_map(void) { + for (uint8_t i = 0; i < NUM_DRUMSET_CONFIG - 1; i++) { + drum_map[i] = constrain(drum_map[i], -1, DRUMS_MIDI_NOTE_MAX); + if (drum_map[i] >= 0 && drum_map[i] < DRUMS_MIDI_NOTE_MIN) + drum_map[i] = -1; + } +} + void init_configuration(void) { #ifdef DEBUG Serial.println(F("INITIALIZING CONFIGURATION")); @@ -2183,69 +2106,6 @@ void eeprom_update(void) { EEPROM.update(EEPROM_START_ADDRESS + 2, configuration.sys.vol); } -/****************************************************************************** - PARAMETER-HELPERS -******************************************************************************/ - -void set_sample_note(uint8_t sample, uint8_t note) { - drum_config[sample].midinote = note; -} - -void set_sample_pitch(uint8_t sample, float playbackspeed) { - drum_config[sample].pitch = playbackspeed; -} - -void set_sample_pan(uint8_t sample, float s_pan) { - drum_config[sample].pan = s_pan; -} - -void set_sample_vol_max(uint8_t sample, float s_max) { - drum_config[sample].vol_max = s_max; -} - -void set_sample_vol_min(uint8_t sample, float s_min) { - drum_config[sample].vol_min = s_min; -} - -void set_sample_reverb_send(uint8_t sample, float s_reverb) { - drum_config[sample].reverb_send = s_reverb; -} - -uint8_t get_sample_note(uint8_t sample) { - return (drum_config[sample].midinote); -} - -float get_sample_pitch(uint8_t sample) { - return (drum_config[sample].pitch); -} - -float get_sample_pan(uint8_t sample) { - return (drum_config[sample].pan); -} - -float get_sample_vol_max(uint8_t sample) { - return (drum_config[sample].vol_max); -} - -float get_sample_vol_min(uint8_t sample) { - return (drum_config[sample].vol_min); -} - -float get_sample_reverb_send(uint8_t sample) { - return (drum_config[sample].reverb_send); -} - -uint8_t find_drum_number_from_note(uint8_t note) { - uint8_t number = 0; - for (uint8_t d = 0; d < NUM_DRUMSET_CONFIG - 1; d++) { - if (note == drum_config[d].midinote) { - number = d; - break; - } - } - return number; -} - void set_fx_params(void) { #if defined(USE_FX) for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) { @@ -2442,7 +2302,7 @@ void set_sys_params(void) { // https://www.reddit.com/r/Teensy/comments/7r19uk/reset_and_reboot_teensy_lc_via_code/ #define SCB_AIRCR (*(volatile uint32_t*)0xE000ED0C) // Application Interrupt and Reset Control location void _softRestart(void) { - Serial.end(); //clears the serial monitor if used + Serial.end(); //clears the serial monitor if used SCB_AIRCR = 0x05FA0004; //write value for restart } @@ -2454,6 +2314,114 @@ void _softRestart(void) { return (pow(value, 2.2)); }*/ +#if NUM_DRUMS > 0 +uint8_t drum_get_slot(uint8_t dt) { + for (uint8_t i = 0; i < NUM_DRUMS; i++) { + if (!Drum[i]->isPlaying()) { + drum_type[i] = DRUM_NONE; + Drum[i]->enableInterpolation(false); + Drum[i]->setPlaybackRate(1.0); + } + // else + // { + // if (drum_type[i] == dt) + // { + //#ifdef DEBUG + // Serial.print(F("Stopping Drum ")); + // Serial.print(i); + // Serial.print(F(" type ")); + // Serial.println(dt); + //#endif + // Drum[i]->stop(); + // + // return (i); + // } + // } + } +#ifdef DEBUG + Serial.print(F("Using next free Drum slot ")); + Serial.println(drum_counter % NUM_DRUMS); +#endif + drum_type[drum_counter % NUM_DRUMS] = dt; + drum_counter++; + return (drum_counter - 1 % NUM_DRUMS); +} +#endif + +int8_t handle_midi_learn(int8_t note) { + int8_t ret_channel = -1; + +#ifdef DEBUG + Serial.print("MIDI learning for "); + Serial.println(note); +#endif + + if (LCDML.FUNC_getID() == LCDML.OTHER_getIDFromFunction(UI_func_drum_midi_note)) { + ret_channel = configuration.drums.drum_midi_channel; + //LCDML.OTHER_jumpToFunc(UI_func_drum_midi_note); + } else if (LCDML.FUNC_getID() == LCDML.OTHER_getIDFromFunction(UI_func_epiano_lowest_note)) { + if (note > configuration.epiano.highest_note) + configuration.epiano.lowest_note = configuration.epiano.highest_note; + else + configuration.epiano.lowest_note = note; + ret_channel = configuration.epiano.midi_channel; +#ifdef DEBUG + Serial.print("MIDI learned lowest note: "); + Serial.print(note); + Serial.print(" for EPiano, ghosting MIDI channel "); + Serial.println(ret_channel); +#endif + } else if (LCDML.FUNC_getID() == LCDML.OTHER_getIDFromFunction(UI_func_epiano_highest_note)) { + if (note < configuration.epiano.lowest_note) + configuration.epiano.highest_note = configuration.epiano.lowest_note; + else + configuration.epiano.highest_note = note; + ret_channel = configuration.epiano.midi_channel; +#ifdef DEBUG + Serial.print("MIDI learned highest note: "); + Serial.print(note); + Serial.print(" for EPiano, ghosting MIDI channel "); + Serial.println(ret_channel); +#endif + } + + // Check for Dexed + for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) { + if (LCDML.FUNC_getID() == LCDML.OTHER_getIDFromFunction(UI_func_lowest_note)) { + if (note > configuration.dexed[selected_instance_id].highest_note) + configuration.dexed[selected_instance_id].lowest_note = configuration.dexed[selected_instance_id].highest_note; + else + configuration.dexed[selected_instance_id].lowest_note = note; + ret_channel = configuration.dexed[selected_instance_id].midi_channel; +#ifdef DEBUG + Serial.print("MIDI learned lowest note: "); + Serial.print(note); + Serial.print(" for instance: "); + Serial.print(selected_instance_id); + Serial.print(", ghosting MIDI channel "); + Serial.println(ret_channel); +#endif + } else if (LCDML.FUNC_getID() == LCDML.OTHER_getIDFromFunction(UI_func_highest_note)) { + if (note < configuration.dexed[selected_instance_id].lowest_note) + configuration.dexed[selected_instance_id].highest_note = configuration.dexed[selected_instance_id].lowest_note; + else + configuration.dexed[selected_instance_id].highest_note = note; + ret_channel = configuration.dexed[selected_instance_id].midi_channel; +#ifdef DEBUG + Serial.print("MIDI learned highest note: "); + Serial.print(note); + Serial.print(" for instance: "); + Serial.print(selected_instance_id); + Serial.print(", ghosting MIDI channel "); + Serial.println(ret_channel); +#endif + } + LCDML.OTHER_updateFunc(); + } + + return (ret_channel); +} + float midi_volume_transform(uint8_t midi_amp) { #ifdef DEBUG Serial.print(F("midi_amp=")); diff --git a/addon/SD/PERFORMANCE/0/drmmap.json b/addon/SD/PERFORMANCE/0/drmmap.json index 7649ed2..4ff1f3a 100755 --- a/addon/SD/PERFORMANCE/0/drmmap.json +++ b/addon/SD/PERFORMANCE/0/drmmap.json @@ -1,106 +1,68 @@ -{ - "type": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], - "in": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], - "out": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], - "channel": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ] -} +{ + "map": [ + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1 + ] +} diff --git a/addon/SD/PERFORMANCE/0/drums.json b/addon/SD/PERFORMANCE/0/drums.json index 51dfcdc..4d86f6e 100755 --- a/addon/SD/PERFORMANCE/0/drums.json +++ b/addon/SD/PERFORMANCE/0/drums.json @@ -1,507 +1,465 @@ -{ - "drums_volume": 0.95, - "note": [ - 210, - 211, - 212, - 213, - 214, - 45, - 47, - 48, - 49, - 50, - 51, - 52, - 53, - 54, - 55, - 56, - 57, - 58, - 59, - 60, - 61, - 62, - 63, - 64, - 65, - 66, - 67, - 68, - 69, - 70, - 71, - 72, - 73, - 74, - 75, - 76, - 77, - 78, - 79, - 80, - 81, - 82, - 83, - 84, - 85, - 86, - 87, - 88, - 89, - 90, - 92, - 91, - 93, - 94, - 95, - 96, - 97, - 98, - 99, - 100, - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 0, - 0 - ], - "pitch": [ - 0, - 0, - 0, - 0, - 0, - 0, - 1.2, - 0, - 0, - 0, - 1.1, - 1.3, - 0, - 1.4, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 0, - 1, - 0.9, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1.427136, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], - "p_offset": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], - "pan": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0.282828, - 0.343434, - 0.1, - 0, - 0, - 0.191919, - 0, - 0, - -0.343434, - -0.484849, - 0, - 0, - 0, - 0.323232, - 0, - 0, - 0, - -0.2, - 0, - 0.272727, - 0, - 0, - 0.080808, - 0, - 0, - 0.414141, - -0.151515, - 0, - 0, - 0, - 0, - 0, - -0.252525, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], - "vol_max": [ - 0, - 1, - 1, - 1, - 1, - 1, - 1, - 0.7, - 1, - 0.7, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 0.75, - 0.56, - 1, - 1, - 1, - 0.79, - 0.73, - 1, - 0.89, - 0.74, - 0.93, - 1, - 1, - 0.86, - 0.74, - 0.9, - 0.9, - 0.8, - 0.8, - 0.77, - 0.8, - 0.8, - 0.83, - 1, - 0.78, - 0.88, - 0.9, - 0.94, - 0.9, - 0.9, - 0.9, - 0.8, - 0.9, - 0.9, - 1, - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0.8, - 0, - 0 - ], - "vol_min": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ], - "reverb_send": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0.52, - 0.59, - 0, - 0, - 0, - 0, - 0, - 0.34, - 0, - 0.65, - 0, - 0, - 0, - 0, - 0, - 0, - 0.53, - 0, - 0, - 0, - 0, - 0.2, - 0, - 0, - 0.52, - 0.25, - 0.66, - 0, - 0, - 0.69, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ] -} \ No newline at end of file +{ + "drums_volume": 0.95, + "note": [ + 45, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 92, + 91, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 0 + ], + "pitch": [ + 0, + 1.2, + 0, + 0, + 0, + 1.1, + 1.3, + 0, + 1.4, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 1, + 0.9, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1.427136, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "p_offset": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "pan": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0.282828, + 0.343434, + 0.1, + 0, + 0, + 0.191919, + 0, + 0, + -0.343434, + -0.484849, + 0, + 0, + 0, + 0.323232, + 0, + 0, + 0, + -0.2, + 0, + 0.272727, + 0, + 0, + 0.080808, + 0, + 0, + 0.414141, + -0.151515, + 0, + 0, + 0, + 0, + 0, + -0.252525, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "vol_max": [ + 1, + 1, + 0.7, + 1, + 0.7, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 0.75, + 0.56, + 1, + 1, + 1, + 0.79, + 0.73, + 1, + 0.89, + 0.74, + 0.93, + 1, + 1, + 0.86, + 0.74, + 0.9, + 0.9, + 0.8, + 0.8, + 0.77, + 0.8, + 0.8, + 0.83, + 1, + 0.78, + 0.88, + 0.9, + 0.94, + 0.9, + 0.9, + 0.9, + 0.8, + 0.9, + 0.9, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0.8, + 0 + ], + "vol_min": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ], + "reverb_send": [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0.52, + 0.59, + 0, + 0, + 0, + 0, + 0, + 0.34, + 0, + 0.65, + 0, + 0, + 0, + 0, + 0, + 0, + 0.53, + 0, + 0, + 0, + 0, + 0.2, + 0, + 0, + 0.52, + 0.25, + 0.66, + 0, + 0, + 0.69, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] +} diff --git a/addon/SD/PERFORMANCE/0/epiano.json b/addon/SD/PERFORMANCE/0/epiano.json index 21dab3e..ed4bd83 100755 --- a/addon/SD/PERFORMANCE/0/epiano.json +++ b/addon/SD/PERFORMANCE/0/epiano.json @@ -1,20 +1,20 @@ -{ - "decay": 50, - "release": 50, - "hardness": 50, - "treble": 50, - "pan_tremolo": 50, - "pan_lfo": 0, - "velocity_sense": 0, - "stereo": 50, - "polyphony": 16, - "tune": 50, - "detune": 15, - "overdrive": 0, - "lowest_note": 21, - "highest_note": 108, - "transpose": 24, - "sound_intensity": 100, - "pan": 20, - "midi_channel": 4 -} +{ + "decay": 50, + "release": 50, + "hardness": 50, + "treble": 50, + "pan_tremolo": 50, + "pan_lfo": 0, + "velocity_sense": 0, + "stereo": 50, + "polyphony": 16, + "tune": 50, + "detune": 15, + "overdrive": 0, + "lowest_note": 21, + "highest_note": 108, + "transpose": 24, + "sound_intensity": 100, + "pan": 20, + "midi_channel": 4 +} diff --git a/addon/SD/PERFORMANCE/0/fx.json b/addon/SD/PERFORMANCE/0/fx.json index df11334..c3819bc 100755 --- a/addon/SD/PERFORMANCE/0/fx.json +++ b/addon/SD/PERFORMANCE/0/fx.json @@ -1,65 +1,65 @@ -{ - "filter_cutoff": [ - 0, - 0 - ], - "filter_resonance": [ - 0, - 0 - ], - "chorus_frequency": [ - 0, - 0 - ], - "chorus_waveform": [ - 0, - 0 - ], - "chorus_depth": [ - 0, - 0 - ], - "chorus_level": [ - 0, - 0 - ], - "delay_time": [ - 0, - 0 - ], - "delay_feedback": [ - 60, - 88 - ], - "delay_level": [ - 83, - 82 - ], - "delay_sync": [ - 3, - 3 - ], - "reverb_send": [ - 81, - 99 - ], - "reverb_roomsize": 99, - "reverb_damping": 0, - "reverb_lowpass": 81, - "reverb_lodamp": 59, - "reverb_hidamp": 0, - "reverb_diffusion": 100, - "reverb_level": 78, - "eq_1": 15, - "eq_2": 0, - "eq_3": 1, - "eq_4": 0, - "eq_5": 0, - "eq_6": -2, - "eq_7": 8, - "ep_chorus_frequency": 0, - "ep_chorus_waveform": 0, - "ep_chorus_depth": 0, - "ep_chorus_level": 0, - "ep_reverb_send": 0 +{ + "filter_cutoff": [ + 0, + 0 + ], + "filter_resonance": [ + 0, + 0 + ], + "chorus_frequency": [ + 0, + 0 + ], + "chorus_waveform": [ + 0, + 0 + ], + "chorus_depth": [ + 0, + 0 + ], + "chorus_level": [ + 0, + 0 + ], + "delay_time": [ + 0, + 0 + ], + "delay_feedback": [ + 60, + 88 + ], + "delay_level": [ + 83, + 82 + ], + "delay_sync": [ + 3, + 3 + ], + "reverb_send": [ + 81, + 99 + ], + "reverb_roomsize": 99, + "reverb_damping": 0, + "reverb_lowpass": 81, + "reverb_lodamp": 59, + "reverb_hidamp": 0, + "reverb_diffusion": 100, + "reverb_level": 78, + "eq_1": 15, + "eq_2": 0, + "eq_3": 1, + "eq_4": 0, + "eq_5": 0, + "eq_6": -2, + "eq_7": 8, + "ep_chorus_frequency": 0, + "ep_chorus_waveform": 0, + "ep_chorus_depth": 0, + "ep_chorus_level": 0, + "ep_reverb_send": 0 } \ No newline at end of file diff --git a/addon/SD/PERFORMANCE/0/performance.json b/addon/SD/PERFORMANCE/0/performance.json index aa49324..5c3f71d 100644 --- a/addon/SD/PERFORMANCE/0/performance.json +++ b/addon/SD/PERFORMANCE/0/performance.json @@ -1,27 +1,27 @@ -{ - "name": [ - 73, - 78, - 73, - 84, - 32, - 80, - 101, - 114, - 102, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0 - ] +{ + "name": [ + 73, + 78, + 73, + 84, + 32, + 80, + 101, + 114, + 102, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 + ] } \ No newline at end of file diff --git a/addon/SD/PERFORMANCE/0/voice1.json b/addon/SD/PERFORMANCE/0/voice1.json index 586e2e3..eefab85 100755 --- a/addon/SD/PERFORMANCE/0/voice1.json +++ b/addon/SD/PERFORMANCE/0/voice1.json @@ -1,33 +1,33 @@ -{ - "bank": 18, - "voice": 11, - "lowest_note": 21, - "highest_note": 108, - "transpose": 12, - "tune": 100, - "sound_intensity": 91, - "pan": 15, - "polyphony": 16, - "velocity_level": 100, - "monopoly": 0, - "note_refresh": 0, - "pb_range": 1, - "pb_step": 0, - "mw_range": 50, - "mw_assign": 0, - "mw_mode": 0, - "fc_range": 50, - "fc_assign": 0, - "fc_mode": 0, - "bc_range": 50, - "bc_assign": 0, - "bc_mode": 0, - "at_range": 50, - "at_assign": 0, - "at_mode": 0, - "portamento_mode": 0, - "portamento_glissando": 0, - "portamento_time": 0, - "op_enabled": 63, - "midi_channel": 2 -} +{ + "bank": 18, + "voice": 11, + "lowest_note": 21, + "highest_note": 108, + "transpose": 12, + "tune": 100, + "sound_intensity": 91, + "pan": 15, + "polyphony": 16, + "velocity_level": 100, + "monopoly": 0, + "note_refresh": 0, + "pb_range": 1, + "pb_step": 0, + "mw_range": 50, + "mw_assign": 0, + "mw_mode": 0, + "fc_range": 50, + "fc_assign": 0, + "fc_mode": 0, + "bc_range": 50, + "bc_assign": 0, + "bc_mode": 0, + "at_range": 50, + "at_assign": 0, + "at_mode": 0, + "portamento_mode": 0, + "portamento_glissando": 0, + "portamento_time": 0, + "op_enabled": 63, + "midi_channel": 2 +} diff --git a/addon/SD/PERFORMANCE/0/voice2.json b/addon/SD/PERFORMANCE/0/voice2.json index 33cc661..38d834c 100755 --- a/addon/SD/PERFORMANCE/0/voice2.json +++ b/addon/SD/PERFORMANCE/0/voice2.json @@ -1,33 +1,33 @@ -{ - "bank": 63, - "voice": 2, - "lowest_note": 21, - "highest_note": 108, - "transpose": 24, - "tune": 100, - "sound_intensity": 67, - "pan": 23, - "polyphony": 16, - "velocity_level": 100, - "monopoly": 0, - "note_refresh": 0, - "pb_range": 1, - "pb_step": 0, - "mw_range": 50, - "mw_assign": 0, - "mw_mode": 0, - "fc_range": 50, - "fc_assign": 0, - "fc_mode": 0, - "bc_range": 50, - "bc_assign": 0, - "bc_mode": 0, - "at_range": 50, - "at_assign": 0, - "at_mode": 0, - "portamento_mode": 0, - "portamento_glissando": 0, - "portamento_time": 0, - "op_enabled": 63, - "midi_channel": 3 -} +{ + "bank": 63, + "voice": 2, + "lowest_note": 21, + "highest_note": 108, + "transpose": 24, + "tune": 100, + "sound_intensity": 67, + "pan": 23, + "polyphony": 16, + "velocity_level": 100, + "monopoly": 0, + "note_refresh": 0, + "pb_range": 1, + "pb_step": 0, + "mw_range": 50, + "mw_assign": 0, + "mw_mode": 0, + "fc_range": 50, + "fc_assign": 0, + "fc_mode": 0, + "bc_range": 50, + "bc_assign": 0, + "bc_mode": 0, + "at_range": 50, + "at_assign": 0, + "at_mode": 0, + "portamento_mode": 0, + "portamento_glissando": 0, + "portamento_time": 0, + "op_enabled": 63, + "midi_channel": 3 +} diff --git a/config.h b/config.h index 574160c..c5035c2 100644 --- a/config.h +++ b/config.h @@ -56,7 +56,7 @@ // // Information about memory layout, etc.: https://www.pjrc.com/store/teensy41.html -#define VERSION "1.2.3" +#define VERSION "1.2.4" //************************************************************************************************* //* DEVICE SETTINGS diff --git a/dexed_sd.cpp b/dexed_sd.cpp index 28f70c5..11bda9f 100644 --- a/dexed_sd.cpp +++ b/dexed_sd.cpp @@ -35,6 +35,7 @@ #include "drums.h" extern void set_drums_volume(float vol); extern drum_config_t drum_config[]; +extern int8_t drum_map[]; #endif extern void init_MIDI_send_CC(void); @@ -42,37 +43,26 @@ extern void check_configuration_dexed(uint8_t instance_id); extern void check_configuration_performance(void); extern void check_configuration_fx(void); extern void check_configuration_epiano(void); +#if NUM_DRUMS > 0 +extern void check_configuration_drum_config(void); +extern void check_configuration_drum_map(void); +#endif extern float midi_volume_transform(uint8_t midi_amp); -extern void set_sample_note(uint8_t sample, uint8_t note); -extern void set_sample_pitch(uint8_t sample, float playbackspeed); -extern void set_sample_pan(uint8_t sample, float s_pan); -extern void set_sample_vol_max(uint8_t sample, float s_max); -extern void set_sample_vol_min(uint8_t sample, float s_min); -extern void set_sample_reverb_send(uint8_t sample, float s_reverb); extern void handleStop(void); extern void handleStart(void); extern void dac_mute(void); extern void dac_unmute(void); extern void check_configuration_sys(void); -extern uint8_t get_sample_note(uint8_t sample); -extern float get_sample_pitch(uint8_t sample); -extern float get_sample_pan(uint8_t sample); -extern float get_sample_vol_max(uint8_t sample); -extern float get_sample_vol_min(uint8_t sample); -extern float get_sample_reverb_send(uint8_t sample); -extern uint8_t find_drum_number_from_note(uint8_t note); extern bool save_sys_flag; /****************************************************************************** SD BANK/VOICE LOADING ******************************************************************************/ -bool load_sd_voice(uint8_t b, uint8_t v, uint8_t instance_id) -{ +bool load_sd_voice(uint8_t b, uint8_t v, uint8_t instance_id) { v = constrain(v, 0, MAX_VOICES - 1); b = constrain(b, 0, MAX_BANKS - 1); - if (sd_card > 0) - { + if (sd_card > 0) { File sysex; char filename[FILENAME_LEN]; char bank_name[BANK_NAME_LEN]; @@ -84,8 +74,7 @@ bool load_sd_voice(uint8_t b, uint8_t v, uint8_t instance_id) AudioNoInterrupts(); sysex = SD.open(filename); AudioInterrupts(); - if (!sysex) - { + if (!sysex) { #ifdef DEBUG Serial.print(F("E : Cannot open ")); Serial.print(filename); @@ -94,8 +83,7 @@ bool load_sd_voice(uint8_t b, uint8_t v, uint8_t instance_id) return (false); } - if (get_sd_voice(sysex, v, data)) - { + if (get_sd_voice(sysex, v, data)) { #ifdef DEBUG char voice_name[VOICE_NAME_LEN]; get_voice_name(b, v, voice_name, sizeof(voice_name)); @@ -137,13 +125,11 @@ bool load_sd_voice(uint8_t b, uint8_t v, uint8_t instance_id) return (false); } -bool save_sd_voice(uint8_t b, uint8_t v, uint8_t instance_id) -{ +bool save_sd_voice(uint8_t b, uint8_t v, uint8_t instance_id) { v = constrain(v, 0, MAX_VOICES - 1); b = constrain(b, 0, MAX_BANKS - 1); - if (sd_card > 0) - { + if (sd_card > 0) { File sysex; char filename[FILENAME_LEN]; char bank_name[BANK_NAME_LEN]; @@ -155,8 +141,7 @@ bool save_sd_voice(uint8_t b, uint8_t v, uint8_t instance_id) AudioNoInterrupts(); sysex = SD.open(filename, FILE_WRITE); AudioInterrupts(); - if (!sysex) - { + if (!sysex) { #ifdef DEBUG Serial.print(F("E : Cannot open ")); Serial.print(filename); @@ -167,8 +152,7 @@ bool save_sd_voice(uint8_t b, uint8_t v, uint8_t instance_id) MicroDexed[instance_id]->encodeVoice(data); - if (put_sd_voice(sysex, v, data)) - { + if (put_sd_voice(sysex, v, data)) { #ifdef DEBUG char voice_name[VOICE_NAME_LEN]; @@ -197,14 +181,13 @@ bool save_sd_voice(uint8_t b, uint8_t v, uint8_t instance_id) return (false); } -bool get_sd_voice(File sysex, uint8_t voice_number, uint8_t* data) -{ +bool get_sd_voice(File sysex, uint8_t voice_number, uint8_t* data) { uint16_t n; int32_t bulk_checksum_calc = 0; int8_t bulk_checksum; AudioNoInterrupts(); - if (sysex.size() != 4104) // check sysex size + if (sysex.size() != 4104) // check sysex size { #ifdef DEBUG Serial.println(F("E : SysEx file size wrong.")); @@ -241,12 +224,11 @@ bool get_sd_voice(File sysex, uint8_t voice_number, uint8_t* data) #endif return (false); } - sysex.seek(4102); // Bulk checksum + sysex.seek(4102); // Bulk checksum bulk_checksum = sysex.read(); - sysex.seek(6); // start of bulk data - for (n = 0; n < 4096; n++) - { + sysex.seek(6); // start of bulk data + for (n = 0; n < 4096; n++) { uint8_t d = sysex.read(); if (n >= voice_number * 128 && n < (voice_number + 1) * 128) data[n - (voice_number * 128)] = d; @@ -263,8 +245,7 @@ bool get_sd_voice(File sysex, uint8_t voice_number, uint8_t* data) Serial.println(F("]")); #endif - if (bulk_checksum_calc != bulk_checksum) - { + if (bulk_checksum_calc != bulk_checksum) { #ifdef DEBUG Serial.print(F("E : Bulk checksum mismatch : 0x")); @@ -280,15 +261,14 @@ bool get_sd_voice(File sysex, uint8_t voice_number, uint8_t* data) return (true); } -bool put_sd_voice(File sysex, uint8_t voice_number, uint8_t* data) -{ +bool put_sd_voice(File sysex, uint8_t voice_number, uint8_t* data) { uint16_t n; int32_t bulk_checksum_calc = 0; AudioNoInterrupts(); sysex.seek(0); - if (sysex.size() != 4104) // check sysex size + if (sysex.size() != 4104) // check sysex size { #ifdef DEBUG Serial.println(F("E : SysEx file size wrong.")); @@ -330,13 +310,12 @@ bool put_sd_voice(File sysex, uint8_t voice_number, uint8_t* data) sysex.write(data, 128); // checksum calculation - sysex.seek(6); // start of bulk data - for (n = 0; n < 4096; n++) - { + sysex.seek(6); // start of bulk data + for (n = 0; n < 4096; n++) { uint8_t d = sysex.read(); bulk_checksum_calc -= d; } - sysex.seek(4102); // Bulk checksum + sysex.seek(4102); // Bulk checksum sysex.write(bulk_checksum_calc & 0x7f); AudioInterrupts(); @@ -348,15 +327,13 @@ bool put_sd_voice(File sysex, uint8_t voice_number, uint8_t* data) return (true); } -bool save_sd_bank(const char* bank_filename, uint8_t* data) -{ +bool save_sd_bank(const char* bank_filename, uint8_t* data) { char tmp[FILENAME_LEN]; char tmp2[FILENAME_LEN]; int bank_number; File root, entry; - if (sd_card > 0) - { + if (sd_card > 0) { #ifdef DEBUG Serial.print(F("Trying so store ")); Serial.print(bank_filename); @@ -368,13 +345,10 @@ bool save_sd_bank(const char* bank_filename, uint8_t* data) snprintf_P(tmp, sizeof(tmp), PSTR("/%d"), bank_number); AudioNoInterrupts(); root = SD.open(tmp); - while (42 == 42) - { + while (42 == 42) { entry = root.openNextFile(); - if (entry) - { - if (!entry.isDirectory()) - { + if (entry) { + if (!entry.isDirectory()) { #ifdef DEBUG Serial.print(F("Removing ")); Serial.print(tmp); @@ -387,8 +361,7 @@ bool save_sd_bank(const char* bank_filename, uint8_t* data) SD.remove(tmp2); #else bool r = SD.remove(tmp2); - if (r == false) - { + if (r == false) { Serial.print(F("E: cannot remove ")); Serial.print(tmp2); Serial.println(F(".")); @@ -396,9 +369,7 @@ bool save_sd_bank(const char* bank_filename, uint8_t* data) #endif break; } - } - else - { + } else { break; } } @@ -417,8 +388,7 @@ bool save_sd_bank(const char* bank_filename, uint8_t* data) #ifdef DEBUG Serial.println(F(" done.")); #endif - } - else + } else return (false); return (true); @@ -427,15 +397,14 @@ bool save_sd_bank(const char* bank_filename, uint8_t* data) /****************************************************************************** SD DRUMSETTINGS ******************************************************************************/ -bool load_sd_drumsettings_json(uint8_t number) -{ + #if NUM_DRUMS > 0 +bool load_sd_drumsettings_json(uint8_t number) { if (number < 0) return (false); number = constrain(number, PERFORMANCE_NUM_MIN, PERFORMANCE_NUM_MAX); - if (sd_card > 0) - { + if (sd_card > 0) { File json; StaticJsonDocument data_json; char filename[CONFIG_FILENAME_LEN]; @@ -444,8 +413,7 @@ bool load_sd_drumsettings_json(uint8_t number) // first check if file exists... AudioNoInterrupts(); - if (SD.exists(filename)) - { + if (SD.exists(filename)) { // ... and if: load #ifdef DEBUG Serial.print(F("Found drums configuration [")); @@ -453,8 +421,7 @@ bool load_sd_drumsettings_json(uint8_t number) Serial.println(F("]... loading...")); #endif json = SD.open(filename); - if (json) - { + if (json) { deserializeJson(data_json, json); json.close(); AudioInterrupts(); @@ -466,31 +433,24 @@ bool load_sd_drumsettings_json(uint8_t number) configuration.drums.drum_main_vol = data_json["drums_volume"]; - for (uint8_t i = 0; i < NUM_DRUMSET_CONFIG - 1; i++) - { - uint8_t drumnumber = 0; - drumnumber = find_drum_number_from_note( data_json["note"][i] ); - if (((int)data_json["note"][i] > 0 && find_drum_number_from_note(data_json["note"][i]) > 0) || (i == 0 && (int)data_json["note"][i] == 210)) - { - set_sample_pitch( drumnumber, data_json["pitch"][i] ); - set_sample_pan( drumnumber, data_json["pan"][i]) ; - set_sample_vol_max( drumnumber, data_json["vol_max"][i]) ; - set_sample_vol_min( drumnumber, data_json["vol_min"][i] ); - set_sample_reverb_send( drumnumber, data_json["reverb_send"][i]); - } + for (uint8_t i = 0; i < NUM_DRUMSET_CONFIG - 1; i++) { + drum_config[i].midinote = data_json["pitch"][i]; + drum_config[i].pitch = data_json["pitch"][i]; + drum_config[i].pan = data_json["pan"][i]; + drum_config[i].vol_max = data_json["vol_max"][i]; + drum_config[i].vol_min = data_json["vol_min"][i]; + drum_config[i].reverb_send = data_json["reverb_send"][i]; } + check_configuration_drum_config(); return (true); } #ifdef DEBUG - else - { + else { Serial.print(F("E : Cannot open ")); Serial.print(filename); Serial.println(F(" on SD.")); } - } - else - { + } else { Serial.print(F("No ")); Serial.print(filename); Serial.println(F(" available.")); @@ -501,18 +461,15 @@ bool load_sd_drumsettings_json(uint8_t number) return (false); } -bool save_sd_drumsettings_json(uint8_t number) -{ +bool save_sd_drumsettings_json(uint8_t number) { char filename[CONFIG_FILENAME_LEN]; number = constrain(number, PERFORMANCE_NUM_MIN, PERFORMANCE_NUM_MAX); - if (sd_card > 0) - { + if (sd_card > 0) { File json; StaticJsonDocument data_json; - if (check_performance_directory(number)) - { + if (check_performance_directory(number)) { snprintf_P(filename, sizeof(filename), PSTR("/%s/%d/%s.json"), PERFORMANCE_CONFIG_PATH, number, DRUMS_CONFIG_NAME); #ifdef DEBUG @@ -530,18 +487,17 @@ bool save_sd_drumsettings_json(uint8_t number) SD.remove(filename); } json = SD.open(filename, FILE_WRITE); - if (json) - { + if (json) { data_json["drums_volume"] = configuration.drums.drum_main_vol; - for (uint8_t i = 0; i < NUM_DRUMSET_CONFIG - 1; i++) - { - data_json["note"][i] = get_sample_note(i); - data_json["pitch"][i] = get_sample_pitch(i); - data_json["pan"][i] = get_sample_pan(i); - data_json["vol_max"][i] = get_sample_vol_max(i); - data_json["vol_min"][i] = get_sample_vol_min(i); - data_json["reverb_send"][i] = get_sample_reverb_send(i); + for (uint8_t i = 0; i < NUM_DRUMSET_CONFIG - 1; i++) { + data_json["note"][i] = drum_config[i].midinote; + data_json["pitch"][i] = drum_config[i].pitch; + data_json["pan"][i] = drum_config[i].pan; + data_json["vol_max"][i] = drum_config[i].vol_max; + data_json["vol_min"][i] = drum_config[i].vol_min; + data_json["reverb_send"][i] = drum_config[i].reverb_send; } + #if defined(DEBUG) && defined(DEBUG_SHOW_JSON) Serial.println(F("Write JSON data:")); serializeJsonPretty(data_json, Serial); @@ -551,9 +507,7 @@ bool save_sd_drumsettings_json(uint8_t number) json.close(); AudioInterrupts(); return (true); - } - else - { + } else { #ifdef DEBUG Serial.print(F("E : Cannot open ")); Serial.print(filename); @@ -562,33 +516,158 @@ bool save_sd_drumsettings_json(uint8_t number) AudioInterrupts(); return (false); } + } else { + AudioInterrupts(); + return (false); } - else - { + } +#ifdef DEBUG + else { + Serial.println(F("E: SD card not available")); + } +#endif + return (false); +} + +bool load_sd_drummap_json(uint8_t number) { + if (number < 0) + return (false); + + number = constrain(number, PERFORMANCE_NUM_MIN, PERFORMANCE_NUM_MAX); + + if (sd_card > 0) { + File json; + StaticJsonDocument data_json; + char filename[CONFIG_FILENAME_LEN]; + + snprintf_P(filename, sizeof(filename), PSTR("/%s/%d/%s.json"), PERFORMANCE_CONFIG_PATH, number, DRUMS_MAPPING_NAME); + + // first check if file exists... + AudioNoInterrupts(); + if (SD.exists(filename)) { + // ... and if: load +#ifdef DEBUG + Serial.print(F("Found drum mapping [")); + Serial.print(filename); + Serial.println(F("]... loading...")); +#endif + json = SD.open(filename); + if (json) { + deserializeJson(data_json, json); + json.close(); + AudioInterrupts(); +#if defined(DEBUG) && defined(DEBUG_SHOW_JSON) + Serial.println(F("Read JSON data:")); + serializeJsonPretty(data_json, Serial); + Serial.println(); +#endif + + for (uint8_t i = 0; i < NUM_DRUMSET_CONFIG - 1; i++) + drum_map[i] = data_json["map"][i]; + check_configuration_drum_map(); + return (true); + } +#ifdef DEBUG + else { + Serial.print(F("E : Cannot open ")); + Serial.print(filename); + Serial.println(F(" on SD.")); + } + } else { + Serial.print(F("No ")); + Serial.print(filename); + Serial.println(F(" available.")); +#endif + } + } + AudioInterrupts(); + return (false); +} + +bool save_sd_drummap_json(uint8_t number) { + char filename[CONFIG_FILENAME_LEN]; + number = constrain(number, PERFORMANCE_NUM_MIN, PERFORMANCE_NUM_MAX); + + if (sd_card > 0) { + File json; + StaticJsonDocument data_json; + + if (check_performance_directory(number)) { + snprintf_P(filename, sizeof(filename), PSTR("/%s/%d/%s.json"), PERFORMANCE_CONFIG_PATH, number, DRUMS_MAPPING_NAME); + +#ifdef DEBUG + Serial.print(F("Saving drums-map ")); + Serial.print(number); + Serial.print(F(" to ")); + Serial.println(filename); +#endif + AudioNoInterrupts(); + if (SD.exists(filename)) { +#ifdef DEBUG + Serial.println(F("remove old drum-map file")); +#endif + SD.begin(); + SD.remove(filename); + } + json = SD.open(filename, FILE_WRITE); + if (json) { + for (uint8_t i = 0; i < NUM_DRUMSET_CONFIG - 1; i++) + data_json["map"][i] = drum_map[i]; + +#if defined(DEBUG) && defined(DEBUG_SHOW_JSON) + Serial.println(F("Write JSON data:")); + serializeJsonPretty(data_json, Serial); + Serial.println(); +#endif + serializeJsonPretty(data_json, json); + json.close(); + AudioInterrupts(); + return (true); + } else { +#ifdef DEBUG + Serial.print(F("E : Cannot open ")); + Serial.print(filename); + Serial.println(F(" on SD.")); +#endif + AudioInterrupts(); + return (false); + } + } else { AudioInterrupts(); return (false); } } #ifdef DEBUG - else - { + else { Serial.println(F("E: SD card not available")); } #endif return (false); } +/* +uint8_t find_drum_number_from_note(uint8_t note) { + uint8_t number = 0; + for (uint8_t d = 0; d < NUM_DRUMSET_CONFIG - 1; d++) { + if (note == drum_config[d].midinote) { + number = d; + break; + } + } + return number; +} +*/ +#endif + /****************************************************************************** SD VOICECONFIG ******************************************************************************/ -bool load_sd_voiceconfig_json(uint8_t vc, uint8_t instance_id) -{ +bool load_sd_voiceconfig_json(uint8_t vc, uint8_t instance_id) { char filename[CONFIG_FILENAME_LEN]; vc = constrain(vc, PERFORMANCE_NUM_MIN, PERFORMANCE_NUM_MAX); - if (sd_card > 0) - { + if (sd_card > 0) { File json; StaticJsonDocument data_json; @@ -596,8 +675,7 @@ bool load_sd_voiceconfig_json(uint8_t vc, uint8_t instance_id) // first check if file exists... AudioNoInterrupts(); - if (SD.exists(filename)) - { + if (SD.exists(filename)) { // ... and if: load #ifdef DEBUG Serial.print(F("Found voice configuration [")); @@ -605,8 +683,7 @@ bool load_sd_voiceconfig_json(uint8_t vc, uint8_t instance_id) Serial.println(F("]... loading...")); #endif json = SD.open(filename); - if (json) - { + if (json) { deserializeJson(data_json, json); json.close(); @@ -655,15 +732,12 @@ bool load_sd_voiceconfig_json(uint8_t vc, uint8_t instance_id) return (true); } #ifdef DEBUG - else - { + else { Serial.print(F("E : Cannot open ")); Serial.print(filename); Serial.println(F(" on SD.")); } - } - else - { + } else { Serial.print(F("No ")); Serial.print(filename); Serial.println(F(" available.")); @@ -675,14 +749,12 @@ bool load_sd_voiceconfig_json(uint8_t vc, uint8_t instance_id) return (false); } -bool save_sd_voiceconfig_json(uint8_t vc, uint8_t instance_id) -{ +bool save_sd_voiceconfig_json(uint8_t vc, uint8_t instance_id) { char filename[CONFIG_FILENAME_LEN]; vc = constrain(vc, PERFORMANCE_NUM_MIN, PERFORMANCE_NUM_MAX); - if (sd_card > 0) - { + if (sd_card > 0) { File json; StaticJsonDocument data_json; snprintf_P(filename, sizeof(filename), PSTR("/%s/%d/%s%d.json"), PERFORMANCE_CONFIG_PATH, vc, VOICE_CONFIG_NAME, instance_id + 1); @@ -701,8 +773,7 @@ bool save_sd_voiceconfig_json(uint8_t vc, uint8_t instance_id) SD.begin(); SD.remove(filename); json = SD.open(filename, FILE_WRITE); - if (json) - { + if (json) { data_json["bank"] = configuration.dexed[instance_id].bank; data_json["voice"] = configuration.dexed[instance_id].voice; data_json["lowest_note"] = configuration.dexed[instance_id].lowest_note; @@ -748,9 +819,7 @@ bool save_sd_voiceconfig_json(uint8_t vc, uint8_t instance_id) return (true); } json.close(); - } - else - { + } else { #ifdef DEBUG Serial.print(F("E : Cannot open ")); Serial.print(filename); @@ -765,14 +834,12 @@ bool save_sd_voiceconfig_json(uint8_t vc, uint8_t instance_id) /****************************************************************************** SD FX ******************************************************************************/ -bool load_sd_fx_json(uint8_t number) -{ +bool load_sd_fx_json(uint8_t number) { number = constrain(number, PERFORMANCE_NUM_MIN, PERFORMANCE_NUM_MAX); load_sd_drumsettings_json(number); - if (sd_card > 0) - { + if (sd_card > 0) { File json; StaticJsonDocument data_json; char filename[CONFIG_FILENAME_LEN]; @@ -780,8 +847,7 @@ bool load_sd_fx_json(uint8_t number) // first check if file exists... AudioNoInterrupts(); - if (SD.exists(filename)) - { + if (SD.exists(filename)) { // ... and if: load #ifdef DEBUG Serial.print(F("Found fx configuration [")); @@ -789,8 +855,7 @@ bool load_sd_fx_json(uint8_t number) Serial.println(F("]... loading...")); #endif json = SD.open(filename); - if (json) - { + if (json) { deserializeJson(data_json, json); json.close(); @@ -801,8 +866,7 @@ bool load_sd_fx_json(uint8_t number) serializeJsonPretty(data_json, Serial); Serial.println(); #endif - for (uint8_t i = 0; i < MAX_DEXED; i++) - { + for (uint8_t i = 0; i < MAX_DEXED; i++) { configuration.fx.filter_cutoff[i] = data_json["filter_cutoff"][i]; configuration.fx.filter_resonance[i] = data_json["filter_resonance"][i]; configuration.fx.chorus_frequency[i] = data_json["chorus_frequency"][i]; @@ -814,8 +878,7 @@ bool load_sd_fx_json(uint8_t number) configuration.fx.delay_level[i] = data_json["delay_level"][i]; configuration.fx.delay_sync[i] = data_json["delay_sync"][i]; configuration.fx.reverb_send[i] = data_json["reverb_send"][i]; - if (configuration.fx.delay_sync[i] > 0) - { + if (configuration.fx.delay_sync[i] > 0) { configuration.fx.delay_time[i] = 0; } } @@ -845,15 +908,12 @@ bool load_sd_fx_json(uint8_t number) return (true); } #ifdef DEBUG - else - { + else { Serial.print(F("E : Cannot open ")); Serial.print(filename); Serial.println(F(" on SD.")); } - } - else - { + } else { Serial.print(F("No ")); Serial.print(filename); Serial.println(F(" available.")); @@ -865,15 +925,13 @@ bool load_sd_fx_json(uint8_t number) return (false); } -bool save_sd_fx_json(uint8_t number) -{ +bool save_sd_fx_json(uint8_t number) { char filename[CONFIG_FILENAME_LEN]; number = constrain(number, PERFORMANCE_NUM_MIN, PERFORMANCE_NUM_MAX); save_sd_drumsettings_json(number); - if (sd_card > 0) - { + if (sd_card > 0) { File json; StaticJsonDocument data_json; snprintf_P(filename, sizeof(filename), PSTR("/%s/%d/%s.json"), PERFORMANCE_CONFIG_PATH, number, FX_CONFIG_NAME); @@ -889,10 +947,8 @@ bool save_sd_fx_json(uint8_t number) SD.begin(); SD.remove(filename); json = SD.open(filename, FILE_WRITE); - if (json) - { - for (uint8_t i = 0; i < MAX_DEXED; i++) - { + if (json) { + for (uint8_t i = 0; i < MAX_DEXED; i++) { data_json["filter_cutoff"][i] = configuration.fx.filter_cutoff[i]; data_json["filter_resonance"][i] = configuration.fx.filter_resonance[i]; data_json["chorus_frequency"][i] = configuration.fx.chorus_frequency[i]; @@ -936,9 +992,7 @@ bool save_sd_fx_json(uint8_t number) return (true); } json.close(); - } - else - { + } else { #ifdef DEBUG Serial.print(F("E : Cannot open ")); Serial.print(filename); @@ -953,12 +1007,10 @@ bool save_sd_fx_json(uint8_t number) /****************************************************************************** SD EPIANO ******************************************************************************/ -bool load_sd_epiano_json(uint8_t number) -{ +bool load_sd_epiano_json(uint8_t number) { number = constrain(number, PERFORMANCE_NUM_MIN, PERFORMANCE_NUM_MAX); - if (sd_card > 0) - { + if (sd_card > 0) { File json; StaticJsonDocument data_json; char filename[CONFIG_FILENAME_LEN]; @@ -966,8 +1018,7 @@ bool load_sd_epiano_json(uint8_t number) // first check if file exists... AudioNoInterrupts(); - if (SD.exists(filename)) - { + if (SD.exists(filename)) { // ... and if: load #ifdef DEBUG Serial.print(F("Found epiano configuration [")); @@ -975,8 +1026,7 @@ bool load_sd_epiano_json(uint8_t number) Serial.println(F("]... loading...")); #endif json = SD.open(filename); - if (json) - { + if (json) { deserializeJson(data_json, json); json.close(); @@ -1012,15 +1062,12 @@ bool load_sd_epiano_json(uint8_t number) return (true); } #ifdef DEBUG - else - { + else { Serial.print(F("E : Cannot open ")); Serial.print(filename); Serial.println(F(" on SD.")); } - } - else - { + } else { Serial.print(F("No ")); Serial.print(filename); Serial.println(F(" available.")); @@ -1032,14 +1079,12 @@ bool load_sd_epiano_json(uint8_t number) return (false); } -bool save_sd_epiano_json(uint8_t number) -{ +bool save_sd_epiano_json(uint8_t number) { char filename[CONFIG_FILENAME_LEN]; number = constrain(number, PERFORMANCE_NUM_MIN, PERFORMANCE_NUM_MAX); - if (sd_card > 0) - { + if (sd_card > 0) { File json; StaticJsonDocument data_json; snprintf_P(filename, sizeof(filename), PSTR("/%s/%d/%s.json"), PERFORMANCE_CONFIG_PATH, number, EPIANO_CONFIG_NAME); @@ -1055,8 +1100,7 @@ bool save_sd_epiano_json(uint8_t number) SD.begin(); SD.remove(filename); json = SD.open(filename, FILE_WRITE); - if (json) - { + if (json) { data_json["decay"] = configuration.epiano.decay; data_json["release"] = configuration.epiano.release; data_json["hardness"] = configuration.epiano.hardness; @@ -1087,9 +1131,7 @@ bool save_sd_epiano_json(uint8_t number) return (true); } json.close(); - } - else - { + } else { #ifdef DEBUG Serial.print(F("E : Cannot open ")); Serial.print(filename); @@ -1104,10 +1146,8 @@ bool save_sd_epiano_json(uint8_t number) /****************************************************************************** SD SYS ******************************************************************************/ -bool load_sd_sys_json(void) -{ - if (sd_card > 0) - { +bool load_sd_sys_json(void) { + if (sd_card > 0) { File json; StaticJsonDocument data_json; char filename[CONFIG_FILENAME_LEN]; @@ -1115,15 +1155,13 @@ bool load_sd_sys_json(void) // first check if file exists... AudioNoInterrupts(); - if (SD.exists(filename)) - { + if (SD.exists(filename)) { // ... and if: load #ifdef DEBUG Serial.println(F("Found sys configuration")); #endif json = SD.open(filename); - if (json) - { + if (json) { deserializeJson(data_json, json); json.close(); @@ -1148,15 +1186,12 @@ bool load_sd_sys_json(void) return (true); } #ifdef DEBUG - else - { + else { Serial.print(F("E : Cannot open ")); Serial.print(filename); Serial.println(F(" on SD.")); } - } - else - { + } else { Serial.print(F("No ")); Serial.print(filename); Serial.println(F(" available.")); @@ -1168,12 +1203,10 @@ bool load_sd_sys_json(void) return (false); } -bool save_sd_sys_json(void) -{ +bool save_sd_sys_json(void) { char filename[CONFIG_FILENAME_LEN]; - if (sd_card > 0) - { + if (sd_card > 0) { File json; StaticJsonDocument data_json; snprintf_P(filename, sizeof(filename), PSTR("/%s.json"), SYS_CONFIG_NAME); @@ -1187,8 +1220,7 @@ bool save_sd_sys_json(void) SD.begin(); SD.remove(filename); json = SD.open(filename, FILE_WRITE); - if (json) - { + if (json) { data_json["vol"] = configuration.sys.vol; data_json["mono"] = configuration.sys.mono; data_json["soft_midi_thru"] = configuration.sys.soft_midi_thru; @@ -1208,9 +1240,7 @@ bool save_sd_sys_json(void) return (true); } json.close(); - } - else - { + } else { #ifdef DEBUG Serial.print(F("E : Cannot open ")); Serial.print(filename); @@ -1222,8 +1252,7 @@ bool save_sd_sys_json(void) return (false); } -bool save_sd_performance_json(uint8_t number) -{ +bool save_sd_performance_json(uint8_t number) { char filename[CONFIG_FILENAME_LEN]; number = constrain(number, PERFORMANCE_NUM_MIN, PERFORMANCE_NUM_MAX); @@ -1241,8 +1270,7 @@ bool save_sd_performance_json(uint8_t number) save_sd_fx_json(number); save_sd_epiano_json(number); - for (uint8_t i = 0; i < MAX_DEXED; i++) - { + for (uint8_t i = 0; i < MAX_DEXED; i++) { snprintf_P(filename, sizeof(filename), PSTR("/%s/%d/%s%d.json"), PERFORMANCE_CONFIG_PATH, number, VOICE_CONFIG_NAME, i); #ifdef DEBUG Serial.print(F("Write Voice-Config")); @@ -1251,8 +1279,7 @@ bool save_sd_performance_json(uint8_t number) save_sd_voiceconfig_json(number, i); } - if (sd_card > 0) - { + if (sd_card > 0) { File json; StaticJsonDocument data_json; snprintf_P(filename, sizeof(filename), PSTR("/%s/%d/%s.json"), PERFORMANCE_CONFIG_PATH, number, PERFORMANCE_CONFIG_NAME); @@ -1265,8 +1292,7 @@ bool save_sd_performance_json(uint8_t number) SD.remove(filename); json = SD.open(filename, FILE_WRITE); - if (json) - { + if (json) { for (uint8_t i = 0; i < FILENAME_LEN; i++) { data_json["name"][i] = configuration.performance.name[i]; } @@ -1285,8 +1311,7 @@ bool save_sd_performance_json(uint8_t number) AudioInterrupts(); } #ifdef DEBUG - else - { + else { Serial.print(F("E : Cannot open ")); Serial.print(filename); Serial.println(F(" on SD.")); @@ -1297,26 +1322,20 @@ bool save_sd_performance_json(uint8_t number) return (false); } -bool check_performance_directory(uint8_t number) -{ +bool check_performance_directory(uint8_t number) { char dir[CONFIG_FILENAME_LEN]; - if (sd_card > 0) - { + if (sd_card > 0) { snprintf_P(dir, sizeof(dir), PSTR("/%s/%d"), PERFORMANCE_CONFIG_PATH, number); AudioNoInterrupts(); SD.begin(); - if (!SD.exists(dir)) - { + if (!SD.exists(dir)) { #ifdef DEBUG - if (SD.mkdir(dir)) - { + if (SD.mkdir(dir)) { Serial.print(F("Creating directory ")); Serial.println(dir); - } - else - { + } else { Serial.print(F("E: Cannot create ")); Serial.println(dir); AudioInterrupts(); @@ -1330,19 +1349,16 @@ bool check_performance_directory(uint8_t number) return (true); } #ifdef DEBUG - else - { + else { Serial.println(F("E: SD card not available")); } #endif return (false); } -void get_sd_performance_name_json(uint8_t number) -{ +void get_sd_performance_name_json(uint8_t number) { number = constrain(number, PERFORMANCE_NUM_MIN, PERFORMANCE_NUM_MAX); - if (sd_card > 0) - { + if (sd_card > 0) { File json; StaticJsonDocument data_json; char filename[CONFIG_FILENAME_LEN]; @@ -1351,13 +1367,11 @@ void get_sd_performance_name_json(uint8_t number) // first check if file exists... AudioNoInterrupts(); - if (SD.exists(filename)) - { + if (SD.exists(filename)) { // ... and if: load json = SD.open(filename); - if (json) - { + if (json) { deserializeJson(data_json, json); json.close(); @@ -1376,8 +1390,7 @@ void get_sd_performance_name_json(uint8_t number) #endif } #ifdef DEBUG - else - { + else { Serial.print(F("Cannot get performance name for ")); Serial.print(number); Serial.println(); @@ -1387,22 +1400,23 @@ void get_sd_performance_name_json(uint8_t number) } } -bool load_sd_performance_json(uint8_t number) -{ +bool load_sd_performance_json(uint8_t number) { dac_mute(); handleStop(); number = constrain(number, PERFORMANCE_NUM_MIN, PERFORMANCE_NUM_MAX); AudioNoInterrupts(); load_sd_fx_json(number); load_sd_epiano_json(number); +#if NUM_DRUMS > 0 + load_sd_drumsettings_json(number); + load_sd_drummap_json(number); +#endif - if (sd_card > 0) - { + if (sd_card > 0) { File json; StaticJsonDocument data_json; - for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) - { + for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) { #ifdef DEBUG Serial.print(F("Load Voice-Config ")); Serial.println(instance_id + 1); @@ -1422,32 +1436,26 @@ bool load_sd_performance_json(uint8_t number) return (false); } -bool check_sd_performance_exists(uint8_t number) -{ +bool check_sd_performance_exists(uint8_t number) { if (number < 0) return (false); number = constrain(number, PERFORMANCE_NUM_MIN, PERFORMANCE_NUM_MAX); AudioNoInterrupts(); - if (sd_card > 0) - { + if (sd_card > 0) { char filename[CONFIG_FILENAME_LEN]; snprintf_P(filename, sizeof(filename), PSTR("/%s/%d/%s.json"), PERFORMANCE_CONFIG_PATH, number, PERFORMANCE_CONFIG_NAME); // check if file exists... - if (SD.exists(filename)) - { + if (SD.exists(filename)) { AudioInterrupts(); return (true); - } else - { + } else { AudioInterrupts(); return (false); } - } - else - { + } else { AudioInterrupts(); return (false); } @@ -1456,8 +1464,7 @@ bool check_sd_performance_exists(uint8_t number) /****************************************************************************** HELPER FUNCTIONS ******************************************************************************/ -bool get_sd_data(File sysex, uint8_t format, uint8_t* conf) -{ +bool get_sd_data(File sysex, uint8_t format, uint8_t* conf) { uint16_t n; int32_t bulk_checksum_calc = 0; int8_t bulk_checksum; @@ -1483,7 +1490,7 @@ bool get_sd_data(File sysex, uint8_t format, uint8_t* conf) #endif return (false); } - if (sysex.read() != format) // check for sysex type + if (sysex.read() != format) // check for sysex type { #ifdef DEBUG Serial.println(F("E : SysEx type not found.")); @@ -1499,12 +1506,11 @@ bool get_sd_data(File sysex, uint8_t format, uint8_t* conf) return (false); } - sysex.seek(sysex.size() - 2); // Bulk checksum + sysex.seek(sysex.size() - 2); // Bulk checksum bulk_checksum = sysex.read(); - sysex.seek(3); // start of bulk data - for (n = 0; n < sysex.size() - 6; n++) - { + sysex.seek(3); // start of bulk data + for (n = 0; n < sysex.size() - 6; n++) { uint8_t d = sysex.read(); bulk_checksum_calc -= d; #ifdef DEBUG @@ -1514,8 +1520,7 @@ bool get_sd_data(File sysex, uint8_t format, uint8_t* conf) } bulk_checksum_calc &= 0x7f; - if (int8_t(bulk_checksum_calc) != bulk_checksum) - { + if (int8_t(bulk_checksum_calc) != bulk_checksum) { #ifdef DEBUG Serial.print(F("E : Bulk checksum mismatch : 0x")); Serial.print(int8_t(bulk_checksum_calc), HEX); @@ -1525,8 +1530,7 @@ bool get_sd_data(File sysex, uint8_t format, uint8_t* conf) return (false); } #ifdef DEBUG - else - { + else { Serial.print(F("Bulk checksum : 0x")); Serial.print(int8_t(bulk_checksum_calc), HEX); Serial.print(F(" [0x")); @@ -1535,9 +1539,8 @@ bool get_sd_data(File sysex, uint8_t format, uint8_t* conf) } #endif - sysex.seek(3); // start of bulk data - for (n = 0; n < sysex.size() - 6; n++) - { + sysex.seek(3); // start of bulk data + for (n = 0; n < sysex.size() - 6; n++) { uint8_t d = sysex.read(); *(conf++) = d; } @@ -1550,8 +1553,7 @@ bool get_sd_data(File sysex, uint8_t format, uint8_t* conf) return (true); } -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) { #ifdef DEBUG Serial.print(F("Storing SYSEX format 0x")); Serial.print(format, HEX); @@ -1580,8 +1582,7 @@ bool write_sd_data(File sysex, uint8_t format, uint8_t* data, uint16_t len) // write data sysex.write(data, len); #ifdef DEBUG - for (uint16_t i = 0; i < len; i++) - { + for (uint16_t i = 0; i < len; i++) { Serial.print(F("Write SYSEX data: 0x")); Serial.println(data[i], HEX); } @@ -1605,8 +1606,7 @@ bool write_sd_data(File sysex, uint8_t format, uint8_t* data, uint16_t len) return (true); } -uint8_t calc_checksum(uint8_t* data, uint16_t len) -{ +uint8_t calc_checksum(uint8_t* data, uint16_t len) { int32_t bulk_checksum_calc = 0; for (uint16_t n = 0; n < len; n++) @@ -1615,8 +1615,7 @@ uint8_t calc_checksum(uint8_t* data, uint16_t len) return (bulk_checksum_calc & 0x7f); } -void strip_extension(const char* s, char* target, uint8_t len) -{ +void strip_extension(const char* s, char* target, uint8_t len) { char tmp[CONFIG_FILENAME_LEN]; char* token; @@ -1630,12 +1629,10 @@ void strip_extension(const char* s, char* target, uint8_t len) target[len] = '\0'; } -bool get_bank_name(uint8_t b, char* name, uint8_t len) -{ +bool get_bank_name(uint8_t b, char* name, uint8_t len) { File sysex; - if (sd_card > 0) - { + if (sd_card > 0) { char bankdir[4]; File entry; @@ -1648,13 +1645,11 @@ bool get_bank_name(uint8_t b, char* name, uint8_t len) if (!sysex) return (false); - do - { + do { entry = sysex.openNextFile(); } while (entry.isDirectory()); - if (entry.isDirectory()) - { + if (entry.isDirectory()) { entry.close(); sysex.close(); return (false); @@ -1679,12 +1674,10 @@ bool get_bank_name(uint8_t b, char* name, uint8_t len) return (false); } -bool get_voice_name(uint8_t b, uint8_t v, char* name, uint8_t len) -{ +bool get_voice_name(uint8_t b, uint8_t v, char* name, uint8_t len) { File sysex; - if (sd_card > 0) - { + if (sd_card > 0) { char bank_name[BANK_NAME_LEN]; char filename[FILENAME_LEN]; @@ -1728,12 +1721,10 @@ bool get_voice_name(uint8_t b, uint8_t v, char* name, uint8_t len) return (false); } -bool get_voice_by_bank_name(uint8_t b, const char* bank_name, uint8_t v, char* voice_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) { File sysex; - if (sd_card > 0) - { + if (sd_card > 0) { char filename[FILENAME_LEN]; snprintf_P(filename, sizeof(filename), PSTR("/%d/%s.syx"), b, bank_name); @@ -1774,11 +1765,9 @@ bool get_voice_by_bank_name(uint8_t b, const char* bank_name, uint8_t v, char* v return (false); } -void string_toupper(char* s) -{ - while (*s) - { - *s = toupper((unsigned char) * s); +void string_toupper(char* s) { + while (*s) { + *s = toupper((unsigned char)*s); s++; } } diff --git a/dexed_sd.h b/dexed_sd.h index 6fd0c80..9caba34 100644 --- a/dexed_sd.h +++ b/dexed_sd.h @@ -30,7 +30,7 @@ #include "synth_dexed.h" extern uint8_t sd_card; -extern AudioSynthDexed* MicroDexed[NUM_DEXED]; +extern AudioSynthDexed* MicroDexed[NUM_DEXED]; extern void show_patch(uint8_t instance_id); extern void send_sysex_voice(uint8_t midi_channel, uint8_t* data); @@ -40,7 +40,7 @@ extern uint8_t voice; extern uint8_t ui_state; extern uint8_t ui_main_state; extern config_t configuration; -extern uint32_t crc32(byte * calc_start, uint16_t calc_bytes); +extern uint32_t crc32(byte* calc_start, uint16_t calc_bytes); extern void set_fx_params(void); extern void set_voiceconfig_params(uint8_t instance_id); extern void set_sys_params(void); @@ -64,8 +64,10 @@ bool save_sd_sys_json(void); bool load_sd_performance_json(uint8_t p); bool save_sd_performance_json(uint8_t p); -bool load_sd_seq_json(uint8_t p); -bool save_sd_seq_json(uint8_t p); +bool load_sd_drumsettings_json(uint8_t number); +bool save_sd_drumsettings_json(uint8_t number); +bool load_sd_drummap_json(uint8_t p); +bool save_sd_drummap_json(uint8_t p); bool check_performance_directory(uint8_t seq_number);