From cb08f297102e36a722ca80909fba6a3fc3069847 Mon Sep 17 00:00:00 2001 From: positionhigh Date: Tue, 4 Jan 2022 20:25:37 +0100 Subject: [PATCH] =?UTF-8?q?Dateien=20hochladen=20nach=20=E2=80=9E=E2=80=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.h | 2 + dexed_sd.cpp | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++ drums.h | 12 ++++- 3 files changed, 161 insertions(+), 2 deletions(-) diff --git a/config.h b/config.h index 8499de9..a35a7f0 100644 --- a/config.h +++ b/config.h @@ -119,6 +119,7 @@ #endif // DEFAULT MIDI CHANNEL FOR DRUMSAMPLER #define DRUM_MIDI_CHANNEL 10 +#define NUM_CUSTOM_MIDI_MAPPINGS 20 //Number of Custom Key, CC and Button Mappings // NUMBER OF SAMPLES IN DRUMSET #if defined(ARDUINO_TEENSY41) @@ -335,6 +336,7 @@ #define PERFORMANCE_CONFIG_PATH "PERFORMANCE" #define SEQUENCER_CONFIG_NAME "sequencer" #define DRUMS_CONFIG_NAME "drums" +#define DRUMS_MAPPING_NAME "drmmap" #define PATTERN_CONFIG_NAME "patterns" #define VELOCITY_CONFIG_NAME "velocity" #define FX_CONFIG_NAME "fx" diff --git a/dexed_sd.cpp b/dexed_sd.cpp index b1fdf5e..9830531 100644 --- a/dexed_sd.cpp +++ b/dexed_sd.cpp @@ -38,6 +38,7 @@ using namespace TeensyTimerTool; #include "drums.h" extern void set_drums_volume(float vol); extern drum_config_t drum_config[]; +extern custom_midi_map_t custom_midi_map[NUM_CUSTOM_MIDI_MAPPINGS]; #endif extern void init_MIDI_send_CC(void); @@ -434,6 +435,148 @@ bool save_sd_bank(const char* bank_filename, uint8_t* data) return (true); } +/****************************************************************************** + SD DRUM CUSTOM MAPPINGS + ******************************************************************************/ + +bool load_sd_drummappings_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]; + + sprintf(filename, "/%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(); +#ifdef DEBUG + Serial.println(F("Read JSON data:")); + serializeJsonPretty(data_json, Serial); + Serial.println(); +#endif + + for (uint8_t i = 0; i < NUM_CUSTOM_MIDI_MAPPINGS - 1; i++) + { + custom_midi_map[i].type = data_json["type"][i]; + custom_midi_map[i].in = data_json["in"][i]; + custom_midi_map[i].out = data_json["out"][i]; + custom_midi_map[i].channel = data_json["channel"][i]; + } + 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 + } + } + return (false); +} + +bool save_sd_drummappings_json(uint8_t number) +{ + char filename[CONFIG_FILENAME_LEN]; + number = constrain(number, 0, 99); + + if (sd_card > 0) + { + File json; + StaticJsonDocument data_json; + + if (check_performance_directory(number)) + { + sprintf(filename, "/%s/%d/%s.json", PERFORMANCE_CONFIG_PATH, number, DRUMS_MAPPING_NAME); + +#ifdef DEBUG + Serial.print(F("Saving drum mapping ")); + Serial.print(number); + Serial.print(F(" to ")); + Serial.println(filename); +#endif + AudioNoInterrupts(); + if (SD.exists(filename)) { + Serial.println("remove old drum mapping file"); + SD.begin(); + SD.remove(filename); + } + json = SD.open(filename, FILE_WRITE); + if (json) + { + for (uint8_t i = 0; i < NUM_CUSTOM_MIDI_MAPPINGS - 1; i++) + { + data_json["type"][i] = custom_midi_map[i].type; + data_json["in"][i] = custom_midi_map[i].in; + data_json["out"][i] = custom_midi_map[i].out; + data_json["channel"][i] = custom_midi_map[i].channel; + } +#ifdef DEBUG + 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 + { + Serial.println(F("E: SD card not available")); + } +#endif + return (false); +} + + /****************************************************************************** SD DRUMSETTINGS ******************************************************************************/ @@ -532,7 +675,9 @@ bool save_sd_drumsettings_json(uint8_t number) #endif AudioNoInterrupts(); if (SD.exists(filename)) { +#ifdef DEBUG Serial.println("remove old drumsettings file"); +#endif SD.begin(); SD.remove(filename); } @@ -1371,6 +1516,7 @@ bool save_sd_performance_json(uint8_t number) save_sd_seq_sub_vel_json(number); save_sd_seq_sub_patterns_json(number); + save_sd_drummappings_json(number); save_sd_fx_json(number); save_sd_epiano_json(number); @@ -1456,6 +1602,7 @@ bool save_sd_performance_json(uint8_t number) return (true); } json.close(); + AudioInterrupts(); } #ifdef DEBUG else @@ -1463,6 +1610,7 @@ bool save_sd_performance_json(uint8_t number) Serial.print(F("E : Cannot open ")); Serial.print(filename); Serial.println(F(" on SD.")); + AudioInterrupts(); } #endif @@ -1718,6 +1866,7 @@ bool load_sd_performance_json(uint8_t number) load_sd_seq_sub_vel_json(number); load_sd_fx_json(number); load_sd_epiano_json(number); + load_sd_drummappings_json(number); if (sd_card > 0) { diff --git a/drums.h b/drums.h index 30ab926..0f3c216 100644 --- a/drums.h +++ b/drums.h @@ -38,7 +38,7 @@ typedef struct drum_config_s { const uint8_t* drum_data; char shortname[2]; // 1 char name for sequencer uint32_t len; // number of elements in drum_data - float32_t pitch; // variable pitch per note for sequencer + float32_t pitch; // variable pitch per note for sequencer float32_t p_offset; // "static" pitch offset to correct root note to root of other samples float32_t pan; // Panorama (-1.0 - +1.0) float32_t vol_max; // max. Volume (0.0 - 1.0) @@ -46,6 +46,14 @@ typedef struct drum_config_s { float32_t reverb_send; // how much signal to send to the reverb (0.0 - 1.0) } drum_config_t; -enum {DRUM_NONE, DRUM_BASS, DRUM_SNARE, DRUM_HIHAT, DRUM_HANDCLAP, DRUM_RIDE, DRUM_CRASH, DRUM_LOWTOM, DRUM_MIDTOM, DRUM_HIGHTOM, DRUM_PERCUSSION,DRUM_POLY}; +enum {DRUM_NONE, DRUM_BASS, DRUM_SNARE, DRUM_HIHAT, DRUM_HANDCLAP, DRUM_RIDE, DRUM_CRASH, DRUM_LOWTOM, DRUM_MIDTOM, DRUM_HIGHTOM, DRUM_PERCUSSION, DRUM_POLY}; + +typedef struct custom_midi_map_s { + uint8_t type; // 0 = empty, 1 = Key/Pad, 2 = CC / Values, 3 = Button push on/off + uint8_t channel; // Midi Channel + uint8_t in; // Midi Input Key/Pad / Value + uint8_t out; // Destination Key / Value + +} custom_midi_map_t; #endif