MostlyHarmless 0.0.1
 
Loading...
Searching...
No Matches
marvin_Interpolators.h
Go to the documentation of this file.
1// ========================================================================================================
2// _______ _______ ______ ___ ___ _______ _______
3// | | | _ | __ \ | |_ _| | |
4// | | | < | |_| |_| |
5// |__|_|__|___|___|___|__|\_____/|_______|__|____|
6//
7// This file is part of the Marvin open source library and is licensed under the terms of the MIT License.
8//
9// ========================================================================================================
10
11#ifndef MARVIN_INTERPOLATORS_H
12#define MARVIN_INTERPOLATORS_H
14#include <marvin/library/marvin_Literals.h>
17#include <span>
18#include <cassert>
19#include <vector>
20#include <functional>
76 template <FloatType SampleType, size_t N, windows::WindowType WindowType>
77 requires(N % 2 == 0)
79 public:
84 requires(WindowType == windows::WindowType::Sine)
85 {
86 auto windowFunc = [](SampleType i) -> SampleType {
87 const auto res = windows::sine(i, static_cast<SampleType>(N));
88 return res;
89 };
90 fillLookupTable(std::move(windowFunc));
91 }
92
97 explicit WindowedSincInterpolator(SampleType alpha)
98 requires(WindowType == windows::WindowType::Tukey)
99 {
100 auto windowFunc = [alpha](SampleType i) -> SampleType {
101 const auto res = windows::tukey(i, static_cast<SampleType>(N), alpha);
102 return res;
103 };
104 fillLookupTable(std::move(windowFunc));
105 }
106
115 [[nodiscard]] SampleType interpolate(std::span<SampleType> sampleContext, SampleType ratio) {
116 assert(sampleContext.size() == N);
117 auto sum = static_cast<SampleType>(0.0);
118 const auto inverseRatio = static_cast<SampleType>(1.0) - ratio;
119 constexpr static auto halfN = static_cast<int>(N) / 2;
120 for (auto i = 0_sz; i < N; ++i) {
121 auto n = static_cast<int>(i) - static_cast<int>(halfN);
122 const auto windowedSinc = lookupSinc(static_cast<SampleType>(n), inverseRatio);
123 const auto res = sampleContext[i] * windowedSinc;
124 sum += res;
125 }
126 return sum;
127 }
128
129 private:
130 void fillLookupTable(std::function<SampleType(SampleType)>&& windowFunction) {
131 m_lut.reserve(N + 2);
132 m_lut.resize(N);
133 constexpr static auto halfWidth{ N / 2 };
134 for (auto i = 0_sz; i < N; ++i) {
135 const auto n{ static_cast<int>(i) - static_cast<int>(halfWidth) };
136 const auto window = windowFunction(static_cast<SampleType>(i));
137 const auto sincRes = sinc(static_cast<SampleType>(n));
138 const auto windowedSinc = sincRes * window;
139 m_lut[i] = windowedSinc;
140 }
141 const auto start = m_lut.front();
142 const auto end = m_lut[m_lut.size() - 1];
143 m_lut.emplace_back(end);
144 m_lut.emplace_back(start);
145 std::rotate(m_lut.begin(), m_lut.end() - 1, m_lut.end()); // [ x x x x e s ] -> [s x x x x e]
146 }
147
148
149 [[nodiscard]] SampleType lookupSinc(SampleType x, SampleType frac) {
150 constexpr static auto halfN{ static_cast<int>(N / 2) };
151 const auto nBelow = static_cast<int>(std::floor(x));
152 const auto nAbove = static_cast<int>(nBelow) + 1;
153 const auto ratio = frac;
154 // const auto ratio = x - static_cast<SampleType>(nBelow);
155 // So this is now in range -N to N
156 // translating this to an actual index into the LUT means just adding (N / 2)..
157 // LUT has an extra point at the start compared to what we actually expect....
158 const auto idxBelow = static_cast<size_t>(nBelow + halfN) + 1;
159 const auto idxAbove = static_cast<size_t>(nAbove + halfN) + 1;
160 const auto start = m_lut[idxBelow];
161 const auto end = m_lut[idxAbove];
162 const auto interpolated = math::lerp<SampleType>(start, end, ratio);
163 return interpolated;
164 }
165
166 std::vector<SampleType> m_lut;
167 };
168} // namespace marvin::math::interpolators
169
170#endif
SampleType interpolate(std::span< SampleType > sampleContext, SampleType ratio)
Definition marvin_Interpolators.h:115
WindowedSincInterpolator()
Definition marvin_Interpolators.h:83
WindowedSincInterpolator(SampleType alpha)
Definition marvin_Interpolators.h:97
Definition marvin_Interpolators.h:21
SampleType sine(SampleType n, SampleType N)
Definition marvin_Windows.h:73
SampleType tukey(SampleType n, SampleType NumPoints, SampleType alpha)
Definition marvin_Windows.h:88
@ Sine
Definition marvin_Windows.h:23
@ Tukey
Definition marvin_Windows.h:24
T lerp(T start, T end, T ratio) noexcept
Definition marvin_Math.h:32
T sinc(T x) noexcept
Definition marvin_Math.h:122