New try for linear interpolation.

Added a lowpass after chorus output.
master
Holger Wirtz 5 years ago
parent 0027b62530
commit 0e91d775f7
  1. 36
      MicroMDAEPiano.ino
  2. 6
      config.h
  3. 39
      effect_modulated_delay.cpp
  4. 3
      effect_modulated_delay.h

@ -58,6 +58,8 @@ AudioEffectModulatedDelay modchorus_r;
AudioEffectModulatedDelay modchorus_l;
AudioSynthWaveform modulator;
AudioFilterBiquad modulator_filter;
AudioFilterBiquad chorus_filter_r;
AudioFilterBiquad chorus_filter_l;
AudioConnection patchCord0(queue_r, peak_r);
AudioConnection patchCord1(queue_l, peak_l);
AudioConnection patchCord2(queue_r, freeverb_r);
@ -70,20 +72,24 @@ AudioConnection patchCord8(modulator_filter, inverter);
AudioConnection patchCord9(inverter, 0, modchorus_l, 1);
AudioConnection patchCord10(queue_r, 0, mixer_r, 0);
AudioConnection patchCord11(queue_l, 0, mixer_l, 0);
AudioConnection patchCord12(modchorus_r, 0, mixer_r, 2);
AudioConnection patchCord13(modchorus_l, 0, mixer_l, 2);
AudioConnection patchCord14(freeverb_r, 0, mixer_r, 1);
AudioConnection patchCord15(freeverb_l, 0, mixer_l, 1);
AudioConnection patchCord16(mixer_r, volume_r);
AudioConnection patchCord17(mixer_l, volume_l);
AudioConnection patchCord12(modchorus_r, chorus_filter_r);
AudioConnection patchCord13(modchorus_l, chorus_filter_l);
AudioConnection patchCord14(chorus_filter_r, 0, mixer_r, 2);
AudioConnection patchCord15(chorus_filter_l, 0, mixer_l, 2);
AudioConnection patchCord16(modchorus_r, 0, mixer_r, 2);
AudioConnection patchCord17(modchorus_l, 0, mixer_l, 2);
AudioConnection patchCord18(freeverb_r, 0, mixer_r, 1);
AudioConnection patchCord19(freeverb_l, 0, mixer_l, 1);
AudioConnection patchCord20(mixer_r, volume_r);
AudioConnection patchCord21(mixer_l, volume_l);
#ifdef USB_AUDIO
AudioOutputUSB usb1;
AudioConnection patchCord18(volume_r, 0, usb1, 0);
AudioConnection patchCord19(volume_l, 0, usb1, 1);
AudioConnection patchCord22(volume_r, 0, usb1, 0);
AudioConnection patchCord23(volume_l, 0, usb1, 1);
#endif
AudioOutputI2S i2s1;
AudioConnection patchCord20(volume_r, 0, i2s1, 0);
AudioConnection patchCord21(volume_l, 0, i2s1, 1);
AudioConnection patchCord24(volume_r, 0, i2s1, 0);
AudioConnection patchCord25(volume_l, 0, i2s1, 1);
AudioControlSGTL5000 sgtl5000_1;
// Objects
@ -238,8 +244,10 @@ void setup()
inverter.gain(-1.0); // change phase for second modulated delay (faked stereo mode)
modchorus_r.offset(15.0);
modchorus_r.intensity(1.0);
chorus_filter_r.setLowpass(0, 10000.0, CHORUS_MODULATOR_FILTER_Q);
modchorus_l.offset(15.0);
modchorus_l.intensity(1.0);
chorus_filter_l.setLowpass(0, 10000.0, CHORUS_MODULATOR_FILTER_Q);
// internal mixing of original signal(0), reverb(1) and chorus(2)
mixer_r.gain(VOL_MAIN, 0.5);
@ -255,12 +263,12 @@ void setup()
// init random generator
srand(analogRead(A0));
Serial.println(F("<setup end>"));
Serial.println(F("<setup end>"));
#if defined (SHOW_DEBUG) && defined (SHOW_CPU_LOAD_MSEC)
Serial.println();
show_cpu_and_mem_usage();
cpu_mem_millis = 0;
Serial.println();
show_cpu_and_mem_usage();
cpu_mem_millis = 0;
#endif
}

