|
|
|
@ -60,37 +60,25 @@ boolean AudioEffectModulatedDelay::begin(short *delayline, int d_length) |
|
|
|
|
_delayline = delayline; |
|
|
|
|
_delay_length = d_length; |
|
|
|
|
|
|
|
|
|
set_modulator_filter_coeffs(1.0, configuration.chorus_frequency / 10, 1.0); // gain, center frerquency
|
|
|
|
|
modulator_filter_data = {1, &modulator_filter_state, modulator_filter_coeffs}; |
|
|
|
|
set_modulator_filter_coeffs(); |
|
|
|
|
modulator_filter_data = {1, modulator_filter_state, modulator_filter_coeffs}; |
|
|
|
|
|
|
|
|
|
return (true); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void AudioEffectModulatedDelay::set_modulator_filter_coeffs(float gain, float fc, float width) |
|
|
|
|
void AudioEffectModulatedDelay::set_modulator_filter_coeffs(void) |
|
|
|
|
{ |
|
|
|
|
// modulator filter
|
|
|
|
|
// coefficients calculated with "IOWA Hills IIR Filter Designer 6.5", http://www.iowahills.com/8DownloadPage.html
|
|
|
|
|
// "IOWA Hills IIR Filter Designer 6.5", http://www.iowahills.com/8DownloadPage.html
|
|
|
|
|
// Example: https://web.fhnw.ch/technik/projekte/eit/Fruehling2016/MuelZum/html/parametric_equalizer_example_8c-example.html
|
|
|
|
|
|
|
|
|
|
/* float32_t A = sqrt(powf(10, gain / 20.0f));
|
|
|
|
|
float32_t w0 = 2.0f * PI * fc / ((float32_t)AUDIO_SAMPLE_RATE_EXACT); |
|
|
|
|
float32_t cosw0 = cosf(w0); |
|
|
|
|
float32_t sinw0 = sinf(w0); |
|
|
|
|
float32_t alpha = sinw0 / (2.0f * width); |
|
|
|
|
float32_t a0 = 1.0f + alpha / A; |
|
|
|
|
|
|
|
|
|
modulator_filter_coeffs[0] = (1.0f + alpha * A) / a0; // b0
|
|
|
|
|
modulator_filter_coeffs[1] = (-2.0f * cosw0) / a0; // b1
|
|
|
|
|
modulator_filter_coeffs[2] = (1.0f - alpha * A) / a0; // b2
|
|
|
|
|
modulator_filter_coeffs[3] = -(2.0f * cosw0) / -a0; // -a1
|
|
|
|
|
modulator_filter_coeffs[4] = (1.0f - alpha / A) / -a0; // -a2 */
|
|
|
|
|
|
|
|
|
|
// OmegaC = 0.1, SR = 44117.64706, Fc = 2.21 kHz, N=2
|
|
|
|
|
modulator_filter_coeffs[0] = 0.020727217357494492; // b0
|
|
|
|
|
modulator_filter_coeffs[1] = 0.020727217357494492; // b1
|
|
|
|
|
modulator_filter_coeffs[2] = 0.020727217357494492; // b2
|
|
|
|
|
modulator_filter_coeffs[3] = 1.563046149664217620; // -a1
|
|
|
|
|
modulator_filter_coeffs[4] = -0.642749223719756180; // -a2
|
|
|
|
|
// Coeeficients calculated with https://arachnoid.com/BiQuadDesigner/index.html
|
|
|
|
|
|
|
|
|
|
// SR = 44110, Fc = 400 Hz; Q=0.707
|
|
|
|
|
modulator_filter_coeffs[0] = 7.80321719e-4; // b0
|
|
|
|
|
modulator_filter_coeffs[1] = 0.00156064; // b1
|
|
|
|
|
modulator_filter_coeffs[2] = 7.80321719e-4; // b2
|
|
|
|
|
modulator_filter_coeffs[3] = 1.91943335; // -a1
|
|
|
|
|
modulator_filter_coeffs[4] = -0.92255463; // -a2
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void AudioEffectModulatedDelay::update(void) |
|
|
|
@ -116,7 +104,7 @@ void AudioEffectModulatedDelay::update(void) |
|
|
|
|
|
|
|
|
|
bp = block->data; |
|
|
|
|
arm_q15_to_float(modulation->data, modulation_f32, AUDIO_BLOCK_SAMPLES); |
|
|
|
|
//arm_biquad_cascade_df1_f32(&modulator_filter_data, modulation_f32, modulation_f32, AUDIO_BLOCK_SAMPLES);
|
|
|
|
|
arm_biquad_cascade_df1_f32(&modulator_filter_data, modulation_f32, modulation_f32, AUDIO_BLOCK_SAMPLES); |
|
|
|
|
mp = modulation_f32; |
|
|
|
|
|
|
|
|
|
for (uint16_t i = 0; i < AUDIO_BLOCK_SAMPLES; i++) |
|
|
|
@ -131,9 +119,9 @@ void AudioEffectModulatedDelay::update(void) |
|
|
|
|
mod_fraction = modff(mod_index, &mod_number); // split float of mod_index into integer (= mod_number) and fraction part
|
|
|
|
|
|
|
|
|
|
// calculate modulation index into circular buffer
|
|
|
|
|
cb_mod_index = (_cb_index - (_delay_offset + int(mod_index))); |
|
|
|
|
if (cb_mod_index >= _delay_length) |
|
|
|
|
cb_mod_index -= _delay_length; |
|
|
|
|
cb_mod_index = (_cb_index - (_delay_offset + mod_number)); |
|
|
|
|
/* if (cb_mod_index >= _delay_length)
|
|
|
|
|
cb_mod_index -= _delay_length; */ |
|
|
|
|
if (cb_mod_index < 0) // check for negative offsets and correct them
|
|
|
|
|
cb_mod_index += _delay_length; |
|
|
|
|
|
|
|
|
@ -143,6 +131,7 @@ void AudioEffectModulatedDelay::update(void) |
|
|
|
|
cb_mod_index_neighbor = _delay_length; |
|
|
|
|
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)); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
@ -150,13 +139,9 @@ void AudioEffectModulatedDelay::update(void) |
|
|
|
|
cb_mod_index_neighbor = 0; |
|
|
|
|
else |
|
|
|
|
cb_mod_index_neighbor = cb_mod_index + 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (*mp < 0.0) |
|
|
|
|
*bp = round(float(_delayline[cb_mod_index]) * mod_fraction + float(_delayline[cb_mod_index_neighbor]) * (1.0 - mod_fraction)); |
|
|
|
|
else |
|
|
|
|
*bp = round(float(_delayline[cb_mod_index_neighbor]) * mod_fraction + float(_delayline[cb_mod_index]) * (1.0 - mod_fraction)); |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// push the pointers forward
|
|
|
|
|
bp++; // next audio data
|
|
|
|
|
mp++; // next modulation data
|
|
|
|
|