diff --git a/MicroDexed.ino b/MicroDexed.ino index 818a0b7..ed15cb8 100644 --- a/MicroDexed.ino +++ b/MicroDexed.ino @@ -91,6 +91,10 @@ AudioAmplifier* drum_volume[NUM_DRUMS]; AudioEffectMonoStereo* drum_mono2stereo[NUM_DRUMS]; AudioMixer4 drum_mixer_r; AudioMixer4 drum_mixer_l; +#ifdef USE_FX +AudioMixer4 drum_reverb_send_mixer_r; +AudioMixer4 drum_reverb_send_mixer_l; +#endif #endif // Audio chain tail @@ -164,8 +168,8 @@ AudioConnection patchCord20(audio_thru_mixer_l, 0, i2s1, 1); #if NUM_DRUMS > 0 #ifdef USE_FX -AudioConnection patchCord21(drum_mixer_r, 0, reverb_mixer_r, 2); -AudioConnection patchCord22(drum_mixer_l, 0, reverb_mixer_l, 2); +AudioConnection patchCord21(drum_reverb_send_mixer_r, 0, reverb_mixer_r, 2); +AudioConnection patchCord22(drum_reverb_send_mixer_l, 0, reverb_mixer_l, 2); AudioConnection patchCord23(drum_mixer_r, 0, master_mixer_r, 2); AudioConnection patchCord24(drum_mixer_l, 0, master_mixer_l, 2); #else @@ -179,9 +183,9 @@ AudioConnection patchCord22(drum_mixer_l, 0, master_mixer_l, 2); // uint8_t nDynamic = 0; #if defined(USE_FX) && MOD_FILTER_OUTPUT != MOD_NO_FILTER_OUTPUT -AudioConnection* dynamicConnections[NUM_DEXED * 16 + NUM_DRUMS * 4 ]; +AudioConnection* dynamicConnections[NUM_DEXED * 16 + NUM_DRUMS * 6 ]; #elif defined(USE_FX) && MOD_FILTER_OUTPUT == MOD_NO_FILTER_OUTPUT -AudioConnection* dynamicConnections[NUM_DEXED * 15 + NUM_DRUMS * 4]; +AudioConnection* dynamicConnections[NUM_DEXED * 15 + NUM_DRUMS * 6]; #else AudioConnection* dynamicConnections[NUM_DEXED * 4 + NUM_DRUMS * 4]; #endif @@ -248,6 +252,10 @@ void create_audio_drum_chain(uint8_t instance_id) dynamicConnections[nDynamic++] = new AudioConnection(*drum_volume[instance_id], 0, *drum_mono2stereo[instance_id], 0); dynamicConnections[nDynamic++] = new AudioConnection(*drum_mono2stereo[instance_id], 0, drum_mixer_r, instance_id); dynamicConnections[nDynamic++] = new AudioConnection(*drum_mono2stereo[instance_id], 1, drum_mixer_l, instance_id); +#ifdef USE_FX + dynamicConnections[nDynamic++] = new AudioConnection(*drum_mono2stereo[instance_id], 0, drum_reverb_send_mixer_r, instance_id); + dynamicConnections[nDynamic++] = new AudioConnection(*drum_mono2stereo[instance_id], 1, drum_reverb_send_mixer_l, instance_id); +#endif #ifdef DEBUG Serial.print(F("Drum-Instance: ")); @@ -293,7 +301,7 @@ uint8_t seqsteptimer = 0; uint32_t seqtimer_old = 0; bool seq_running = false; bool seq_recording = false; -uint8_t seq_note_in; +uint8_t seq_note_in; //uint8_t seqdata[1][16]={48,48,54,48,49,54,54,48,54,54,48,54,49,54,54,54}; //uint8_t seqdata[1][16]={72,72,78,72,75,78,78,72,78,78,72,78,75,78,78,78}; uint8_t seqdata[3][16] = {72, 72, 0, 72, 75, 0, 0, 72, 0, 0, 72, 0, 75, 0, 0, 0, @@ -620,11 +628,11 @@ void loop() if (LCDML.FUNC_getID() == LCDML.OTHER_getIDFromFunction(UI_func_sequencer)) { - //write to sequencer if in sequencer menu (step recording and live recording) - if (seq_note_in>0 && seq_recording == true){ - seqdata[active_seq_track][seqsteptimer]=seq_note_in; - seq_note_in=0; - } + //write to sequencer if in sequencer menu (step recording and live recording) + if (seq_note_in > 0 && seq_recording == true) { + seqdata[active_seq_track][seqsteptimer] = seq_note_in; + seq_note_in = 0; + } lcd.setCursor(seqsteptimer, 1); lcd.print("X"); if (seqsteptimer == 0) { @@ -802,6 +810,8 @@ void handleNoteOn(byte inChannel, byte inNumber, byte inVelocity) uint8_t slot = drum_get_slot(drum_config[d].type); drum_volume[slot]->gain(pseudo_log_curve(mapfloat(inVelocity, 0, 127, drum_config[d].vol_min, drum_config[d].vol_max))); drum_mono2stereo[slot]->panorama(drum_config[d].pan); + drum_reverb_send_mixer_r.gain(slot, pseudo_log_curve(mapfloat(inVelocity, 0, 127, drum_config[d].vol_min, drum_config[d].vol_max))); + drum_reverb_send_mixer_l.gain(slot, pseudo_log_curve(mapfloat(inVelocity, 0, 127, drum_config[d].vol_min, drum_config[d].vol_max))); Drum[slot]->play(drum_config[d].filename); break; } diff --git a/dexed_sd.cpp b/dexed_sd.cpp index c22eb38..8891a40 100644 --- a/dexed_sd.cpp +++ b/dexed_sd.cpp @@ -51,7 +51,9 @@ bool load_sd_voice(uint8_t b, uint8_t v, uint8_t instance_id) get_bank_name(b, bank_name, sizeof(bank_name)); sprintf(filename, "/%d/%s.syx", b, bank_name); + AudioNoInterrupts(); sysex = SD.open(filename); + AudioInterrupts(); if (!sysex) { #ifdef DEBUG @@ -81,8 +83,9 @@ bool load_sd_voice(uint8_t b, uint8_t v, uint8_t instance_id) #endif configuration.dexed[instance_id].transpose = MicroDexed[instance_id]->getTranspose(); - + AudioNoInterrupts(); sysex.close(); + AudioInterrupts(); uint8_t data_copy[155]; MicroDexed[instance_id]->getVoiceData(data_copy); @@ -94,7 +97,9 @@ bool load_sd_voice(uint8_t b, uint8_t v, uint8_t instance_id) else Serial.println(F("E : Cannot load voice data")); #endif + AudioNoInterrupts(); sysex.close(); + AudioInterrupts(); } return (false); @@ -115,7 +120,9 @@ bool save_sd_voice(uint8_t b, uint8_t v, uint8_t instance_id) get_bank_name(b, bank_name, sizeof(bank_name)); sprintf(filename, "/%d/%s.syx", b, bank_name); + AudioNoInterrupts(); sysex = SD.open(filename, FILE_WRITE); + AudioInterrupts(); if (!sysex) { #ifdef DEBUG @@ -140,7 +147,9 @@ bool save_sd_voice(uint8_t b, uint8_t v, uint8_t instance_id) Serial.print(voice_name); Serial.println(F("]")); #endif + AudioNoInterrupts(); sysex.close(); + AudioInterrupts(); return (true); } @@ -148,7 +157,9 @@ bool save_sd_voice(uint8_t b, uint8_t v, uint8_t instance_id) else Serial.println(F("E : Cannot load voice data")); #endif + AudioNoInterrupts(); sysex.close(); + AudioInterrupts(); } return (false); @@ -160,6 +171,7 @@ bool get_sd_voice(File sysex, uint8_t voice_number, uint8_t* data) int32_t bulk_checksum_calc = 0; int8_t bulk_checksum; + AudioNoInterrupts(); if (sysex.size() != 4104) // check sysex size { #ifdef DEBUG @@ -209,6 +221,7 @@ bool get_sd_voice(File sysex, uint8_t voice_number, uint8_t* data) bulk_checksum_calc -= d; } bulk_checksum_calc &= 0x7f; + AudioInterrupts(); #ifdef DEBUG Serial.print(F("Bulk checksum : 0x")); @@ -240,6 +253,7 @@ 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 @@ -292,6 +306,7 @@ bool put_sd_voice(File sysex, uint8_t voice_number, uint8_t* data) } sysex.seek(4102); // Bulk checksum sysex.write(bulk_checksum_calc & 0x7f); + AudioInterrupts(); #ifdef DEBUG Serial.print(F("Bulk checksum : 0x")); @@ -319,6 +334,7 @@ bool save_sd_bank(const char* bank_filename, uint8_t* data) // first remove old bank sscanf(bank_filename, "/%d/%s", &bank_number, tmp); sprintf(tmp, "/%d", bank_number); + AudioNoInterrupts(); root = SD.open(tmp); while (42 == 42) { @@ -365,6 +381,7 @@ bool save_sd_bank(const char* bank_filename, uint8_t* data) root = SD.open(bank_filename, FILE_WRITE); root.write(data, 4104); root.close(); + AudioInterrupts(); #ifdef DEBUG Serial.println(F(" done.")); #endif @@ -393,6 +410,7 @@ bool load_sd_voiceconfig(int8_t vc, uint8_t instance_id) sprintf(filename, "/%s/%s%d.syx", VOICE_CONFIG_PATH, VOICE_CONFIG_NAME, vc); // first check if file exists... + AudioNoInterrupts(); if (SD.exists(filename)) { // ... and if: load @@ -407,12 +425,14 @@ bool load_sd_voiceconfig(int8_t vc, uint8_t instance_id) get_sd_data(sysex, 0x42, (uint8_t*)&configuration.dexed[instance_id]); set_voiceconfig_params(instance_id); sysex.close(); + AudioInterrupts(); return (true); } #ifdef DEBUG else { + AudioInterrupts(); Serial.print(F("E : Cannot open ")); Serial.print(filename); Serial.println(F(" on SD.")); @@ -452,15 +472,18 @@ bool save_sd_voiceconfig(uint8_t vc, uint8_t instance_id) Serial.println(filename); #endif + AudioNoInterrupts(); sysex = SD.open(filename, FILE_WRITE); if (sysex) { if (write_sd_data(sysex, 0x42, (uint8_t*)&configuration.dexed[instance_id], sizeof(configuration.dexed[instance_id]))) { sysex.close(); + AudioInterrupts(); return (true); } sysex.close(); + AudioInterrupts(); } else { @@ -493,6 +516,7 @@ bool load_sd_fx(int8_t fx) sprintf(filename, "/%s/%s%d.syx", FX_CONFIG_PATH, FX_CONFIG_NAME, fx); // first check if file exists... + AudioNoInterrupts(); if (SD.exists(filename)) { // ... and if: load @@ -507,12 +531,14 @@ bool load_sd_fx(int8_t fx) get_sd_data(sysex, 0x43, (uint8_t*)&configuration.fx); set_fx_params(); sysex.close(); + AudioInterrupts(); return (true); } #ifdef DEBUG else { + AudioInterrupts(); Serial.print(F("E : Cannot open ")); Serial.print(filename); Serial.println(F(" on SD.")); @@ -550,15 +576,18 @@ bool save_sd_fx(uint8_t fx) Serial.println(filename); #endif + AudioNoInterrupts(); sysex = SD.open(filename, FILE_WRITE); if (sysex) { if (write_sd_data(sysex, 0x43, (uint8_t*)&configuration.fx, sizeof(configuration.fx))) { sysex.close(); + AudioInterrupts(); return (true); } sysex.close(); + AudioInterrupts(); } else { @@ -592,6 +621,7 @@ bool load_sd_performance(int8_t p) sprintf(filename, "/%s/%s%d.syx", PERFORMANCE_CONFIG_PATH, PERFORMANCE_CONFIG_NAME, p); // first check if file exists... + AudioNoInterrupts(); if (SD.exists(filename)) { // ... and if: load @@ -605,6 +635,7 @@ bool load_sd_performance(int8_t p) { get_sd_data(sysex, 0x44, (uint8_t*)&configuration.performance); sysex.close(); + AudioInterrupts(); for (uint8_t instance_id = 0; instance_id < NUM_DEXED; instance_id++) { @@ -657,15 +688,18 @@ bool save_sd_performance(uint8_t p) Serial.println(filename); #endif + AudioNoInterrupts(); sysex = SD.open(filename, FILE_WRITE); if (sysex) { if (write_sd_data(sysex, 0x44, (uint8_t*)&configuration.performance, sizeof(configuration.performance))) { sysex.close(); + AudioInterrupts(); return (true); } sysex.close(); + AudioInterrupts(); } else { @@ -695,6 +729,7 @@ bool get_sd_data(File sysex, uint8_t format, uint8_t* conf) Serial.println(F(" bytes.")); #endif + AudioNoInterrupts(); if (sysex.read() != 0xf0) // check sysex start-byte { #ifdef DEBUG @@ -767,6 +802,7 @@ bool get_sd_data(File sysex, uint8_t format, uint8_t* conf) uint8_t d = sysex.read(); *(conf++) = d; } + AudioInterrupts(); #ifdef DEBUG Serial.println(F("SD data loaded.")); @@ -786,6 +822,7 @@ bool write_sd_data(File sysex, uint8_t format, uint8_t* data, uint16_t len) #endif // write sysex start + AudioNoInterrupts(); sysex.write(0xf0); #ifdef DEBUG Serial.println(F("Write SYSEX start: 0xf0")); @@ -820,6 +857,8 @@ bool write_sd_data(File sysex, uint8_t format, uint8_t* data, uint16_t len) #endif // write sysex end sysex.write(0xf7); + AudioInterrupts(); + #ifdef DEBUG Serial.println(F("Write SYSEX end: 0xf7")); #endif @@ -922,6 +961,7 @@ bool get_voice_name(uint8_t b, uint8_t v, char* name, uint8_t len) #endif // try to open directory + AudioNoInterrupts(); sysex = SD.open(filename); if (!sysex) return (false); @@ -941,6 +981,7 @@ bool get_voice_name(uint8_t b, uint8_t v, char* name, uint8_t len) #endif sysex.close(); + AudioInterrupts(); return (true); } @@ -964,6 +1005,7 @@ bool get_voice_by_bank_name(uint8_t b, const char* bank_name, uint8_t v, char* v #endif // try to open directory + AudioNoInterrupts(); sysex = SD.open(filename); if (!sysex) return (false); @@ -985,6 +1027,7 @@ bool get_voice_by_bank_name(uint8_t b, const char* bank_name, uint8_t v, char* v #endif sysex.close(); + AudioInterrupts(); return (true); } diff --git a/drums.h b/drums.h index 7683bf6..437c1ac 100644 --- a/drums.h +++ b/drums.h @@ -36,6 +36,7 @@ typedef struct drum_config_s { float32_t pan; // Panorama (-1.0 - +1.0) float32_t vol_max; // max. Volume (0.0 - 1.0) float32_t vol_min; // min. Volume (0.0 - 1.0, should be <= vol_max) + float32_t reverb_send; // how much signal to send to the reverb (0.0 - 1.0) } drum_config_t; #define NUM_DRUMCONFIG 15 @@ -47,6 +48,7 @@ drum_config_t drum_config[NUM_DRUMCONFIG] = { "B", 0.0, 0.8, + 0.0, 0.0 }, { @@ -56,6 +58,7 @@ drum_config_t drum_config[NUM_DRUMCONFIG] = { "C", -0.4, 0.6, + 0.0, 0.0 }, { @@ -65,7 +68,8 @@ drum_config_t drum_config[NUM_DRUMCONFIG] = { "S", 0.2, 0.6, - 0.2 + 0.2, + 0.0 }, { DRUM_HIHAT, @@ -74,6 +78,7 @@ drum_config_t drum_config[NUM_DRUMCONFIG] = { "h", 0.8, 0.2, + 0.0, 0.0 }, { @@ -83,6 +88,7 @@ drum_config_t drum_config[NUM_DRUMCONFIG] = { "h", 0.8, 0.2, + 0.0, 0.0 }, { @@ -92,6 +98,7 @@ drum_config_t drum_config[NUM_DRUMCONFIG] = { "H", 0.8, 0.2, + 0.0, 0.0 }, { @@ -101,6 +108,7 @@ drum_config_t drum_config[NUM_DRUMCONFIG] = { "T", -0.7, 0.8, + 0.0, 0.0 }, { @@ -110,6 +118,7 @@ drum_config_t drum_config[NUM_DRUMCONFIG] = { "T", -0.5, 0.8, + 0.0, 0.0 }, { @@ -119,6 +128,7 @@ drum_config_t drum_config[NUM_DRUMCONFIG] = { "R", -0.6, 0.3, + 0.0, 0.0 }, { @@ -128,6 +138,7 @@ drum_config_t drum_config[NUM_DRUMCONFIG] = { "R", -0.6, 0.3, + 0.0, 0.0 }, { @@ -137,6 +148,7 @@ drum_config_t drum_config[NUM_DRUMCONFIG] = { "B", 0.0, 0.9, + 0.0, 0.0 }, { @@ -146,6 +158,7 @@ drum_config_t drum_config[NUM_DRUMCONFIG] = { "C", 0.0, 0.9, + 0.0, 0.0 }, { @@ -155,6 +168,7 @@ drum_config_t drum_config[NUM_DRUMCONFIG] = { "R", -0.3, 0.5, + 0.0, 0.0 }, { @@ -164,6 +178,7 @@ drum_config_t drum_config[NUM_DRUMCONFIG] = { "H", 0.4, 0.6, + 0.0, 0.0 }, { @@ -173,6 +188,7 @@ drum_config_t drum_config[NUM_DRUMCONFIG] = { "-", 0.0, 0.0, + 0.0, 0.0 } };