From 81ce42ec63360028dcef26b630a4daac27ce86a8 Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Tue, 3 Sep 2019 16:36:35 +0200 Subject: [PATCH] Added function for LP coefficient calculation based on frequency and q. Small fixes for calculating the delay offset. --- effect_modulated_delay.cpp | 60 +++++++++++++++++++++----------------- effect_modulated_delay.h | 5 ---- name.c | 2 +- 3 files changed, 34 insertions(+), 33 deletions(-) diff --git a/effect_modulated_delay.cpp b/effect_modulated_delay.cpp index 4dd3c83..8688394 100644 --- a/effect_modulated_delay.cpp +++ b/effect_modulated_delay.cpp @@ -26,9 +26,6 @@ #include "arm_math.h" #include "effect_modulated_delay.h" #include "config.h" -#include "DCfilter.h" -#include "OnePoleLP.h" -#include "limits.h" extern config_t configuration; @@ -52,7 +49,6 @@ boolean AudioEffectModulatedDelay::begin(short *delayline, int d_length) _delay_length = 0; _delay_offset = 0.0; _cb_index = 0; - z1 = 0; if (delayline == NULL) { return (false); @@ -63,13 +59,11 @@ boolean AudioEffectModulatedDelay::begin(short *delayline, int d_length) _delayline = delayline; _delay_length = d_length; + memset(_delayline, 0, d_length); set_modulator_filter_coeffs(); modulator_filter_data = {1, modulator_filter_state, modulator_filter_coeffs}; - lp = new OnePoleLP(); - dcFilter = new DCfilter(0.9); - return (true); } @@ -80,12 +74,31 @@ void AudioEffectModulatedDelay::set_modulator_filter_coeffs(void) // Example: https://web.fhnw.ch/technik/projekte/eit/Fruehling2016/MuelZum/html/parametric_equalizer_example_8c-example.html // Coeeficients calculated with https://arachnoid.com/BiQuadDesigner/index.html - // SR = 44110, Fc = 20 Hz; Q=0.707 - modulator_filter_coeffs[0] = 5.06973332e-7; // b0 - modulator_filter_coeffs[1] = 1.01394666e-6; // b1 - modulator_filter_coeffs[2] = modulator_filter_coeffs[0]; // b2 - modulator_filter_coeffs[3] = 1.99798478; // -a1 - modulator_filter_coeffs[4] = -0.99798681; // -a2 + double frequency = 20.0; + double q = 0.1; + + // low-pass + double w0 = frequency * (2 * M_PI / AUDIO_SAMPLE_RATE_EXACT); + double sinW0 = sin(w0); + double alpha = sinW0 / ((double)q * 2.0); + double cosW0 = cos(w0); + //double scale = 1073741824.0 / (1.0 + alpha); // for integers + double scale = 1.0 / (1.0 + alpha); + + modulator_filter_coeffs[0] = ((1.0 - cosW0) / 2.0) * scale; // b0 + modulator_filter_coeffs[1] = (1.0 - cosW0) * scale; // b1 + modulator_filter_coeffs[2] = modulator_filter_coeffs[0]; // b2 + modulator_filter_coeffs[3] = (2.0 * cosW0) * scale; // -a1 + modulator_filter_coeffs[4] = (-1.0 - alpha) * scale; // -a2 + + /* + // SR = 44110, Fc = 20 Hz; Q=0.707 + modulator_filter_coeffs[0] = 5.06973332e-7; // b0 + modulator_filter_coeffs[1] = 1.01394666e-6; // b1 + modulator_filter_coeffs[2] = modulator_filter_coeffs[0]; // b2 + modulator_filter_coeffs[3] = 1.99798478; // -a1 + modulator_filter_coeffs[4] = -0.99798681; // -a2 + */ } void AudioEffectModulatedDelay::update(void) @@ -135,14 +148,7 @@ void AudioEffectModulatedDelay::update(void) else cb_mod_index_neighbor = cb_mod_index - 1; - //*bp = round(float(_delayline[cb_mod_index]) * mod_fraction + float(_delayline[cb_mod_index_neighbor]) * (1.0 - mod_fraction)); - *bp = (round(float(_delayline[cb_mod_index]) * mod_fraction + float(_delayline[cb_mod_index_neighbor]) * (1.0 - mod_fraction))+z1)/2; - z1 = *bp; - - float bp_f = *bp / float(SHRT_MAX); - lp->tick(&bp_f, 0.95f); - *bp = round(bp_f * SHRT_MAX); - *bp = dcFilter->next(*bp); + *bp = round(float(_delayline[cb_mod_index]) * mod_fraction + float(_delayline[cb_mod_index_neighbor]) * (1.0 - mod_fraction)); // push the pointers forward bp++; // next audio data @@ -163,13 +169,13 @@ void AudioEffectModulatedDelay::update(void) 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) - _delay_offset = _delay_length * MODULATION_MAX_FACTOR; - else if (offset_frames <= _delay_length * (1 - MODULATION_MAX_FACTOR)) - _delay_offset = _delay_length * (1 - MODULATION_MAX_FACTOR); + uint16_t offset_frames = floor((offset_value / 1000) * AUDIO_SAMPLE_RATE); + if (offset_frames > round( _delay_length * MODULATION_MAX_FACTOR)) + _delay_offset = floor(_delay_length * MODULATION_MAX_FACTOR); + else if (offset_frames <= round(_delay_length * (1 - MODULATION_MAX_FACTOR))) + _delay_offset = floor(_delay_length * (1 - MODULATION_MAX_FACTOR)); else _delay_offset = offset_frames; - return (offset_frames / AUDIO_SAMPLE_RATE * 1000); + return (floor(offset_frames / AUDIO_SAMPLE_RATE * 1000)); } diff --git a/effect_modulated_delay.h b/effect_modulated_delay.h index 48f8edd..9ded4a1 100644 --- a/effect_modulated_delay.h +++ b/effect_modulated_delay.h @@ -27,8 +27,6 @@ #include "Arduino.h" #include "AudioStream.h" #include "config.h" -#include "DCfilter.h" -#include "OnePoleLP.h" #define MODULATION_MAX_FACTOR 0.75 @@ -61,9 +59,6 @@ class AudioEffectModulatedDelay : arm_biquad_casd_df1_inst_f32 modulator_filter_data; float32_t modulator_filter_state[4]; float32_t modulator_filter_coeffs[5]; - int16_t z1; - OnePoleLP *lp; - DCfilter *dcFilter; }; #endif diff --git a/name.c b/name.c index f08fcfb..419afea 100644 --- a/name.c +++ b/name.c @@ -1,5 +1,5 @@ #include "usb_names.h" -#define MIDI_NAME {'M','i','c','r','o','M','D','A','E','p','i','a','n','o'} +#define MIDI_NAME {'M','i','c','r','o','M','D','A','E','P','i','a','n','o'} #define MIDI_NAME_LEN 14 // Do not change this part. This exact format is required by USB.