LMMS
Loading...
Searching...
No Matches
BasicFilters.h
Go to the documentation of this file.
1/*
2 * BasicFilters.h - simple but powerful filter-class with most used filters
3 *
4 * original file by ???
5 * modified and enhanced by Tobias Doerffel
6 *
7 * Lowpass_SV code originally from Nekobee, Copyright (C) 2004 Sean Bolton and others
8 * adapted & modified for use in LMMS
9 *
10 * Copyright (c) 2004-2009 Tobias Doerffel <tobydox/at/users.sourceforge.net>
11 *
12 * This file is part of LMMS - https://lmms.io
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public
16 * License as published by the Free Software Foundation; either
17 * version 2 of the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public
25 * License along with this program (see COPYING); if not, write to the
26 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
27 * Boston, MA 02110-1301 USA.
28 *
29 */
30
31#ifndef LMMS_BASIC_FILTERS_H
32#define LMMS_BASIC_FILTERS_H
33
34#include <algorithm>
35#include <array>
36#include <cmath>
37#include <numbers>
38
39#include "lmms_constants.h"
40#include "LmmsTypes.h"
41
42
43namespace lmms
44{
45
46template<ch_cnt_t CHANNELS=DEFAULT_CHANNELS> class BasicFilters;
47
48template<ch_cnt_t CHANNELS>
50{
51public:
52 LinkwitzRiley( float sampleRate )
53 {
54 m_sampleRate = sampleRate;
56 }
57 virtual ~LinkwitzRiley() = default;
58
59 inline void clearHistory()
60 {
61 for( int i = 0; i < CHANNELS; ++i )
62 {
63 m_z1[i] = m_z2[i] = m_z3[i] = m_z4[i] = 0.0f;
64 }
65 }
66
67 inline void setSampleRate( float sampleRate )
68 {
69 m_sampleRate = sampleRate;
70 }
71
72 inline void setCoeffs( float freq )
73 {
74 using namespace std::numbers;
75 // wc
76 const double wc = 2 * pi * freq;
77 const double wc2 = wc * wc;
78 const double wc3 = wc2 * wc;
79 m_wc4 = wc2 * wc2;
80
81 // k
82 const double k = wc / std::tan(pi * freq / m_sampleRate);
83 const double k2 = k * k;
84 const double k3 = k2 * k;
85 m_k4 = k2 * k2;
86
87 // a
88 const double sq_tmp1 = sqrt2 * wc3 * k;
89 const double sq_tmp2 = sqrt2 * wc * k3;
90
91 m_a = 1.0 / ( 4.0 * wc2 * k2 + 2.0 * sq_tmp1 + m_k4 + 2.0 * sq_tmp2 + m_wc4 );
92
93 // b
94 m_b1 = ( 4.0 * ( m_wc4 + sq_tmp1 - m_k4 - sq_tmp2 ) ) * m_a;
95 m_b2 = ( 6.0 * m_wc4 - 8.0 * wc2 * k2 + 6.0 * m_k4 ) * m_a;
96 m_b3 = ( 4.0 * ( m_wc4 - sq_tmp1 + sq_tmp2 - m_k4 ) ) * m_a;
97 m_b4 = ( m_k4 - 2.0 * sq_tmp1 + m_wc4 - 2.0 * sq_tmp2 + 4.0 * wc2 * k2 ) * m_a;
98 }
99
100 inline void setLowpass( float freq )
101 {
102 setCoeffs( freq );
103 m_a0 = m_wc4 * m_a;
104 m_a1 = 4.0 * m_a0;
105 m_a2 = 6.0 * m_a0;
106 }
107
108 inline void setHighpass( float freq )
109 {
110 setCoeffs( freq );
111 m_a0 = m_k4 * m_a;
112 m_a1 = -4.0 * m_a0;
113 m_a2 = 6.0 * m_a0;
114 }
115
116 inline float update( float in, ch_cnt_t ch )
117 {
118 const double x = in - ( m_z1[ch] * m_b1 ) - ( m_z2[ch] * m_b2 ) -
119 ( m_z3[ch] * m_b3 ) - ( m_z4[ch] * m_b4 );
120 const double y = ( m_a0 * x ) + ( m_z1[ch] * m_a1 ) + ( m_z2[ch] * m_a2 ) +
121 ( m_z3[ch] * m_a1 ) + ( m_z4[ch] * m_a0 );
122 m_z4[ch] = m_z3[ch];
123 m_z3[ch] = m_z2[ch];
124 m_z2[ch] = m_z1[ch];
125 m_z1[ch] = x;
126
127 return y;
128 }
129
130private:
132 double m_wc4;
133 double m_k4;
134 double m_a, m_a0, m_a1, m_a2;
135 double m_b1, m_b2, m_b3, m_b4;
136
137 using frame = std::array<double, CHANNELS>;
139};
141
142template<ch_cnt_t CHANNELS>
144{
145public:
147 m_a1(0.),
148 m_a2(0.),
149 m_b0(0.),
150 m_b1(0.),
151 m_b2(0.)
152 {
153 clearHistory();
154 }
155 virtual ~BiQuad() = default;
156
157 inline void setCoeffs( float a1, float a2, float b0, float b1, float b2 )
158 {
159 m_a1 = a1;
160 m_a2 = a2;
161 m_b0 = b0;
162 m_b1 = b1;
163 m_b2 = b2;
164 }
165 inline void clearHistory()
166 {
167 for( int i = 0; i < CHANNELS; ++i )
168 {
169 m_z1[i] = 0.0f;
170 m_z2[i] = 0.0f;
171 }
172 }
173 inline float update( float in, ch_cnt_t ch )
174 {
175 // biquad filter in transposed form
176 const float out = m_z1[ch] + m_b0 * in;
177 m_z1[ch] = m_b1 * in + m_z2[ch] - m_a1 * out;
178 m_z2[ch] = m_b2 * in - m_a2 * out;
179 return out;
180 }
181private:
182 float m_a1, m_a2, m_b0, m_b1, m_b2;
183 float m_z1 [CHANNELS], m_z2 [CHANNELS];
184
185 friend class BasicFilters<CHANNELS>; // needed for subfilter stuff in BasicFilters
186};
188
189template<ch_cnt_t CHANNELS>
191{
192public:
194 {
195 m_a0 = 1.0;
196 m_b1 = 0.0;
197 for( int i = 0; i < CHANNELS; ++i )
198 {
199 m_z1[i] = 0.0;
200 }
201 }
202 virtual ~OnePole() = default;
203
204 inline void setCoeffs( float a0, float b1 )
205 {
206 m_a0 = a0;
207 m_b1 = b1;
208 }
209
210 inline float update( float s, ch_cnt_t ch )
211 {
212 if (std::abs(s) < F_EPSILON && std::abs(m_z1[ch]) < F_EPSILON) { return 0.0f; }
213 return m_z1[ch] = s * m_a0 + m_z1[ch] * m_b1;
214 }
215
216private:
217 float m_a0, m_b1;
218 float m_z1 [CHANNELS];
219};
221
222template<ch_cnt_t CHANNELS>
224{
225public:
251
252 static inline float minFreq()
253 {
254 return( 5.0f );
255 }
256
257 static inline float minQ()
258 {
259 return( 0.01f );
260 }
261
262 inline void setFilterType( const FilterType _idx )
263 {
265 if( !m_doubleFilter )
266 {
267 m_type = _idx;
268 return;
269 }
270
271 // Double lowpass mode, backwards-compat for the goofy
272 // Add-NumFilters to signify doubleFilter stuff
276 if( m_subFilter == nullptr )
277 {
279 static_cast<sample_rate_t>(
280 m_sampleRate ) );
281 }
282 m_subFilter->m_type = m_type;
283 }
284
285 inline BasicFilters( const sample_rate_t _sample_rate ) :
287 m_sampleRate( (float) _sample_rate ),
288 m_sampleRatio( 1.0f / m_sampleRate ),
290 {
291 clearHistory();
292 }
293
295 {
296 delete m_subFilter;
297 }
298
299 inline void clearHistory()
300 {
301 // reset in/out history for biquads
302 m_biQuad.clearHistory();
303
304 // reset in/out history
305 for( ch_cnt_t _chnl = 0; _chnl < CHANNELS; ++_chnl )
306 {
307 // reset in/out history for moog-filter
308 m_y1[_chnl] = m_y2[_chnl] = m_y3[_chnl] = m_y4[_chnl] =
309 m_oldx[_chnl] = m_oldy1[_chnl] =
310 m_oldy2[_chnl] = m_oldy3[_chnl] = 0.0f;
311
312 // tripole
313 m_last[_chnl] = 0.0f;
314
315 // reset in/out history for RC-filters
316 m_rclp0[_chnl] = m_rcbp0[_chnl] = m_rchp0[_chnl] = m_rclast0[_chnl] = 0.0f;
317 m_rclp1[_chnl] = m_rcbp1[_chnl] = m_rchp1[_chnl] = m_rclast1[_chnl] = 0.0f;
318
319 for(int i=0; i<6; i++)
320 m_vfbp[i][_chnl] = m_vfhp[i][_chnl] = m_vflast[i][_chnl] = 0.0f;
321
322 // reset in/out history for SV-filters
323 m_delay1[_chnl] = 0.0f;
324 m_delay2[_chnl] = 0.0f;
325 m_delay3[_chnl] = 0.0f;
326 m_delay4[_chnl] = 0.0f;
327 }
328 }
329
330 inline void setSampleRate(const sample_rate_t sampleRate)
331 {
332 m_sampleRate = sampleRate;
334 if (m_subFilter != nullptr)
335 {
336 m_subFilter->setSampleRate(m_sampleRate);
337 }
338 }
339
340 inline sample_t update( sample_t _in0, ch_cnt_t _chnl )
341 {
342 sample_t out = 0.0f;
343 switch( m_type )
344 {
345 case FilterType::Moog:
346 {
347 sample_t x = _in0 - m_r*m_y4[_chnl];
348
349 // four cascaded onepole filters
350 // (bilinear transform)
351 m_y1[_chnl] = std::clamp((x + m_oldx[_chnl]) * m_p
352 - m_k * m_y1[_chnl], -10.0f,
353 10.0f);
354 m_y2[_chnl] = std::clamp((m_y1[_chnl] + m_oldy1[_chnl]) * m_p
355 - m_k * m_y2[_chnl], -10.0f,
356 10.0f);
357 m_y3[_chnl] = std::clamp((m_y2[_chnl] + m_oldy2[_chnl]) * m_p
358 - m_k * m_y3[_chnl], -10.0f,
359 10.0f );
360 m_y4[_chnl] = std::clamp((m_y3[_chnl] + m_oldy3[_chnl]) * m_p
361 - m_k * m_y4[_chnl], -10.0f,
362 10.0f);
363
364 m_oldx[_chnl] = x;
365 m_oldy1[_chnl] = m_y1[_chnl];
366 m_oldy2[_chnl] = m_y2[_chnl];
367 m_oldy3[_chnl] = m_y3[_chnl];
368 out = m_y4[_chnl] - m_y4[_chnl] * m_y4[_chnl] *
369 m_y4[_chnl] * ( 1.0f / 6.0f );
370 break;
371 }
372
373 // 3x onepole filters with 4x oversampling and interpolation of oversampled signal:
374 // input signal is linear-interpolated after oversampling, output signal is averaged from oversampled outputs
376 {
377 float ip = 0.0f;
378 for( int i = 0; i < 4; ++i )
379 {
380 ip += 0.25f;
381 sample_t x = std::lerp(m_last[_chnl], _in0, ip) - m_r * m_y3[_chnl];
382
383 m_y1[_chnl] = std::clamp((x + m_oldx[_chnl]) * m_p
384 - m_k * m_y1[_chnl], -10.0f,
385 10.0f);
386 m_y2[_chnl] = std::clamp((m_y1[_chnl] + m_oldy1[_chnl]) * m_p
387 - m_k * m_y2[_chnl], -10.0f,
388 10.0f);
389 m_y3[_chnl] = std::clamp((m_y2[_chnl] + m_oldy2[_chnl]) * m_p
390 - m_k * m_y3[_chnl], -10.0f,
391 10.0f);
392 m_oldx[_chnl] = x;
393 m_oldy1[_chnl] = m_y1[_chnl];
394 m_oldy2[_chnl] = m_y2[_chnl];
395
396 out += ( m_y3[_chnl] - m_y3[_chnl] * m_y3[_chnl] * m_y3[_chnl] * ( 1.0f / 6.0f ) );
397 }
398 out *= 0.25f;
399 m_last[_chnl] = _in0;
400 return out;
401 }
402
403 // 4-pole state-variant lowpass filter, adapted from Nekobee source code
404 // and extended to other SV filter types
405 // /* Hal Chamberlin's state variable filter */
406
409 {
410 float highpass;
411
412 for( int i = 0; i < 2; ++i ) // 2x oversample
413 {
414 m_delay2[_chnl] = m_delay2[_chnl] + m_svf1 * m_delay1[_chnl]; /* delay2/4 = lowpass output */
415 highpass = _in0 - m_delay2[_chnl] - m_svq * m_delay1[_chnl];
416 m_delay1[_chnl] = m_svf1 * highpass + m_delay1[_chnl]; /* delay1/3 = bandpass output */
417
418 m_delay4[_chnl] = m_delay4[_chnl] + m_svf2 * m_delay3[_chnl];
419 highpass = m_delay2[_chnl] - m_delay4[_chnl] - m_svq * m_delay3[_chnl];
420 m_delay3[_chnl] = m_svf2 * highpass + m_delay3[_chnl];
421 }
422
423 /* mix filter output into output buffer */
425 ? m_delay4[_chnl]
426 : m_delay3[_chnl];
427 }
428
430 {
431 float hp;
432 for( int i = 0; i < 2; ++i ) // 2x oversample
433 {
434 m_delay2[_chnl] = m_delay2[_chnl] + m_svf1 * m_delay1[_chnl];
435 hp = _in0 - m_delay2[_chnl] - m_svq * m_delay1[_chnl];
436 m_delay1[_chnl] = m_svf1 * hp + m_delay1[_chnl];
437 }
438
439 return hp;
440 }
441
443 {
444 float hp1;
445 for( int i = 0; i < 2; ++i ) // 2x oversample
446 {
447 m_delay2[_chnl] = m_delay2[_chnl] + m_svf1 * m_delay1[_chnl]; /* delay2/4 = lowpass output */
448 hp1 = _in0 - m_delay2[_chnl] - m_svq * m_delay1[_chnl];
449 m_delay1[_chnl] = m_svf1 * hp1 + m_delay1[_chnl]; /* delay1/3 = bandpass output */
450
451 m_delay4[_chnl] = m_delay4[_chnl] + m_svf2 * m_delay3[_chnl];
452 float hp2 = m_delay2[_chnl] - m_delay4[_chnl] - m_svq * m_delay3[_chnl];
453 m_delay3[_chnl] = m_svf2 * hp2 + m_delay3[_chnl];
454 }
455
456 /* mix filter output into output buffer */
457 return m_delay4[_chnl] + hp1;
458 }
459
460
461 // 4-times oversampled simulation of an active RC-Bandpass,-Lowpass,-Highpass-
462 // Filter-Network as it was used in nearly all modern analog synthesizers. This
463 // can be driven up to self-oscillation (BTW: do not remove the limits!!!).
464 // (C) 1998 ... 2009 S.Fendt. Released under the GPL v2.0 or any later version.
465
467 {
468 sample_t lp = 0.0f;
469 for( int n = 4; n != 0; --n )
470 {
471 sample_t in = _in0 + m_rcbp0[_chnl] * m_rcq;
472 in = std::clamp(in, -1.0f, 1.0f);
473
474 lp = in * m_rcb + m_rclp0[_chnl] * m_rca;
475 lp = std::clamp(lp, -1.0f, 1.0f);
476
477 sample_t hp = m_rcc * (m_rchp0[_chnl] + in - m_rclast0[_chnl]);
478 hp = std::clamp(hp, -1.0f, 1.0f);
479
480 sample_t bp = hp * m_rcb + m_rcbp0[_chnl] * m_rca;
481 bp = std::clamp(bp, -1.0f, 1.0f);
482
483 m_rclast0[_chnl] = in;
484 m_rclp0[_chnl] = lp;
485 m_rchp0[_chnl] = hp;
486 m_rcbp0[_chnl] = bp;
487 }
488 return lp;
489 }
492 {
493 sample_t hp, bp;
494 for( int n = 4; n != 0; --n )
495 {
496 sample_t in = _in0 + m_rcbp0[_chnl] * m_rcq;
497 in = std::clamp(in, -1.0f, 1.0f);
498
499 hp = m_rcc * ( m_rchp0[_chnl] + in - m_rclast0[_chnl] );
500 hp = std::clamp(hp, -1.0f, 1.0f);
501
502 bp = hp * m_rcb + m_rcbp0[_chnl] * m_rca;
503 bp = std::clamp(bp, -1.0f, 1.0f);
504
505 m_rclast0[_chnl] = in;
506 m_rchp0[_chnl] = hp;
507 m_rcbp0[_chnl] = bp;
508 }
509 return m_type == FilterType::Highpass_RC12 ? hp : bp;
510 }
511
513 {
514 sample_t lp;
515 for( int n = 4; n != 0; --n )
516 {
517 // first stage is as for the 12dB case...
518 sample_t in = _in0 + m_rcbp0[_chnl] * m_rcq;
519 in = std::clamp(in, -1.0f, 1.0f);
520
521 lp = in * m_rcb + m_rclp0[_chnl] * m_rca;
522 lp = std::clamp(lp, -1.0f, 1.0f);
523
524 sample_t hp = m_rcc * ( m_rchp0[_chnl] + in - m_rclast0[_chnl] );
525 hp = std::clamp(hp, -1.0f, 1.0f);
526
527 sample_t bp = hp * m_rcb + m_rcbp0[_chnl] * m_rca;
528 bp = std::clamp(bp, -1.0f, 1.0f);
529
530 m_rclast0[_chnl] = in;
531 m_rclp0[_chnl] = lp;
532 m_rcbp0[_chnl] = bp;
533 m_rchp0[_chnl] = hp;
534
535 // second stage gets the output of the first stage as input...
536 in = lp + m_rcbp1[_chnl] * m_rcq;
537 in = std::clamp(in, -1.0f, 1.0f );
538
539 lp = in * m_rcb + m_rclp1[_chnl] * m_rca;
540 lp = std::clamp(lp, -1.0f, 1.0f);
541
542 hp = m_rcc * ( m_rchp1[_chnl] + in - m_rclast1[_chnl] );
543 hp = std::clamp(hp, -1.0f, 1.0f);
544
545 bp = hp * m_rcb + m_rcbp1[_chnl] * m_rca;
546 bp = std::clamp(bp, -1.0f, 1.0f);
547
548 m_rclast1[_chnl] = in;
549 m_rclp1[_chnl] = lp;
550 m_rcbp1[_chnl] = bp;
551 m_rchp1[_chnl] = hp;
552 }
553 return lp;
554 }
557 {
558 sample_t hp, bp;
559 for( int n = 4; n != 0; --n )
560 {
561 // first stage is as for the 12dB case...
562 sample_t in = _in0 + m_rcbp0[_chnl] * m_rcq;
563 in = std::clamp(in, -1.0f, 1.0f);
564
565 hp = m_rcc * ( m_rchp0[_chnl] + in - m_rclast0[_chnl] );
566 hp = std::clamp(hp, -1.0f, 1.0f);
567
568 bp = hp * m_rcb + m_rcbp0[_chnl] * m_rca;
569 bp = std::clamp(bp, -1.0f, 1.0f);
570
571 m_rclast0[_chnl] = in;
572 m_rchp0[_chnl] = hp;
573 m_rcbp0[_chnl] = bp;
574
575 // second stage gets the output of the first stage as input...
577 ? hp + m_rcbp1[_chnl] * m_rcq
578 : bp + m_rcbp1[_chnl] * m_rcq;
579
580 in = std::clamp(in, -1.0f, 1.0f);
581
582 hp = m_rcc * ( m_rchp1[_chnl] + in - m_rclast1[_chnl] );
583 hp = std::clamp(hp, -1.0f, 1.0f);
584
585 bp = hp * m_rcb + m_rcbp1[_chnl] * m_rca;
586 bp = std::clamp(bp, -1.0f, 1.0f);
587
588 m_rclast1[_chnl] = in;
589 m_rchp1[_chnl] = hp;
590 m_rcbp1[_chnl] = bp;
591 }
592 return m_type == FilterType::Highpass_RC24 ? hp : bp;
593 }
594
597 {
598 if (std::abs(_in0) < F_EPSILON && std::abs(m_vflast[0][_chnl]) < F_EPSILON) { return 0.0f; } // performance hack - skip processing when the numbers get too small
599
600 const int os = m_type == FilterType::FastFormant ? 1 : 4; // no oversampling for fast formant
601 for( int o = 0; o < os; ++o )
602 {
603 // first formant
604 sample_t in = _in0 + m_vfbp[0][_chnl] * m_vfq;
605 in = std::clamp(in, -1.0f, 1.0f);
606
607 sample_t hp = m_vfc[0] * ( m_vfhp[0][_chnl] + in - m_vflast[0][_chnl] );
608 hp = std::clamp(hp, -1.0f, 1.0f);
609
610 sample_t bp = hp * m_vfb[0] + m_vfbp[0][_chnl] * m_vfa[0];
611 bp = std::clamp(bp, -1.0f, 1.0f);
612
613 m_vflast[0][_chnl] = in;
614 m_vfhp[0][_chnl] = hp;
615 m_vfbp[0][_chnl] = bp;
616
617 in = bp + m_vfbp[2][_chnl] * m_vfq;
618 in = std::clamp(in, -1.0f, 1.0f);
619
620 hp = m_vfc[0] * ( m_vfhp[2][_chnl] + in - m_vflast[2][_chnl] );
621 hp = std::clamp(hp, -1.0f, 1.0f);
622
623 bp = hp * m_vfb[0] + m_vfbp[2][_chnl] * m_vfa[0];
624 bp = std::clamp(bp, -1.0f, 1.0f);
625
626 m_vflast[2][_chnl] = in;
627 m_vfhp[2][_chnl] = hp;
628 m_vfbp[2][_chnl] = bp;
629
630 in = bp + m_vfbp[4][_chnl] * m_vfq;
631 in = std::clamp(in, -1.0f, 1.0f);
632
633 hp = m_vfc[0] * ( m_vfhp[4][_chnl] + in - m_vflast[4][_chnl] );
634 hp = std::clamp(hp, -1.0f, 1.0f);
635
636 bp = hp * m_vfb[0] + m_vfbp[4][_chnl] * m_vfa[0];
637 bp = std::clamp(bp, -1.0f, 1.0f);
638
639 m_vflast[4][_chnl] = in;
640 m_vfhp[4][_chnl] = hp;
641 m_vfbp[4][_chnl] = bp;
642
643 out += bp;
644
645 // second formant
646 in = _in0 + m_vfbp[0][_chnl] * m_vfq;
647 in = std::clamp(in, -1.0f, 1.0f);
648
649 hp = m_vfc[1] * ( m_vfhp[1][_chnl] + in - m_vflast[1][_chnl] );
650 hp = std::clamp(hp, -1.0f, 1.0f);
651
652 bp = hp * m_vfb[1] + m_vfbp[1][_chnl] * m_vfa[1];
653 bp = std::clamp(bp, -1.0f, 1.0f);
654
655 m_vflast[1][_chnl] = in;
656 m_vfhp[1][_chnl] = hp;
657 m_vfbp[1][_chnl] = bp;
658
659 in = bp + m_vfbp[3][_chnl] * m_vfq;
660 in = std::clamp(in, -1.0f, 1.0f);
661
662 hp = m_vfc[1] * ( m_vfhp[3][_chnl] + in - m_vflast[3][_chnl] );
663 hp = std::clamp(hp, -1.0f, 1.0f);
664
665 bp = hp * m_vfb[1] + m_vfbp[3][_chnl] * m_vfa[1];
666 bp = std::clamp(bp, -1.0f, 1.0f);
667
668 m_vflast[3][_chnl] = in;
669 m_vfhp[3][_chnl] = hp;
670 m_vfbp[3][_chnl] = bp;
671
672 in = bp + m_vfbp[5][_chnl] * m_vfq;
673 in = std::clamp(in, -1.0f, 1.0f);
674
675 hp = m_vfc[1] * ( m_vfhp[5][_chnl] + in - m_vflast[5][_chnl] );
676 hp = std::clamp(hp, -1.0f, 1.0f);
677
678 bp = hp * m_vfb[1] + m_vfbp[5][_chnl] * m_vfa[1];
679 bp = std::clamp(bp, -1.0f, 1.0f);
680
681 m_vflast[5][_chnl] = in;
682 m_vfhp[5][_chnl] = hp;
683 m_vfbp[5][_chnl] = bp;
684
685 out += bp;
686 }
687 return m_type == FilterType::FastFormant ? out * 2.0f : out * 0.5f;
688 }
689
690 default:
691 out = m_biQuad.update( _in0, _chnl );
692 break;
693 }
694
695 if( m_doubleFilter )
696 {
697 return m_subFilter->update( out, _chnl );
698 }
699
700 // Clipper band limited sigmoid
701 return out;
702 }
703
704
705 inline void calcFilterCoeffs( float _freq, float _q )
706 {
707 using namespace std::numbers;
708 // temp coef vars
709 _q = std::max(_q, minQ());
710
717 {
718 _freq = std::clamp(_freq, 50.0f, 20000.0f);
719 const float sr = m_sampleRatio * 0.25f;
720 const float f = 1.0f / (_freq * 2 * pi_v<float>);
721
722 m_rca = 1.0f - sr / ( f + sr );
723 m_rcb = 1.0f - m_rca;
724 m_rcc = f / ( f + sr );
725
726 // Stretch Q/resonance, as self-oscillation reliably starts at a q of ~2.5 - ~2.6
727 m_rcq = _q * 0.25f;
728 return;
729 }
730
733 {
734 _freq = std::clamp(_freq, minFreq(), 20000.0f); // limit freq and q for not getting bad noise out of the filter...
735
736 // formats for a, e, i, o, u, a
737 static const float _f[6][2] = { { 1000, 1400 }, { 500, 2300 },
738 { 320, 3200 },
739 { 500, 1000 },
740 { 320, 800 },
741 { 1000, 1400 } };
742 static const float freqRatio = 4.0f / 14000.0f;
743
744 // Stretch Q/resonance
745 m_vfq = _q * 0.25f;
746
747 // frequency in lmms ranges from 1Hz to 14000Hz
748 const float vowelf = _freq * freqRatio;
749 const int vowel = static_cast<int>( vowelf );
750 const float fract = vowelf - vowel;
751
752 // interpolate between formant frequencies
753 const float f0 = 1.f / (std::lerp(_f[vowel+0][0], _f[vowel+1][0], fract) * 2 * pi_v<float>);
754 const float f1 = 1.f / (std::lerp(_f[vowel+0][1], _f[vowel+1][1], fract) * 2 * pi_v<float>);
755
756 // samplerate coeff: depends on oversampling
757 const float sr = m_type == FilterType::FastFormant ? m_sampleRatio : m_sampleRatio * 0.25f;
758
759 m_vfa[0] = 1.0f - sr / ( f0 + sr );
760 m_vfb[0] = 1.0f - m_vfa[0];
761 m_vfc[0] = f0 / ( f0 + sr );
762 m_vfa[1] = 1.0f - sr / ( f1 + sr );
763 m_vfb[1] = 1.0f - m_vfa[1];
764 m_vfc[1] = f1 / ( f1 + sr );
765 return;
766 }
767
768 if( m_type == FilterType::Moog ||
770 {
771 // [ 0 - 0.5 ]
772 const float f = std::clamp(_freq, minFreq(), 20000.0f) * m_sampleRatio;
773 // (Empirical tuning)
774 m_p = ( 3.6f - 3.2f * f ) * f;
775 m_k = 2.0f * m_p - 1;
776 m_r = _q * std::exp((1 - m_p) * 1.386249f);
777
778 if( m_doubleFilter )
779 {
780 m_subFilter->m_r = m_r;
781 m_subFilter->m_p = m_p;
782 m_subFilter->m_k = m_k;
783 }
784 return;
785 }
786
788 {
789 const float f = std::clamp(_freq, 20.0f, 20000.0f) * m_sampleRatio * 0.25f;
790
791 m_p = ( 3.6f - 3.2f * f ) * f;
792 m_k = 2.0f * m_p - 1.0f;
793 m_r = _q * 0.1f * std::exp((1 - m_p) * 1.386249f);
794
795 return;
796 }
797
802 {
803 const float f = std::sin(std::max(minFreq(), _freq) * m_sampleRatio * pi_v<float>);
804 m_svf1 = std::min(f, 0.825f);
805 m_svf2 = std::min(f * 2.0f, 0.825f);
806 m_svq = std::max(0.0001f, 2.0f - (_q * 0.1995f));
807 return;
808 }
809
810 // other filters
811 _freq = std::clamp(_freq, minFreq(), 20000.0f);
812 const float omega = 2 * pi_v<float> * _freq * m_sampleRatio;
813 const float tsin = std::sin(omega) * 0.5f;
814 const float tcos = std::cos(omega);
815
816 const float alpha = tsin / _q;
817
818 const float a0 = 1.0f / ( 1.0f + alpha );
819
820 const float a1 = -2.0f * tcos * a0;
821 const float a2 = ( 1.0f - alpha ) * a0;
822
823 switch( m_type )
824 {
826 {
827 const float b1 = ( 1.0f - tcos ) * a0;
828 const float b0 = b1 * 0.5f;
829 m_biQuad.setCoeffs( a1, a2, b0, b1, b0 );
830 break;
831 }
833 {
834 const float b1 = ( -1.0f - tcos ) * a0;
835 const float b0 = b1 * -0.5f;
836 m_biQuad.setCoeffs( a1, a2, b0, b1, b0 );
837 break;
838 }
840 {
841 const float b0 = tsin * a0;
842 m_biQuad.setCoeffs( a1, a2, b0, 0.0f, -b0 );
843 break;
844 }
846 {
847 const float b0 = alpha * a0;
848 m_biQuad.setCoeffs( a1, a2, b0, 0.0f, -b0 );
849 break;
850 }
852 {
853 m_biQuad.setCoeffs( a1, a2, a0, a1, a0 );
854 break;
855 }
857 {
858 m_biQuad.setCoeffs( a1, a2, a2, a1, 1.0f );
859 break;
860 }
861 default:
862 break;
863 }
864
865 if( m_doubleFilter )
866 {
867 m_subFilter->m_biQuad.setCoeffs( m_biQuad.m_a1, m_biQuad.m_a2, m_biQuad.m_b0, m_biQuad.m_b1, m_biQuad.m_b2 );
868 }
869 }
870
871
872private:
873 // biquad filter
875
876 // coeffs for moog-filter
877 float m_r, m_p, m_k;
878
879 // coeffs for RC-type-filters
881
882 // coeffs for formant-filters
883 float m_vfa[4], m_vfb[4], m_vfc[4], m_vfq;
884
885 // coeffs for Lowpass_SV (state-variant lowpass)
887
888 using frame = std::array<sample_t, CHANNELS>;
889
890 // in/out history for moog-filter
892 // additional one for Tripole filter
894
895 // in/out history for RC-type-filters
898
899 // in/out history for Formant-filters
901
902 // in/out history for Lowpass_SV (state-variant lowpass)
904
907
911
912} ;
913
914
915} // namespace lmms
916
917#endif // LMMS_BASIC_FILTERS_H
#define nullptr
Definition DistrhoDefines.h:75
Definition BasicFilters.h:224
BasicFilters< CHANNELS > * m_subFilter
Definition BasicFilters.h:910
frame m_delay1
Definition BasicFilters.h:903
void calcFilterCoeffs(float _freq, float _q)
Definition BasicFilters.h:705
void setFilterType(const FilterType _idx)
Definition BasicFilters.h:262
float m_vfq
Definition BasicFilters.h:883
frame m_oldy1
Definition BasicFilters.h:891
~BasicFilters()
Definition BasicFilters.h:294
frame m_rcbp1
Definition BasicFilters.h:897
float m_svf2
Definition BasicFilters.h:886
frame m_vfhp[6]
Definition BasicFilters.h:900
void setSampleRate(const sample_rate_t sampleRate)
Definition BasicFilters.h:330
frame m_y2
Definition BasicFilters.h:891
frame m_last
Definition BasicFilters.h:893
float m_r
Definition BasicFilters.h:877
float m_sampleRate
Definition BasicFilters.h:908
void clearHistory()
Definition BasicFilters.h:299
frame m_rchp1
Definition BasicFilters.h:897
static float minQ()
Definition BasicFilters.h:257
frame m_rcbp0
Definition BasicFilters.h:896
frame m_oldy2
Definition BasicFilters.h:891
bool m_doubleFilter
Definition BasicFilters.h:906
frame m_rchp0
Definition BasicFilters.h:896
float m_rca
Definition BasicFilters.h:880
float m_sampleRatio
Definition BasicFilters.h:909
float m_rcc
Definition BasicFilters.h:880
frame m_delay3
Definition BasicFilters.h:903
float m_vfc[4]
Definition BasicFilters.h:883
float m_p
Definition BasicFilters.h:877
frame m_rclp0
Definition BasicFilters.h:896
frame m_oldy3
Definition BasicFilters.h:891
BasicFilters(const sample_rate_t _sample_rate)
Definition BasicFilters.h:285
frame m_vflast[6]
Definition BasicFilters.h:900
frame m_rclast0
Definition BasicFilters.h:896
float m_rcq
Definition BasicFilters.h:880
float m_k
Definition BasicFilters.h:877
float m_svq
Definition BasicFilters.h:886
float m_svf1
Definition BasicFilters.h:886
sample_t update(sample_t _in0, ch_cnt_t _chnl)
Definition BasicFilters.h:340
FilterType m_type
Definition BasicFilters.h:905
float m_vfb[4]
Definition BasicFilters.h:883
frame m_oldx
Definition BasicFilters.h:891
float m_rcb
Definition BasicFilters.h:880
frame m_y4
Definition BasicFilters.h:891
BiQuad< CHANNELS > m_biQuad
Definition BasicFilters.h:874
frame m_vfbp[6]
Definition BasicFilters.h:900
frame m_rclp1
Definition BasicFilters.h:897
frame m_delay2
Definition BasicFilters.h:903
frame m_y3
Definition BasicFilters.h:891
float m_vfa[4]
Definition BasicFilters.h:883
static float minFreq()
Definition BasicFilters.h:252
frame m_delay4
Definition BasicFilters.h:903
std::array< sample_t, CHANNELS > frame
Definition BasicFilters.h:888
frame m_rclast1
Definition BasicFilters.h:897
FilterType
Definition BasicFilters.h:227
@ Bandpass_SV
Definition BasicFilters.h:245
@ Lowpass_RC12
Definition BasicFilters.h:236
@ AllPass
Definition BasicFilters.h:233
@ DoubleMoog
Definition BasicFilters.h:243
@ BandPass_CSG
Definition BasicFilters.h:230
@ Formantfilter
Definition BasicFilters.h:242
@ BandPass_CZPG
Definition BasicFilters.h:231
@ Moog
Definition BasicFilters.h:234
@ Highpass_RC24
Definition BasicFilters.h:241
@ FastFormant
Definition BasicFilters.h:248
@ Bandpass_RC24
Definition BasicFilters.h:240
@ LowPass
Definition BasicFilters.h:228
@ HiPass
Definition BasicFilters.h:229
@ Tripole
Definition BasicFilters.h:249
@ Notch
Definition BasicFilters.h:232
@ Highpass_SV
Definition BasicFilters.h:246
@ Notch_SV
Definition BasicFilters.h:247
@ Lowpass_SV
Definition BasicFilters.h:244
@ Bandpass_RC12
Definition BasicFilters.h:237
@ Lowpass_RC24
Definition BasicFilters.h:239
@ DoubleLowPass
Definition BasicFilters.h:235
@ Highpass_RC12
Definition BasicFilters.h:238
frame m_y1
Definition BasicFilters.h:891
Definition BasicFilters.h:144
float update(float in, ch_cnt_t ch)
Definition BasicFilters.h:173
float m_z2[CHANNELS]
Definition BasicFilters.h:183
void clearHistory()
Definition BasicFilters.h:165
float m_b2
Definition BasicFilters.h:182
float m_a1
Definition BasicFilters.h:182
float m_b1
Definition BasicFilters.h:182
float m_a2
Definition BasicFilters.h:182
float m_b0
Definition BasicFilters.h:182
float m_z1[CHANNELS]
Definition BasicFilters.h:183
BiQuad()
Definition BasicFilters.h:146
void setCoeffs(float a1, float a2, float b0, float b1, float b2)
Definition BasicFilters.h:157
virtual ~BiQuad()=default
Definition BasicFilters.h:50
void setHighpass(float freq)
Definition BasicFilters.h:108
void setCoeffs(float freq)
Definition BasicFilters.h:72
void setSampleRate(float sampleRate)
Definition BasicFilters.h:67
double m_a
Definition BasicFilters.h:134
frame m_z1
Definition BasicFilters.h:138
double m_b3
Definition BasicFilters.h:135
double m_a2
Definition BasicFilters.h:134
frame m_z2
Definition BasicFilters.h:138
void setLowpass(float freq)
Definition BasicFilters.h:100
virtual ~LinkwitzRiley()=default
double m_wc4
Definition BasicFilters.h:132
frame m_z4
Definition BasicFilters.h:138
double m_b4
Definition BasicFilters.h:135
float update(float in, ch_cnt_t ch)
Definition BasicFilters.h:116
double m_b1
Definition BasicFilters.h:135
std::array< double, CHANNELS > frame
Definition BasicFilters.h:137
frame m_z3
Definition BasicFilters.h:138
LinkwitzRiley(float sampleRate)
Definition BasicFilters.h:52
double m_a0
Definition BasicFilters.h:134
void clearHistory()
Definition BasicFilters.h:59
float m_sampleRate
Definition BasicFilters.h:131
double m_k4
Definition BasicFilters.h:133
double m_b2
Definition BasicFilters.h:135
double m_a1
Definition BasicFilters.h:134
Definition BasicFilters.h:191
float update(float s, ch_cnt_t ch)
Definition BasicFilters.h:210
float m_z1[CHANNELS]
Definition BasicFilters.h:218
float m_a0
Definition BasicFilters.h:217
OnePole()
Definition BasicFilters.h:193
void setCoeffs(float a0, float b1)
Definition BasicFilters.h:204
virtual ~OnePole()=default
float m_b1
Definition BasicFilters.h:217
register unsigned k
Definition inflate.c:946
int y
Definition inflate.c:1588
register unsigned i
Definition inflate.c:1575
unsigned s
Definition inflate.c:1555
unsigned x[BMAX+1]
Definition inflate.c:1586
unsigned f
Definition inflate.c:1572
const double pi
Definition exprtk_benchmark.cpp:186
JHUFF_TBL long freq[]
Definition jchuff.h:50
float in
Definition lilv_test.c:1460
float out
Definition lilv_test.c:1461
Definition AudioAlsa.cpp:35
std::uint16_t ch_cnt_t
Definition LmmsTypes.h:44
std::uint32_t sample_rate_t
Definition LmmsTypes.h:42
float sample_t
Definition LmmsTypes.h:39
OnePole< 2 > StereoOnePole
Definition BasicFilters.h:220
LinkwitzRiley< 2 > StereoLinkwitzRiley
Definition BasicFilters.h:140
constexpr float F_EPSILON
Definition lmms_constants.h:35
BiQuad< 2 > StereoBiQuad
Definition BasicFilters.h:187
#define false
Definition ordinals.h:83
int n
Definition crypt.c:458
static ZCONST char Far * os[NUM_HOSTS]
Definition zipinfo.c:1001