swift
biquadfilter.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2019 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
4 #include "biquadfilter.h"
5 #include "misc/verify.h"
6 #include "config/buildconfig.h"
7 
8 #include <QtMath>
9 #include <algorithm>
10 
11 using namespace swift::misc;
12 using namespace swift::config;
13 
14 namespace swift::sound::dsp
15 {
16  float BiQuadFilter::transform(float inSample)
17  {
18  // compute result
19  double result = m_a0 * inSample + m_a1 * m_x1 + m_a2 * m_x2 - m_a3 * m_y1 - m_a4 * m_y2;
20 
21  // shift x1 to x2, sample to x1
22  m_x2 = m_x1;
23  m_x1 = inSample;
24 
25  // shift y1 to y2, result to y1
26  m_y2 = m_y1;
27  m_y1 = static_cast<float>(result);
28 
29  return m_y1;
30  }
31 
32  void BiQuadFilter::setCoefficients(double aa0, double aa1, double aa2, double b0, double b1, double b2)
33  {
34  if (CBuildConfig::isLocalDeveloperDebugBuild()) { SWIFT_VERIFY_X(qAbs(aa0) > 1E-06, Q_FUNC_INFO, "Div by zero?"); }
35 
36  // precompute the coefficients
37  m_a0 = b0 / aa0;
38  m_a1 = b1 / aa0;
39  m_a2 = b2 / aa0;
40  m_a3 = aa1 / aa0;
41  m_a4 = aa2 / aa0;
42  }
43 
44  void BiQuadFilter::setLowPassFilter(float sampleRate, float cutoffFrequency, float q)
45  {
46  // H(s) = 1 / (s^2 + s/Q + 1)
47  auto w0 = 2 * M_PI * cutoffFrequency / sampleRate;
48  auto cosw0 = qCos(w0);
49  auto alpha = qSin(w0) / (2 * q);
50 
51  auto b0 = (1 - cosw0) / 2;
52  auto b1 = 1 - cosw0;
53  auto b2 = (1 - cosw0) / 2;
54  auto aa0 = 1 + alpha;
55  auto aa1 = -2 * cosw0;
56  auto aa2 = 1 - alpha;
57  setCoefficients(aa0, aa1, aa2, b0, b1, b2);
58  }
59 
60  void BiQuadFilter::setPeakingEq(float sampleRate, float centreFrequency, float q, float dbGain)
61  {
62  // H(s) = (s^2 + s*(A/Q) + 1) / (s^2 + s/(A*Q) + 1)
63  auto w0 = 2 * M_PI * centreFrequency / sampleRate;
64  auto cosw0 = qCos(w0);
65  auto sinw0 = qSin(w0);
66  auto alpha = sinw0 / (2 * q);
67  auto a = qPow(10, dbGain / 40); // TODO: should we square root this value?
68 
69  auto b0 = 1 + alpha * a;
70  auto b1 = -2 * cosw0;
71  auto b2 = 1 - alpha * a;
72  auto aa0 = 1 + alpha / a;
73  auto aa1 = -2 * cosw0;
74  auto aa2 = 1 - alpha / a;
75  setCoefficients(aa0, aa1, aa2, b0, b1, b2);
76  }
77 
78  void BiQuadFilter::setHighPassFilter(float sampleRate, float cutoffFrequency, float q)
79  {
80  // H(s) = s^2 / (s^2 + s/Q + 1)
81  auto w0 = 2 * M_PI * cutoffFrequency / sampleRate;
82  auto cosw0 = qCos(w0);
83  auto alpha = qSin(w0) / (2 * q);
84 
85  auto b0 = (1 + cosw0) / 2;
86  auto b1 = -(1 + cosw0);
87  auto b2 = (1 + cosw0) / 2;
88  auto aa0 = 1 + alpha;
89  auto aa1 = -2 * cosw0;
90  auto aa2 = 1 - alpha;
91  setCoefficients(aa0, aa1, aa2, b0, b1, b2);
92  }
93 
94  BiQuadFilter BiQuadFilter::lowPassFilter(float sampleRate, float cutoffFrequency, float q)
95  {
96  BiQuadFilter filter;
97  filter.setLowPassFilter(sampleRate, cutoffFrequency, q);
98  return filter;
99  }
100 
101  BiQuadFilter BiQuadFilter::highPassFilter(float sampleRate, float cutoffFrequency, float q)
102  {
103  BiQuadFilter filter;
104  filter.setHighPassFilter(sampleRate, cutoffFrequency, q);
105  return filter;
106  }
107 
108  BiQuadFilter BiQuadFilter::peakingEQ(float sampleRate, float centreFrequency, float q, float dbGain)
109  {
110  BiQuadFilter filter;
111  filter.setPeakingEq(sampleRate, centreFrequency, q, dbGain);
112  return filter;
113  }
114 } // ns
Digital biquad filter.
Definition: biquadfilter.h:15
Free functions in swift::misc.
#define SWIFT_VERIFY_X(COND, WHERE, WHAT)
A weaker kind of assert.
Definition: verify.h:26