From 5c987723d646b19bedbdb3cb24f8e9f1f620f573 Mon Sep 17 00:00:00 2001 From: Holger Wirtz Date: Mon, 17 Jun 2019 11:42:18 +0200 Subject: [PATCH] Fixed rounding of floats for working with negative numbers. --- config.h | 2 +- effect_modulated_delay.cpp | 38 ++++++++++++-------------------------- 2 files changed, 13 insertions(+), 27 deletions(-) diff --git a/config.h b/config.h index 2b80ebc..ebf74a8 100644 --- a/config.h +++ b/config.h @@ -57,7 +57,7 @@ #define USE_XFADE_DATA 1 // CHORUS parameters #define INTERPOLATION_WINDOW_SIZE 21 // use only odd numbers!!! -#define INTERPOLATE_MODE 11 +//#define INTERPOLATE_MODE 11 #define CHORUS_WAVEFORM WAVEFORM_SINE // WAVEFORM_SINE WAVEFORM_TRIANGLE WAVEFORM_SAWTOOTH WAVEFORM_SAWTOOTH_REVERSE #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! diff --git a/effect_modulated_delay.cpp b/effect_modulated_delay.cpp index 6d738c1..c0e06f1 100644 --- a/effect_modulated_delay.cpp +++ b/effect_modulated_delay.cpp @@ -87,7 +87,8 @@ void AudioEffectModulatedDelay::update(void) if (block && modulation) { - float _tmp; + float mod_number; + float mod_fraction; for (uint16_t i = 0; i < AUDIO_BLOCK_SAMPLES; i++) { @@ -99,11 +100,12 @@ void AudioEffectModulatedDelay::update(void) // Calculate modulation index as a float, for interpolation later. // The index is located around the half of the delay length multiplied by the current amount of the modulator mod_idx = float(*mp) / SHRT_MAX * float(_delay_length >> 1); + mod_fraction = modff(mod_idx, &mod_number); #ifdef INTERPOLATE_MODE // Generate a an array with the size of INTERPOLATION_WINDOW_SIZE of x/y values around mod_idx for interpolation uint8_t c; - int16_t c_mod_idx = _circ_idx - int(mod_idx + 0.5); // This is the pointer to the value in the circular buffer at the current modulation index + 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 for (j = ~(INTERPOLATION_WINDOW_SIZE >> 1) | 0x01, c = 0; j <= INTERPOLATION_WINDOW_SIZE >> 1; j++, c++) // only another way to say: from -INTERPOLATION_WINDOW_SIZE/2 to INTERPOLATION_WINDOW_SIZE/2 { int16_t jc_mod_idx = (c_mod_idx + j) % _delay_length; // The modulation index pointer plus the value of the current window pointer @@ -113,39 +115,23 @@ void AudioEffectModulatedDelay::update(void) y[c] = float(_delayline[jc_mod_idx]); x[c] = float(j); } - *bp = int(s.value(modff(mod_idx, &_tmp)) + 0.5); + *bp = int(round(s.value(mod_fraction))); #else // Simple interpolation - int16_t c_mod_idx = (_circ_idx - int(mod_idx + 0.5)) % _delay_length; - float fraction = modff(mod_idx, &_tmp); + int16_t c_mod_idx = (_circ_idx - int(round(mod_idx))) % _delay_length; float value1, value2; + if (c_mod_idx < 0) { - if (fraction < 0.5) - { - value1 = _delayline[_delay_length + c_mod_idx - 1]; - value2 = _delayline[_delay_length + c_mod_idx]; - } - else - { - value1 = _delayline[_delay_length + c_mod_idx]; - value2 = _delayline[_delay_length + c_mod_idx + 1]; - } + value1 = _delayline[_delay_length + c_mod_idx]; + value2 = _delayline[_delay_length + c_mod_idx - 1]; } else { - if (fraction < 0.5) - { - value1 = _delayline[c_mod_idx - 1]; - value2 = _delayline[c_mod_idx]; - } - else - { - value1 = _delayline[c_mod_idx]; - value2 = _delayline[c_mod_idx + 1]; - } + value1 = _delayline[c_mod_idx]; + value2 = _delayline[c_mod_idx - 1]; } - *bp = int ((fraction * value1) + ((1.0 - fraction) * value2) + 0.5); + *bp = mod_fraction * value1 + (1.0 - mod_fraction) * value2; #endif bp++; // next audio data