From 65bc71a03e1a243474542c565024190d390a58ba Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Mon, 21 Oct 2019 13:09:42 +0200 Subject: [PATCH] Added class for softening value changes. --- MicroDexed.ino | 76 +++++++++++++++++++++++-------------------------- SoftenValue.hpp | 46 ++++++++++++++++++++++++++---- UI.hpp | 32 ++++++++++----------- config.h | 5 ++-- 4 files changed, 94 insertions(+), 65 deletions(-) diff --git a/MicroDexed.ino b/MicroDexed.ino index 7613736..e0e8067 100644 --- a/MicroDexed.ino +++ b/MicroDexed.ino @@ -130,9 +130,9 @@ uint8_t midi_timing_counter = 0; // 24 per qarter elapsedMillis midi_timing_timestep; uint16_t midi_timing_quarter = 0; elapsedMillis long_button_pressed; -//SoftenValue effect_filter_volume[NUM_DEXED](SOFTEN_VALUE_CHANGE_STEPS); -//SoftenValue soften_filter_res[NUM_DEXED](SOFTEN_VALUE_CHANGE_STEPS); -//SoftenValue soften_filter_cut[NUM_DEXED](SOFTEN_VALUE_CHANGE_STEPS); +SoftenValue soften_volume; +SoftenValue soften_filter_res[NUM_DEXED]; +SoftenValue soften_filter_cut[NUM_DEXED]; uint8_t effect_filter_cutoff = 0; uint8_t effect_filter_resonance = 0; uint8_t effect_delay_time = 0; @@ -147,9 +147,6 @@ elapsedMillis cpu_mem_millis; #endif config_t configuration = {0xffff, 0, 0, VOLUME, 0.5f, 0, DEFAULT_MIDI_CHANNEL}; bool eeprom_update_flag = false; -value_change_t soften_volume = {0.0, 0}; -value_change_t soften_filter_res = {0.0, 0}; -value_change_t soften_filter_cut = {0.0, 0}; // Allocate the delay lines for left and right channels short delayline[MOD_DELAY_SAMPLE_BUFFER]; @@ -348,13 +345,16 @@ void setup() for (uint8_t i = 0; i < NUM_DEXED; i++) { + soften_filter_res[i].init(1.0, 0.0, 1.0); + soften_filter_cut[i].init(1.0, 0.0, 1.0); MicroDexed[i]->fx.Gain = 1.0; - MicroDexed[i]->fx.Reso = 1.0 - float(effect_filter_resonance) / ENC_FILTER_RES_STEPS; - MicroDexed[i]->fx.Cutoff = 1.0 - float(effect_filter_cutoff) / ENC_FILTER_CUT_STEPS; + MicroDexed[i]->fx.Reso = 1.0; + MicroDexed[i]->fx.Cutoff = 1.0; } // set initial volume and pan (read from EEPROM) set_volume(configuration.vol, configuration.pan); + soften_volume.init(configuration.vol, 0.0, 1.0); #if defined (DEBUG) && defined (SHOW_CPU_LOAD_MSEC) // Initialize processor and memory measurements @@ -447,62 +447,56 @@ void loop() #endif control_rate = 0; - // Shutdown unused voices + // check for value changes and unused voices + soften_volume.tick(); + for (uint8_t i = 0; i < NUM_DEXED; i++) { active_voices = MicroDexed[i]->getNumNotesPlaying(); - } - // check for value changes - if (soften_volume.steps > 0) - { - // soften volume value - soften_volume.steps--; - set_volume(configuration.vol + soften_volume.diff, configuration.pan); -#ifdef DEBUG - Serial.print(F("Volume: ")); - Serial.print(configuration.vol, 5); - Serial.print(F(" Volume step: ")); - Serial.print(soften_volume.steps); - Serial.print(F(" Volume diff: ")); - Serial.println(soften_volume.diff, 5); -#endif - } - if (soften_filter_res.steps > 0) - { - // soften filter resonance value - soften_filter_res.steps--; - for (uint8_t i = 0; i < NUM_DEXED; i++) + soften_filter_res[i].tick(); + soften_filter_cut[i].tick(); + + if (soften_filter_res[i].running()) { - MicroDexed[i]->fx.Reso = MicroDexed[i]->fx.Reso + soften_filter_res.diff; + // soften filter resonance value + MicroDexed[i]->fx.Reso = soften_filter_res[i].value(); #ifdef DEBUG Serial.print(F("Filter-Resonance: ")); Serial.print(MicroDexed[i]->fx.Reso, 5); Serial.print(F(" Filter-Resonance step: ")); - Serial.print(soften_filter_res.steps); + Serial.print(soften_filter_res[i].steps()); Serial.print(F(" Filter-Resonance diff: ")); - Serial.println(soften_filter_res.diff, 5); + Serial.println(soften_filter_res[i].diff(), 5); #endif } - } - if (soften_filter_cut.steps > 0) - { // soften filter cutoff value - soften_filter_cut.steps--; - for (uint8_t i = 0; i < NUM_DEXED; i++) + if (soften_filter_cut[i].running()) { - MicroDexed[i]->fx.Cutoff = MicroDexed[i]->fx.Cutoff + soften_filter_cut.diff; + MicroDexed[i]->fx.Cutoff = soften_filter_cut[i].value(); #ifdef DEBUG Serial.print(F("Filter-Cutoff: ")); Serial.print(MicroDexed[i]->fx.Cutoff, 5); Serial.print(F(" Filter-Cutoff step: ")); - Serial.print(soften_filter_cut.steps); + Serial.print(soften_filter_cut[i].steps()); Serial.print(F(" Filter-Cutoff diff: ")); - Serial.println(soften_filter_cut.diff, 5); + Serial.println(soften_filter_cut[i].diff(), 5); #endif } } + if (soften_volume.running()) + { + set_volume(soften_volume.value(), configuration.pan); +#ifdef DEBUG + Serial.print(F("Volume: ")); + Serial.print(configuration.vol, 5); + Serial.print(F(" step: ")); + Serial.print(soften_volume.steps()); + Serial.print(F(" diff: ")); + Serial.println(soften_volume.diff(), 5); +#endif + } } #if defined (DEBUG) && defined (SHOW_CPU_LOAD_MSEC) diff --git a/SoftenValue.hpp b/SoftenValue.hpp index 7b52230..0ba11aa 100644 --- a/SoftenValue.hpp +++ b/SoftenValue.hpp @@ -24,19 +24,26 @@ */ #ifndef SOFTEN_VALUE_H_INCLUDED +#define SOFTEN_VALUE_H_INCLUDED 1 template class SoftenValue { public: - SoftenValue(uint16_t steps = 10); - SoftenValue(T from, T to, uint16_t steps = 10) + init(T value, T minimum, T maximum) + { + _from = value; + _to = value; + _steps = 0; + _diff = 0.0; + _min = minimum; + _max = maximum; + } + + void update(T to, uint16_t steps) { - _from = from; _to = to; _steps = steps; - _diff = (from - to) / _steps; - _calculate(); } @@ -58,6 +65,12 @@ class SoftenValue { _from -= _diff; _steps--; +#ifdef DEBUG + Serial.print(F("Steps: ")); + Serial.print(_steps, DEC); + Serial.print(F(" Diff=")); + Serial.println(_diff, 5); +#endif } } @@ -74,11 +87,21 @@ class SoftenValue return (_steps); } + T diff(void) + { + return (_diff); + } + T value(void) { if (_steps == 0) return (_to); + if (_from < _min) + _from = _min; + else if (_from > _max) + _from = _max; + if (std::is_same::value) return (_from); else @@ -90,6 +113,8 @@ class SoftenValue float _to; uint16_t _steps; float _diff; + T _min; + T _max; void _calculate(void) { @@ -100,6 +125,17 @@ class SoftenValue } else _diff = (_from - _to) / _steps; + +#ifdef DEBUG + Serial.print(F("Update SoftenValue: from=")); + Serial.print(_from, 5); + Serial.print(F(" to=")); + Serial.print(_to, 5); + Serial.print(F(" diff=")); + Serial.print(_diff, 5); + Serial.print(F(" steps=")); + Serial.println(_steps, DEC); +#endif } }; diff --git a/UI.hpp b/UI.hpp index 11cbef7..3fd35b2 100644 --- a/UI.hpp +++ b/UI.hpp @@ -28,6 +28,8 @@ #include "config.h" #include "LiquidCrystalPlus_I2C.h" +#include "SoftenValue.hpp" + #include #include @@ -47,9 +49,9 @@ extern void strip_extension(char* s, char *target); extern void eeprom_write(void); extern bool get_voice_names_from_bank(uint8_t b); extern bool load_sysex(uint8_t b, uint8_t v); -extern value_change_t soften_volume; -extern value_change_t soften_filter_res; -extern value_change_t soften_filter_cut; +extern SoftenValue soften_volume; +extern SoftenValue soften_filter_res[NUM_DEXED]; +extern SoftenValue soften_filter_cut[NUM_DEXED]; /*********************************************************************** GLOBAL @@ -331,7 +333,7 @@ void encoder_right_up(void) } break; case MENU_VOICE_SOUND: - if (configuration.voice < MAX_VOICES-1) + if (configuration.voice < MAX_VOICES - 1) configuration.voice++; else { @@ -432,12 +434,11 @@ void encoder_left_up(void) #ifdef DEBUG Serial.println(F("Volume +")); #endif - if (configuration.vol < 0.96) - { - soften_volume.diff = 0.05 / SOFTEN_VALUE_CHANGE_STEPS; - soften_volume.steps = SOFTEN_VALUE_CHANGE_STEPS; - eeprom_write(); - } + if (configuration.vol < 1.0) + soften_volume.update(soften_volume.value() + 0.05, SOFTEN_VALUE_CHANGE_STEPS); + else + soften_volume.update(1.0, SOFTEN_VALUE_CHANGE_STEPS); + eeprom_write(); UI_func_volume(0); } @@ -446,12 +447,11 @@ void encoder_left_down(void) #ifdef DEBUG Serial.println(F("Volume -")); #endif - if (configuration.vol > 0.04) - { - soften_volume.diff = -0.05 / SOFTEN_VALUE_CHANGE_STEPS; - soften_volume.steps = SOFTEN_VALUE_CHANGE_STEPS; - eeprom_write(); - } + if (configuration.vol > 0.0) + soften_volume.update(soften_volume.value() - 0.05, SOFTEN_VALUE_CHANGE_STEPS); + else + soften_volume.update(0.0, SOFTEN_VALUE_CHANGE_STEPS); + eeprom_write(); UI_func_volume(0); } diff --git a/config.h b/config.h index bd26179..d38d8a6 100644 --- a/config.h +++ b/config.h @@ -69,14 +69,12 @@ //************************************************************************************************* #define DEXED_ENGINE DEXED_ENGINE_MODERN // DEXED_ENGINE_MARKI // DEXED_ENGINE_OPL -// EFFECTS -#define FILTER_MAX_FREQ 10000 // CHORUS parameters #define MOD_DELAY_SAMPLE_BUFFER int32_t(TIME_MS2SAMPLES(20.0)) // 20.0 ms delay buffer. #define MOD_WAVEFORM WAVEFORM_TRIANGLE // WAVEFORM_SINE WAVEFORM_TRIANGLE WAVEFORM_SAWTOOTH WAVEFORM_SAWTOOTH_REVERSE #define MOD_FILTER_OUTPUT MOD_LINKWITZ_RILEY_FILTER_OUTPUT // MOD_LINKWITZ_RILEY_FILTER_OUTPUT MOD_BUTTERWORTH_FILTER_OUTPUT MOD_NO_FILTER_OUTPUT #define MOD_FILTER_CUTOFF_HZ 3000 -//#define USE_REVERB 1 +#define USE_REVERB 1 //************************************************************************************************* //* AUDIO SETTINGS @@ -191,6 +189,7 @@ // Teensy-3.5 settings #undef MIDI_DEVICE_USB_HOST #define MAX_NOTES 11 +#undef USE_REVERB #endif #define TRANSPOSE_FIX 24