Filter.cpp
Go to the documentation of this file.
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4  QM DSP Library
5 
6  Centre for Digital Music, Queen Mary, University of London.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2 of the
11  License, or (at your option) any later version. See the file
12  COPYING included with this distribution for more information.
13 */
14 
15 #include "Filter.h"
16 
17 #include <stdexcept>
18 
19 using namespace std;
20 
22 {
23  if (params.a.empty()) {
24  m_fir = true;
25  if (params.b.empty()) {
26  throw logic_error("Filter must have at least one pair of coefficients");
27  }
28  } else {
29  m_fir = false;
30  if (params.a.size() != params.b.size()) {
31  throw logic_error("Inconsistent numbers of filter coefficients");
32  }
33  }
34 
35  m_sz = int(params.b.size());
36  m_order = m_sz - 1;
37 
38  m_a = params.a;
39  m_b = params.b;
40 
41  // We keep some empty space at the start of the buffer, and
42  // encroach gradually into it as we add individual sample
43  // calculations at the start. Then when we run out of space, we
44  // move the buffer back to the end and begin again. This is
45  // significantly faster than moving the whole buffer along in
46  // 1-sample steps every time.
47 
48  m_offmax = 20;
49  m_offa = m_offmax;
50  m_offb = m_offmax;
51 
52  if (!m_fir) {
53  m_bufa.resize(m_order + m_offmax);
54  }
55 
56  m_bufb.resize(m_sz + m_offmax);
57 }
58 
60 {
61 }
62 
63 void
65 {
66  m_offb = m_offmax;
67  m_offa = m_offmax;
68 
69  if (!m_fir) {
70  m_bufa.assign(m_bufa.size(), 0.0);
71  }
72 
73  m_bufb.assign(m_bufb.size(), 0.0);
74 }
75 
76 void
77 Filter::process(const double *const QM_R__ in,
78  double *const QM_R__ out,
79  const int n)
80 {
81  for (int s = 0; s < n; ++s) {
82 
83  if (m_offb > 0) {
84  --m_offb;
85  } else {
86  for (int i = m_sz - 2; i >= 0; --i) {
87  m_bufb[i + m_offmax + 1] = m_bufb[i];
88  }
89  m_offb = m_offmax;
90  }
91  m_bufb[m_offb] = in[s];
92 
93  double b_sum = 0.0;
94  for (int i = 0; i < m_sz; ++i) {
95  b_sum += m_b[i] * m_bufb[i + m_offb];
96  }
97 
98  double outval;
99 
100  if (m_fir) {
101 
102  outval = b_sum;
103 
104  } else {
105 
106  double a_sum = 0.0;
107  for (int i = 0; i < m_order; ++i) {
108  a_sum += m_a[i + 1] * m_bufa[i + m_offa];
109  }
110 
111  outval = b_sum - a_sum;
112 
113  if (m_offa > 0) {
114  --m_offa;
115  } else {
116  for (int i = m_order - 2; i >= 0; --i) {
117  m_bufa[i + m_offmax + 1] = m_bufa[i];
118  }
119  m_offa = m_offmax;
120  }
121  m_bufa[m_offa] = outval;
122  }
123 
124  out[s] = outval;
125  }
126 }
127 
~Filter()
Definition: Filter.cpp:59
#define QM_R__
Definition: Restrict.h:15
void process(const double *const QM_R__ in, double *const QM_R__ out, const int n)
Filter the input sequence.
Definition: Filter.cpp:77
Filter(Parameters params)
Construct an IIR filter with numerators b and denominators a.
Definition: Filter.cpp:21
std::vector< double > a
Definition: Filter.h:26
void reset()
Definition: Filter.cpp:64
std::vector< double > b
Definition: Filter.h:27