@ -58,12 +58,12 @@
// 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_WAVEFORM WAVEFORM_TRIANGLE // WAVEFORM_SINE WAVEFORM_TRIANGLE WAVEFORM_SAWTOOTH WAVEFORM_SAWTOOTH_REVERSE
#define CHORUS_MODULATOR_FILTER_FRQ 1000
#define CHORUS_MODULATOR_FILTER_FRQ 500
#define CHORUS_MODULATOR_FILTER_Q 0.7
//#define CHORUS_INTERPOLATION_MODE 0 // no interpolation
#define CHORUS_INTERPOLATION_MODE 1 // linear interpolation
//#define CHORUS_INTERPOLATION_MODE 1 // linear interpolation
//#define CHORUS_INTERPOLATION_MODE Catmull // spline interpolation
#define CHORUS_INTERPOLATION_WINDOW_SIZE 3 // only uneven numbers bigger than 3!!!
#define CHORUS_INTERPOLATION_WINDOW_SIZE 5 // only uneven numbers bigger than 3!!!
//*************************************************************************************************
//* DEBUG OUTPUT SETTINGS

@ -106,10 +106,10 @@ void AudioEffectModulatedDelay::update(void)
// The index is located around the half of the delay length multiplied by the current amount of the modulator
mod_idx = _delay_offset + ((float(*mp) / SHRT_MAX) * _modulation_intensity);
mod_fraction = modff(mod_idx, &mod_number);
#ifdef CHORUS_INTERPOLATION_MODE
// Spline interpolation
// Generate a an array with the size of CHORUS_INTERPOLATION_WINDOW_SIZE of x/y values around mod_idx for interpolation
int16_t c_mod_idx = _circ_idx - int(round(mod_idx)); // This is the pointer to the value in the circular buffer at the current modulation index
#ifdef CHORUS_INTERPOLATION_MODE
// spline interpolation
c_mod_idx = _circ_idx - int(mod_idx); // This is the pointer to the value in the circular buffer at the current modulation index
for (j = (CHORUS_INTERPOLATION_WINDOW_SIZE / -2), c = 0; j <= (CHORUS_INTERPOLATION_WINDOW_SIZE / 2); j++, c++)
{
int16_t jc_mod_idx = (c_mod_idx + j) % _delay_length; // The modulation index pointer plus the value of the current window pointer
@ -121,26 +121,29 @@ void AudioEffectModulatedDelay::update(void)
}
*bp = int(round(spline->value(mod_fraction))); // use spline interpolated value
#else
// Simple interpolation
int16_t c_mod_idx = (_circ_idx + int(round(mod_idx))) % _delay_length;
float value1, value2;
if (c_mod_idx < 0)
// linear interpolation
c_mod_idx = _circ_idx - round(mod_idx);
if (mod_idx < 0.0) // c_mod_idx is the pointer to the value in the circular buffer at the current modulation index
c_mod_idx--;
c_mod_idx %= _delay_length; // The modulation index pointer plus the value of the current window pointer
if (c_mod_idx < 0) // check for negative offsets and correct them
c_mod_idx += _delay_length;
if (c_mod_idx - 1 < 0)
{
value1 = _delayline[_delay_length + c_mod_idx - 1];
value2 = _delayline[_delay_length + c_mod_idx];
idx[0] = 0;
idx[1] = _delay_length - 1;
}
else
else if (c_mod_idx + 1 >= _delay_length)
{
value1 = _delayline[c_mod_idx - 1];
value2 = _delayline[c_mod_idx];
idx[0] = c_mod_idx;
idx[1] = 0;
}
if (mod_fraction < 0)
*bp = int(round((1.0 + mod_fraction) * value1 + fabs(mod_fraction) * value2));
else
*bp = int(round(mod_fraction * value1 + (1.0 - mod_fraction) * value2));
{
idx[0] = c_mod_idx;
idx[1] = c_mod_idx + 1;
}
*bp = round(float(_delayline[idx[0]]) * (1.0 - mod_fraction) + float(_delayline[idx[1]]) * mod_fraction);
#endif
bp++; // next audio data
mp++; // next modulation data

@ -56,10 +56,13 @@ class AudioEffectModulatedDelay :
uint16_t _delay_offset;
uint16_t _modulation_intensity;
uint16_t _delay_length;
int16_t c_mod_idx;
#ifdef CHORUS_INTERPOLATION_MODE
float x[CHORUS_INTERPOLATION_WINDOW_SIZE];
float y[CHORUS_INTERPOLATION_WINDOW_SIZE];
Spline* spline;
#else
uint16_t idx[2];
#endif
};

Loading…
Cancel
Save