SDRAngel  4.11.5
Developer docs for <a href="https://github.com/f4exb/sdrangel">SDRangel<\a>, an Open Source Qt5 / OpenGL 3.0+ SDR and signal analyzer frontend to various hardware.
Public Member Functions | Private Member Functions | Private Attributes | Static Private Attributes | List of all members
AudioFilter Class Reference

#include <audiofilter.h>

+ Collaboration diagram for AudioFilter:

Public Member Functions

 AudioFilter ()
 
 ~AudioFilter ()
 
void useHP (bool useHP)
 
bool usesHP () const
 
void setDecimFilters (int srHigh, int srLow, float fcHigh, float fcLow, float gain=1.0f)
 
float run (const float &sample)
 
float runHP (const float &sample)
 
float runLP (const float &sample)
 

Private Member Functions

void calculate2 (bool highPass, double fc, float *a, float *b, float fgain)
 
void cheby (bool highPass, double fc, float pr, int np, double *a, double *b, float fgain)
 
void cheby_sub (bool highPass, double fc, float pr, int np, int stage, double &a0, double &a1, double &a2, double &b1, double &b2)
 

Private Attributes

IIRFilter< float, 2 > m_filterLP
 
IIRFilter< float, 2 > m_filterHP
 
bool m_useHP
 
float m_lpva [3]
 
float m_lpvb [3]
 
float m_hpva [3]
 
float m_hpvb [3]
 

Static Private Attributes

static const float m_lpa [3] = {1.0, 1.392667E+00, -5.474446E-01}
 
static const float m_lpb [3] = {3.869430E-02, 7.738860E-02, 3.869430E-02}
 
static const float m_hpa [3] = {1.000000e+00, 1.667871e+00, -7.156964e-01}
 
static const float m_hpb [3] = {8.459039e-01, -1.691760e+00, 8.459039e-01}
 

Detailed Description

By default this is a 2 pole lowpass Chebyshev (recursive) filter at fc=0.075 using coefficients found in table 20-1 of http://www.analog.com/media/en/technical-documentation/dsp-book/dsp_book_Ch20.pdf

At the interpolated sampling frequency of 48 kHz the -3 dB corner is at 48 * .075 = 3.6 kHz which is perfect for voice

a0= 3.869430E-02 a1= 7.738860E-02 b1= 1.392667E+00 a2= 3.869430E-02 b2= -5.474446E-01

given x[n] is the new input sample and y[n] the returned output sample:

y[n] = a0*x[n] + a1*x[n] + a2*x[n] + b1*y[n-1] + b2*y[n-2]

This one works directly with floats

It can be generalized using the program found in tables 20-4 and 20-5 of the same document. This form is used as a decimation filter and can be set with the setDecimFilters method

Definition at line 44 of file audiofilter.h.

Constructor & Destructor Documentation

◆ AudioFilter()

AudioFilter::AudioFilter ( )

Definition at line 32 of file audiofilter.cpp.

32  :
35  m_useHP(false)
36 {}
bool m_useHP
Definition: audiofilter.h:64
static const float m_hpb[3]
Definition: audiofilter.h:72
IIRFilter< float, 2 > m_filterLP
Definition: audiofilter.h:62
IIRFilter< float, 2 > m_filterHP
Definition: audiofilter.h:63
static const float m_hpa[3]
Definition: audiofilter.h:71
static const float m_lpb[3]
Definition: audiofilter.h:70
static const float m_lpa[3]
Definition: audiofilter.h:69

◆ ~AudioFilter()

AudioFilter::~AudioFilter ( )

Definition at line 38 of file audiofilter.cpp.

39 {}

Member Function Documentation

◆ calculate2()

void AudioFilter::calculate2 ( bool  highPass,
double  fc,
float *  a,
float *  b,
float  fgain 
)
private

Definition at line 54 of file audiofilter.cpp.

References cheby(), and i.

Referenced by setDecimFilters().

