master
Holger Wirtz 5 years ago
parent 1356774e8e
commit 2989ea2eac
  1. 7
      MicroMDAEPiano.ino
  2. 7
      config.h
  3. 32
      effect_modulated_delay.cpp
  4. 10
      effect_modulated_delay.h

@ -57,16 +57,14 @@ AudioAmplifier inverter;
AudioEffectModulatedDelay modchorus_r;
AudioEffectModulatedDelay modchorus_l;
AudioSynthWaveform modulator;
AudioFilterBiquad modulator_filter;
AudioConnection patchCord0(queue_r, peak_r);
AudioConnection patchCord1(queue_l, peak_l);
AudioConnection patchCord2(queue_r, freeverb_r);
AudioConnection patchCord3(queue_l, freeverb_l);
AudioConnection patchCord4(queue_r, 0, modchorus_r, 0);
AudioConnection patchCord5(queue_l, 0, modchorus_l, 0);
AudioConnection patchCord6(modulator, modulator_filter);
AudioConnection patchCord7(modulator_filter, 0, modchorus_r, 1);
AudioConnection patchCord8(modulator_filter, inverter);
AudioConnection patchCord6(modulator, 0, modchorus_r, 1);
AudioConnection patchCord8(modulator, inverter);
AudioConnection patchCord9(inverter, 0, modchorus_l, 1);
AudioConnection patchCord10(queue_r, 0, mixer_r, 0);
AudioConnection patchCord11(queue_l, 0, mixer_l, 0);
@ -235,7 +233,6 @@ void setup()
modulator.phase(0);
modulator.amplitude(1.0);
modulator.offset(0.0);
modulator_filter.setLowpass(0, CHORUS_MODULATOR_FILTER_FRQ, CHORUS_MODULATOR_FILTER_Q);
inverter.gain(-1.0); // change phase for second modulated delay (faked stereo mode)
modchorus_r.offset(15.0);
modchorus_l.offset(15.0);

@ -57,9 +57,10 @@
// CHORUS parameters
#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 10 // see https://www.earlevel.com/main/2013/10/13/biquad-calculator-v2/
#define CHORUS_MODULATOR_FILTER_Q 0.7
//#define CHORUS_MODULATOR_FILTER_FRQ 10 // see https://www.earlevel.com/main/2013/10/13/biquad-calculator-v2/
//#define CHORUS_MODULATOR_FILTER_Q 0.7
#define CHORUS_MODULATOR_BIQUAD 1
//#define CHORUS_OUTPUT_BIQUAD 1
//*************************************************************************************************
//* DEBUG OUTPUT SETTINGS
//*************************************************************************************************

@ -58,6 +58,22 @@ boolean AudioEffectModulatedDelay::begin(short *delayline, int d_length)
_delayline = delayline;
_delay_length = d_length;
#ifdef CHORUS_MODULATOR_BIQUAD
mod_lp_coeffs[0] = -1.98982427; // https://arachnoid.com/BiQuadDesigner/ Lopass Fc=50Hz, Q=0.7
mod_lp_coeffs[1] = 0.98987476;
mod_lp_coeffs[2] = 1.26228228e-5;
mod_lp_coeffs[3] = 2.52456456e-5;
mod_lp_coeffs[4] = 1.26228228e-5;
biquad_mod = {1, mod_lp_state, mod_lp_coeffs};
#endif
#ifdef CHORUS_OUTUT_BIQUAD // https://web.fhnw.ch/technik/projekte/eit/Fruehling2016/MuelZum/html/parametric__equalizer__example_8c_source.html
out_lp_coeffs[0] = -0.10987036; // https://arachnoid.com/BiQuadDesigner/ Lopass Fc=10000Hz, Q=0.3
out_lp_coeffs[1] = -0.24497694;
out_lp_coeffs[2] = 0.16128817;
out_lp_coeffs[3] = 0.32257635;
out_lp_coeffs[4] = 0.16128817;
biquad_out = {1, out_lp_state, out_lp_coeffs, 0};
#endif
return (true);
}
@ -84,6 +100,9 @@ void AudioEffectModulatedDelay::update(void)
bp = block->data;
arm_q15_to_float(modulation->data, mod_float, AUDIO_BLOCK_SAMPLES);
mp = mod_float;
#ifdef CHORUS_MODULATOR_BIQUAD
arm_biquad_cascade_df1_f32(&biquad_mod, mod_float, mod_float, AUDIO_BLOCK_SAMPLES);
#endif
for (uint16_t i = 0; i < AUDIO_BLOCK_SAMPLES; i++)
{
@ -93,11 +112,11 @@ void AudioEffectModulatedDelay::update(void)
_delayline[_circ_idx] = *bp;
// Calculate the modulation-index as a floating point number for interpolation
mod_idx = _delay_offset + (*mp * (1 - MODULATION_MAX_FACTOR) * _delay_length);
mod_idx = *mp * (1 - MODULATION_MAX_FACTOR) * _delay_length;
mod_fraction = modff(mod_idx, &mod_number);
// calculate modulation index into circular buffer
c_mod_idx = (_circ_idx - int(mod_number)) % _delay_length;
c_mod_idx = (_circ_idx - _delay_offset - int(mod_number)) % _delay_length;
if (c_mod_idx < 0) // check for negative offsets and correct them
c_mod_idx += _delay_length;
@ -117,7 +136,11 @@ void AudioEffectModulatedDelay::update(void)
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));
if (mod_idx < 0.0)
*bp = round(float(_delayline[idx[0]]) * (mod_fraction) + float(_delayline[idx[1]]) * (1.0 - mod_fraction));
else
*bp = round(float(_delayline[idx[0]]) * (1.0 - mod_fraction) + float(_delayline[idx[1]]) * mod_fraction);
// push the pointers forward
bp++; // next audio data
@ -131,6 +154,9 @@ void AudioEffectModulatedDelay::update(void)
if (block)
{
#ifdef CHORUS_OUTPUT_BIQUAD
arm_biquad_cascade_df1_fast_q15(&biquad_out, (q15_t*)block, (q15_t*)block, AUDIO_BLOCK_SAMPLES);
#endif
transmit(block, 0);
release(block);
}

@ -56,6 +56,16 @@ class AudioEffectModulatedDelay :
uint16_t _delay_length;
int16_t c_mod_idx;
uint16_t idx[2];
#ifdef CHORUS_MODULATOR_BIQUAD
arm_biquad_casd_df1_inst_f32 biquad_mod;
float mod_lp_state[2];
float mod_lp_coeffs[5];
#endif
#ifdef CHORUS_OUTPUT_BIQUAD
arm_biquad_casd_df1_inst_q15 biquad_out;
float out_lp_state[2];
float out_lp_coeffs[5];
#endif
};
#endif

Loading…
Cancel
Save