Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
interpolator.hpp
Go to the documentation of this file.
1#pragma once
2
5
7
8#include <cmath>
9#include <algorithm>
10#include <cstddef>
11
12namespace pulp::signal {
13
29
32 template <typename SampleType>
33 static SampleType linear(SampleType frac, SampleType y0, SampleType y1) {
34 return y0 + frac * (y1 - y0);
35 }
36
40 template <typename SampleType>
41 static SampleType hermite(SampleType frac,
42 SampleType ym1,
43 SampleType y0,
44 SampleType y1,
45 SampleType y2) {
46 SampleType c0 = y0;
47 SampleType c1 = SampleType{0.5f} * (y1 - ym1);
48 SampleType c2 = ym1 - SampleType{2.5f} * y0 +
49 SampleType{2.0f} * y1 - SampleType{0.5f} * y2;
50 SampleType c3 = SampleType{0.5f} * (y2 - ym1) +
51 SampleType{1.5f} * (y0 - y1);
52 return ((c3 * frac + c2) * frac + c1) * frac + c0;
53 }
54
59 template <typename SampleType>
60 static SampleType lagrange(SampleType frac,
61 SampleType ym1,
62 SampleType y0,
63 SampleType y1,
64 SampleType y2) {
65 // Nodes at x = -1, 0, 1, 2. Evaluate at x = frac (in [0,1]).
66 SampleType d = frac;
67 // L_{-1}(d) = d(d-1)(d-2) / ((-1-0)(-1-1)(-1-2)) = d(d-1)(d-2) / (-1)(-2)(-3) = -d(d-1)(d-2)/6
68 SampleType L0 = -d * (d - SampleType{1.0f}) *
69 (d - SampleType{2.0f}) / SampleType{6.0f};
70 // L_0(d) = (d+1)(d-1)(d-2) / ((0+1)(0-1)(0-2)) = (d+1)(d-1)(d-2) / (1)(-1)(-2) = (d+1)(d-1)(d-2)/2
71 SampleType L1 = (d + SampleType{1.0f}) * (d - SampleType{1.0f}) *
72 (d - SampleType{2.0f}) / SampleType{2.0f};
73 // L_1(d) = (d+1)d(d-2) / ((1+1)(1-0)(1-2)) = (d+1)d(d-2) / (2)(1)(-1) = -(d+1)d(d-2)/2
74 SampleType L2 = -(d + SampleType{1.0f}) * d *
75 (d - SampleType{2.0f}) / SampleType{2.0f};
76 // L_2(d) = (d+1)d(d-1) / ((2+1)(2-0)(2-1)) = (d+1)d(d-1) / (3)(2)(1) = (d+1)d(d-1)/6
77 SampleType L3 = (d + SampleType{1.0f}) * d *
78 (d - SampleType{1.0f}) / SampleType{6.0f};
79
80 return L0 * ym1 + L1 * y0 + L2 * y1 + L3 * y2;
81 }
82
86 template <typename SampleType>
87 static SampleType sinc6(SampleType frac,
88 SampleType ym2,
89 SampleType ym1,
90 SampleType y0,
91 SampleType y1,
92 SampleType y2,
93 SampleType y3) {
94 // Evaluate windowed sinc at 6 fractional offsets
95 SampleType sum = SampleType{0.0f};
96 SampleType samples[6] = {ym2, ym1, y0, y1, y2, y3};
97 for (int i = 0; i < 6; ++i) {
98 SampleType x = frac - static_cast<SampleType>(i - 2);
99 sum += samples[i] * windowed_sinc(x);
100 }
101 return sum;
102 }
103
104private:
105 template <typename SampleType>
106 static constexpr SampleType pi = SampleType{3.14159265358979323846f};
107
108 template <typename SampleType>
109 static SampleType sinc(SampleType x) {
110 if (std::abs(x) < SampleType{1e-7f}) return SampleType{1.0f};
111 SampleType px = pi<SampleType> * x;
112 return std::sin(px) / px;
113 }
114
116 template <typename SampleType>
117 static SampleType blackman_harris(SampleType x, SampleType half_width) {
118 if (std::abs(x) >= half_width) return SampleType{0.0f};
119 SampleType n = (x / half_width + SampleType{1.0f}) *
120 SampleType{0.5f}; // normalize to [0, 1]
121 SampleType t = SampleType{2.0f} * pi<SampleType> * n;
123 }
124
125 template <typename SampleType>
126 static SampleType windowed_sinc(SampleType x) {
127 return sinc(x) * blackman_harris(x, SampleType{3.0f});
128 }
129};
130
131} // namespace pulp::signal
SampleType blackman_harris_window(SampleType phase)
Definition windowing.hpp:22
Definition additive_bank.hpp:218
@ 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
@ px
Absolute pixels.
Definition geometry.hpp:393
@ n
Definition input_events.hpp:40
@ x
Definition input_events.hpp:41
@ t
Definition input_events.hpp:41
Collection of interpolation algorithms for reading between samples.
Definition interpolator.hpp:28
static SampleType linear(SampleType frac, SampleType y0, SampleType y1)
Linear interpolation between two samples.
Definition interpolator.hpp:33
static SampleType lagrange(SampleType frac, SampleType ym1, SampleType y0, SampleType y1, SampleType y2)
4-point Lagrange interpolation.
Definition interpolator.hpp:60
static SampleType hermite(SampleType frac, SampleType ym1, SampleType y0, SampleType y1, SampleType y2)
Cubic Hermite (Catmull-Rom) interpolation.
Definition interpolator.hpp:41
static SampleType sinc6(SampleType frac, SampleType ym2, SampleType ym1, SampleType y0, SampleType y1, SampleType y2, SampleType y3)
Windowed-sinc interpolation (6-point).
Definition interpolator.hpp:87