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
void setPeakingEq(float sampleRate, float centreFrequency, float q, float dbGain)
Set filter parameters.
void setLowPassFilter(float sampleRate, float cutoffFrequency, float q)
Set filter parameters.
void setHighPassFilter(float sampleRate, float cutoffFrequency, float q)
Set filter parameters.
Free functions in swift::misc.
#define SWIFT_VERIFY_X(COND, WHERE, WHAT)
A weaker kind of assert.
Definition: verify.h:26