Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
delay_line.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <vector>
4#include <cmath>
5#include <algorithm>
6
7namespace pulp::signal {
8
9// Delay line with linear interpolation for fractional delays.
10// RT contract: prepare() allocates storage; push/read/process/reset allocate no
11// memory after prepare().
12template <typename SampleType = float>
14public:
15 // Allocate buffer for max delay in samples
16 void prepare(int max_delay_samples) {
17 buffer_.assign(max_delay_samples + 1, SampleType{0.0f});
18 write_pos_ = 0;
19 valid_samples_ = 0;
20 }
21
22 // Push a sample into the delay line
23 void push(SampleType sample) {
24 if (buffer_.empty()) return;
25 buffer_[write_pos_] = sample;
26 write_pos_ = (write_pos_ + 1) % static_cast<int>(buffer_.size());
27 valid_samples_ = std::min(valid_samples_ + 1, static_cast<int>(buffer_.size()));
28 }
29
30 // Read at a fractional delay (in samples) with linear interpolation
31 SampleType read(SampleType delay_samples) const {
32 int size = static_cast<int>(buffer_.size());
33 if (size == 0 || !std::isfinite(static_cast<double>(delay_samples)) ||
34 delay_samples < SampleType{0})
35 return SampleType{0.0f};
36
37 const int younger = static_cast<int>(std::floor(delay_samples));
38 const SampleType frac = delay_samples - static_cast<SampleType>(younger);
39 const SampleType a = read(younger);
40 const SampleType b = read(younger + 1);
41 return a * (SampleType{1.0f} - frac) + b * frac;
42 }
43
44 // Read at integer delay
45 SampleType read(int delay_samples) const {
46 int size = static_cast<int>(buffer_.size());
47 if (size == 0 || delay_samples < 0 ||
48 (valid_samples_ < size && delay_samples >= valid_samples_))
49 return SampleType{0.0f};
50 int idx = (write_pos_ - delay_samples - 1 + size * 2) % size;
51 return buffer_[idx];
52 }
53
54 // Push a sample and read at a fixed delay
55 SampleType process(SampleType input, SampleType delay_samples) {
56 push(input);
57 return read(delay_samples);
58 }
59
60 void reset() {
61 std::fill(buffer_.begin(), buffer_.end(), SampleType{0.0f});
62 write_pos_ = 0;
63 valid_samples_ = 0;
64 }
65
69 void discard_history() noexcept {
70 write_pos_ = 0;
71 valid_samples_ = 0;
72 }
73
74 int max_delay() const { return static_cast<int>(buffer_.size()) - 1; }
75
76private:
77 std::vector<SampleType> buffer_;
78 int write_pos_ = 0;
79 int valid_samples_ = 0;
80};
81
84
85} // namespace pulp::signal
Definition delay_line.hpp:13
int max_delay() const
Definition delay_line.hpp:74
void discard_history() noexcept
Logically clears the delay history in constant time.
Definition delay_line.hpp:69
SampleType process(SampleType input, SampleType delay_samples)
Definition delay_line.hpp:55
void reset()
Definition delay_line.hpp:60
SampleType read(int delay_samples) const
Definition delay_line.hpp:45
void prepare(int max_delay_samples)
Definition delay_line.hpp:16
void push(SampleType sample)
Definition delay_line.hpp:23
SampleType read(SampleType delay_samples) const
Definition delay_line.hpp:31
Definition additive_bank.hpp:218
DelayLineT< float > DelayLine
Definition delay_line.hpp:82
DelayLineT< double > DelayLine64
Definition delay_line.hpp:83
@ a
Definition formant_filter_bank.hpp:20