Added function for LP coefficient calculation based on frequency and q.

Small fixes for calculating the delay offset.
dev
Holger Wirtz 5 years ago
parent 41ad26f3a0
commit 3605d6b6a8
  1. 48
      effect_modulated_delay.cpp
  2. 5
      effect_modulated_delay.h
  3. 2
      name.c

@ -26,9 +26,6 @@
#include "arm_math.h" #include "arm_math.h"
#include "effect_modulated_delay.h" #include "effect_modulated_delay.h"
#include "config.h" #include "config.h"
#include "DCfilter.h"
#include "OnePoleLP.h"
#include "limits.h"
extern config_t configuration; extern config_t configuration;
@ -52,7 +49,6 @@ boolean AudioEffectModulatedDelay::begin(short *delayline, int d_length)
_delay_length = 0; _delay_length = 0;
_delay_offset = 0.0; _delay_offset = 0.0;
_cb_index = 0; _cb_index = 0;
z1 = 0;
if (delayline == NULL) { if (delayline == NULL) {
return (false); return (false);
@ -63,13 +59,11 @@ boolean AudioEffectModulatedDelay::begin(short *delayline, int d_length)
_delayline = delayline; _delayline = delayline;
_delay_length = d_length; _delay_length = d_length;
memset(_delayline, 0, d_length);
set_modulator_filter_coeffs(); set_modulator_filter_coeffs();
modulator_filter_data = {1, modulator_filter_state, modulator_filter_coeffs}; modulator_filter_data = {1, modulator_filter_state, modulator_filter_coeffs};
lp = new OnePoleLP();
dcFilter = new DCfilter(0.9);
return (true); 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 // 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 // Coeeficients calculated with https://arachnoid.com/BiQuadDesigner/index.html
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 // SR = 44110, Fc = 20 Hz; Q=0.707
modulator_filter_coeffs[0] = 5.06973332e-7; // b0 modulator_filter_coeffs[0] = 5.06973332e-7; // b0
modulator_filter_coeffs[1] = 1.01394666e-6; // b1 modulator_filter_coeffs[1] = 1.01394666e-6; // b1
modulator_filter_coeffs[2] = modulator_filter_coeffs[0]; // b2 modulator_filter_coeffs[2] = modulator_filter_coeffs[0]; // b2
modulator_filter_coeffs[3] = 1.99798478; // -a1 modulator_filter_coeffs[3] = 1.99798478; // -a1
modulator_filter_coeffs[4] = -0.99798681; // -a2 modulator_filter_coeffs[4] = -0.99798681; // -a2
*/
} }
void AudioEffectModulatedDelay::update(void) void AudioEffectModulatedDelay::update(void)
@ -135,14 +148,7 @@ void AudioEffectModulatedDelay::update(void)
else else
cb_mod_index_neighbor = cb_mod_index - 1; 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));
*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);
// push the pointers forward // push the pointers forward
bp++; // next audio data bp++; // next audio data
@ -163,13 +169,13 @@ void AudioEffectModulatedDelay::update(void)
float AudioEffectModulatedDelay::offset(float offset_value) // in ms float AudioEffectModulatedDelay::offset(float offset_value) // in ms
{ {
uint16_t offset_frames = (offset_value / 1000) * AUDIO_SAMPLE_RATE; uint16_t offset_frames = floor((offset_value / 1000) * AUDIO_SAMPLE_RATE);
if (offset_frames > _delay_length * MODULATION_MAX_FACTOR) if (offset_frames > round( _delay_length * MODULATION_MAX_FACTOR))
_delay_offset = _delay_length * MODULATION_MAX_FACTOR; _delay_offset = floor(_delay_length * MODULATION_MAX_FACTOR);
else if (offset_frames <= _delay_length * (1 - MODULATION_MAX_FACTOR)) else if (offset_frames <= round(_delay_length * (1 - MODULATION_MAX_FACTOR)))
_delay_offset = _delay_length * (1 - MODULATION_MAX_FACTOR); _delay_offset = floor(_delay_length * (1 - MODULATION_MAX_FACTOR));
else else
_delay_offset = offset_frames; _delay_offset = offset_frames;
return (offset_frames / AUDIO_SAMPLE_RATE * 1000); return (floor(offset_frames / AUDIO_SAMPLE_RATE * 1000));
} }

@ -27,8 +27,6 @@
#include "Arduino.h" #include "Arduino.h"
#include "AudioStream.h" #include "AudioStream.h"
#include "config.h" #include "config.h"
#include "DCfilter.h"
#include "OnePoleLP.h"
#define MODULATION_MAX_FACTOR 0.75 #define MODULATION_MAX_FACTOR 0.75
@ -61,9 +59,6 @@ class AudioEffectModulatedDelay :
arm_biquad_casd_df1_inst_f32 modulator_filter_data; arm_biquad_casd_df1_inst_f32 modulator_filter_data;
float32_t modulator_filter_state[4]; float32_t modulator_filter_state[4];
float32_t modulator_filter_coeffs[5]; float32_t modulator_filter_coeffs[5];
int16_t z1;
OnePoleLP *lp;
DCfilter *dcFilter;
}; };
#endif #endif

@ -1,5 +1,5 @@
#include "usb_names.h" #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 #define MIDI_NAME_LEN 14
// Do not change this part. This exact format is required by USB. // Do not change this part. This exact format is required by USB.

Loading…
Cancel
Save