From 3f5f7544607ae1b4b0a57b6f5e353b3ff18d284f Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Tue, 16 Jul 2019 13:30:27 +0200 Subject: [PATCH] Changed chorus mix-in. Small fixes for interpolation. --- UI.hpp | 4 +++- config.h | 4 ++-- effect_modulated_delay.cpp | 42 +++++++++++++++++++++----------------- 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/UI.hpp b/UI.hpp index ecea5d0..f7c312d 100644 --- a/UI.hpp +++ b/UI.hpp @@ -2068,7 +2068,9 @@ void set_chorus_level(uint8_t value) Serial.print(F("Set CHORUS_LEVEL ")); Serial.println(value); #endif - float tmp = mapfloat(float(value), ENC_CHORUS_LEVEL_MIN, ENC_CHORUS_LEVEL_MAX, 0.0, 1.0); + float tmp = mapfloat(float(value), ENC_CHORUS_LEVEL_MIN, ENC_CHORUS_LEVEL_MAX, 0.0, 0.5); + mixer_r.gain(0, 1.0-tmp); + mixer_l.gain(0, 1.0-tmp); mixer_r.gain(2, tmp); mixer_l.gain(2, tmp); configuration.chorus_level = value; diff --git a/config.h b/config.h index 6a81f83..b25883d 100644 --- a/config.h +++ b/config.h @@ -55,9 +55,9 @@ #define REDUCE_LOUDNESS 0 #define USE_XFADE_DATA 1 // CHORUS parameters -#define CHORUS_DELAY_LENGTH_SAMPLES (15*AUDIO_BLOCK_SAMPLES) // one AUDIO_BLOCK_SAMPLES = 2.902ms; you need doubled length, e.g. delay point is 20ms, so you need up to 40ms delay! +#define CHORUS_DELAY_LENGTH_SAMPLES (15*AUDIO_BLOCK_SAMPLES) // one AUDIO_BLOCK_SAMPLES = 2.902ms #define CHORUS_WAVEFORM WAVEFORM_TRIANGLE // WAVEFORM_SINE WAVEFORM_TRIANGLE WAVEFORM_SAWTOOTH WAVEFORM_SAWTOOTH_REVERSE -#define CHORUS_MODULATOR_FILTER_FRQ 500 +#define CHORUS_MODULATOR_FILTER_FRQ 50 // see https://www.earlevel.com/main/2013/10/13/biquad-calculator-v2/ #define CHORUS_MODULATOR_FILTER_Q 0.7 //************************************************************************************************* diff --git a/effect_modulated_delay.cpp b/effect_modulated_delay.cpp index a0a6ecd..960d67b 100644 --- a/effect_modulated_delay.cpp +++ b/effect_modulated_delay.cpp @@ -23,7 +23,7 @@ #include #include -#include "limits.h" +#include "arm_math.h" #include "effect_modulated_delay.h" #include "config.h" @@ -73,50 +73,54 @@ void AudioEffectModulatedDelay::update(void) block = receiveWritable(0); modulation = receiveReadOnly(1); - if (block && modulation) + if (block && modulation && _modulation_intensity > 0.1) { int16_t *bp; - int16_t *mp; + float *mp; float mod_idx; float mod_number; float mod_fraction; + float mod_float[AUDIO_BLOCK_SAMPLES]; bp = block->data; - mp = modulation->data; + arm_q15_to_float(modulation->data, mod_float, AUDIO_BLOCK_SAMPLES); + mp = mod_float; for (uint16_t i = 0; i < AUDIO_BLOCK_SAMPLES; i++) { - // write data into circular buffer + // write data into circular buffer (delayline) if (_circ_idx >= _delay_length) _circ_idx = 0; _delayline[_circ_idx] = *bp; - // Calculate the modulation-index as a floating point number fo later interpolation - mod_idx = _delay_offset + ((float(*mp) / SHRT_MAX) * _modulation_intensity); + // Calculate the modulation-index as a floating point number for interpolation + mod_idx = _delay_offset + (*mp * _modulation_intensity); mod_fraction = modff(mod_idx, &mod_number); - // linear interpolation - c_mod_idx = _circ_idx - round(mod_idx); - c_mod_idx %= _delay_length; + // calculate modulation index into circular buffer + c_mod_idx = (_circ_idx - int(mod_number)) % _delay_length; if (c_mod_idx < 0) // check for negative offsets and correct them c_mod_idx += _delay_length; - if (c_mod_idx - 1 < 0) + + // linear interpolation + if (c_mod_idx < 1) { - idx[0] = 0; - idx[1] = _delay_length - 1; + idx[0] = _delay_length - 1; + idx[1] = 0; } else if (c_mod_idx + 1 >= _delay_length) { - idx[0] = c_mod_idx; - idx[1] = 0; + idx[0] = 0; + idx[1] = c_mod_idx; } else { - idx[0] = c_mod_idx; - idx[1] = c_mod_idx + 1; + idx[0] = c_mod_idx + 1; + idx[1] = c_mod_idx; } - *bp = round(float(_delayline[idx[0]]) * mod_fraction + float(_delayline[idx[1]]) * (1.0 - mod_fraction)); + *bp = round(float(_delayline[idx[0]]) * (mod_fraction) + float(_delayline[idx[1]]) * (1.0 - mod_fraction)); + // push the pointers forward bp++; // next audio data mp++; // next modulation data _circ_idx++; // next circular buffer index @@ -133,7 +137,7 @@ void AudioEffectModulatedDelay::update(void) } } -float AudioEffectModulatedDelay::offset(float offset_value) +float AudioEffectModulatedDelay::offset(float offset_value) // in ms { uint16_t offset_frames = (offset_value / 1000) * AUDIO_SAMPLE_RATE; if (offset_frames > _delay_length * MODULATION_MAX_FACTOR)