29#include <pulp/signal/detail/simd_lanes.hpp>
35template <
typename SampleType =
float>
46 void prepare(
int max_delay_samples, std::size_t stagger = 0) {
47 const int needed = std::max(max_delay_samples, 1) + 4;
49 while (
size <
static_cast<std::size_t
>(needed))
size <<= 1;
50 buffer_.assign(
size + stagger + kMirror, SampleType{0});
55 max_delay_ =
static_cast<int>(
size) - 4;
59 std::fill(buffer_.begin(), buffer_.end(), SampleType{0});
66 SampleType* r = ring();
70 for (std::size_t j = size_ + write_; j < size_ + kMirror; j += size_)
72 write_ = (write_ + 1) & mask_;
77 const std::size_t idx = (write_ -
static_cast<std::size_t
>(
delay)) & mask_;
85 const std::size_t idx =
86 (write_ +
static_cast<std::size_t
>(ahead) -
static_cast<std::size_t
>(
delay)) & mask_;
94 const std::size_t start =
95 (write_ +
static_cast<std::size_t
>(ahead) -
static_cast<std::size_t
>(
delay)) & mask_;
96 const SampleType* src = ring();
97 if (start +
static_cast<std::size_t
>(n) <= size_) {
98 for (
int k = 0; k < n; ++k)
99 dst[k] = src[start +
static_cast<std::size_t
>(k)];
101 for (
int k = 0; k < n; ++k)
102 dst[k] = src[(start +
static_cast<std::size_t
>(k)) & mask_];
110 SampleType* dst = ring() + write_;
111 for (
int k = 0; k < piece; ++k)
112 dst[k] = x[done + k];
119 for (
int k = 0; k < n; ++k)
120 push(x[
static_cast<std::size_t
>(k) * stride]);
127 const SampleType*
taps_at(std::size_t start)
const {
128 return ring() + (start & mask_);
136 const double d = std::clamp(
delay, 2.0,
static_cast<double>(max_delay_));
137 const int i =
static_cast<int>(d);
138 const auto f =
static_cast<SampleType
>(d -
static_cast<double>(
i));
139 const std::size_t base =
140 (write_ +
static_cast<std::size_t
>(ahead) -
static_cast<std::size_t
>(
i));
141 const SampleType* r = ring();
143 r[(base + 1) & mask_], SampleType{1} - f);
157 const double whole = std::floor(delays[0]);
158 if (whole >= 2.0 && whole + 1.0 <=
static_cast<double>(max_delay_)) {
159 const std::size_t start =
160 (write_ -
static_cast<std::size_t
>(behind) -
static_cast<std::size_t
>(whole) - 2) &
167 if (start +
static_cast<std::size_t
>(n) + 3 <= size_ + kMirror &&
168 fractions(delays, whole, t, n)) {
169 hermite_run(ring() + start, t, out, n);
173 for (
int k = 0; k < n; ++k)
179 const double d = std::clamp(
delay, 2.0,
static_cast<double>(max_delay_));
180 const double whole = std::floor(d);
181 const std::size_t start =
182 (write_ -
static_cast<std::size_t
>(behind) -
static_cast<std::size_t
>(whole) - 2) &
184 if (start +
static_cast<std::size_t
>(n) + 3 <= size_ + kMirror) {
186 const SampleType tk = SampleType{1} -
static_cast<SampleType
>(d - whole);
187 for (
int k = 0; k < n; ++k)
189 hermite_run(ring() + start, t, out, n);
192 for (
int k = 0; k < n; ++k)
217 write_ = (write_ +
static_cast<std::size_t
>(n)) & mask_;
227 const std::size_t end = write_ +
static_cast<std::size_t
>(n);
228 SampleType* r = ring();
230 for (std::size_t j = size_; j < end; ++j)
232 if (write_ < kMirror || end > size_)
234 write_ = end & mask_;
241 const double d = std::clamp(
delay, 2.0,
static_cast<double>(max_delay_));
242 const int i =
static_cast<int>(d);
243 const double f = d -
static_cast<double>(
i);
247 return static_cast<SampleType
>(
hermite4(
248 static_cast<double>(
read(
i + 2)),
static_cast<double>(
read(
i + 1)),
249 static_cast<double>(
read(
i)),
static_cast<double>(
read(
i - 1)), 1.0 - f));
255 static constexpr std::size_t kMirror =
static_cast<std::size_t
>(
kMaxBlockSamples) + 4;
257 void refresh_mirror() {
260 SampleType* r = ring();
261 for (std::size_t j = 0; j < kMirror; ++j)
266 return buffer_.data() + base_;
268 const SampleType* ring()
const {
269 return buffer_.data() + base_;
274 static bool fractions(
const double* delays,
double whole, SampleType* t,
int n) {
275 namespace lanes = detail::lanes;
278 if constexpr (std::is_same_v<SampleType, float>) {
279 const lanes::D2 base = lanes::splat(whole);
280 const lanes::F4 zero = lanes::splat(0.0f);
281 const lanes::F4 one = lanes::splat(1.0f);
282 auto ok = lanes::less_equal(zero, zero);
283 for (; k + 4 <= n; k += 4) {
284 const lanes::F4 f = lanes::narrow(lanes::load(delays + k) - base,
285 lanes::load(delays + k + 2) - base);
286 ok = lanes::both(
ok, lanes::both(lanes::less_equal(zero, f), lanes::less(f, one)));
287 lanes::store(t + k, one - f);
289 inside = lanes::all(
ok);
292 const auto f =
static_cast<SampleType
>(delays[
k] -
whole);
293 inside = inside &&
f >= SampleType{0} &&
f < SampleType{1};
294 t[
k] = SampleType{1} -
f;
302 static void hermite_run(
const SampleType* p,
const SampleType* t, SampleType* out,
int n) {
304 if constexpr (std::is_same_v<SampleType, float>) {
305 namespace lanes = detail::lanes;
306 const lanes::F4
half = lanes::splat(0.5f);
307 const lanes::F4 two_and_half = lanes::splat(2.5f);
308 const lanes::F4 two = lanes::splat(2.0f);
309 const lanes::F4 one_and_half = lanes::splat(1.5f);
310 for (;
k + 4 <=
n;
k += 4) {
311 const lanes::F4 ym1 = lanes::load(p + k);
312 const lanes::F4 y0 = lanes::load(p + k + 1);
313 const lanes::F4 y1 = lanes::load(p + k + 2);
314 const lanes::F4 y2 = lanes::load(p + k + 3);
315 const lanes::F4 frac = lanes::load(t + k);
316 const lanes::F4 c0 = y0;
317 const lanes::F4
c1 =
half * (y1 - ym1);
318 const lanes::F4
c2 = ym1 - two_and_half * y0 + two * y1 -
half * y2;
319 const lanes::F4
c3 =
half * (y2 - ym1) + one_and_half * (y0 - y1);
320 lanes::store(out + k, ((
c3 * frac +
c2) * frac +
c1) * frac + c0);
327 std::vector<SampleType> buffer_;
328 std::size_t base_ = 0;
329 std::size_t size_ = 0;
330 std::size_t mask_ = 0;
331 std::size_t write_ = 0;
Definition frac_delay.hpp:36
static constexpr std::size_t mirror_samples()
Definition frac_delay.hpp:210
void advance(int n)
Definition frac_delay.hpp:226
SampleType read_at(int ahead, int delay) const
Definition frac_delay.hpp:84
int max_delay() const
Definition frac_delay.hpp:63
std::size_t mask() const
Definition frac_delay.hpp:203
std::size_t write_index() const
Definition frac_delay.hpp:206
void reset()
Definition frac_delay.hpp:58
const SampleType * taps_at(std::size_t start) const
Definition frac_delay.hpp:127
void prepare(int max_delay_samples, std::size_t stagger=0)
Definition frac_delay.hpp:46
void copy_out(int ahead, int delay, SampleType *dst, int n) const
Definition frac_delay.hpp:93
void push_strided(const SampleType *x, std::size_t stride, int n)
Definition frac_delay.hpp:118
void push_block(const SampleType *x, int n)
Definition frac_delay.hpp:107
SampleType read(int delay) const
Definition frac_delay.hpp:76
SampleType read(double delay) const
Definition frac_delay.hpp:240
void push(SampleType x)
Definition frac_delay.hpp:65
std::size_t size() const
Definition frac_delay.hpp:200
SampleType read_hermite_at(int ahead, double delay) const
Definition frac_delay.hpp:135
void read_hermite_span(double delay, SampleType *out, int n, int behind=0) const
Definition frac_delay.hpp:178
void read_hermite_span(const double *delays, SampleType *out, int n, int behind=0) const
Definition frac_delay.hpp:156
void skip(int n)
Definition frac_delay.hpp:216
SampleType * data()
Definition frac_delay.hpp:197
@ f
Definition pitch.hpp:25
FracDelayT< float > FracDelay
Definition frac_delay.hpp:335
T hermite4_t(T y0, T y1, T y2, T y3, T t)
Definition interp.hpp:32
constexpr int kMaxBlockSamples
Definition config.hpp:190
double hermite4(double y0, double y1, double y2, double y3, double t)
Definition interp.hpp:27
@ whole
Definition units.hpp:287
@ half
Definition units.hpp:290
@ delay
Definition envelope.hpp:57
@ c3
Full chorus. The lush one.
Definition scanner_vibrato.hpp:28
@ c2
Medium chorus.
Definition scanner_vibrato.hpp:27
@ c1
Shallow chorus — scanner plus dry.
Definition scanner_vibrato.hpp:26
@ i
Definition formant_filter_bank.hpp:20
@ ok
Definition breakpoint_envelope.hpp:36
@ n
Definition input_events.hpp:40
@ k
Definition input_events.hpp:40
@ t
Definition input_events.hpp:41