From b649552f425252160785319ebacef2a466e1fe77 Mon Sep 17 00:00:00 2001 From: copych <70332557+copych@users.noreply.github.com> Date: Fri, 10 Feb 2023 07:33:56 +0300 Subject: [PATCH] drum filter fix, effects gain compensation --- AcidBanger.ino | 8 +- AcidBox.ino | 4 +- config.h | 1 + fx_filtercrusher.ino | 14 +-- midi_config.h | 194 ++++++++++++++++++++--------------------- overdrive.h | 81 ++++++++--------- overdrive.ino | 5 +- rosic_TeeBeeFilter.ino | 2 +- wavefolder.h | 4 +- wavefolder.ino | 7 +- 10 files changed, 166 insertions(+), 154 deletions(-) diff --git a/AcidBanger.ino b/AcidBanger.ino index 632364a..a10e6b4 100644 --- a/AcidBanger.ino +++ b/AcidBanger.ino @@ -134,15 +134,15 @@ sSynthCCs synth2_ramps[NUM_SYNTH_CCS] = { }; sSynthCCs drum_ramps[NUM_DRUM_CCS] = { - //cc cpl def min max reset + //cc cpl def min max reset {CC_808_CUTOFF, 0, 64, 64, 127, true}, - {CC_808_RESO, 0, 0, 0, 127, true}, + {CC_808_RESO, 0, 64, 0, 127, true}, {CC_808_SD_TONE, 0, 64, 64, 127, true}, #ifndef NO_PSRAM {CC_808_REVERB_SEND, 0, 5, 30, 127, true}, // reverb is not available with no psram {CC_808_DELAY_SEND, 0, 0, 64, 127, true}, // delay for drums needs more delay time (read 'RAM') than we can afford #endif - {CC_808_BD_DECAY, 0, 127, 50, 127, true}, + {CC_808_BD_DECAY, 0, 127, 50, 127, true}, {CC_808_BD_TONE, 0, 64, 40, 64, true} }; @@ -1224,8 +1224,10 @@ void run_tick() { run_ui(); button_divider = 0; +#ifdef DEBUG_TIMING // DEBF ("synt1=%dus synt2=%dus drums=%dus mixer=%dus DMA_BUF=%dus\r\n" , s1T, s2T, drT, fxT, DMA_BUF_TIME); DEBF ("Core0=%dus Core1=%dus DMA_BUF=%dus\r\n" , s2T + drT + fxT, s1T, DMA_BUF_TIME); +#endif } /* If MIDI is playing, then check for tick */ diff --git a/AcidBox.ino b/AcidBox.ino index 0db8a78..40d22c3 100644 --- a/AcidBox.ino +++ b/AcidBox.ino @@ -271,11 +271,11 @@ static void audio_task2(void *userData) { /* - * Some service routines ***************************************************************************************************************************** + * Some debug service routines ***************************************************************************************************************************** */ void readPots() { - static const float snap = 0.005; + static const float snap = 0.008f; static float tmp; static const float NORMALIZE_ADC = 1.0f / 4096.0f; for (uint8_t i = 0; i < POT_NUM; i++) { diff --git a/config.h b/config.h index 48218ed..243023b 100644 --- a/config.h +++ b/config.h @@ -6,6 +6,7 @@ //#define DEBUG_SAMPLER //#define DEBUG_JUKEBOX //#define DEBUG_FX +//#define DEBUG_TIMING //#define USE_INTERNAL_DAC // use this for testing, SOUND QUALITY SACRIFICED: NOISY 8BIT STEREO //#define NO_PSRAM // if you don't have PSRAM on your board, then use this define, but REVERB TO BE SACRIFICED, SMALL DRUM KIT SAMPLES USED diff --git a/fx_filtercrusher.ino b/fx_filtercrusher.ino index 5f60e61..b5f4a4b 100644 --- a/fx_filtercrusher.ino +++ b/fx_filtercrusher.ino @@ -7,11 +7,13 @@ void FxFilterCrusher::Process( float* left, float* right ) { Filter_Process(right, &mainFilterR_LP); Filter_Process(left, &mainFilterL_HP); Filter_Process(right, &mainFilterR_HP); +/* + cutoff_lp_slow = (float)cutoff_lp_slow * 0.99f + 0.01f * ((float)lowpassC - (float)cutoff_lp_slow); + cutoff_hp_slow = (float)cutoff_hp_slow * 0.99f + 0.01f * ((float)highpassC - (float)cutoff_hp_slow); +*/ - cutoff_lp_slow = (float)cutoff_lp_slow * 0.9f + 0.1f * ((float)lowpassC - (float)cutoff_lp_slow); - cutoff_hp_slow = (float)cutoff_hp_slow * 0.9f + 0.1f * ((float)highpassC - (float)cutoff_hp_slow); - - + cutoff_lp_slow = lowpassC ; + cutoff_hp_slow = highpassC ; /* we can not calculate in each cycle */ if ( effect_prescaler % 8 == 0 ) { Filter_CalculateTP(cutoff_lp_slow, filtReso, &filterGlobalC_LP); @@ -53,7 +55,7 @@ inline void FxFilterCrusher::Filter_CalculateTP(float c, float reso, struct filt cosOmega = sine[WAVEFORM_I((uint32_t)((float)((1ULL << 31) - 1) * omega + (float)((1ULL << 30) - 1)))]; sinOmega = sine[WAVEFORM_I((uint32_t)((float)((1ULL << 31) - 1) * omega))]; - alpha = sinOmega * one_div(2.0 * Q); + alpha = sinOmega * one_div(2.0f * Q); b[0] = (1 - cosOmega) * 0.5f; b[1] = 1 - cosOmega; b[2] = b[0]; @@ -100,7 +102,7 @@ inline void FxFilterCrusher::Filter_CalculateHP(float c, float reso, struct filt cosOmega = sine[WAVEFORM_I((uint32_t)((float)((1ULL << 31) - 1) * omega + (float)((1ULL << 30) - 1)))]; sinOmega = sine[WAVEFORM_I((uint32_t)((float)((1ULL << 31) - 1) * omega))]; - alpha = sinOmega * one_div(2.0 * Q); + alpha = sinOmega * one_div(2.0f * Q); b[0] = (1 + cosOmega) * 0.5f; b[1] = -(1 + cosOmega); b[2] = b[0]; diff --git a/midi_config.h b/midi_config.h index b747cf3..c6d14d5 100644 --- a/midi_config.h +++ b/midi_config.h @@ -6,58 +6,58 @@ #ifdef GM_MIDI // 303 Synths MIDI CC -#define CC_303_PORTATIME 5 -#define CC_303_VOLUME 7 -#define CC_303_PORTAMENTO 65 -#define CC_303_PAN 10 -#define CC_303_WAVEFORM 70 -#define CC_303_RESO 71 -#define CC_303_CUTOFF 74 -#define CC_303_ATTACK 73 -#define CC_303_DECAY 72 -#define CC_303_ENVMOD_LVL 75 -#define CC_303_ACCENT_LVL 76 -#define CC_303_REVERB_SEND 91 -#define CC_303_DELAY_SEND 92 -#define CC_303_DISTORTION 94 -#define CC_303_OVERDRIVE 95 -#define CC_303_SATURATOR 128 +#define CC_303_PORTATIME 5 +#define CC_303_VOLUME 7 +#define CC_303_PORTAMENTO 65 +#define CC_303_PAN 10 +#define CC_303_WAVEFORM 70 +#define CC_303_RESO 71 +#define CC_303_CUTOFF 74 +#define CC_303_ATTACK 73 +#define CC_303_DECAY 72 +#define CC_303_ENVMOD_LVL 75 +#define CC_303_ACCENT_LVL 76 +#define CC_303_REVERB_SEND 91 +#define CC_303_DELAY_SEND 92 +#define CC_303_DISTORTION 94 +#define CC_303_OVERDRIVE 95 +#define CC_303_SATURATOR 128 // 808 Drums MIDI CC -#define CC_808_VOLUME 7 -#define CC_808_NOTE_PAN 8 -#define CC_808_PAN 10 -#define CC_808_RESO 71 -#define CC_808_CUTOFF 74 -#define CC_808_REVERB_SEND 91 -#define CC_808_DELAY_SEND 92 -#define CC_808_DISTORTION 94 -#define CC_808_PITCH 89 -#define CC_808_NOTE_SEL 90 // select note, all the following CC note modifiers will be applied to this sample as it was RPN or NRPN -#define CC_808_NOTE_ATTACK 73 -#define CC_808_NOTE_DECAY 72 -#define CC_808_BD_TONE 21 // Specific per drum control -#define CC_808_BD_DECAY 23 -#define CC_808_BD_LEVEL 24 -#define CC_808_SD_TONE 25 -#define CC_808_SD_SNAP 26 -#define CC_808_SD_LEVEL 29 -#define CC_808_CH_TUNE 61 -#define CC_808_CH_LEVEL 63 -#define CC_808_OH_TUNE 80 -#define CC_808_OH_DECAY 81 -#define CC_808_OH_LEVEL 82 +#define CC_808_VOLUME 7 +#define CC_808_NOTE_PAN 8 +#define CC_808_PAN 10 +#define CC_808_RESO 71 +#define CC_808_CUTOFF 74 +#define CC_808_REVERB_SEND 91 +#define CC_808_DELAY_SEND 92 +#define CC_808_DISTORTION 94 +#define CC_808_PITCH 89 +#define CC_808_NOTE_SEL 90 // select note, all the following CC note modifiers will be applied to this sample as it was RPN or NRPN +#define CC_808_NOTE_ATTACK 73 +#define CC_808_NOTE_DECAY 72 +#define CC_808_BD_TONE 21 // Specific per drum control +#define CC_808_BD_DECAY 23 +#define CC_808_BD_LEVEL 24 +#define CC_808_SD_TONE 25 +#define CC_808_SD_SNAP 26 +#define CC_808_SD_LEVEL 29 +#define CC_808_CH_TUNE 61 +#define CC_808_CH_LEVEL 63 +#define CC_808_OH_TUNE 80 +#define CC_808_OH_DECAY 81 +#define CC_808_OH_LEVEL 82 // Global -#define CC_ANY_COMPRESSOR 93 -#define CC_ANY_DELAY_TIME 84 -#define CC_ANY_DELAY_FB 85 -#define CC_ANY_DELAY_LVL 86 -#define CC_ANY_REVERB_TIME 87 -#define CC_ANY_REVERB_LVL 88 -#define CC_ANY_RESET_CCS 121 -#define CC_ANY_NOTES_OFF 123 -#define CC_ANY_SOUND_OFF 120 +#define CC_ANY_COMPRESSOR 93 +#define CC_ANY_DELAY_TIME 84 +#define CC_ANY_DELAY_FB 85 +#define CC_ANY_DELAY_LVL 86 +#define CC_ANY_REVERB_TIME 87 +#define CC_ANY_REVERB_LVL 88 +#define CC_ANY_RESET_CCS 121 +#define CC_ANY_NOTES_OFF 123 +#define CC_ANY_SOUND_OFF 120 #endif @@ -65,57 +65,57 @@ #ifdef VINTAGE_MIDI // 303 Synths MIDI CC -#define CC_303_PORTATIME 5 -#define CC_303_VOLUME 11 -#define CC_303_PORTAMENTO 65 -#define CC_303_PAN 10 -#define CC_303_WAVEFORM 70 -#define CC_303_RESO 71 -#define CC_303_CUTOFF 74 -#define CC_303_ATTACK 73 -#define CC_303_DECAY 75 -#define CC_303_ENVMOD_LVL 12 -#define CC_303_ACCENT_LVL 76 -#define CC_303_REVERB_SEND 91 -#define CC_303_DELAY_SEND 19 -#define CC_303_DISTORTION 17 -#define CC_303_SATURATOR 95 +#define CC_303_PORTATIME 5 +#define CC_303_VOLUME 11 +#define CC_303_PORTAMENTO 65 +#define CC_303_PAN 10 +#define CC_303_WAVEFORM 70 +#define CC_303_RESO 71 +#define CC_303_CUTOFF 74 +#define CC_303_ATTACK 73 +#define CC_303_DECAY 75 +#define CC_303_ENVMOD_LVL 12 +#define CC_303_ACCENT_LVL 76 +#define CC_303_REVERB_SEND 91 +#define CC_303_DELAY_SEND 19 +#define CC_303_DISTORTION 17 +#define CC_303_SATURATOR 95 // 808 Drums MIDI CC -#define CC_808_VOLUME 7 -#define CC_808_NOTE_PAN 8 -#define CC_808_PAN 10 -#define CC_808_RESO 71 -#define CC_808_CUTOFF 74 -#define CC_808_REVERB_SEND 91 -#define CC_808_DELAY_SEND 92 -#define CC_808_DISTORTION 94 -#define CC_808_PITCH 89 -#define CC_808_NOTE_SEL 90 // select note, all the following CC note modifiers will be applied to this sample as it was RPN or NRPN -#define CC_808_NOTE_ATTACK 73 // universal for all drums -#define CC_808_NOTE_DECAY 72 -#define CC_808_BD_TONE 21 // Specific per drum control -#define CC_808_BD_DECAY 23 -#define CC_808_BD_LEVEL 24 -#define CC_808_SD_TONE 25 -#define CC_808_SD_SNAP 26 -#define CC_808_SD_LEVEL 29 -#define CC_808_CH_TUNE 61 -#define CC_808_CH_LEVEL 63 -#define CC_808_OH_TUNE 80 -#define CC_808_OH_DECAY 81 -#define CC_808_OH_LEVEL 82 - - -#define CC_ANY_COMPRESSOR 93 -#define CC_ANY_DELAY_TIME 84 -#define CC_ANY_DELAY_FB 85 -#define CC_ANY_DELAY_LVL 86 -#define CC_ANY_REVERB_TIME 87 -#define CC_ANY_REVERB_LVL 88 -#define CC_ANY_RESET_CCS 121 -#define CC_ANY_NOTES_OFF 123 -#define CC_ANY_SOUND_OFF 120 +#define CC_808_VOLUME 7 +#define CC_808_NOTE_PAN 8 +#define CC_808_PAN 10 +#define CC_808_RESO 71 +#define CC_808_CUTOFF 74 +#define CC_808_REVERB_SEND 91 +#define CC_808_DELAY_SEND 92 +#define CC_808_DISTORTION 94 +#define CC_808_PITCH 89 +#define CC_808_NOTE_SEL 90 // select note, all the following CC note modifiers will be applied to this sample as it was RPN or NRPN +#define CC_808_NOTE_ATTACK 73 // universal for all drums +#define CC_808_NOTE_DECAY 72 +#define CC_808_BD_TONE 21 // Specific per drum control +#define CC_808_BD_DECAY 23 +#define CC_808_BD_LEVEL 24 +#define CC_808_SD_TONE 25 +#define CC_808_SD_SNAP 26 +#define CC_808_SD_LEVEL 29 +#define CC_808_CH_TUNE 61 +#define CC_808_CH_LEVEL 63 +#define CC_808_OH_TUNE 80 +#define CC_808_OH_DECAY 81 +#define CC_808_OH_LEVEL 82 + + +#define CC_ANY_COMPRESSOR 93 +#define CC_ANY_DELAY_TIME 84 +#define CC_ANY_DELAY_FB 85 +#define CC_ANY_DELAY_LVL 86 +#define CC_ANY_REVERB_TIME 87 +#define CC_ANY_REVERB_LVL 88 +#define CC_ANY_RESET_CCS 121 +#define CC_ANY_NOTES_OFF 123 +#define CC_ANY_SOUND_OFF 120 diff --git a/overdrive.h b/overdrive.h index f93d484..cb64351 100644 --- a/overdrive.h +++ b/overdrive.h @@ -1,40 +1,41 @@ -#pragma once -#ifndef DSY_OVERDRIVE_H -#define DSY_OVERDRIVE_H - - -/** @file overdrive.h */ - -/** - @brief Distortion / Overdrive Module - @author Ported by Ben Sergentanis - @date Jan 2021 - Ported from pichenettes/eurorack/plaits/dsp/fx/overdrive.h \n - to an independent module. \n - Original code written by Emilie Gillet in 2014. \n -*/ -class Overdrive -{ - public: - Overdrive() {} - ~Overdrive() {} - - /** Initializes the module with 0 gain */ - void Init(); - - /** Get the next sample - \param in Input to be overdriven - */ - float Process(float in); - - /** Set the amount of drive - \param drive Works from 0-1 - */ - void SetDrive(float drive); - - private: - float drive_; - float pre_gain_; - float post_gain_; -}; -#endif \ No newline at end of file +#pragma once +#ifndef DSY_OVERDRIVE_H +#define DSY_OVERDRIVE_H + + +/** @file overdrive.h */ + +/** + @brief Distortion / Overdrive Module + @author Ported by Ben Sergentanis + @date Jan 2021 + Ported from pichenettes/eurorack/plaits/dsp/fx/overdrive.h \n + to an independent module. \n + Original code written by Emilie Gillet in 2014. \n +*/ +class Overdrive +{ + public: + Overdrive() {} + ~Overdrive() {} + + /** Initializes the module with 0 gain */ + void Init(); + + /** Get the next sample + \param in Input to be overdriven + */ + float Process(float in); + + /** Set the amount of drive + \param drive Works from 0-1 + */ + void SetDrive(float drive); + + private: + float drive_; + float pre_gain_; + float post_gain_; + float compens_; +}; +#endif diff --git a/overdrive.ino b/overdrive.ino index 1e7263c..5ba92dc 100644 --- a/overdrive.ino +++ b/overdrive.ino @@ -10,12 +10,13 @@ float Overdrive::Process(float in) { float pre = (float)(pre_gain_ * in * 2.0f); - return (float)(fast_tanh(pre) * post_gain_); + return (float)(fast_tanh(pre) * post_gain_ * compens_); // return SoftClip(pre) * post_gain_; } void Overdrive::SetDrive(float drive) { + compens_ = fast_tanh(0.09f - 3.05f * drive) * 0.77f + 1.0f ; drive = 0.125f + (float)drive * (0.875f); //drive = fclamp(drive, 0.f, 1.f); drive_ = 1.999f * (float)drive; @@ -26,7 +27,7 @@ void Overdrive::SetDrive(float drive) pre_gain_ = (float)pre_gain_a + (float)(pre_gain_b - pre_gain_a) * drive_2; const float drive_squashed = drive_ * (2.0f - drive_); - post_gain_ = 0.5f / fast_tanh((float)(0.33f + drive_squashed * (float)(pre_gain_ - 0.33f))); + post_gain_ = 0.5f / fast_tanh((float)(0.33f + drive_squashed * (float)(pre_gain_ - 0.33f))); #ifdef DEBUG_FX DEBF("pre %0.4f post %0.4f drive %0.4f\r\n", pre_gain_, post_gain_, drive_); #endif diff --git a/rosic_TeeBeeFilter.ino b/rosic_TeeBeeFilter.ino index 97e6a77..45e83d3 100644 --- a/rosic_TeeBeeFilter.ino +++ b/rosic_TeeBeeFilter.ino @@ -98,7 +98,7 @@ inline void TeeBeeFilter::SetCutoff(float newCutoff, bool updateCoefficients) inline void TeeBeeFilter::SetResonance(float newResonance, bool updateCoefficients) { resonanceRaw = newResonance; - compens = 1.8f * (resonanceRaw + 0.1f) * one_div((resonanceRaw + 0.1f) * 0.75f + 0.113f); // gain compensation; one_div(x) = 1/x + compens = 1.8f * (resonanceRaw + 0.25f) * one_div((resonanceRaw + 0.25f) * 0.75f + 0.113f); // gain compensation; one_div(x) = 1/x resonanceSkewed = (1.0f - exp(-3.0f * resonanceRaw)) / (1.0f - exp(-3.0f)); if ( updateCoefficients == true ) calculateCoefficientsApprox4(); diff --git a/wavefolder.h b/wavefolder.h index 78f2242..c5f1f00 100644 --- a/wavefolder.h +++ b/wavefolder.h @@ -26,14 +26,14 @@ class Wavefolder { \param gain Set input gain. Supports negative values for thru-zero */ - inline void SetDrive(float gain) { gain_ = 10.0f * gain + 1.0f; } + inline void SetDrive(float gain); /** \param offset Offset odded to input (pre-gain) for asymmetrical folding. */ inline void SetOffset(float offset) { offset_ = offset; } private: - float gain_, offset_; + float gain_, offset_, compens_; }; #endif diff --git a/wavefolder.ino b/wavefolder.ino index 2b9f330..d4f7ad7 100644 --- a/wavefolder.ino +++ b/wavefolder.ino @@ -5,6 +5,11 @@ void Wavefolder::Init() { SetOffset(0.0f); } +inline void Wavefolder::SetDrive(float gain) { + gain_ = 10.0f * gain + 1.0f; + compens_ = fast_tanh(0.09f - 3.05f * gain) * 0.77f + 1.0f ; +} + float Wavefolder::Process(float in) { float ft; float sgn; @@ -14,5 +19,5 @@ float Wavefolder::Process(float in) { sgn = (static_cast(ft) % 2 == 0) ? 1.0f : -1.0f; //int rem = static_cast(ft) % 2 ; //sgn = (float)(1 - 2 * rem); // should work a bit faster ??? - return sgn * (in - 2.0f * ft); + return sgn * (in - 2.0f * ft) * compens_; }