41 : buffer_(buffer), max_delay_(
max_delay), write_pos_(0) {}
64 buffer_[write_pos_] = sample;
66 if (write_pos_ >= max_delay_) {
78 float read(
float delay_samples)
const {
80 if (delay_samples < 1.0f) delay_samples = 1.0f;
81 float max_f =
static_cast<float>(max_delay_ - 1);
82 if (delay_samples > max_f) delay_samples = max_f;
85 uint32_t int_delay =
static_cast<uint32_t
>(delay_samples);
86 float frac = delay_samples -
static_cast<float>(int_delay);
89 float y0 = read_at(int_delay);
90 float y1 = read_at(int_delay + 1);
93 return y0 + frac * (y1 - y0);
109 if (delay_samples < 2.0f) delay_samples = 2.0f;
110 float max_f =
static_cast<float>(max_delay_ - 2);
111 if (delay_samples > max_f) delay_samples = max_f;
113 uint32_t int_delay =
static_cast<uint32_t
>(delay_samples);
114 float frac = delay_samples -
static_cast<float>(int_delay);
117 float y0 = read_at(int_delay - 1);
118 float y1 = read_at(int_delay);
119 float y2 = read_at(int_delay + 1);
120 float y3 = read_at(int_delay + 2);
123 float a = -0.5f * y0 + 1.5f * y1 - 1.5f * y2 + 0.5f * y3;
124 float b = y0 - 2.5f * y1 + 2.0f * y2 - 0.5f * y3;
125 float c = -0.5f * y0 + 0.5f * y2;
128 return ((a * frac + b) * frac + c) * frac + d;
147 const float* delay, uint16_t frames) {
148 for (uint16_t i = 0; i < frames; ++i) {
150 out[i] =
read(delay[i]);
157 for (uint32_t i = 0; i < max_delay_; ++i) {
175 float read_at(uint32_t delay)
const {
178 uint32_t pos = (write_pos_ + max_delay_ - delay) % max_delay_;
182 float* buffer_ =
nullptr;
183 uint32_t max_delay_ = 0;
184 uint32_t write_pos_ = 0;
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.
void process(const float *in, float *out, const float *delay, uint16_t frames)
Block processing with per-sample modulated delay.
ModulatedDelayLine()=default
Default constructor for deferred initialization (must call init() before use)
uint32_t max_delay() const
Maximum delay in samples (buffer size)
uint32_t write_pos() const
Current write position (for external tap reads)
ModulatedDelayLine(float *buffer, uint32_t max_delay)
Construct with caller-provided buffer.
void clear()
Zero all samples in the buffer and reset write position.
float read_cubic(float delay_samples) const
Read at fractional delay with 4-point Hermite cubic interpolation.
void write(float sample)
Write a sample to the delay line.
DSP atoms for audio signal processing.