|
|
|
@ -33,19 +33,19 @@ |
|
|
|
|
// Written by Pete (El Supremo) Jan 2014
|
|
|
|
|
// 140529 - change to handle mono stream - change modify() to voices()
|
|
|
|
|
// 140219 - correct storage class (not static)
|
|
|
|
|
// 190527 - adding modulation input (by Holger Wirtz)
|
|
|
|
|
// 190527 - added modulation input handling (by Holger Wirtz)
|
|
|
|
|
|
|
|
|
|
boolean AudioModulatedEffectChorus::begin(short *delayline, int d_length) |
|
|
|
|
boolean AudioEffectModulatedDelay::begin(short *delayline, int d_length) |
|
|
|
|
{ |
|
|
|
|
#if 0 |
|
|
|
|
Serial.print("AudioModulatedEffectChorus.begin(Chorus delay line length = "); |
|
|
|
|
Serial.print("AudioEffectModulatedDelay.begin(Chorus delay line length = "); |
|
|
|
|
Serial.print(d_length); |
|
|
|
|
Serial.println(")"); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
l_delayline = NULL; |
|
|
|
|
delay_length = 0; |
|
|
|
|
l_circ_idx = 0; |
|
|
|
|
_delayline = NULL; |
|
|
|
|
_delay_length = 0; |
|
|
|
|
_circ_idx = 0; |
|
|
|
|
|
|
|
|
|
if (delayline == NULL) { |
|
|
|
|
return (false); |
|
|
|
@ -54,43 +54,47 @@ boolean AudioModulatedEffectChorus::begin(short *delayline, int d_length) |
|
|
|
|
return (false); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
l_delayline = delayline; |
|
|
|
|
delay_length = d_length; |
|
|
|
|
delay_length_half = d_length / 2; |
|
|
|
|
_delayline = delayline; |
|
|
|
|
_delay_length = d_length; |
|
|
|
|
_delay_length_half = d_length / 2; |
|
|
|
|
|
|
|
|
|
memset(_delayline, 0, sizeof(short)*_delay_length); |
|
|
|
|
|
|
|
|
|
return (true); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//int last_idx = 0;
|
|
|
|
|
void AudioModulatedEffectChorus::update(void) |
|
|
|
|
void AudioEffectModulatedDelay::update(void) |
|
|
|
|
{ |
|
|
|
|
audio_block_t *block; |
|
|
|
|
audio_block_t *modulation; |
|
|
|
|
|
|
|
|
|
short *bp; |
|
|
|
|
short *mp; |
|
|
|
|
float mod_idx; |
|
|
|
|
|
|
|
|
|
if (_delayline == NULL) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
#ifdef INTERPOLATE |
|
|
|
|
interpolation* modulation_interpolate; |
|
|
|
|
modulation_interpolate = new interpolation; |
|
|
|
|
interpolation modulation_interpolate; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
if (l_delayline == NULL) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
block = receiveWritable(0); |
|
|
|
|
modulation = receiveReadOnly(1); |
|
|
|
|
|
|
|
|
|
if (block && modulation) |
|
|
|
|
{ |
|
|
|
|
#ifdef INTERPOLATE |
|
|
|
|
uint8_t j; |
|
|
|
|
int16_t interpolation_idx; |
|
|
|
|
int8_t j; |
|
|
|
|
float x[INTERPOLATION_WINDOW_SIZE]; |
|
|
|
|
float y[INTERPOLATION_WINDOW_SIZE]; |
|
|
|
|
modulation_interpolate->valuelenXY(INTERPOLATION_WINDOW_SIZE); |
|
|
|
|
modulation_interpolate->valueX(x); |
|
|
|
|
modulation_interpolate->valueY(y); |
|
|
|
|
modulation_interpolate.valuelenXY(INTERPOLATION_WINDOW_SIZE); |
|
|
|
|
modulation_interpolate.valueX(x); |
|
|
|
|
modulation_interpolate.valueY(y); |
|
|
|
|
|
|
|
|
|
for (j = 0; j < INTERPOLATION_WINDOW_SIZE; j++) |
|
|
|
|
x[j] = j; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
bp = block->data; |
|
|
|
@ -99,54 +103,56 @@ void AudioModulatedEffectChorus::update(void) |
|
|
|
|
for (int i = 0; i < AUDIO_BLOCK_SAMPLES; i++) |
|
|
|
|
{ |
|
|
|
|
// write data into circular buffer
|
|
|
|
|
if (l_circ_idx >= delay_length) |
|
|
|
|
l_circ_idx = 0; |
|
|
|
|
l_delayline[l_circ_idx] = *bp; // write signal into circular buffer
|
|
|
|
|
if (_circ_idx >= _delay_length) |
|
|
|
|
_circ_idx = 0; |
|
|
|
|
_delayline[_circ_idx] = *bp; |
|
|
|
|
|
|
|
|
|
// calculate modulation index
|
|
|
|
|
mod_idx = float(*mp) / SHRT_MAX * delay_length_half + l_circ_idx; // calculate index with modulation as a float
|
|
|
|
|
if (mod_idx > float(delay_length - 1)) |
|
|
|
|
mod_idx = mod_idx - float(delay_length - 1); |
|
|
|
|
mod_idx = float(*mp) / SHRT_MAX * _delay_length_half + _circ_idx; // calculate index with modulation as a float(!!!)
|
|
|
|
|
if (mod_idx > float(_delay_length - 1)) |
|
|
|
|
mod_idx = mod_idx - float(_delay_length - 1); |
|
|
|
|
else if (mod_idx < 0.0) |
|
|
|
|
mod_idx = float(delay_length - 1) + mod_idx; |
|
|
|
|
mod_idx = float(_delay_length - 1) + mod_idx; |
|
|
|
|
|
|
|
|
|
#ifdef INTERPOLATE |
|
|
|
|
// get value with interpolation
|
|
|
|
|
interpolation_idx = int(mod_idx + 0.5) + (INTERPOLATION_WINDOW_SIZE / -2); |
|
|
|
|
for (j = interpolation_idx; j < INTERPOLATION_WINDOW_SIZE; j++) |
|
|
|
|
// get x/y values around mod_idx
|
|
|
|
|
uint16_t i_mod_idx = int(mod_idx + 0.5); |
|
|
|
|
for (j = INTERPOLATION_WINDOW_SIZE / -2; j <= INTERPOLATION_WINDOW_SIZE / 2; j++) |
|
|
|
|
{ |
|
|
|
|
x[j] = interpolation_idx; |
|
|
|
|
|
|
|
|
|
if (j >= delay_length) |
|
|
|
|
y[j] = l_delayline[j - delay_length]; |
|
|
|
|
else if (j < 0) |
|
|
|
|
y[j] = l_delayline[delay_length + j]; |
|
|
|
|
int16_t ji_mod_idx = i_mod_idx + j; |
|
|
|
|
if (ji_mod_idx > _delay_length) |
|
|
|
|
y[j] = _delayline[ji_mod_idx - _delay_length - 1]; |
|
|
|
|
else if (ji_mod_idx < 0) |
|
|
|
|
y[j] = _delayline[_delay_length + j + 1]; |
|
|
|
|
else |
|
|
|
|
y[j] = _delayline[ji_mod_idx]; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
modulation_interpolate->valueI(mod_idx); |
|
|
|
|
modulation_interpolate.valueI(mod_idx); |
|
|
|
|
|
|
|
|
|
#if INTERPOLATE == CUBIC |
|
|
|
|
*bp = int(modulation_interpolate->CubicInterpolate() + 0.5); |
|
|
|
|
*bp = int(modulation_interpolate.CubicInterpolate() + 0.5); |
|
|
|
|
#elif INTERPOLATE == LINEAR |
|
|
|
|
*bp = int(modulation_interpolate->LinearInterpolate() + 0.5); |
|
|
|
|
*bp = int(modulation_interpolate.LinearInterpolate() + 0.5); |
|
|
|
|
#elif INTERPOLATE == COSINE |
|
|
|
|
*bp = int(modulation_interpolate->CosineInterpolate() + 0.5); |
|
|
|
|
*bp = int(modulation_interpolate.CosineInterpolate() + 0.5); |
|
|
|
|
#elif INTERPOLATE == LAGRANGE |
|
|
|
|
*bp = int(modulation_interpolate->LagrangeInterpolate() + 0.5); |
|
|
|
|
*bp = int(modulation_interpolate.LagrangeInterpolate() + 0.5); |
|
|
|
|
#elif INTERPOLATE == QUDRATIC |
|
|
|
|
*bp = int(modulation_interpolate->QuadraticInterpolate() + 0.5); |
|
|
|
|
*bp = int(modulation_interpolate.QuadraticInterpolate() + 0.5); |
|
|
|
|
#else |
|
|
|
|
// No interpolation - should sound really bad...
|
|
|
|
|
*bp = l_delayline[int(mod_idx + 0.5)]; |
|
|
|
|
*bp = _delayline[int(mod_idx + 0.5)]; |
|
|
|
|
#endif |
|
|
|
|
#else |
|
|
|
|
// No interpolation - should sound really bad...
|
|
|
|
|
*bp = l_delayline[int(mod_idx + 0.5)]; |
|
|
|
|
*bp = _delayline[int(mod_idx + 0.5)]; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
bp++; |
|
|
|
|
mp++; |
|
|
|
|
l_circ_idx++; |
|
|
|
|
_circ_idx++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// transmit the block
|
|
|
|
@ -154,9 +160,3 @@ void AudioModulatedEffectChorus::update(void) |
|
|
|
|
release(block); |
|
|
|
|
release(modulation); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
#ifdef INTERPOLATION |
|
|
|
|
if (modulation_interpolate) |
|
|
|
|
delete(modulation_interpolate); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|