Changed chorus mix-in.

Small fixes for interpolation.
master
Holger Wirtz 5 years ago
parent 78aac5e8a9
commit 3f5f754460
  1. 4
      UI.hpp
  2. 4
      config.h
  3. 42
      effect_modulated_delay.cpp

@ -2068,7 +2068,9 @@ void set_chorus_level(uint8_t value)
Serial.print(F("Set CHORUS_LEVEL ")); Serial.print(F("Set CHORUS_LEVEL "));
Serial.println(value); Serial.println(value);
#endif #endif
float tmp = mapfloat(float(value), ENC_CHORUS_LEVEL_MIN, ENC_CHORUS_LEVEL_MAX, 0.0, 1.0); float tmp = mapfloat(float(value), ENC_CHORUS_LEVEL_MIN, ENC_CHORUS_LEVEL_MAX, 0.0, 0.5);
mixer_r.gain(0, 1.0-tmp);
mixer_l.gain(0, 1.0-tmp);
mixer_r.gain(2, tmp); mixer_r.gain(2, tmp);
mixer_l.gain(2, tmp); mixer_l.gain(2, tmp);
configuration.chorus_level = value; configuration.chorus_level = value;

@ -55,9 +55,9 @@
#define REDUCE_LOUDNESS 0 #define REDUCE_LOUDNESS 0
#define USE_XFADE_DATA 1 #define USE_XFADE_DATA 1
// CHORUS parameters // 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_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_WAVEFORM WAVEFORM_TRIANGLE // WAVEFORM_SINE WAVEFORM_TRIANGLE WAVEFORM_SAWTOOTH WAVEFORM_SAWTOOTH_REVERSE
#define CHORUS_MODULATOR_FILTER_FRQ 500 #define CHORUS_MODULATOR_FILTER_FRQ 50 // see https://www.earlevel.com/main/2013/10/13/biquad-calculator-v2/
#define CHORUS_MODULATOR_FILTER_Q 0.7 #define CHORUS_MODULATOR_FILTER_Q 0.7
//************************************************************************************************* //*************************************************************************************************

@ -23,7 +23,7 @@
#include <Arduino.h> #include <Arduino.h>
#include <Audio.h> #include <Audio.h>
#include "limits.h" #include "arm_math.h"
#include "effect_modulated_delay.h" #include "effect_modulated_delay.h"
#include "config.h" #include "config.h"
@ -73,50 +73,54 @@ void AudioEffectModulatedDelay::update(void)
block = receiveWritable(0); block = receiveWritable(0);
modulation = receiveReadOnly(1); modulation = receiveReadOnly(1);
if (block && modulation) if (block && modulation && _modulation_intensity > 0.1)
{ {
int16_t *bp; int16_t *bp;
int16_t *mp; float *mp;
float mod_idx; float mod_idx;
float mod_number; float mod_number;
float mod_fraction; float mod_fraction;
float mod_float[AUDIO_BLOCK_SAMPLES];
bp = block->data; bp = block->data;
mp = modulation->data; arm_q15_to_float(modulation->data, mod_float, AUDIO_BLOCK_SAMPLES);
mp = mod_float;
for (uint16_t i = 0; i < AUDIO_BLOCK_SAMPLES; i++) for (uint16_t i = 0; i < AUDIO_BLOCK_SAMPLES; i++)
{ {
// write data into circular buffer // write data into circular buffer (delayline)
if (_circ_idx >= _delay_length) if (_circ_idx >= _delay_length)
_circ_idx = 0; _circ_idx = 0;
_delayline[_circ_idx] = *bp; _delayline[_circ_idx] = *bp;
// Calculate the modulation-index as a floating point number fo later interpolation // Calculate the modulation-index as a floating point number for interpolation
mod_idx = _delay_offset + ((float(*mp) / SHRT_MAX) * _modulation_intensity); mod_idx = _delay_offset + (*mp * _modulation_intensity);
mod_fraction = modff(mod_idx, &mod_number); mod_fraction = modff(mod_idx, &mod_number);
// linear interpolation // calculate modulation index into circular buffer
c_mod_idx = _circ_idx - round(mod_idx); c_mod_idx = (_circ_idx - int(mod_number)) % _delay_length;
c_mod_idx %= _delay_length;
if (c_mod_idx < 0) // check for negative offsets and correct them if (c_mod_idx < 0) // check for negative offsets and correct them
c_mod_idx += _delay_length; c_mod_idx += _delay_length;
if (c_mod_idx - 1 < 0)
// linear interpolation
if (c_mod_idx < 1)
{ {
idx[0] = 0; idx[0] = _delay_length - 1;
idx[1] = _delay_length - 1; idx[1] = 0;
} }
else if (c_mod_idx + 1 >= _delay_length) else if (c_mod_idx + 1 >= _delay_length)
{ {
idx[0] = c_mod_idx; idx[0] = 0;
idx[1] = 0; idx[1] = c_mod_idx;
} }
else else
{ {
idx[0] = c_mod_idx; idx[0] = c_mod_idx + 1;
idx[1] = 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)); *bp = round(float(_delayline[idx[0]]) * (mod_fraction) + float(_delayline[idx[1]]) * (1.0 - mod_fraction));
// push the pointers forward
bp++; // next audio data bp++; // next audio data
mp++; // next modulation data mp++; // next modulation data
_circ_idx++; // next circular buffer index _circ_idx++; // next circular buffer index
@ -133,7 +137,7 @@ void AudioEffectModulatedDelay::update(void)
} }
} }
float AudioEffectModulatedDelay::offset(float offset_value) float AudioEffectModulatedDelay::offset(float offset_value) // in ms
{ {
uint16_t offset_frames = (offset_value / 1000) * AUDIO_SAMPLE_RATE; uint16_t offset_frames = (offset_value / 1000) * AUDIO_SAMPLE_RATE;
if (offset_frames > _delay_length * MODULATION_MAX_FACTOR) if (offset_frames > _delay_length * MODULATION_MAX_FACTOR)

Loading…
Cancel
Save