53 for (
auto& s : states_)
70 assert(channel >= 0 && channel < MaxChannels);
74 channel = std::clamp(channel, 0, MaxChannels - 1);
75 auto& tp = states_[
static_cast<size_t>(channel)];
81 tp.history[
static_cast<size_t>(tp.writePos)] = sample;
82 tp.history[
static_cast<size_t>(tp.writePos + kHistSize)] = sample;
83 const int newest = tp.writePos;
84 tp.writePos = (tp.writePos + 1) & kHistMask;
87 const T* window = &tp.history[
static_cast<size_t>(newest + kHistSize - (kTaps - 1))];
89 T peak = std::abs(sample);
90 for (
int phase = 0; phase < kPhases; ++phase)
93 kReversedCoeffs[
static_cast<size_t>(phase)].data(), window, kTaps);
94 const T a = std::abs(interp);
95 if (a > peak) peak = a;
101 [[nodiscard]]
static constexpr int getLatency() noexcept {
return kTaps / 2; }
104 static constexpr int kTaps = 12;
105 static constexpr int kPhases = 4;
106 static constexpr int kHistSize = 16;
107 static constexpr int kHistMask = kHistSize - 1;
113 T history[kHistSize * 2] = {};
127 [[nodiscard]]
static constexpr std::array<std::array<T, kTaps>, kPhases>
128 buildReversedPhaseTable() noexcept
130 constexpr double kAnnex2[kPhases][kTaps] = {
131 { 0.0017089843750, 0.0109863281250, -0.0196533203125,
132 0.0332031250000, -0.0594482421875, 0.1373291015625,
133 0.9721679687500, -0.1022949218750, 0.0476074218750,
134 -0.0266113281250, 0.0148925781250, -0.0083007812500 },
135 { -0.0291748046875, 0.0292968750000, -0.0517578125000,
136 0.0891113281250, -0.1665039062500, 0.4650878906250,
137 0.7797851562500, -0.2003173828125, 0.1015625000000,
138 -0.0582275390625, 0.0330810546875, -0.0189208984375 },
139 { -0.0189208984375, 0.0330810546875, -0.0582275390625,
140 0.1015625000000, -0.2003173828125, 0.7797851562500,
141 0.4650878906250, -0.1665039062500, 0.0891113281250,
142 -0.0517578125000, 0.0292968750000, -0.0291748046875 },
143 { -0.0083007812500, 0.0148925781250, -0.0266113281250,
144 0.0476074218750, -0.1022949218750, 0.9721679687500,
145 0.1373291015625, -0.0594482421875, 0.0332031250000,
146 -0.0196533203125, 0.0109863281250, 0.0017089843750 },
149 std::array<std::array<T, kTaps>, kPhases> result {};
150 for (
int phase = 0; phase < kPhases; ++phase)
151 for (
int k = 0; k < kTaps; ++k)
152 result[
static_cast<size_t>(phase)][
static_cast<size_t>(kTaps - 1 - k)]
153 =
static_cast<T
>(kAnnex2[phase][k]);
159 static constexpr std::array<std::array<T, kTaps>, kPhases> kReversedCoeffs =
160 buildReversedPhaseTable();
162 std::array<State, MaxChannels> states_ {};