55 {
56  double a[22], b[22];
57 
58  cheby(highPass, fc, 0.5, 2, a, b, fgain); // low-pass, 0.5% ripple, 2 pole filter
59 
60  // Copy to the 2-pole filter coefficients
61  for (int i=0; i<3; i++) {
62  vb[i] = a[i];
63  va[i] = b[i];
64  }
65 
66  va[0] = 1.0;
67 
68  qDebug() << "AudioFilter::calculate2:"
69  << " highPass: " << highPass
70  << " fc: " << fc
71  << " a0: " << va[0]
72  << " a1: " << va[1]
73  << " a2: " << va[2]
74  << " b0: " << vb[0]
75  << " b1: " << vb[1]
76  << " b2: " << vb[2];
77 }
int32_t i
Definition: decimators.h:244
void cheby(bool highPass, double fc, float pr, int np, double *a, double *b, float fgain)
Definition: audiofilter.cpp:83
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cheby()

void AudioFilter::cheby ( bool  highPass,
double  fc,
float  pr,
int  np,
double *  a,
double *  b,
float  fgain 
)
private

Definition at line 83 of file audiofilter.cpp.

References b1, b2, cheby_sub(), and i.

Referenced by calculate2().

84 {
85  double a0, a1, a2, b1, b2;
86  double ta[22], tb[22];
87 
88  std::fill(a, a+22, 0.0);
89  std::fill(b, b+22, 0.0);
90  a[2] = 1.0;
91  b[2] = 1.0;
92 
93  for (int p = 1; p <= np/2; p++)
94  {
95  cheby_sub(highPass, fc, pr, np, p, a0, a1, a2, b1, b2);
96 
97  // Add coefficients to the cascade
98  for (int i=0; i<22; i++)
99  {
100  ta[i] = a[i];
101  tb[i] = b[i];
102  }
103 
104  for (int i=2; i<22; i++)
105  {
106  a[i] = a0*ta[i] + a1*ta[i-1] + a2*ta[i-2];
107  b[i] = tb[i] - b1*tb[i-1] - b2*tb[i-2];
108  }
109  }
110 
111  // Finish combining coefficients
112  b[2] = 0;
113 
114  for (int i=0; i<20; i++)
115  {
116  a[i] = a[i+2];
117  b[i] = -b[i+2];
118  }
119 
120  // Normalize the gain
121  double sa = 0.0;
122  double sb = 0.0;
123 
124  for (int i=0; i<20; i++)
125  {
126  if (highPass)
127  {
128  sa += i%2 == 0 ? a[i] : -a[i];
129  sb += i%2 == 0 ? b[i] : -b[i];
130  }
131  else
132  {
133  sa += a[i];
134  sb += b[i];
135  }
136  }
137 
138  double gain = sa/(1.0 -sb);
139  gain /= fgain;
140 
141  for (int i=0; i<20; i++) {
142  a[i] /= gain;
143  }
144 }
uint8_t b2
Definition: decimators.h:57
uint8_t b1
Definition: decimators.h:56
int32_t i
Definition: decimators.h:244
void cheby_sub(bool highPass, double fc, float pr, int np, int stage, double &a0, double &a1, double &a2, double &b1, double &b2)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ cheby_sub()

void AudioFilter::cheby_sub ( bool  highPass,
double  fc,
float  pr,
int  np,
int  stage,
double &  a0,
double &  a1,
double &  a2,
double &  b1,
double &  b2 
)
private

Definition at line 150 of file audiofilter.cpp.

References b1, cos(), exp(), log(), M_PI, sin(), sqrt(), and tan().

Referenced by cheby().

