kwave  18.07.70
NotchFilter.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  NotchFilter.cpp - transmission function of a notch filter
3  -------------------
4  begin : Thu Jun 19 2003
5  copyright : (C) 2003 by Dave Flogeras
6  email : d.flogeras@unb.ca
7 
8  filter functions:
9  Copyright (C) 1998 Juhana Sadeharju <kouhia@nic.funet.fi>
10  ***************************************************************************/
11 
12 /***************************************************************************
13  * *
14  * This program is free software; you can redistribute it and/or modify *
15  * it under the terms of the GNU General Public License as published by *
16  * the Free Software Foundation; either version 2 of the License, or *
17  * (at your option) any later version. *
18  * *
19  ***************************************************************************/
20 
21 #include "config.h"
22 #include <complex>
23 #include <math.h>
24 
25 #include "NotchFilter.h"
26 
27 //***************************************************************************
30  m_buffer(blockSize()), m_f_cutoff(M_PI), m_f_bw(M_PI / 2)
31 {
32  initFilter();
33 }
34 
35 //***************************************************************************
37 {
38 }
39 
40 //***************************************************************************
42 {
43  emit output(m_buffer);
44 }
45 
46 //***************************************************************************
47 double Kwave::NotchFilter::at(double f)
48 {
49  /*
50  * filter function as extracted from the aRts code:
51  *
52  * y[t] = cx*x[t] + cx1*x[t-1] + cx2*x[t-2]
53  * + cy1*y[t-1] + cy2*y[t-2];
54  *
55  * convert filter coefficients to our notation:
56  */
57  double a0, a1, a2, b1, b2;
58  a0 = m_filter.cx;
59  a1 = m_filter.cx1;
60  a2 = m_filter.cx2;
61  b1 = m_filter.cy1;
62  b2 = m_filter.cy2;
63 
64  /*
65  * a0*z^2 + a1*z + a2
66  * H(z) = ------------------ | z = e ^ (j*2*pi*f)
67  * z^2 - b1*z - b0
68  */
69  std::complex<double> h;
70  std::complex<double> w;
71  std::complex<double> j(0.0,1.0);
72  std::complex<double> z;
73 
74  w = f;
75  z = std::exp(j*w);
76 
77  // get h[z] at z=e^jw
78  h = 0.95 * (a0 * (z*z) + (a1*z) + a2) / ((z*z) - (b1*z) - b2);
79 
80  return sqrt(std::norm(h));
81 }
82 
83 //***************************************************************************
85 {
86  m_filter.x1 = 0.0;
87  m_filter.x2 = 0.0;
88  m_filter.y1 = 0.0;
89  m_filter.y2 = 0.0;
90  m_filter.y = 0.0;
91 }
92 
93 //***************************************************************************
94 /*
95  * Some JAES's article on ladder filter.
96  * freq (Hz), gdb (dB), bw (Hz)
97  */
98 void Kwave::NotchFilter::setfilter_peaknotch2(double freq, double bw)
99 {
100  const double gdb = -100;
101  double k, w, bwr, abw, gain;
102 
103  k = pow(10.0, gdb / 20.0);
104  /* w = 2.0 * PI * freq / (double)SR; */
105  /* bwr = 2.0 * PI * bw / (double)SR; */
106  w = freq;
107  bwr = bw;
108  abw = (1.0 - tan(bwr / 2.0)) / (1.0 + tan(bwr / 2.0));
109  gain = 0.5 * (1.0 + k + abw - k * abw);
110  m_filter.cx = 1.0 * gain;
111  m_filter.cx1 = gain * (-2.0 * cos(w) * (1.0 + abw)) /
112  (1.0 + k + abw - k * abw);
113  m_filter.cx2 = gain * (abw + k * abw + 1.0 - k) /
114  (abw - k * abw + 1.0 + k);
115  m_filter.cy1 = 2.0 * cos(w) / (1.0 + tan(bwr / 2.0));
116  m_filter.cy2 = -abw;
117 }
118 
119 //***************************************************************************
121 {
122  const Kwave::SampleArray &in = data;
123  bool ok = m_buffer.resize(in.size());
124  Q_ASSERT(ok);
125  Q_UNUSED(ok);
126 
128 
129  for (unsigned i = 0; i < in.size(); ++i)
130  {
131  // do the filtering
132  m_filter.x = sample2double(in[i]);
133  m_filter.y =
134  m_filter.cx * m_filter.x +
135  m_filter.cx1 * m_filter.x1 +
136  m_filter.cx2 * m_filter.x2 +
137  m_filter.cy1 * m_filter.y1 +
138  m_filter.cy2 * m_filter.y2;
139  m_filter.x2 = m_filter.x1;
140  m_filter.x1 = m_filter.x;
141  m_filter.y2 = m_filter.y1;
142  m_filter.y1 = m_filter.y;
143  m_buffer[i] = double2sample(0.95 * m_filter.y);
144  }
145 }
146 
147 //***************************************************************************
148 void Kwave::NotchFilter::setFrequency(const QVariant fc)
149 {
150  double new_freq = QVariant(fc).toDouble();
151  if (qFuzzyCompare(new_freq, m_f_cutoff)) return; // nothing to do
152 
153  m_f_cutoff = new_freq;
154  initFilter();
156 }
157 
158 //***************************************************************************
159 void Kwave::NotchFilter::setBandwidth(const QVariant bw)
160 {
161  double new_bw = QVariant(bw).toDouble();
162  if (qFuzzyCompare(new_bw, m_f_bw)) return; // nothing to do
163 
164  m_f_bw = new_bw;
165  initFilter();
167 }
168 
169 //***************************************************************************
170 //***************************************************************************
void setBandwidth(const QVariant bw)
Definition: App.h:33
virtual double at(double f) Q_DECL_OVERRIDE
Definition: NotchFilter.cpp:47
Kwave::SampleArray m_buffer
Definition: NotchFilter.h:92
struct Kwave::NotchFilter::@14 m_filter
virtual void goOn() Q_DECL_OVERRIDE
Definition: NotchFilter.cpp:41
static double sample2double(const sample_t s)
Definition: Sample.h:73
void setFrequency(const QVariant fc)
void input(Kwave::SampleArray data)
static sample_t double2sample(const double f)
Definition: Sample.h:81
void setfilter_peaknotch2(double freq, double bw)
Definition: NotchFilter.cpp:98
unsigned int size() const
virtual ~NotchFilter() Q_DECL_OVERRIDE
Definition: NotchFilter.cpp:36
bool resize(unsigned int size) Q_REQUIRED_RESULT
void output(Kwave::SampleArray data)