parent
2b6ebae664
commit
6eef3f9107
@ -0,0 +1,204 @@ |
|||||||
|
/* Stereo Ping Pong delay for Teensy 4
|
||||||
|
* |
||||||
|
* Author: Piotr Zapart |
||||||
|
* www.hexefx.com |
||||||
|
* |
||||||
|
* Copyright (c) 2024 by Piotr Zapart |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
* of this software and associated documentation files (the "Software"), to deal |
||||||
|
* in the Software without restriction, including without limitation the rights |
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
* copies of the Software, and to permit persons to whom the Software is |
||||||
|
* furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice shall be included in all |
||||||
|
* copies or substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||||
|
* SOFTWARE. |
||||||
|
*/ |
||||||
|
#include "effect_delaystereo.h" |
||||||
|
|
||||||
|
#define TREBLE_LOSS_FREQ (0.20f) |
||||||
|
#define BASS_LOSS_FREQ (0.05f) |
||||||
|
#define BASS_FREQ (0.15f) |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AudioEffectDelayStereo_F32::AudioEffectDelayStereo_F32(uint32_t dly_range_ms, bool use_psram) : AudioStream_F32(2, inputQueueArray) |
||||||
|
{ |
||||||
|
psram_mode = use_psram; |
||||||
|
bool memOk = true; |
||||||
|
dly_length = ((float32_t)(dly_range_ms+500)/1000.0f) * AUDIO_SAMPLE_RATE_EXACT;
|
||||||
|
if (!dly0a.init(dly_length, use_psram)) memOk = false; |
||||||
|
if (!dly0b.init(dly_length, use_psram)) memOk = false; |
||||||
|
if (!dly1a.init(dly_length, use_psram)) memOk = false; |
||||||
|
if (!dly1b.init(dly_length, use_psram)) memOk = false; |
||||||
|
flt0L.init(BASS_LOSS_FREQ, &bassCut_k, TREBLE_LOSS_FREQ, &trebleCut_k); |
||||||
|
flt1L.init(BASS_LOSS_FREQ, &bass_k, TREBLE_LOSS_FREQ, &treble_k); |
||||||
|
flt0R.init(BASS_LOSS_FREQ, &bassCut_k, TREBLE_LOSS_FREQ, &trebleCut_k); |
||||||
|
flt1R.init(BASS_LOSS_FREQ, &bass_k, TREBLE_LOSS_FREQ, &treble_k); |
||||||
|
mix(0.5f); |
||||||
|
feedback(0.5f); |
||||||
|
cleanup_done = true; |
||||||
|
if (memOk) initialized = true; |
||||||
|
} |
||||||
|
|
||||||
|
void AudioEffectDelayStereo_F32::update() |
||||||
|
{ |
||||||
|
if (!initialized) return; |
||||||
|
if (!memsetup_done) |
||||||
|
{ |
||||||
|
dly0a.reset(); |
||||||
|
dly0b.reset(); |
||||||
|
dly1a.reset(); |
||||||
|
dly1b.reset(); |
||||||
|
memsetup_done = true; |
||||||
|
return;
|
||||||
|
} |
||||||
|
|
||||||
|
audio_block_f32_t *blockL, *blockR; |
||||||
|
int i; |
||||||
|
float32_t acc1, acc2, outL, outR, mod_fr[4]; |
||||||
|
uint32_t mod_int; |
||||||
|
static float32_t dly_time_flt = 0.0f; |
||||||
|
|
||||||
|
if (bp) |
||||||
|
{ |
||||||
|
if (!cleanup_done) |
||||||
|
{ |
||||||
|
dly0a.reset(); |
||||||
|
dly0b.reset(); |
||||||
|
dly1a.reset(); |
||||||
|
dly1b.reset(); |
||||||
|
cleanup_done = true; |
||||||
|
tap_active = false; // reset tap tempo
|
||||||
|
tap_counter = 0; |
||||||
|
} |
||||||
|
if (dry_gain > 0.0f) // if dry/wet mixer is used
|
||||||
|
{ |
||||||
|
blockL = AudioStream_F32::receiveReadOnly_f32(0); |
||||||
|
blockR = AudioStream_F32::receiveReadOnly_f32(1); |
||||||
|
if (!blockL || !blockR)
|
||||||
|
{ |
||||||
|
if (blockL) AudioStream_F32::release(blockL); |
||||||
|
if (blockR) AudioStream_F32::release(blockR); |
||||||
|
return; |
||||||
|
} |
||||||
|
AudioStream_F32::transmit(blockL, 0);
|
||||||
|
AudioStream_F32::transmit(blockR, 1); |
||||||
|
AudioStream_F32::release(blockL); |
||||||
|
AudioStream_F32::release(blockR); |
||||||
|
return; |
||||||
|
} |
||||||
|
blockL = AudioStream_F32::allocate_f32(); |
||||||
|
if (!blockL) return; |
||||||
|
memset(&blockL->data[0], 0, blockL->length*sizeof(float32_t)); |
||||||
|
AudioStream_F32::transmit(blockL, 0);
|
||||||
|
AudioStream_F32::transmit(blockL, 1); |
||||||
|
AudioStream_F32::release(blockL);
|
||||||
|
return; |
||||||
|
} |
||||||
|
cleanup_done = false; |
||||||
|
blockL = AudioStream_F32::receiveWritable_f32(0); |
||||||
|
blockR = AudioStream_F32::receiveWritable_f32(1); |
||||||
|
if (!blockL || !blockR) |
||||||
|
{ |
||||||
|
if (blockL) |
||||||
|
AudioStream_F32::release(blockL); |
||||||
|
if (blockR) |
||||||
|
AudioStream_F32::release(blockR); |
||||||
|
return; |
||||||
|
} |
||||||
|
for (i=0; i < blockL->length; i++)
|
||||||
|
{
|
||||||
|
// tap tempo
|
||||||
|
if (tap_active) |
||||||
|
{ |
||||||
|
if (++tap_counter > tap_counter_max) |
||||||
|
{ |
||||||
|
tap_active = false; |
||||||
|
tap_counter = 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (dly_time < dly_time_set) |
||||||
|
{ |
||||||
|
dly_time += dly_time_step; |
||||||
|
if (dly_time > dly_time_set) dly_time = dly_time_set; |
||||||
|
} |
||||||
|
if (dly_time > dly_time_set) |
||||||
|
{ |
||||||
|
dly_time -= dly_time_step; |
||||||
|
if (dly_time < dly_time_set) dly_time = dly_time_set; |
||||||
|
} |
||||||
|
// lowpass the dely time
|
||||||
|
acc1 = dly_time - dly_time_flt; |
||||||
|
dly_time_flt += acc1 * 0.1f; |
||||||
|
dly_time = dly_time_flt; |
||||||
|
|
||||||
|
lfo.update(); |
||||||
|
|
||||||
|
lfo.get(BASIC_LFO_PHASE_0, &mod_int, &mod_fr[0]); |
||||||
|
mod_fr[0] = (float32_t)mod_int + mod_fr[0]; |
||||||
|
acc2 = (float32_t)dly_length - 1.0f - (dly_time + mod_fr[0]); |
||||||
|
if (acc2 < 0.0f) mod_fr[0] += acc2; |
||||||
|
|
||||||
|
lfo.get(BASIC_LFO_PHASE_60, &mod_int, &mod_fr[1]); |
||||||
|
mod_fr[1] = (float32_t)mod_int + mod_fr[1]; |
||||||
|
acc2 = (float32_t)dly_length - 1.0f - (dly_time + mod_fr[1]); |
||||||
|
if (acc2 < 0.0f) mod_fr[1] += acc2; |
||||||
|
|
||||||
|
lfo.get(BASIC_LFO_PHASE_120, &mod_int, &mod_fr[2]); |
||||||
|
mod_fr[2] = (float32_t)mod_int + mod_fr[2]; |
||||||
|
acc2 = (float32_t)dly_length - 1.0f - (dly_time + mod_fr[2]); |
||||||
|
if (acc2 < 0.0f) mod_fr[2] += acc2;
|
||||||
|
|
||||||
|
lfo.get(BASIC_LFO_PHASE_180, &mod_int, &mod_fr[3]); |
||||||
|
mod_fr[3] = (float32_t)mod_int + mod_fr[3];
|
||||||
|
acc2 = (float32_t)dly_length - 1.0f - (dly_time + mod_fr[3]); |
||||||
|
if (acc2 < 0.0f) mod_fr[3] += acc2;
|
||||||
|
|
||||||
|
float32_t idx = dly_time + mod_fr[0]; |
||||||
|
if (idx > maxV) maxV = idx; |
||||||
|
if (idx < minV) minV = idx; |
||||||
|
|
||||||
|
acc1 = dly0b.getTapHermite(dly_time+mod_fr[0]); |
||||||
|
outR = acc1 * 0.6f; |
||||||
|
acc1 = flt0R.process(acc1) * feedb; |
||||||
|
acc1 += blockR->data[i] * input_attn; |
||||||
|
acc1 = flt1R.process(acc1); |
||||||
|
acc2 = dly0a.getTapHermite(dly_time+mod_fr[1]); |
||||||
|
dly0b.write_toOffset(acc2, 0); |
||||||
|
outL = acc2 * 0.6f; |
||||||
|
dly0a.write_toOffset(acc1, 0); |
||||||
|
|
||||||
|
acc1 = dly1b.getTapHermite(dly_time+mod_fr[2]); |
||||||
|
outR += acc1 * 0.6f; |
||||||
|
acc1 = flt0L.process(acc1) * feedb; |
||||||
|
acc1 += blockL->data[i] * input_attn; |
||||||
|
acc1 = flt1L.process(acc1); |
||||||
|
acc2 = dly1a.getTapHermite(dly_time+mod_fr[3]); |
||||||
|
dly1b.write_toOffset(acc2, 0); |
||||||
|
outL += acc2 * 0.6f; |
||||||
|
dly1a.write_toOffset(acc1, 0); |
||||||
|
|
||||||
|
dly0a.updateIndex(); |
||||||
|
dly0b.updateIndex(); |
||||||
|
dly1a.updateIndex(); |
||||||
|
dly1b.updateIndex(); |
||||||
|
blockL->data[i] = outL * wet_gain + blockL->data[i] * dry_gain; |
||||||
|
blockR->data[i] = outR * wet_gain + blockR->data[i] * dry_gain; |
||||||
|
|
||||||
|
} |
||||||
|
AudioStream_F32::transmit(blockL, 0); |
||||||
|
AudioStream_F32::transmit(blockR, 1); |
||||||
|
AudioStream_F32::release(blockL); |
||||||
|
AudioStream_F32::release(blockR); |
||||||
|
} |
@ -0,0 +1,292 @@ |
|||||||
|
/* Stereo Ping Pong delay for Teensy 4
|
||||||
|
* |
||||||
|
* Author: Piotr Zapart |
||||||
|
* www.hexefx.com |
||||||
|
* |
||||||
|
* Copyright (c) 2024 by Piotr Zapart |
||||||
|
* |
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy |
||||||
|
* of this software and associated documentation files (the "Software"), to deal |
||||||
|
* in the Software without restriction, including without limitation the rights |
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
||||||
|
* copies of the Software, and to permit persons to whom the Software is |
||||||
|
* furnished to do so, subject to the following conditions: |
||||||
|
* |
||||||
|
* The above copyright notice and this permission notice shall be included in all |
||||||
|
* copies or substantial portions of the Software. |
||||||
|
* |
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
||||||
|
* SOFTWARE. |
||||||
|
*/ |
||||||
|
#ifndef _EFFECT_DELAYSTEREO_H_ |
||||||
|
#define _EFFECT_DELAYSTEREO_H_ |
||||||
|
|
||||||
|
#include <Arduino.h> |
||||||
|
#include "Audio.h" |
||||||
|
#include "AudioStream.h" |
||||||
|
#include "AudioStream_F32.h" |
||||||
|
#include "arm_math.h" |
||||||
|
#include "basic_components.h" |
||||||
|
|
||||||
|
class AudioEffectDelayStereo_F32 : public AudioStream_F32 |
||||||
|
{ |
||||||
|
public: |
||||||
|
AudioEffectDelayStereo_F32(uint32_t dly_range_ms=400, bool use_psram=false); |
||||||
|
~AudioEffectDelayStereo_F32(){}; |
||||||
|
virtual void update(); |
||||||
|
/**
|
||||||
|
* @brief delay time |
||||||
|
*
|
||||||
|
* @param t scaled to 0.0f-1.0f range |
||||||
|
*/ |
||||||
|
void time(float t) |
||||||
|
{ |
||||||
|
t = constrain(t, 0.0f, 1.0f); |
||||||
|
t = t * t; |
||||||
|
t = map(t, 0.0f, 1.0f, (float32_t)(dly_length-dly_time_min), 0.0f); |
||||||
|
__disable_irq(); |
||||||
|
dly_time_set = t; |
||||||
|
__enable_irq(); |
||||||
|
} |
||||||
|
/**
|
||||||
|
* @brief delay time set in samples |
||||||
|
*
|
||||||
|
* @param samples range is from 0 to delay buffer lengts - minimum delay |
||||||
|
*/ |
||||||
|
void delay(uint32_t samples) |
||||||
|
{ |
||||||
|
samples = constrain(samples, 0u, dly_length-dly_time_min); |
||||||
|
samples = dly_length-dly_time_min - samples; |
||||||
|
__disable_irq(); |
||||||
|
dly_time_set = samples; |
||||||
|
__enable_irq();
|
||||||
|
} |
||||||
|
/**
|
||||||
|
* @brief Amount of repeats |
||||||
|
*
|
||||||
|
* @param n 0.0f-1.0f range |
||||||
|
*/ |
||||||
|
void feedback(float n) |
||||||
|
{ |
||||||
|
float32_t fb, attn; |
||||||
|
n = constrain(n, 0.0f, 1.0f); |
||||||
|
fb = map(n, 0.0f, 1.0f, 0.0f, feedb_max) * hp_feedb_limit; |
||||||
|
attn = map(n*n*n, 0.0f, 1.0f, 1.0f, 0.4f); |
||||||
|
__disable_irq(); |
||||||
|
feedb = fb; |
||||||
|
input_attn = attn; |
||||||
|
__enable_irq(); |
||||||
|
} |
||||||
|
/**
|
||||||
|
* @brief How fast the delay time is updated |
||||||
|
* emulates analog tape machines |
||||||
|
*
|
||||||
|
* @param n 0.0f-1.0f range, 0 - fastest update |
||||||
|
*/ |
||||||
|
void inertia(float n) |
||||||
|
{ |
||||||
|
n = constrain(n, 0.0f, 1.0f); |
||||||
|
n = 2.0f * n - (n*n); |
||||||
|
n = map (n, 0.0f, 1.0f, 10.0f, 0.3f); |
||||||
|
__disable_irq(); |
||||||
|
dly_time_step = n; |
||||||
|
__enable_irq();
|
||||||
|
} |
||||||
|
/**
|
||||||
|
* @brief Output treble control |
||||||
|
*
|
||||||
|
* @param n 0.0f-1.0f range |
||||||
|
*/ |
||||||
|
void treble(float n) |
||||||
|
{ |
||||||
|
n = constrain(n, 0.0f, 1.0f); |
||||||
|
__disable_irq(); |
||||||
|
treble_k = n; |
||||||
|
__enable_irq(); |
||||||
|
} |
||||||
|
/**
|
||||||
|
* @brief Treble loss control (darkens the repeats) |
||||||
|
*
|
||||||
|
* @param n 0.0f-1.0f range |
||||||
|
*/ |
||||||
|
void treble_cut(float n) |
||||||
|
{ |
||||||
|
n = 1.0f - constrain(n, 0.0f, 1.0f); |
||||||
|
__disable_irq(); |
||||||
|
trebleCut_k = n; |
||||||
|
__enable_irq(); |
||||||
|
} |
||||||
|
/**
|
||||||
|
* @brief Output bass control |
||||||
|
*
|
||||||
|
* @param n 0.0f-1.0f range |
||||||
|
*/ |
||||||
|
void bass(float n) |
||||||
|
{ |
||||||
|
n = constrain(n, 0.0f, 1.0f); |
||||||
|
n = 1.0f - 2.0f*n + (n*n); |
||||||
|
__disable_irq(); |
||||||
|
bass_k = -n; |
||||||
|
__enable_irq(); |
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief Bass loss (repeats will loose low end) |
||||||
|
*
|
||||||
|
* @param n 0.0f-1.0f range |
||||||
|
*/ |
||||||
|
void bass_cut(float n) |
||||||
|
{ |
||||||
|
n = constrain(n, 0.0f, 1.0f); |
||||||
|
n = 2.0f * n - (n*n); |
||||||
|
__disable_irq(); |
||||||
|
bassCut_k = -n; |
||||||
|
__enable_irq(); |
||||||
|
} |
||||||
|
/**
|
||||||
|
* @brief dry/wet mixer |
||||||
|
* 0 = dry only, 1=wet only |
||||||
|
*
|
||||||
|
* @param m 0.0f-1-0f range |
||||||
|
*/ |
||||||
|
void mix(float m) |
||||||
|
{ |
||||||
|
float32_t dry, wet; |
||||||
|
m = constrain(m, 0.0f, 1.0f); |
||||||
|
mix_pwr(m, &wet, &dry); |
||||||
|
__disable_irq(); |
||||||
|
wet_gain = wet; |
||||||
|
dry_gain = dry; |
||||||
|
__enable_irq(); |
||||||
|
} |
||||||
|
/**
|
||||||
|
* @brief Modulation frequency in Hz |
||||||
|
*
|
||||||
|
* @param f range 0.0f - 16.0f |
||||||
|
*/ |
||||||
|
void mod_rateHz(float32_t f) |
||||||
|
{ |
||||||
|
f = constrain(f, 0.0f, 16.0f); |
||||||
|
__disable_irq(); |
||||||
|
lfo.setRate(f); |
||||||
|
__enable_irq(); |
||||||
|
} |
||||||
|
/**
|
||||||
|
* @brief modulation frequency scaled to 0.0f-1.0f range |
||||||
|
*
|
||||||
|
* @param r rate |
||||||
|
*/ |
||||||
|
void mod_rate(float32_t r) |
||||||
|
{ |
||||||
|
r = constrain(r*r*r, 0.0f, 1.0f); |
||||||
|
r = map(r, 0.0f, 1.0f, 0.0f, lfo_fmax); |
||||||
|
__disable_irq(); |
||||||
|
lfo.setRate(r); |
||||||
|
__enable_irq();
|
||||||
|
} |
||||||
|
/**
|
||||||
|
* @brief Modulation depth |
||||||
|
*
|
||||||
|
* @param d 0.0f-1-0f range |
||||||
|
*/ |
||||||
|
void mod_depth(float32_t d) |
||||||
|
{ |
||||||
|
d = constrain(d, 0.0f, 1.0f); |
||||||
|
d = map(d, 0.0f, 1.0f, 0.0f, lfo_ampl_max); |
||||||
|
__disable_irq(); |
||||||
|
lfo.setDepth(d); |
||||||
|
__enable_irq();
|
||||||
|
} |
||||||
|
|
||||||
|
bool bypass_get(void) {return bp;} |
||||||
|
void bypass_set(bool state) {bp = state;} |
||||||
|
bool bypass_tgl(void)
|
||||||
|
{ |
||||||
|
bp ^= 1;
|
||||||
|
return bp; |
||||||
|
} |
||||||
|
|
||||||
|
uint32_t tap_tempo(bool avg=true) |
||||||
|
{ |
||||||
|
int32_t delta; |
||||||
|
uint32_t tempo_ticks = 0; |
||||||
|
if (!tap_active) |
||||||
|
{ |
||||||
|
tap_counter = 0; |
||||||
|
tap_active = true; |
||||||
|
}
|
||||||
|
else |
||||||
|
{ |
||||||
|
__disable_irq(); |
||||||
|
tap_counter_new = tap_counter; |
||||||
|
tap_counter = 0; |
||||||
|
__enable_irq(); |
||||||
|
delta = tap_counter_new - tap_counter_last; |
||||||
|
if (abs(delta) > tap_counter_deltamax || !avg) // new tempo?
|
||||||
|
{ |
||||||
|
tempo_ticks = tap_counter_new; |
||||||
|
} |
||||||
|
else
|
||||||
|
{ |
||||||
|
tempo_ticks = (tap_counter_new>>1) + (tap_counter_last>>1); |
||||||
|
} |
||||||
|
while (tempo_ticks > dly_length - dly_time_min) |
||||||
|
{ |
||||||
|
tempo_ticks >>= 1; |
||||||
|
} |
||||||
|
tap_counter_last = tempo_ticks; |
||||||
|
delay(tempo_ticks); |
||||||
|
} |
||||||
|
return tempo_ticks; |
||||||
|
}
|
||||||
|
|
||||||
|
private: |
||||||
|
audio_block_f32_t *inputQueueArray[2]; |
||||||
|
|
||||||
|
uint32_t dly_length; |
||||||
|
AudioBasicDelay dly0a; |
||||||
|
AudioBasicDelay dly0b; |
||||||
|
AudioBasicDelay dly1a; |
||||||
|
AudioBasicDelay dly1b; |
||||||
|
|
||||||
|
AudioFilterShelvingLPHP flt0L; |
||||||
|
AudioFilterShelvingLPHP flt1L; |
||||||
|
AudioFilterShelvingLPHP flt0R; |
||||||
|
AudioFilterShelvingLPHP flt1R; |
||||||
|
|
||||||
|
static constexpr float32_t lfo_fmax = 16.0f; |
||||||
|
static constexpr float32_t lfo_ampl_max = 127.0f; |
||||||
|
float32_t lfo_ampl = 0.0f; |
||||||
|
AudioBasicLfo lfo = AudioBasicLfo(0.0f, lfo_ampl); |
||||||
|
bool psram_mode; |
||||||
|
bool memsetup_done = false; |
||||||
|
bool bp = false; |
||||||
|
bool cleanup_done = false; |
||||||
|
|
||||||
|
static constexpr float32_t feedb_max = 0.96f; |
||||||
|
float32_t feedb = 0; |
||||||
|
float32_t hp_feedb_limit = 1.0f; |
||||||
|
float32_t wet_gain; |
||||||
|
float32_t dry_gain; |
||||||
|
float32_t input_attn = 1.0f; |
||||||
|
float32_t trebleCut_k = 1.0f; |
||||||
|
float32_t bassCut_k = 0.0f; |
||||||
|
float32_t treble_k = 1.0f; |
||||||
|
float32_t bass_k = 0.0f; |
||||||
|
float32_t dly_time, dly_time_set; |
||||||
|
float32_t dly_time_step = 10.0f; |
||||||
|
static const uint32_t dly_time_min = 128; |
||||||
|
bool initialized = false; |
||||||
|
|
||||||
|
bool tap_active = false; |
||||||
|
uint32_t tap_counter = 0; |
||||||
|
uint32_t tap_counter_last=0, tap_counter_new=0; |
||||||
|
static const uint32_t tap_counter_max = 3000*AUDIO_SAMPLE_RATE; // 3 sec
|
||||||
|
static const int32_t tap_counter_deltamax = 0.3f*AUDIO_SAMPLE_RATE_EXACT; |
||||||
|
}; |
||||||
|
|
||||||
|
#endif // _EFFECT_DELAYSTEREO_H_
|
Loading…
Reference in new issue