From 70234d5b2f7fc0e25834edab8d9b543aa246019c Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Tue, 22 Oct 2019 14:53:23 +0200 Subject: [PATCH] Added menu functions for reverb and chorus. --- MicroDexed.ino | 19 ++- UI.hpp | 404 ++++++++++++++++++++++++++++++++++++++++++++++--- config.h | 43 ++++++ 3 files changed, 440 insertions(+), 26 deletions(-) diff --git a/MicroDexed.ino b/MicroDexed.ino index e0e8067..2d12de5 100644 --- a/MicroDexed.ino +++ b/MicroDexed.ino @@ -145,7 +145,22 @@ uint8_t active_voices = 0; #ifdef SHOW_CPU_LOAD_MSEC elapsedMillis cpu_mem_millis; #endif -config_t configuration = {0xffff, 0, 0, VOLUME, 0.5f, 0, DEFAULT_MIDI_CHANNEL}; +config_t configuration = { + 0xffff, + DEFAULT_SYSEXBANK, + DEFAULT_SYSEXSOUND, + VOLUME, + 0.5f, // pan + 0, // mono + DEFAULT_MIDI_CHANNEL, + REVERB_ROOMSIZE_DEFAULT, + REVERB_DAMPING_DEFAULT, + REVERB_LEVEL_DEFAULT, + CHORUS_FREQUENCY_DEFAULT, + CHORUS_WAVEFORM_DEFAULT, + CHORUS_DEPTH_DEFAULT, + CHORUS_LEVEL_DEFAULT +}; bool eeprom_update_flag = false; // Allocate the delay lines for left and right channels @@ -343,6 +358,8 @@ void setup() reverb_mixer_r.gain(1, 0.0); reverb_mixer_l.gain(1, 0.0); + freeverbs1.roomsize(configuration.reverb_roomsize / 100); + for (uint8_t i = 0; i < NUM_DEXED; i++) { soften_filter_res[i].init(1.0, 0.0, 1.0); diff --git a/UI.hpp b/UI.hpp index 3fd35b2..dbbfc93 100644 --- a/UI.hpp +++ b/UI.hpp @@ -29,6 +29,7 @@ #include "config.h" #include "LiquidCrystalPlus_I2C.h" #include "SoftenValue.hpp" +#include "effect_modulated_delay.h" #include #include @@ -52,6 +53,19 @@ extern bool load_sysex(uint8_t b, uint8_t v); extern SoftenValue soften_volume; extern SoftenValue soften_filter_res[NUM_DEXED]; extern SoftenValue soften_filter_cut[NUM_DEXED]; +extern AudioEffectDelay delay1; +#ifdef USE_REVERB +extern AudioEffectFreeverbStereo freeverbs1; +#endif +extern AudioEffectModulatedDelay modchorus; +extern AudioSynthWaveform modulator; +extern AudioMixer4 chorus_mixer; +extern AudioMixer4 delay_mixer; +extern AudioMixer4 delay_fb_mixer; +extern AudioMixer4 reverb_mixer_r; +extern AudioMixer4 reverb_mixer_l; +extern AudioAmplifier volume_r; +extern AudioAmplifier volume_l; /*********************************************************************** GLOBAL @@ -92,6 +106,7 @@ void UI_func_reverb_roomsize(uint8_t param); void UI_func_reverb_damping(uint8_t param); void UI_func_reverb_level(uint8_t param); void UI_func_chorus_frequency(uint8_t param); +void UI_func_chorus_waveform(uint8_t param); void UI_func_chorus_depth(uint8_t param); void UI_func_chorus_level(uint8_t param); void UI_func_delay_time(uint8_t param); @@ -110,6 +125,8 @@ void UI_func_voice_selection(uint8_t param); void UI_func_volume(uint8_t param); void UI_func_back(uint8_t param); void UI_func_goToRootMenu(uint8_t param); +void lcd_display_int(int16_t var, uint8_t size, bool zeros, bool brackets, bool sign); +void lcd_display_float(float var, uint8_t size_number, uint8_t size_fraction, bool zeros, bool brackets, bool sign); // normal menu LCDMenuLib2_menu LCDML_0(255, 0, 0, NULL, NULL); // normal root menu element (do not change) @@ -124,25 +141,26 @@ LCDML_add(4, LCDML_0_2_1, 2, "Damping", UI_func_reverb_damping); LCDML_add(5, LCDML_0_2_1, 3, "Level", UI_func_reverb_level); LCDML_add(6, LCDML_0_2, 2, "Chorus", NULL); LCDML_add(7, LCDML_0_2_2, 1, "Frequency", UI_func_chorus_frequency); -LCDML_add(8, LCDML_0_2_2, 2, "Depth", UI_func_chorus_depth); -LCDML_add(9, LCDML_0_2_2, 3, "Level", UI_func_chorus_level); -LCDML_add(10, LCDML_0_2, 3, "Delay", NULL); -LCDML_add(11, LCDML_0_2_3, 1, "Time", UI_func_delay_time); -LCDML_add(12, LCDML_0_2_3, 2, "Feedback", UI_func_delay_feedback); -LCDML_add(13, LCDML_0_2_3, 3, "Level", UI_func_delay_level); -LCDML_add(14, LCDML_0_2, 4, "Filter", NULL); -LCDML_add(15, LCDML_0_2_4, 1, "Cutoff", UI_func_filter_cutoff); -LCDML_add(16, LCDML_0_2_4, 2, "Resonance", UI_func_filter_resonance); -LCDML_add(17, LCDML_0, 3, "Store", NULL); -LCDML_add(18, LCDML_0, 4, "System", NULL); -LCDML_add(19, LCDML_0_4, 1, "MIDI Channel", UI_func_midi_channel); -LCDML_add(20, LCDML_0_4, 2, "Loudness", UI_func_loudness); -LCDML_add(21, LCDML_0_4, 3, "Panorama", UI_func_panorama); -LCDML_add(22, LCDML_0_4, 4, "Stereo/Mono", UI_func_stereo_mono); -LCDML_add(23, LCDML_0_4, 5, "Polyphony", UI_func_polyphony); -LCDML_add(24, LCDML_0_4, 6, "Engine", UI_func_engine); -LCDML_add(25, LCDML_0, 5, "Info", UI_func_information); -#define _LCDML_DISP_cnt 25 +LCDML_add(8, LCDML_0_2_2, 2, "Waveform", UI_func_chorus_waveform); +LCDML_add(9, LCDML_0_2_2, 3, "Depth", UI_func_chorus_depth); +LCDML_add(10, LCDML_0_2_2, 4, "Level", UI_func_chorus_level); +LCDML_add(11, LCDML_0_2, 3, "Delay", NULL); +LCDML_add(12, LCDML_0_2_3, 1, "Time", UI_func_delay_time); +LCDML_add(13, LCDML_0_2_3, 2, "Feedback", UI_func_delay_feedback); +LCDML_add(14, LCDML_0_2_3, 3, "Level", UI_func_delay_level); +LCDML_add(15, LCDML_0_2, 4, "Filter", NULL); +LCDML_add(16, LCDML_0_2_4, 1, "Cutoff", UI_func_filter_cutoff); +LCDML_add(17, LCDML_0_2_4, 2, "Resonance", UI_func_filter_resonance); +LCDML_add(18, LCDML_0, 3, "Store", NULL); +LCDML_add(19, LCDML_0, 4, "System", NULL); +LCDML_add(20, LCDML_0_4, 1, "MIDI Channel", UI_func_midi_channel); +LCDML_add(21, LCDML_0_4, 2, "Loudness", UI_func_loudness); +LCDML_add(22, LCDML_0_4, 3, "Panorama", UI_func_panorama); +LCDML_add(23, LCDML_0_4, 4, "Stereo/Mono", UI_func_stereo_mono); +LCDML_add(24, LCDML_0_4, 5, "Polyphony", UI_func_polyphony); +LCDML_add(25, LCDML_0_4, 6, "Engine", UI_func_engine); +LCDML_add(26, LCDML_0, 5, "Info", UI_func_information); +#define _LCDML_DISP_cnt 26 // create menu LCDML_createMenu(_LCDML_DISP_cnt); @@ -629,32 +647,303 @@ void UI_func_sound(uint8_t param) void UI_func_reverb_roomsize(uint8_t param) { - ; + if (LCDML.FUNC_setup()) // ****** SETUP ********* + { + // setup function + lcd.setCursor(0, 0); + lcd.print(F("Rev. Roomsize")); + } + + if (LCDML.FUNC_loop()) // ****** LOOP ********* + { + if (LCDML.BT_checkEnter()) + { + LCDML.FUNC_goBackToMenu(); + } + else if (LCDML.BT_checkDown()) + { + if (configuration.reverb_roomsize < REVERB_ROOMSIZE_MAX) + { + configuration.reverb_roomsize++; + } + } + else if (LCDML.BT_checkUp()) + { + if (configuration.reverb_roomsize > REVERB_ROOMSIZE_MIN) + { + configuration.reverb_roomsize--; + } + } + lcd.setCursor(0, 1); + lcd_display_int(configuration.reverb_roomsize, 3, true, true, false); + + freeverbs1.roomsize(configuration.reverb_roomsize / 100); + } + + if (LCDML.FUNC_close()) // ****** STABLE END ********* + { + // you can here reset some global vars or do nothing + } } void UI_func_reverb_damping(uint8_t param) { - ; + if (LCDML.FUNC_setup()) // ****** SETUP ********* + { + // setup function + lcd.setCursor(0, 0); + lcd.print(F("Rev. Damping")); + } + + if (LCDML.FUNC_loop()) // ****** LOOP ********* + { + if (LCDML.BT_checkEnter()) + { + LCDML.FUNC_goBackToMenu(); + } + else if (LCDML.BT_checkDown()) + { + if (configuration.reverb_damping < REVERB_DAMPING_MAX) + { + configuration.reverb_damping++; + } + } + else if (LCDML.BT_checkUp()) + { + if (configuration.reverb_damping > REVERB_DAMPING_MIN) + { + configuration.reverb_damping--; + } + } + lcd.setCursor(0, 1); + lcd_display_int(configuration.reverb_damping, 3, true, true, false); + + freeverbs1.damping(configuration.reverb_damping / 100); + } + + if (LCDML.FUNC_close()) // ****** STABLE END ********* + { + // you can here reset some global vars or do nothing + } } void UI_func_reverb_level(uint8_t param) { - ; + if (LCDML.FUNC_setup()) // ****** SETUP ********* + { + // setup function + lcd.setCursor(0, 0); + lcd.print(F("Reverb Level")); + } + + if (LCDML.FUNC_loop()) // ****** LOOP ********* + { + if (LCDML.BT_checkEnter()) + { + LCDML.FUNC_goBackToMenu(); + } + else if (LCDML.BT_checkDown()) + { + if (configuration.reverb_level < REVERB_LEVEL_MAX) + { + configuration.reverb_level++; + } + } + else if (LCDML.BT_checkUp()) + { + if (configuration.reverb_level > REVERB_LEVEL_MIN) + { + configuration.reverb_level--; + + } + } + lcd.setCursor(0, 1); + lcd_display_int(configuration.reverb_level, 3, true, true, false); + + reverb_mixer_r.gain(1, configuration.reverb_level / 100); + reverb_mixer_l.gain(1, configuration.reverb_level / 100); + } + + if (LCDML.FUNC_close()) // ****** STABLE END ********* + { + // you can here reset some global vars or do nothing + } } void UI_func_chorus_frequency(uint8_t param) { - ; + if (LCDML.FUNC_setup()) // ****** SETUP ********* + { + // setup function + lcd.setCursor(0, 0); + lcd.print(F("Chorus Frequency")); + } + + if (LCDML.FUNC_loop()) // ****** LOOP ********* + { + if (LCDML.BT_checkEnter()) + { + LCDML.FUNC_goBackToMenu(); + } + else if (LCDML.BT_checkDown()) + { + if (configuration.chorus_frequency < CHORUS_FREQUENCY_MAX) + { + configuration.chorus_frequency++; + } + } + else if (LCDML.BT_checkUp()) + { + if (configuration.chorus_frequency > CHORUS_FREQUENCY_MIN) + { + configuration.chorus_frequency--; + } + } + lcd.setCursor(0, 1); + lcd_display_float(configuration.chorus_frequency / 10.0, 2, 1, true, true, false); + + modulator.frequency(configuration.chorus_frequency / 10.0); + } + + if (LCDML.FUNC_close()) // ****** STABLE END ********* + { + // you can here reset some global vars or do nothing + } +} + +void UI_func_chorus_waveform(uint8_t param) +{ + if (LCDML.FUNC_setup()) // ****** SETUP ********* + { + // setup function + lcd.setCursor(0, 0); + lcd.print(F("Chorus Waveform")); + } + + if (LCDML.FUNC_loop()) // ****** LOOP ********* + { + if (LCDML.BT_checkEnter()) + { + LCDML.FUNC_goBackToMenu(); + } + else if (LCDML.BT_checkDown()) + { + if (configuration.chorus_waveform < CHORUS_WAVEFORM_MAX) + { + configuration.chorus_waveform++; + } + } + else if (LCDML.BT_checkUp()) + { + if (configuration.chorus_waveform > CHORUS_WAVEFORM_MIN) + { + configuration.chorus_waveform--; + } + } + lcd.setCursor(0, 1); + switch (configuration.chorus_waveform) + { + case 0: + modulator.begin(WAVEFORM_TRIANGLE); + lcd.print("[TRIANGLE]"); + break; + case 1: + modulator.begin(WAVEFORM_SINE); + lcd.print("[SINE ]"); + break; + default: + modulator.begin(WAVEFORM_TRIANGLE); + lcd.print("[TRIANGLE]"); + break; + } + } + + if (LCDML.FUNC_close()) // ****** STABLE END ********* + { + // you can here reset some global vars or do nothing + } } void UI_func_chorus_depth(uint8_t param) { - ; + if (LCDML.FUNC_setup()) // ****** SETUP ********* + { + // setup function + lcd.setCursor(0, 0); + lcd.print(F("Chorus Depth")); + } + + if (LCDML.FUNC_loop()) // ****** LOOP ********* + { + if (LCDML.BT_checkEnter()) + { + LCDML.FUNC_goBackToMenu(); + } + else if (LCDML.BT_checkDown()) + { + if (configuration.chorus_depth < CHORUS_DEPTH_MAX) + { + configuration.chorus_depth++; + } + } + else if (LCDML.BT_checkUp()) + { + if (configuration.chorus_depth > CHORUS_DEPTH_MIN) + { + configuration.chorus_depth--; + } + } + lcd.setCursor(0, 1); + lcd_display_int(configuration.chorus_depth, 3, true, true, false); + + modulator.amplitude(configuration.chorus_depth / 100); + } + + if (LCDML.FUNC_close()) // ****** STABLE END ********* + { + // you can here reset some global vars or do nothing + } } void UI_func_chorus_level(uint8_t param) { - ; + if (LCDML.FUNC_setup()) // ****** SETUP ********* + { + // setup function + lcd.setCursor(0, 0); + lcd.print(F("Chorus Level")); + } + + if (LCDML.FUNC_loop()) // ****** LOOP ********* + { + if (LCDML.BT_checkEnter()) + { + LCDML.FUNC_goBackToMenu(); + } + else if (LCDML.BT_checkDown()) + { + if (configuration.chorus_level < CHORUS_LEVEL_MAX) + { + configuration.chorus_level++; + } + } + else if (LCDML.BT_checkUp()) + { + if (configuration.chorus_level > CHORUS_LEVEL_MIN) + { + configuration.chorus_level--; + } + } + lcd.setCursor(0, 1); + lcd_display_int(configuration.chorus_level, 3, true, true, false); + + chorus_mixer.gain(1, configuration.chorus_level / 100); + } + + if (LCDML.FUNC_close()) // ****** STABLE END ********* + { + // you can here reset some global vars or do nothing + } } void UI_func_delay_time(uint8_t param) @@ -801,5 +1090,70 @@ void UI_func_volume(uint8_t param) lcd.show(1, 0, 1, "["); lcd.show(1, 15, 1, "]"); } + +void lcd_display_int(int16_t var, uint8_t size, bool zeros, bool brackets, bool sign) +{ + int16_t tmp = 0; + uint16_t p; + + if (size < 1) + return; + + if (brackets == true) + lcd.print(F("[")); + + if (sign == true) + { + if (var < 0) + { + lcd.print(F("-")); + var = abs(var); + } + else if (var > 0) + lcd.print(F("+")); + else + lcd.print(F(" ")); + } + + for (int8_t i = size - 1 ; i >= 0; i--) + { + p = int(pow(10, i)); + tmp = int(var / p); + if (tmp == 0) + { + if (zeros == true) + lcd.print(F("0")); + else + lcd.print(F(" ")); + } + else + lcd.print(tmp); + var -= (tmp * p); + } + + if (brackets == true) + lcd.print(F("]")); +} + +void lcd_display_float(float var, uint8_t size_number, uint8_t size_fraction, bool zeros, bool brackets, bool sign) +{ + float fraction; + float number; + + if (size_number < 1 || size_fraction < 1) + return; + + fraction = modff(var, &number); + + if (brackets == true) + lcd.print(F("[")); + + lcd_display_int(int(number), size_number, zeros, false, sign); + lcd.print(F(".")); + lcd_display_int(round(fraction * pow(10, size_fraction)), size_fraction, true, false, false); + + if (brackets == true) + lcd.print(F("]")); +} #endif #endif diff --git a/config.h b/config.h index d38d8a6..6d34375 100644 --- a/config.h +++ b/config.h @@ -210,6 +210,42 @@ #define MOD_BUTTERWORTH_FILTER_OUTPUT 1 #define MOD_LINKWITZ_RILEY_FILTER_OUTPUT 2 +#define MONO_MIN 0 +#define MONO_MAX 1 +#define MONO_DEFAULT 0 + +#define MIDI_CHANNEL_MIN MIDI_CHANNEL_OMNI +#define MIDI_CHANNEL_MAX 16 +#define MIDI_CHANNEL_DEFAULT MIDI_CHANNEL_OMNI + +#define REVERB_ROOMSIZE_MIN 0 +#define REVERB_ROOMSIZE_MAX 100 +#define REVERB_ROOMSIZE_DEFAULT 0 + +#define REVERB_DAMPING_MIN 0 +#define REVERB_DAMPING_MAX 100 +#define REVERB_DAMPING_DEFAULT 0 + +#define REVERB_LEVEL_MIN 0 +#define REVERB_LEVEL_MAX 100 +#define REVERB_LEVEL_DEFAULT 0 + +#define CHORUS_FREQUENCY_MIN 0 +#define CHORUS_FREQUENCY_MAX 100 +#define CHORUS_FREQUENCY_DEFAULT 0 + +#define CHORUS_WAVEFORM_MIN 0 +#define CHORUS_WAVEFORM_MAX 1 +#define CHORUS_WAVEFORM_DEFAULT 0 + +#define CHORUS_DEPTH_MIN 0 +#define CHORUS_DEPTH_MAX 100 +#define CHORUS_DEPTH_DEFAULT 0 + +#define CHORUS_LEVEL_MIN 0 +#define CHORUS_LEVEL_MAX 100 +#define CHORUS_LEVEL_DEFAULT 0 + // struct for holding the current configuration struct config_t { uint32_t checksum; @@ -219,6 +255,13 @@ struct config_t { float pan; uint8_t mono; uint8_t midi_channel; + uint8_t reverb_roomsize; + uint8_t reverb_damping; + uint8_t reverb_level; + uint8_t chorus_frequency; + uint8_t chorus_waveform; + uint8_t chorus_depth; + uint8_t chorus_level; }; // struct for smoothing value changes