151 {
152  double rp = -cos((M_PI/(np*2)) + (stage-1)*(M_PI/np));
153  double ip = sin((M_PI/(np*2)) + (stage-1)*(M_PI/np));
154 
155  // Warp from a circle to an ellipse
156  double esx = 100.0 / (100.0 - pr);
157  double es = sqrt(esx*esx -1.0);
158  double vx = (1.0/np) * log((1.0/es) + sqrt((1.0/(es*es)) + 1.0));
159  double kx = (1.0/np) * log((1.0/es) + sqrt((1.0/(es*es)) - 1.0));
160  kx = (exp(kx) + exp(-kx))/2.0;
161  rp = rp * ((exp(vx) - exp(-vx))/2.0) / kx;
162  ip = ip * ((exp(vx) + exp(-vx))/2.0) / kx;
163 
164  double t = 2.0 * tan(0.5);
165  double w = 2.0 * M_PI * fc;
166  double m = rp*rp + ip*ip;
167  double d = 4.0 - 4.0*rp*t + m*t*t;
168  double x0 = (t*t)/d;
169  double x1 = (2.0*t*t)/d;
170  double x2 = (t*t)/d;
171  double y1 = (8.0 - 2.0*m*t*t)/d;
172  double y2 = (-4.0 - 4.0*rp*t - m*t*t)/d;
173  double k;
174 
175  if (highPass) {
176  k = -cos(w/2.0 + 0.5) / cos(w/2.0 - 0.5);
177  } else {
178  k = sin(0.5 - w/2.0) / sin(0.5 + w/2.0);
179  }
180 
181  d = 1.0 + y1*k - y2*k*k;
182 
183  a0 = (x0 - x1*k + x2*k*k)/d;
184  a1 = (-2.0*x0*k + x1 + x1*k*k - 2.0*x2*k)/d;
185  a2 = (x0*k*k - x1*k + x2)/d;
186  b1 = (2.0*k + y1 + y1*k*k - 2.0*y2*k)/d;
187  b2 = (-(k*k) - y1*k + y2)/d;
188 
189  if (highPass)
190  {
191  a1 = -a1;
192  b1 = -b1;
193  }
194 }
Fixed< IntType, IntBits > cos(Fixed< IntType, IntBits > const &x)
Definition: fixed.h:2271
Fixed< IntType, IntBits > tan(Fixed< IntType, IntBits > const &x)
Definition: fixed.h:2277
#define M_PI
Definition: rdsdemod.cpp:27
Fixed< IntType, IntBits > exp(Fixed< IntType, IntBits > const &x)
Definition: fixed.h:2289
uint8_t b2
Definition: decimators.h:57
Fixed< IntType, IntBits > log(Fixed< IntType, IntBits > const &x)
Definition: fixed.h:2295
uint8_t b1
Definition: decimators.h:56
Fixed< IntType, IntBits > sin(Fixed< IntType, IntBits > const &x)
Definition: fixed.h:2265
Fixed< IntType, IntBits > sqrt(Fixed< IntType, IntBits > const &x)
Definition: fixed.h:2283
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ run()

float AudioFilter::run ( const float &  sample)

Definition at line 196 of file audiofilter.cpp.

References m_filterHP, m_filterLP, m_useHP, and IIRFilter< Type, Order >::run().

Referenced by AudioResampler::downSample(), AudioResampler::upSample(), and AudioNetSink::write().

197 {
198  return m_useHP ? m_filterLP.run(m_filterHP.run(sample)) : m_filterLP.run(sample);
199 }
bool m_useHP
Definition: audiofilter.h:64
Type run(const Type &sample)
Definition: iirfilter.h:98
IIRFilter< float, 2 > m_filterLP
Definition: audiofilter.h:62
IIRFilter< float, 2 > m_filterHP
Definition: audiofilter.h:63
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ runHP()

float AudioFilter::runHP ( const float &  sample)

Definition at line 201 of file audiofilter.cpp.

References m_filterHP, and IIRFilter< Type, Order >::run().

202 {
203  return m_filterHP.run(sample);
204 }
Type run(const Type &sample)
Definition: iirfilter.h:98
IIRFilter< float, 2 > m_filterHP
Definition: audiofilter.h:63
+ Here is the call graph for this function:

◆ runLP()

float AudioFilter::runLP ( const float &  sample)

Definition at line 206 of file audiofilter.cpp.

References m_filterLP, and IIRFilter< Type, Order >::run().

Referenced by AudioNetSink::write().

207 {
208  return m_filterLP.run(sample);
209 }
Type run(const Type &sample)
Definition: iirfilter.h:98
IIRFilter< float, 2 > m_filterLP
Definition: audiofilter.h:62
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setDecimFilters()

