43 Delay(
float* buf_l,
float* buf_r, uint32_t max_samples)
44 : dl_l_(buf_l, max_samples), dl_r_(buf_r, max_samples) {}
55 void init(
float* buf_l,
float* buf_r, uint32_t max_samples) {
56 dl_l_.
init(buf_l, max_samples);
57 dl_r_.
init(buf_r, max_samples);
68 target_samples_ = (samples < max) ? samples : max - 1;
69 if (!time_initialized_) {
70 current_samples_ =
static_cast<float>(target_samples_);
71 time_initialized_ =
true;
80 set_time(
static_cast<uint32_t
>(ms *
static_cast<float>(sample_rate_) / 1000.0f));
89 if (bpm < 1.0f) bpm = 1.0f;
90 float seconds = 60.0f / (bpm *
static_cast<float>(division));
91 uint32_t samples =
static_cast<uint32_t
>(seconds *
static_cast<float>(sample_rate_));
100 feedback_ = (fb > 0.95f) ? 0.95f : (fb < 0.0f ? 0.0f : fb);
108 mix_ = (
mix > 1.0f) ? 1.0f : (
mix < 0.0f ? 0.0f :
mix);
116 if (tone > 1.0f) tone = 1.0f;
117 if (tone < 0.0f) tone = 0.0f;
120 float coeff = 1.0f - (1.0f - tone) * 0.9f;
129 uint32_t
time()
const {
return target_samples_; }
131 float mix()
const {
return mix_; }
141 void process(
float* left,
float* right, uint16_t frames) {
142 const float fb = feedback_;
143 const float wet = mix_;
144 const float dry = 1.0f - wet;
145 const float target =
static_cast<float>(target_samples_);
147 for (uint16_t i = 0; i < frames; ++i) {
148 current_samples_ += TIME_SMOOTH * (target - current_samples_);
150 float in_l = left[i];
151 float in_r = right[i];
153 float delayed_l = dl_l_.
read(current_samples_);
154 float delayed_r = dl_r_.
read(current_samples_);
156 float filtered_l = tone_l_.
process(delayed_l);
157 float filtered_r = tone_r_.
process(delayed_r);
161 fb_l = filtered_r * fb;
162 fb_r = filtered_l * fb;
164 fb_l = filtered_l * fb;
165 fb_r = filtered_r * fb;
168 dl_l_.
write(in_l + fb_l);
169 dl_r_.
write(in_r + fb_r);
171 left[i] = dry * in_l + wet * delayed_l;
172 right[i] = dry * in_r + wet * delayed_r;
180 current_samples_ =
static_cast<float>(target_samples_);
181 time_initialized_ = (target_samples_ > 0);
187 static constexpr float TIME_SMOOTH = 0.002f;
192 uint32_t target_samples_ = 0;
193 float current_samples_ = 0.0f;
194 bool time_initialized_ =
false;
195 float feedback_ = 0.4f;
199 bool ping_pong_ =
false;
200 uint32_t sample_rate_ = 48000;
void init(float *buffer, uint32_t max_delay)
Initialize after default construction.
float read(float delay_samples) const
Read at fractional delay with linear interpolation.
uint32_t max_delay() const
Maximum delay in samples (buffer size)
void clear()
Zero all samples in the buffer and reset write position.
void write(float sample)
Write a sample to the delay line.
void reset()
Reset filter state to zero.
float process(float x)
Process a single sample.
void set_coefficient(float a)
Set filter coefficient directly.