Revision 71647e09 gnuradio-core/src/lib/filter/gri_iir.h
| b/gnuradio-core/src/lib/filter/gri_iir.h | ||
|---|---|---|
| 43 | 43 |
* The input and output satisfy a difference equation of the form |
| 44 | 44 |
|
| 45 | 45 |
\f[ |
| 46 |
y[n] - \sum_{k=1}^{N} a_k y[n-k] = \sum_{k=0}^{M} b_k x[n-k]
|
|
| 46 |
y[n] - \sum_{k=1}^{M} a_k y[n-k] = \sum_{k=0}^{N} b_k x[n-k]
|
|
| 47 | 47 |
\f] |
| 48 | 48 |
|
| 49 | 49 |
* with the corresponding rational system function |
| 50 | 50 |
|
| 51 | 51 |
\f[ |
| 52 |
H(z) = \frac{\sum_{k=0}^{M} b_k z^{-k}}{1 - \sum_{k=1}^{N} a_k z^{-k}}
|
|
| 52 |
H(z) = \frac{\sum_{k=0}^{N} b_k z^{-k}}{1 - \sum_{k=1}^{M} a_k z^{-k}}
|
|
| 53 | 53 |
\f] |
| 54 | 54 |
|
| 55 | 55 |
* Note that some texts define the system function with a + in the denominator. |
| ... | ... | |
| 61 | 61 |
set_taps (fftaps, fbtaps); |
| 62 | 62 |
} |
| 63 | 63 |
|
| 64 |
gri_iir () : d_latest(0) { }
|
|
| 64 |
gri_iir () : d_latest_n(0),d_latest_m(0) { }
|
|
| 65 | 65 |
|
| 66 | 66 |
~gri_iir () {}
|
| 67 | 67 |
|
| ... | ... | |
| 80 | 80 |
/*! |
| 81 | 81 |
* \return number of taps in filter. |
| 82 | 82 |
*/ |
| 83 |
unsigned ntaps () const { return d_fftaps.size (); }
|
|
| 83 |
unsigned ntaps_ff () const { return d_fftaps.size (); }
|
|
| 84 |
unsigned ntaps_fb () const { return d_fbtaps.size (); }
|
|
| 84 | 85 |
|
| 85 | 86 |
/*! |
| 86 | 87 |
* \brief install new taps. |
| ... | ... | |
| 88 | 89 |
void set_taps (const std::vector<tap_type> &fftaps, |
| 89 | 90 |
const std::vector<tap_type> &fbtaps) throw (std::invalid_argument) |
| 90 | 91 |
{
|
| 91 |
if (fftaps.size () != fbtaps.size ()) |
|
| 92 |
throw std::invalid_argument ("gri_iir::set_taps");
|
|
| 93 | 92 |
|
| 94 |
d_latest = 0; |
|
| 93 |
|
|
| 94 |
d_latest_n = 0; |
|
| 95 |
d_latest_m = 0; |
|
| 95 | 96 |
d_fftaps = fftaps; |
| 96 | 97 |
d_fbtaps = fbtaps; |
| 97 | 98 |
|
| 98 | 99 |
int n = fftaps.size (); |
| 100 |
int m = fbtaps.size (); |
|
| 99 | 101 |
d_prev_input.resize (2 * n); |
| 100 |
d_prev_output.resize (2 * n);
|
|
| 102 |
d_prev_output.resize (2 * m);
|
|
| 101 | 103 |
|
| 102 | 104 |
for (int i = 0; i < 2 * n; i++){
|
| 103 | 105 |
d_prev_input[i] = 0; |
| 106 |
} |
|
| 107 |
for (int i = 0; i < 2 * m; i++){
|
|
| 104 | 108 |
d_prev_output[i] = 0; |
| 105 | 109 |
} |
| 106 | 110 |
} |
| ... | ... | |
| 108 | 112 |
protected: |
| 109 | 113 |
std::vector<tap_type> d_fftaps; |
| 110 | 114 |
std::vector<tap_type> d_fbtaps; |
| 111 |
int d_latest; |
|
| 115 |
int d_latest_n; |
|
| 116 |
int d_latest_m; |
|
| 112 | 117 |
std::vector<tap_type> d_prev_output; |
| 113 | 118 |
std::vector<i_type> d_prev_input; |
| 114 | 119 |
}; |
| ... | ... | |
| 123 | 128 |
{
|
| 124 | 129 |
tap_type acc; |
| 125 | 130 |
unsigned i = 0; |
| 126 |
unsigned n = ntaps (); |
|
| 131 |
unsigned n = ntaps_ff (); |
|
| 132 |
unsigned m = ntaps_fb (); |
|
| 127 | 133 |
|
| 128 | 134 |
if (n == 0) |
| 129 | 135 |
return (o_type) 0; |
| 130 | 136 |
|
| 131 |
int latest = d_latest; |
|
| 137 |
int latest_n = d_latest_n; |
|
| 138 |
int latest_m = d_latest_m; |
|
| 132 | 139 |
|
| 133 | 140 |
acc = d_fftaps[0] * input; |
| 134 | 141 |
for (i = 1; i < n; i ++) |
| 135 |
acc += (d_fftaps[i] * d_prev_input[latest + i] |
|
| 136 |
+ d_fbtaps[i] * d_prev_output[latest + i]); |
|
| 142 |
acc += (d_fftaps[i] * d_prev_input[latest_n + i]); |
|
| 143 |
for (i = 1; i < m; i ++) |
|
| 144 |
acc += (d_fbtaps[i] * d_prev_output[latest_m + i]); |
|
| 137 | 145 |
|
| 138 | 146 |
// store the values twice to avoid having to handle wrap-around in the loop |
| 139 |
d_prev_output[latest] = acc; |
|
| 140 |
d_prev_output[latest+n] = acc; |
|
| 141 |
d_prev_input[latest] = input; |
|
| 142 |
d_prev_input[latest+n] = input; |
|
| 143 |
|
|
| 144 |
latest--; |
|
| 145 |
if (latest < 0) |
|
| 146 |
latest += n; |
|
| 147 |
|
|
| 148 |
d_latest = latest; |
|
| 147 |
d_prev_output[latest_m] = acc; |
|
| 148 |
d_prev_output[latest_m+m] = acc; |
|
| 149 |
d_prev_input[latest_n] = input; |
|
| 150 |
d_prev_input[latest_n+n] = input; |
|
| 151 |
|
|
| 152 |
latest_n--; |
|
| 153 |
latest_m--; |
|
| 154 |
if (latest_n < 0) |
|
| 155 |
latest_n += n; |
|
| 156 |
if (latest_m < 0) |
|
| 157 |
latest_m += m; |
|
| 158 |
|
|
| 159 |
d_latest_m = latest_m; |
|
| 160 |
d_latest_n = latest_n; |
|
| 149 | 161 |
return (o_type) acc; |
| 150 | 162 |
} |
| 151 | 163 |
|
Also available in: Unified diff