marvin 0.0.1
Pure C++ audio helper library
 
Loading...
Searching...
No Matches
marvin_RBJCoefficients.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_RBJCOEFFICIENTS_H
12#define MARVIN_RBJCOEFFICIENTS_H
14#include <cmath>
15#include <numbers>
24 template <FloatType SampleType>
25 [[nodiscard]] BiquadCoefficients<SampleType> lowpass(double sampleRate, SampleType cutoff, SampleType q) noexcept {
26 constexpr static auto twoPi = std::numbers::pi_v<SampleType> * static_cast<SampleType>(2.0);
27 const auto fs{ static_cast<SampleType>(sampleRate) };
28 const auto omega{ twoPi * (cutoff / fs) };
29 const auto cosOmega = std::cos(omega);
30 const auto sinOmega = std::sin(omega);
31 const auto alpha{ sinOmega / (static_cast<SampleType>(2.0) * q) };
32 const auto a0 = (static_cast<SampleType>(1.0) - cosOmega) / static_cast<SampleType>(2.0);
33 const auto a1 = static_cast<SampleType>(1.0) - cosOmega;
34 const auto a2 = a0;
35 const auto b0 = static_cast<SampleType>(1.0) + alpha;
36 const auto b1 = static_cast<SampleType>(-2.0) * cosOmega;
37 const auto b2 = static_cast<SampleType>(1.0) - alpha;
39 .a0 = a0,
40 .a1 = a1,
41 .a2 = a2,
42 .b0 = b0,
43 .b1 = b1,
44 .b2 = b2
45 };
46 }
47
55 template <FloatType SampleType>
56 [[nodiscard]] BiquadCoefficients<SampleType> highpass(double sampleRate, SampleType cutoff, SampleType q) noexcept {
57 constexpr static auto twoPi = std::numbers::pi_v<SampleType> * static_cast<SampleType>(2.0);
58 const auto fs{ static_cast<SampleType>(sampleRate) };
59 const auto omega{ twoPi * (cutoff / fs) };
60 const auto cosOmega = std::cos(omega);
61 const auto sinOmega = std::sin(omega);
62 const auto alpha{ sinOmega / (static_cast<SampleType>(2.0) * q) };
63 const auto a0 = (static_cast<SampleType>(1.0) + cosOmega) / static_cast<SampleType>(2.0);
64 const auto a1 = static_cast<SampleType>(-1.0) * (static_cast<SampleType>(1.0) + cosOmega);
65 const auto a2 = a0;
66 const auto b0 = static_cast<SampleType>(1.0) + alpha;
67 const auto b1 = static_cast<SampleType>(-2.0) * cosOmega;
68 const auto b2 = static_cast<SampleType>(1.0) - alpha;
70 .a0 = a0,
71 .a1 = a1,
72 .a2 = a2,
73 .b0 = b0,
74 .b1 = b1,
75 .b2 = b2
76 };
77 }
78
86 template <FloatType SampleType>
87 [[nodiscard]] BiquadCoefficients<SampleType> bandpass(double sampleRate, SampleType centreFrequency, SampleType bandwidth, SampleType peakGain) noexcept {
88 constexpr static auto twoPi = std::numbers::pi_v<SampleType> * static_cast<SampleType>(2.0);
89 const auto fs{ static_cast<SampleType>(sampleRate) };
90 const auto omega{ twoPi * (centreFrequency / fs) };
91 const auto cosOmega = std::cos(omega);
92 const auto sinOmega = std::sin(omega);
93 const auto log2Over2 = std::log(static_cast<SampleType>(2.0)) / static_cast<SampleType>(2.0);
94 const auto alpha = sinOmega * std::sinh(log2Over2 * bandwidth * (omega / sinOmega));
95 const auto a0 = (sinOmega / static_cast<SampleType>(2.0)) * (peakGain * alpha);
96 const auto a1 = static_cast<SampleType>(0.0);
97 const auto a2 = static_cast<SampleType>(-1.0) * (sinOmega / static_cast<SampleType>(2.0));
98 const auto b0 = static_cast<SampleType>(1.0) + alpha;
99 const auto b1 = static_cast<SampleType>(-2.0) * cosOmega;
100 const auto b2 = static_cast<SampleType>(1.0) - alpha;
102 .a0 = a0,
103 .a1 = a1,
104 .a2 = a2,
105 .b0 = b0,
106 .b1 = b1,
107 .b2 = b2
108 };
109 }
110
118 template <FloatType SampleType>
119 [[nodiscard]] BiquadCoefficients<SampleType> bandpass(double sampleRate, SampleType centreFrequency, SampleType bandwidth) noexcept {
120 constexpr static auto twoPi = std::numbers::pi_v<SampleType> * static_cast<SampleType>(2.0);
121 const auto fs{ static_cast<SampleType>(sampleRate) };
122 const auto omega{ twoPi * (centreFrequency / fs) };
123 const auto cosOmega = std::cos(omega);
124 const auto sinOmega = std::sin(omega);
125 const auto log2Over2 = std::log(static_cast<SampleType>(2.0)) / static_cast<SampleType>(2.0);
126 const auto alpha = sinOmega * std::sinh(log2Over2 * bandwidth * (omega / sinOmega));
127 const auto a0 = alpha;
128 const auto a1 = static_cast<SampleType>(0.0);
129 const auto a2 = static_cast<SampleType>(-1.0) * alpha;
130 const auto b0 = static_cast<SampleType>(1.0) + alpha;
131 const auto b1 = static_cast<SampleType>(-2.0) * cosOmega;
132 const auto b2 = static_cast<SampleType>(1.0) - alpha;
134 .a0 = a0,
135 .a1 = a1,
136 .a2 = a2,
137 .b0 = b0,
138 .b1 = b1,
139 .b2 = b2
140 };
141 }
142
150 template <FloatType SampleType>
151 [[nodiscard]] BiquadCoefficients<SampleType> notch(double sampleRate, SampleType centreFrequency, SampleType bandwidth) noexcept {
152 constexpr static auto twoPi = std::numbers::pi_v<SampleType> * static_cast<SampleType>(2.0);
153 const auto fs{ static_cast<SampleType>(sampleRate) };
154 const auto omega{ twoPi * (centreFrequency / fs) };
155 const auto cosOmega = std::cos(omega);
156 const auto sinOmega = std::sin(omega);
157 const auto log2Over2 = std::log(static_cast<SampleType>(2.0)) / static_cast<SampleType>(2.0);
158 const auto alpha = sinOmega * std::sinh(log2Over2 * bandwidth * (omega / sinOmega));
159 const auto a0 = static_cast<SampleType>(1.0);
160 const auto a1 = static_cast<SampleType>(-2.0) * cosOmega;
161 const auto a2 = static_cast<SampleType>(1.0);
162 const auto b0 = static_cast<SampleType>(1.0) + alpha;
163 const auto b1 = static_cast<SampleType>(-2.0) * cosOmega;
164 const auto b2 = static_cast<SampleType>(1.0) - alpha;
166 .a0 = a0,
167 .a1 = a1,
168 .a2 = a2,
169 .b0 = b0,
170 .b1 = b1,
171 .b2 = b2
172 };
173 }
174
181 template <FloatType SampleType>
182 [[nodiscard]] BiquadCoefficients<SampleType> allpass(double sampleRate, SampleType cutoff, SampleType q) noexcept {
183 constexpr static auto twoPi = std::numbers::pi_v<SampleType> * static_cast<SampleType>(2.0);
184 const auto fs{ static_cast<SampleType>(sampleRate) };
185 const auto omega{ twoPi * (cutoff / fs) };
186 const auto cosOmega = std::cos(omega);
187 const auto sinOmega = std::sin(omega);
188 const auto log2Over2 = std::log(static_cast<SampleType>(2.0)) / static_cast<SampleType>(2.0);
189 const auto alpha = sinOmega * std::sinh(log2Over2 * q * (omega / sinOmega));
190 const auto a0 = static_cast<SampleType>(1.0) - alpha;
191 const auto a1 = static_cast<SampleType>(-2.0) * cosOmega;
192 const auto a2 = static_cast<SampleType>(1.0) + alpha;
193 const auto b0 = static_cast<SampleType>(1.0) + alpha;
194 const auto b1 = static_cast<SampleType>(-2.0) * cosOmega;
195 const auto b2 = static_cast<SampleType>(1.0) - alpha;
197 .a0 = a0,
198 .a1 = a1,
199 .a2 = a2,
200 .b0 = b0,
201 .b1 = b1,
202 .b2 = b2
203 };
204 }
205
214 template <FloatType SampleType>
215 [[nodiscard]] BiquadCoefficients<SampleType> peak(double sampleRate, SampleType centreFrequency, SampleType bandwidth, SampleType dbGain) noexcept {
216 constexpr static auto twoPi = std::numbers::pi_v<SampleType> * static_cast<SampleType>(2.0);
217 const auto fs{ static_cast<SampleType>(sampleRate) };
218 const auto A = std::pow(static_cast<SampleType>(10.0), dbGain / static_cast<SampleType>(40.0));
219 const auto omega{ twoPi * (centreFrequency / fs) };
220 const auto cosOmega = std::cos(omega);
221 const auto sinOmega = std::sin(omega);
222 const auto log2Over2 = std::log(static_cast<SampleType>(2.0)) / static_cast<SampleType>(2.0);
223 const auto alpha = sinOmega * std::sinh(log2Over2 * bandwidth * (omega / sinOmega));
224 const auto a0 = static_cast<SampleType>(1.0) + (alpha * A);
225 const auto a1 = static_cast<SampleType>(-2.0) * cosOmega;
226 const auto a2 = static_cast<SampleType>(1.0) - (alpha * A);
227 const auto b0 = static_cast<SampleType>(1.0) + (alpha / A);
228 const auto b1 = static_cast<SampleType>(-2.0) * cosOmega;
229 const auto b2 = static_cast<SampleType>(1.0) - (alpha / A);
231 .a0 = a0,
232 .a1 = a1,
233 .a2 = a2,
234 .b0 = b0,
235 .b1 = b1,
236 .b2 = b2
237 };
238 }
239
248 template <FloatType SampleType>
249 [[nodiscard]] BiquadCoefficients<SampleType> lowShelf(double sampleRate, SampleType centreFrequency, SampleType slope, SampleType dbGain) noexcept {
250 constexpr static auto twoPi = std::numbers::pi_v<SampleType> * static_cast<SampleType>(2.0);
251 const auto fs{ static_cast<SampleType>(sampleRate) };
252 const auto A = std::pow(static_cast<SampleType>(10.0), dbGain / static_cast<SampleType>(40.0));
253 const auto omega{ twoPi * (centreFrequency / fs) };
254 const auto cosOmega = std::cos(omega);
255 const auto sinOmega = std::sin(omega);
256 // const auto halfSinOmega = sinOmega / static_cast<SampleType>(2.0);
257 // const auto aFrac = (A + (static_cast<SampleType>(1.0) / A));
258 const auto slopeFrac = (static_cast<SampleType>(1.0) / slope) - static_cast<SampleType>(1.0);
259 // const auto alphaInner = (aFrac * slopeFrac) + static_cast<SampleType>(2.0);
260 // const auto alpha = halfSinOmega * std::sqrt(alphaInner);
261 // const auto alpha = halfSinOmega * std::sqrt(((A + (static_cast<SampleType>(1.0) / A)) * ((static_cast<SampleType>(1.0) / slope) - static_cast<SampleType>(1.0))) + static_cast<SampleType>(2.0));
262 // const auto twoRootAAlpha = static_cast<SampleType>(2.0) * std::sqrt(A * alpha);
263 const auto twoRootAAlpha = sinOmega * std::sqrt(((std::pow(A, static_cast<SampleType>(2.0)) + static_cast<SampleType>(1.0)) * slopeFrac) + (static_cast<SampleType>(2.0) * A));
264 const auto a0 = A * ((A + static_cast<SampleType>(1.0)) - ((A - static_cast<SampleType>(1.0)) * cosOmega) + twoRootAAlpha);
265 const auto a1 = static_cast<SampleType>(2.0) * A * ((A - static_cast<SampleType>(1.0)) - ((A + static_cast<SampleType>(1.0)) * cosOmega));
266 const auto a2 = A * ((A + static_cast<SampleType>(1.0)) - ((A - static_cast<SampleType>(1.0)) * cosOmega) - twoRootAAlpha);
267 const auto b0 = (A + static_cast<SampleType>(1.0)) + ((A - static_cast<SampleType>(1.0)) * cosOmega) + twoRootAAlpha;
268 const auto b1 = static_cast<SampleType>(-2.0) * ((A - static_cast<SampleType>(1.0)) + ((A + static_cast<SampleType>(1.0)) * cosOmega));
269 const auto b2 = (A + static_cast<SampleType>(1.0)) + ((A - static_cast<SampleType>(1.0)) * cosOmega) - twoRootAAlpha;
271 .a0 = a0,
272 .a1 = a1,
273 .a2 = a2,
274 .b0 = b0,
275 .b1 = b1,
276 .b2 = b2
277 };
278 }
279
288 template <FloatType SampleType>
289 [[nodiscard]] BiquadCoefficients<SampleType> highShelf(double sampleRate, SampleType centreFrequency, SampleType slope, SampleType dbGain) noexcept {
290 constexpr static auto twoPi = std::numbers::pi_v<SampleType> * static_cast<SampleType>(2.0);
291 const auto fs{ static_cast<SampleType>(sampleRate) };
292 const auto A = std::pow(static_cast<SampleType>(10.0), dbGain / static_cast<SampleType>(40.0));
293 const auto omega{ twoPi * (centreFrequency / fs) };
294 const auto cosOmega = std::cos(omega);
295 const auto sinOmega = std::sin(omega);
296 const auto alpha = (sinOmega / static_cast<SampleType>(2.0)) * std::sqrt(((A + (static_cast<SampleType>(1.0) / A)) * ((static_cast<SampleType>(1.0) / slope) - static_cast<SampleType>(1.0))) + static_cast<SampleType>(2.0));
297 const auto twoRootAAlpha = static_cast<SampleType>(2.0) * std::sqrt(A * alpha);
298 const auto a0 = A * ((A + static_cast<SampleType>(1.0)) + (A - static_cast<SampleType>(1.0)) * cosOmega + twoRootAAlpha);
299 const auto a1 = static_cast<SampleType>(-2.0) * A * ((A - static_cast<SampleType>(1.0)) + (A + static_cast<SampleType>(1.0)) * cosOmega);
300 const auto a2 = A * ((A + static_cast<SampleType>(1.0)) + (A - static_cast<SampleType>(1.0)) * cosOmega - twoRootAAlpha);
301 const auto b0 = (A + static_cast<SampleType>(1.0)) - (A - static_cast<SampleType>(1.0)) * cosOmega + twoRootAAlpha;
302 const auto b1 = static_cast<SampleType>(2.0) * ((A - static_cast<SampleType>(1.0)) - (A + static_cast<SampleType>(1.0)) * cosOmega);
303 const auto b2 = (A + static_cast<SampleType>(1.0)) - (A - static_cast<SampleType>(1.0)) * cosOmega - twoRootAAlpha;
305 .a0 = a0,
306 .a1 = a1,
307 .a2 = a2,
308 .b0 = b0,
309 .b1 = b1,
310 .b2 = b2
311 };
312 }
313} // namespace marvin::dsp::filters::rbj
314
315
316#endif
Implementations of Robert Brinstow Johnson's RBJ Cookbook formulae.
Definition marvin_RBJCoefficients.h:16
BiquadCoefficients< SampleType > allpass(double sampleRate, SampleType cutoff, SampleType q) noexcept
Definition marvin_RBJCoefficients.h:182
BiquadCoefficients< SampleType > lowShelf(double sampleRate, SampleType centreFrequency, SampleType slope, SampleType dbGain) noexcept
Definition marvin_RBJCoefficients.h:249
BiquadCoefficients< SampleType > bandpass(double sampleRate, SampleType centreFrequency, SampleType bandwidth, SampleType peakGain) noexcept
Definition marvin_RBJCoefficients.h:87
BiquadCoefficients< SampleType > highpass(double sampleRate, SampleType cutoff, SampleType q) noexcept
Definition marvin_RBJCoefficients.h:56
BiquadCoefficients< SampleType > lowpass(double sampleRate, SampleType cutoff, SampleType q) noexcept
Definition marvin_RBJCoefficients.h:25
BiquadCoefficients< SampleType > highShelf(double sampleRate, SampleType centreFrequency, SampleType slope, SampleType dbGain) noexcept
Definition marvin_RBJCoefficients.h:289
BiquadCoefficients< SampleType > notch(double sampleRate, SampleType centreFrequency, SampleType bandwidth) noexcept
Definition marvin_RBJCoefficients.h:151
BiquadCoefficients< SampleType > peak(double sampleRate, SampleType centreFrequency, SampleType bandwidth, SampleType dbGain) noexcept
Definition marvin_RBJCoefficients.h:215
A POD type for use with the Biquad class, and the SmoothedBiquadCoefficients class.
Definition marvin_BiquadCoefficients.h:22