void AudioFilter::setDecimFilters ( int  srHigh,
int  srLow,
float  fcHigh,
float  fcLow,
float  gain = 1.0f 
)

Definition at line 42 of file audiofilter.cpp.

References calculate2(), m_filterHP, m_filterLP, m_hpva, m_hpvb, m_lpva, m_lpvb, and IIRFilter< Type, Order >::setCoeffs().

Referenced by AudioResampler::setAudioFilters(), and AudioNetSink::setDecimationFilters().

43 {
44  double fcNormHigh = fcHigh / srHigh;
45  double fcNormLow = fcLow / srLow;
46 
47  calculate2(false, fcNormHigh, m_lpva, m_lpvb, fgain);
48  calculate2(true, fcNormLow, m_hpva, m_hpvb, fgain);
49 
52 }
void setCoeffs(const Type *a, const Type *b)
Definition: iirfilter.h:84
float m_lpvb[3]
Definition: audiofilter.h:66
float m_lpva[3]
Definition: audiofilter.h:65
IIRFilter< float, 2 > m_filterLP
Definition: audiofilter.h:62
IIRFilter< float, 2 > m_filterHP
Definition: audiofilter.h:63
float m_hpva[3]
Definition: audiofilter.h:67
void calculate2(bool highPass, double fc, float *a, float *b, float fgain)
Definition: audiofilter.cpp:54
float m_hpvb[3]
Definition: audiofilter.h:68
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ useHP()

void AudioFilter::useHP ( bool  useHP)
inline

Definition at line 49 of file audiofilter.h.

References useHP().

Referenced by useHP().

49 { m_useHP = useHP; }
bool m_useHP
Definition: audiofilter.h:64
void useHP(bool useHP)
Definition: audiofilter.h:49
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ usesHP()

bool AudioFilter::usesHP ( ) const
inline

Definition at line 50 of file audiofilter.h.

References b1, and b2.

50 { return m_useHP; }
bool m_useHP
Definition: audiofilter.h:64

Member Data Documentation

◆ m_filterHP

IIRFilter<float, 2> AudioFilter::m_filterHP
private

Definition at line 63 of file audiofilter.h.

Referenced by run(), runHP(), and setDecimFilters().

◆ m_filterLP

IIRFilter<float, 2> AudioFilter::m_filterLP
private

Definition at line 62 of file audiofilter.h.

Referenced by run(), runLP(), and setDecimFilters().

◆ m_hpa

const float AudioFilter::m_hpa = {1.000000e+00, 1.667871e+00, -7.156964e-01}
staticprivate

Definition at line 71 of file audiofilter.h.

◆ m_hpb

const float AudioFilter::m_hpb = {8.459039e-01, -1.691760e+00, 8.459039e-01}
staticprivate

Definition at line 72 of file audiofilter.h.

◆ m_hpva

float AudioFilter::m_hpva[3]
private

Definition at line 67 of file audiofilter.h.

Referenced by setDecimFilters().

◆ m_hpvb

float AudioFilter::m_hpvb[3]
private

Definition at line 68 of file audiofilter.h.

Referenced by setDecimFilters().

◆ m_lpa

const float AudioFilter::m_lpa = {1.0, 1.392667E+00, -5.474446E-01}
staticprivate

Definition at line 69 of file audiofilter.h.

◆ m_lpb

const float AudioFilter::m_lpb = {3.869430E-02, 7.738860E-02, 3.869430E-02}
staticprivate

Definition at line 70 of file audiofilter.h.

◆ m_lpva

float AudioFilter::m_lpva[3]
private

Definition at line 65 of file audiofilter.h.

Referenced by setDecimFilters().

◆ m_lpvb

float AudioFilter::m_lpvb[3]
private

Definition at line 66 of file audiofilter.h.

Referenced by setDecimFilters().

◆ m_useHP

bool AudioFilter::m_useHP
private

Definition at line 64 of file audiofilter.h.

Referenced by run().


The documentation for this class was generated from the following files: