From f55cc2b1dbcf4088fc4ad5b33ea34749b64576b7 Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Tue, 3 Aug 2021 13:08:16 +0200 Subject: [PATCH] Drum config is now a JSON file. --- MicroDexed.ino | 7 +- UI.hpp | 31 ++--- addon/SD/drm/CFGDrums.json | 278 ++++++++++++++++++------------------- config.h | 3 +- drums.cpp | 210 +++++++++++++++++++++++++++- drums.h | 9 +- 6 files changed, 369 insertions(+), 169 deletions(-) diff --git a/MicroDexed.ino b/MicroDexed.ino index e23f412..ca29cd8 100644 --- a/MicroDexed.ino +++ b/MicroDexed.ino @@ -325,6 +325,10 @@ int16_t delayline[NUM_DEXED][MOD_DELAY_SAMPLE_BUFFER]; #endif #if NUM_DRUMS > 0 +uint8_t num_drums = 0; +drum_config_t drum_config[DRUM_MAX_INSTRUMENTS]; +uint8_t drum_counter; +uint8_t drum_type[DRUM_MAX_INSTRUMENTS]; extern void sequencer(void); #endif @@ -754,9 +758,10 @@ void handleNoteOn(byte inChannel, byte inNumber, byte inVelocity) Serial.print(drum_counter, DEC); Serial.print(F("]: ")); Serial.println(note_name); + Serial.println(inNumber); #endif - for (uint8_t d = 0; d < NUM_DRUMCONFIG; d++) + for (uint8_t d = 0; d < num_drums; d++) { if (inNumber == drum_config[d].midinote) { diff --git a/UI.hpp b/UI.hpp index 56d64b9..eb07e89 100644 --- a/UI.hpp +++ b/UI.hpp @@ -37,9 +37,6 @@ #include "effect_freeverbf.h" #endif #include "synth_dexed.h" -#if NUM_DRUMS > 0 -#include "drums.h" -#endif #include #include @@ -84,6 +81,8 @@ extern uint8_t seq_chain_active_chainstep; //for editor extern uint8_t seq_chain_active_step; #if NUM_DRUMS > 0 #include "drums.h" +extern drum_config_t drum_config[DRUM_MAX_INSTRUMENTS]; +extern uint8_t num_drums; #endif #ifdef DISPLAY_LCD_SPI @@ -3551,7 +3550,7 @@ const char* seq_find_shortname(uint8_t sstep) bool found = false; if (seq_active_track < 3) { - for (uint8_t d = 0; d < NUM_DRUMCONFIG - 1; d++) + for (uint8_t d = 0; d < num_drums - 1; d++) { if (seq_data[ seq_patternchain[seq_chain_active_step][seq_active_track] ][sstep] == drum_config[d].midinote) { @@ -3575,7 +3574,7 @@ const char* seq_find_shortname(uint8_t sstep) //{ // // if (track < 3) { -// for (uint8_t d = 0; d < NUM_DRUMCONFIG - 1; d++) +// for (uint8_t d = 0; d < num_drums - 1; d++) // { // if (seq_data[track][seq_step_timer] == drum_config[d].midinote) // { @@ -3589,7 +3588,7 @@ const char* seq_find_shortname(uint8_t sstep) void UI_func_sequencer(uint8_t param) { - char displayname[7]={0,0,0,0,0,0}; + char displayname[7] = {0, 0, 0, 0, 0, 0}; if (LCDML.FUNC_setup()) // ****** SETUP ********* { @@ -3635,9 +3634,9 @@ void UI_func_sequencer(uint8_t param) if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) { if (LCDML.BT_checkDown()) - activesample = constrain(activesample + 1, 0, NUM_DRUMCONFIG + 2 ); + activesample = constrain(activesample + 1, 0, num_drums + 2 ); else if (LCDML.BT_checkUp()) - activesample = constrain(activesample - 1, 0, NUM_DRUMCONFIG + 2 ); + activesample = constrain(activesample - 1, 0, num_drums + 2 ); } } else if (seq_active_function == 2) { if ((LCDML.BT_checkDown() && encoderDir[ENC_R].Down()) || (LCDML.BT_checkUp() && encoderDir[ENC_R].Up())) @@ -3656,16 +3655,16 @@ void UI_func_sequencer(uint8_t param) seq_active_function = 0; } else if ( seq_menu == 0 && seq_active_function == 0) { - if (activesample == NUM_DRUMCONFIG + 2) { - for (int i = 0; i < 10; i++) { - memset(seq_data[i], 0, sizeof(seq_data[i])); + if (activesample == num_drums + 2) { + for (int i = 0; i < 10; i++) { + memset(seq_data[i], 0, sizeof(seq_data[i])); } for (int i = 0; i < 16; i++) { lcd.setCursor(i, 1); lcd.print(seq_find_shortname(i) ); } - } else if (activesample == NUM_DRUMCONFIG + 1) { + } else if (activesample == num_drums + 1) { memset(seq_data[seq_active_track], 0, sizeof(seq_data[seq_active_track])); for (int i = 0; i < 16; i++) { lcd.setCursor(i, 1); @@ -3720,17 +3719,17 @@ void UI_func_sequencer(uint8_t param) lcd.setCursor(0, 0); lcd.print("["); - if (activesample < NUM_DRUMCONFIG) { + if (activesample < num_drums) { lcd.setCursor(1, 0); strncpy(displayname, drum_config[activesample].filename + 5, 6); lcd.print(displayname); - } else if (activesample == NUM_DRUMCONFIG) { + } else if (activesample == num_drums) { lcd.setCursor(1, 0); lcd.print("EMPTY "); - } else if (activesample == NUM_DRUMCONFIG + 1) { + } else if (activesample == num_drums + 1) { lcd.setCursor(1, 0); lcd.print("ClrTrk"); - } else if (activesample == NUM_DRUMCONFIG + 2) { + } else if (activesample == num_drums + 2) { lcd.setCursor(1, 0); lcd.print("ClrAll"); } diff --git a/addon/SD/drm/CFGDrums.json b/addon/SD/drm/CFGDrums.json index 720a221..075be89 100644 --- a/addon/SD/drm/CFGDrums.json +++ b/addon/SD/drm/CFGDrums.json @@ -1,141 +1,141 @@ { - "drums": { - "bd01": { - "drum_class": "DRUM_BASS", - "midinote": "MIDI_C3", - "shortname": "B", - "pan": 0.0, - "vol_max": 0.8, - "vol_min": 0.0, - "reverb_send": 0.0 - }, - "cp02": { - "drum_class": "DRUM_HANDCLAP", - "midinote": "MIDI_CIS3", - "shortname": "C", - "pan": -0.4, - "vol_max": 0.6, - "vol_min": 0.0, - "reverb_send": 0.4 - }, - "sd15": { - "drum_class": "DRUM_SNARE", - "midinote": "MIDI_D3", - "shortname": "S", - "pan": 0.2, - "vol_max": 0.6, - "vol_min": 0.2, - "reverb_send": 0.0 - }, - "hh01": { - "drum_class": "DRUM_HIHAT", - "midinote": "MIDI_FIS3", - "shortname": "h", - "pan": 0.8, - "vol_max": 0.2, - "vol_min": 0.0, - "reverb_send": 0.0 - }, - "hh02": { - "drum_class": "DRUM_HIHAT", - "midinote": "MIDI_GIS3", - "shortname": "h", - "pan": 0.8, - "vol_max": 0.2, - "vol_min": 0.0, - "reverb_send": 0.0 - }, - "oh02": { - "drum_class": "DRUM_HIHAT", - "midinote": "MIDI_AIS3", - "shortname": "H", - "pan": 0.8, - "vol_max": 0.2, - "vol_min": 0.0, - "reverb_send": 0.0 - }, - "lt01": { - "drum_class": "DRUM_LOWTOM", - "midinote": "MIDI_G3", - "shortname": "T", - "pan": -0.7, - "vol_max": 0.8, - "vol_min": 0.0, - "reverb_send": 0.0 - }, - "ht01": { - "drum_class": "DRUM_HIGHTOM", - "midinote": "MIDI_A3", - "shortname": "T", - "pan": -0.5, - "vol_max": 0.8, - "vol_min": 0.0, - "reverb_send": 0.0 - }, - "rd01": { - "drum_class": "DRUM_RIDE", - "midinote": "MIDI_CIS4", - "shortname": "R", - "pan": -0.6, - "vol_max": 0.3, - "vol_min": 0.0, - "reverb_send": 0.0 - }, - "rd02": { - "drum_class": "DRUM_RIDE", - "midinote": "MIDI_DIS4", - "shortname": "R", - "pan": -0.6, - "vol_max": 0.3, - "vol_min": 0.0, - "reverb_send": 0.0 - }, - "PHKick1": { - "drum_class": "DRUM_BASS", - "midinote": "MIDI_C5", - "shortname": "B", - "pan": 0.0, - "vol_max": 0.9, - "vol_min": 0.0, - "reverb_send": 0.0 - }, - "808Clap1": { - "drum_class": "DRUM_HANDCLAP", - "midinote": "MIDI_DIS5", - "filename": "808Clap1.raw", - "shortname": "C", - "pan": 0.0, - "vol_max": 0.9, - "vol_min": 0.0, - "reverb_send": 0.4 - }, - "808RimS1": { - "drum_class": "DRUM_SNARE", - "midinote": "MIDI_CIS5", - "shortname": "R", - "pan": -0.3, - "vol_max": 0.5, - "vol_min": 0.0, - "reverb_send": 0.0 - }, - "808HHCL1": { - "drum_class": "DRUM_HIHAT", - "midinote": "MIDI_FIS5", - "shortname": "H", - "pan": 0.4, - "vol_max": 0.6, - "vol_min": 0.0, - "reverb_send": 0.0 - }, - "EMPTY": { - "drum_class": "DRUM_NONE", - "midinote": "MIDI_NONE", - "filename": "EMPTY", - "shortname": "-", - "pan": 0.0, - "vol_max": 0.0, - "vol_min": 0.0, - "reverb_send": 0.0 - } -} + "drums": { + "bd01": { + "drum_class": "DRUM_BASS", + "midinote": "C3", + "shortname": "B", + "pan": 0, + "vol_max": 0.8, + "vol_min": 0, + "reverb_send": 0 + }, + "cp02": { + "drum_class": "DRUM_HANDCLAP", + "midinote": "C#3", + "shortname": "C", + "pan": -0.4, + "vol_max": 0.6, + "vol_min": 0, + "reverb_send": 0.4 + }, + "sd15": { + "drum_class": "DRUM_SNARE", + "midinote": "D3", + "shortname": "S", + "pan": 0.2, + "vol_max": 0.6, + "vol_min": 0.2, + "reverb_send": 0 + }, + "hh01": { + "drum_class": "DRUM_HIHAT", + "midinote": "F#3", + "shortname": "h", + "pan": 0.8, + "vol_max": 0.2, + "vol_min": 0, + "reverb_send": 0 + }, + "hh02": { + "drum_class": "DRUM_HIHAT", + "midinote": "G#3", + "shortname": "h", + "pan": 0.8, + "vol_max": 0.2, + "vol_min": 0, + "reverb_send": 0 + }, + "oh02": { + "drum_class": "DRUM_HIHAT", + "midinote": "A#3", + "shortname": "H", + "pan": 0.8, + "vol_max": 0.2, + "vol_min": 0, + "reverb_send": 0 + }, + "lt01": { + "drum_class": "DRUM_LOWTOM", + "midinote": "G3", + "shortname": "T", + "pan": -0.7, + "vol_max": 0.8, + "vol_min": 0, + "reverb_send": 0 + }, + "ht01": { + "drum_class": "DRUM_HIGHTOM", + "midinote": "A3", + "shortname": "T", + "pan": -0.5, + "vol_max": 0.8, + "vol_min": 0, + "reverb_send": 0 + }, + "rd01": { + "drum_class": "DRUM_RIDE", + "midinote": "C#4", + "shortname": "R", + "pan": -0.6, + "vol_max": 0.3, + "vol_min": 0, + "reverb_send": 0 + }, + "rd02": { + "drum_class": "DRUM_RIDE", + "midinote": "D#4", + "shortname": "R", + "pan": -0.6, + "vol_max": 0.3, + "vol_min": 0, + "reverb_send": 0 + }, + "PHKick1": { + "drum_class": "DRUM_BASS", + "midinote": "C5", + "shortname": "B", + "pan": 0, + "vol_max": 0.9, + "vol_min": 0, + "reverb_send": 0 + }, + "808Clap1": { + "drum_class": "DRUM_HANDCLAP", + "midinote": "D#5", + "filename": "808Clap1.raw", + "shortname": "C", + "pan": 0, + "vol_max": 0.9, + "vol_min": 0, + "reverb_send": 0.4 + }, + "808RimS1": { + "drum_class": "DRUM_SNARE", + "midinote": "C#5", + "shortname": "R", + "pan": -0.3, + "vol_max": 0.5, + "vol_min": 0, + "reverb_send": 0 + }, + "808HHCL1": { + "drum_class": "DRUM_HIHAT", + "midinote": "F#5", + "shortname": "H", + "pan": 0.4, + "vol_max": 0.6, + "vol_min": 0, + "reverb_send": 0 + }, + "EMPTY": { + "drum_class": "DRUM_NONE", + "midinote": "NONE", + "filename": "EMPTY", + "shortname": "-", + "pan": 0, + "vol_max": 0, + "vol_min": 0, + "reverb_send": 0 + } + } } diff --git a/config.h b/config.h index f6e0aa2..927378d 100644 --- a/config.h +++ b/config.h @@ -112,6 +112,7 @@ // NUMBER OF SAMPLEDRUMS #define NUM_DRUMS 8 #define DRUM_MIDI_CHANNEL 1 +#define DRUM_MAX_INSTRUMENTS 24 // CHORUS parameters #define MOD_DELAY_SAMPLE_BUFFER int32_t(TIME_MS2SAMPLES(20.0)) // 20.0 ms delay buffer. @@ -611,7 +612,7 @@ #define EQ_TREBLE_DEFAULT 0 // Buffer for load/save configuration as JSON -#define JSON_BUFFER 3072 +#define JSON_BUFFER 2048 // Internal configuration structure typedef struct dexed_s { diff --git a/drums.cpp b/drums.cpp index 17ebd1c..4901ccb 100644 --- a/drums.cpp +++ b/drums.cpp @@ -29,11 +29,15 @@ #include #include #include "config.h" +#include "drums.h" +extern uint8_t num_drums; +extern drum_config_t drum_config[DRUM_MAX_INSTRUMENTS]; void read_drum_config(void) { File json; + DynamicJsonDocument drums_json(4096); AudioNoInterrupts(); if (SD.exists("/DRM/CFGDrums.json")) @@ -44,18 +48,210 @@ void read_drum_config(void) json = SD.open("/DRM/CFGDrums.json"); if (json) { - DynamicJsonDocument drums_json(5000); - deserializeJson(drums_json, json); + json.close(); + + num_drums = drums_json.size(); #ifdef DEBUG - Serial.println("Drums:"); - serializeJsonPretty(drums_json, Serial); - Serial.println(); Serial.print(F("Drum Objects: ")); - Serial.println(drums_json["drums"].size()); + Serial.println(num_drums); + if (num_drums > DRUM_MAX_INSTRUMENTS) + Serial.println(F("*** Maximum number of drum samples exceeded! ***")); + //Serial.println(F("Drum Configuration:")); + //serializeJsonPretty(drums_json, Serial); + //Serial.println(); #endif - json.close(); + num_drums = constrain(num_drums, 0, DRUM_MAX_INSTRUMENTS); } } AudioInterrupts(); + + uint8_t drum = 0; + JsonObject root = drums_json["drums"].as(); + for (JsonPair kv : root) + { + sprintf(drum_config[drum].filename, "/drm/%s.wav", kv.key().c_str()); + if (!SD.exists(drum_config[drum].filename)) + { +#ifdef DEBUG + Serial.print(F("Cannot find WAV file [")); + Serial.print(drum_config[drum].filename); + Serial.println(F("]")); +#endif + continue; + } + JsonObject drum_root = drums_json["drums"][kv.key().c_str()].as(); + for (JsonPair drum_kv : drum_root) + { + if (strcmp(drum_kv.key().c_str(), "drum_class") == 0) + { + if (drum_kv.value().is()) + { + if (strcmp(drum_kv.value().as(), "DRUM_NONE") == 0) + drum_config[drum].drum_class = DRUM_NONE; + else if (strcmp(drum_kv.value().as(), "DRUM_BASS") == 0) + drum_config[drum].drum_class = DRUM_BASS; + else if (strcmp(drum_kv.value().as(), "DRUM_SNARE") == 0) + drum_config[drum].drum_class = DRUM_SNARE; + else if (strcmp(drum_kv.value().as(), "DRUM_HIHAT") == 0) + drum_config[drum].drum_class = DRUM_HIHAT; + else if (strcmp(drum_kv.value().as(), "DRUM_HANDCLAP") == 0) + drum_config[drum].drum_class = DRUM_HANDCLAP; + else if (strcmp(drum_kv.value().as(), "DRUM_RIDE") == 0) + drum_config[drum].drum_class = DRUM_RIDE; + else if (strcmp(drum_kv.value().as(), "DRUM_CHRASH") == 0) + drum_config[drum].drum_class = DRUM_CHRASH; + else if (strcmp(drum_kv.value().as(), "DRUM_LOWTOM") == 0) + drum_config[drum].drum_class = DRUM_LOWTOM; + else if (strcmp(drum_kv.value().as(), "DRUM_MIDTOM") == 0) + drum_config[drum].drum_class = DRUM_MIDTOM; + else if (strcmp(drum_kv.value().as(), "DRUM_HIGHTOM") == 0) + drum_config[drum].drum_class = DRUM_HIGHTOM; + else if (strcmp(drum_kv.value().as(), "DRUM_PERCUSSION") == 0) + drum_config[drum].drum_class = DRUM_PERCUSSION; + } + } + else if (strcmp(drum_kv.key().c_str(), "midinote") == 0) + { + if (drum_kv.value().is()) + { + uint8_t note_number = 0; + uint8_t oct = 0; + char midi_note[4]; + + strcpy(midi_note, drum_kv.value().as()); + + switch (midi_note[0]) + { + case 'A': + if (midi_note[1] == '#') + { + note_number = 1; + oct = midi_note[2] - 48; + } + else + { + note_number = 0; + oct = midi_note[1] - 48; + } + break; + case 'B': + note_number = 2; + oct = midi_note[1] - 48; + break; + case 'C': + if (midi_note[1] == '#') + { + note_number = 4; + oct = midi_note[2] - 48; + } + else + { + note_number = 3; + oct = midi_note[1] - 48; + } + break; + case 'D': + if (midi_note[1] == '#') + { + note_number = 6; + oct = midi_note[2] - 48; + } + else + { + note_number = 5; + oct = midi_note[1] - 48; + } + break; + case 'E': + note_number = 7; + oct = midi_note[1] - 48; + break; + case 'F': + if (midi_note[1] == '#') + { + note_number = 9; + oct = midi_note[2] - 48; + } + else + { + note_number = 8; + oct = midi_note[1] - 48; + } + break; + case 'G': + if (midi_note[1] == '#') + { + note_number = 11; + oct = midi_note[2] - 48; + } + else + { + note_number = 10; + oct = midi_note[1] - 48; + } + break; + } + drum_config[drum].midinote = note_number + 9 + (oct * 12); + } + } + else if (strcmp(drum_kv.key().c_str(), "shortname") == 0) + { + memset(drum_config[drum].shortname, 0, 2); + if (drum_kv.value().is()) + drum_config[drum].shortname[0] = drum_kv.value().as()[0]; + } + else if (strcmp(drum_kv.key().c_str(), "pan") == 0) + { + if (drum_kv.value().is()) + drum_config[drum].pan = drum_kv.value().as(); + if (drum_kv.value().is()) + drum_config[drum].pan = float(drum_kv.value().as()); + } + else if (strcmp(drum_kv.key().c_str(), "vol_max") == 0) + { + if (drum_kv.value().is()) + drum_config[drum].vol_max = drum_kv.value().as(); + if (drum_kv.value().is()) + drum_config[drum].vol_max = float(drum_kv.value().as()); + } + else if (strcmp(drum_kv.key().c_str(), "vol_min") == 0) + { + if (drum_kv.value().is()) + drum_config[drum].vol_min = drum_kv.value().as(); + if (drum_kv.value().is()) + drum_config[drum].vol_min = float(drum_kv.value().as()); + } + else if (strcmp(drum_kv.key().c_str(), "reverb_send") == 0) + { + if (drum_kv.value().is()) + drum_config[drum].reverb_send = drum_kv.value().as(); + if (drum_kv.value().is()) + drum_config[drum].reverb_send = float(drum_kv.value().as()); + } + } + +#ifdef DEBUG + Serial.print(F("[Drum ")); + Serial.print(drum, DEC); + Serial.println(F("]")); + Serial.print(F("drum_class=")); + Serial.println(drum_config[drum].drum_class, DEC); + Serial.print(F("midinote=")); + Serial.println(drum_config[drum].midinote, DEC); + Serial.print(F("filename=")); + Serial.println(drum_config[drum].filename); + Serial.print(F("shortname=")); + Serial.println(drum_config[drum].shortname); + Serial.print(F("pan=")); + Serial.println(drum_config[drum].pan); + Serial.print(F("vol_max=")); + Serial.println(drum_config[drum].vol_max); + Serial.print(F("vol_min=")); + Serial.println(drum_config[drum].vol_min); + Serial.print(F("reverb_send=")); + Serial.println(drum_config[drum].reverb_send); +#endif + drum++; + } } diff --git a/drums.h b/drums.h index e9ce8e9..3726ca9 100644 --- a/drums.h +++ b/drums.h @@ -46,10 +46,8 @@ typedef struct drum_config_s { enum {DRUM_NONE, DRUM_BASS, DRUM_SNARE, DRUM_HIHAT, DRUM_HANDCLAP, DRUM_RIDE, DRUM_CHRASH, DRUM_LOWTOM, DRUM_MIDTOM, DRUM_HIGHTOM, DRUM_PERCUSSION}; -uint8_t drum_counter; -uint8_t drum_type[NUM_DRUMS]; -#define NUM_DRUMCONFIG 15 -drum_config_t drum_config[NUM_DRUMCONFIG] = { +//drum_config_t drum_config[DRUM_MAX_INSTRUMENTS]; +/* = { { DRUM_BASS, MIDI_C3, @@ -200,5 +198,6 @@ drum_config_t drum_config[NUM_DRUMCONFIG] = { 0.0, 0.0 } -}; + }; +*/ #endif