diff options
author | n4hy <n4hy@221aa14e-8319-0410-a670-987f0aec2ac5> | 2006-12-21 19:41:29 +0000 |
---|---|---|
committer | n4hy <n4hy@221aa14e-8319-0410-a670-987f0aec2ac5> | 2006-12-21 19:41:29 +0000 |
commit | 71647e094f85e520363e579eab4b86e430be4e90 (patch) | |
tree | 9c896238fc68573e4721b96641d75f3298463b21 | |
parent | 566df7b80d836b42b75b63d9a0704a04b387115a (diff) |
Merged changeset r4153:4167 on n4hy/iir into trunk.
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@4182 221aa14e-8319-0410-a670-987f0aec2ac5
-rw-r--r-- | gnuradio-core/src/lib/filter/gr_iir_filter_ffd.cc | 6 | ||||
-rw-r--r-- | gnuradio-core/src/lib/filter/gr_iir_filter_ffd.h | 5 | ||||
-rw-r--r-- | gnuradio-core/src/lib/filter/gri_iir.h | 58 | ||||
-rwxr-xr-x | gnuradio-core/src/python/gnuradio/gr/qa_iir.py | 42 |
4 files changed, 70 insertions, 41 deletions
diff --git a/gnuradio-core/src/lib/filter/gr_iir_filter_ffd.cc b/gnuradio-core/src/lib/filter/gr_iir_filter_ffd.cc index be1cfbc470..1a1a28f031 100644 --- a/gnuradio-core/src/lib/filter/gr_iir_filter_ffd.cc +++ b/gnuradio-core/src/lib/filter/gr_iir_filter_ffd.cc @@ -57,11 +57,6 @@ void gr_iir_filter_ffd::set_taps (const std::vector<double> &fftaps, const std::vector<double> &fbtaps) throw (std::invalid_argument) { - if (fftaps.size () != fbtaps.size ()){ - fprintf (stderr, - "gr_iir_filter_ffd::set_taps: fftaps and fbtaps must have the same number of elements.\n"); - throw std::invalid_argument ("gr_iir_filter_ffd::set_taps"); - } d_new_fftaps = fftaps; d_new_fbtaps = fbtaps; @@ -76,7 +71,6 @@ gr_iir_filter_ffd::work (int noutput_items, const float *in = (const float *) input_items[0]; float *out = (float *) output_items[0]; - // fprintf (stderr, "gr_iir_filter_ffd::work noutput_items = %d\n", noutput_items); if (d_updated){ d_iir.set_taps (d_new_fftaps, d_new_fbtaps); diff --git a/gnuradio-core/src/lib/filter/gr_iir_filter_ffd.h b/gnuradio-core/src/lib/filter/gr_iir_filter_ffd.h index 4e8c8ebcd5..8e98758ec1 100644 --- a/gnuradio-core/src/lib/filter/gr_iir_filter_ffd.h +++ b/gnuradio-core/src/lib/filter/gr_iir_filter_ffd.h @@ -40,12 +40,11 @@ gr_make_iir_filter_ffd (const std::vector<double> &fftaps, * This filter uses the Direct Form I implementation, where * \p fftaps contains the feed-forward taps, and \p fbtaps the feedback ones. * - * \p fftaps and \p fbtaps must have equal numbers of taps - * + * * The input and output satisfy a difference equation of the form \f[ - y[n] - \sum_{k=1}^{N} a_k y[n-k] = \sum_{k=0}^{M} b_k x[n-k] + y[n] - \sum_{k=1}^{M} a_k y[n-k] = \sum_{k=0}^{N} b_k x[n-k] \f] * with the corresponding rational system function diff --git a/gnuradio-core/src/lib/filter/gri_iir.h b/gnuradio-core/src/lib/filter/gri_iir.h index d52c95f02e..587bd102f2 100644 --- a/gnuradio-core/src/lib/filter/gri_iir.h +++ b/gnuradio-core/src/lib/filter/gri_iir.h @@ -43,13 +43,13 @@ public: * The input and output satisfy a difference equation of the form \f[ - y[n] - \sum_{k=1}^{N} a_k y[n-k] = \sum_{k=0}^{M} b_k x[n-k] + y[n] - \sum_{k=1}^{M} a_k y[n-k] = \sum_{k=0}^{N} b_k x[n-k] \f] * with the corresponding rational system function \f[ - H(z) = \frac{\sum_{k=0}^{M} b_k z^{-k}}{1 - \sum_{k=1}^{N} a_k z^{-k}} + H(z) = \frac{\sum_{k=0}^{N} b_k z^{-k}}{1 - \sum_{k=1}^{M} a_k z^{-k}} \f] * Note that some texts define the system function with a + in the denominator. @@ -61,7 +61,7 @@ public: set_taps (fftaps, fbtaps); } - gri_iir () : d_latest(0) { } + gri_iir () : d_latest_n(0),d_latest_m(0) { } ~gri_iir () {} @@ -80,7 +80,8 @@ public: /*! * \return number of taps in filter. */ - unsigned ntaps () const { return d_fftaps.size (); } + unsigned ntaps_ff () const { return d_fftaps.size (); } + unsigned ntaps_fb () const { return d_fbtaps.size (); } /*! * \brief install new taps. @@ -88,19 +89,22 @@ public: void set_taps (const std::vector<tap_type> &fftaps, const std::vector<tap_type> &fbtaps) throw (std::invalid_argument) { - if (fftaps.size () != fbtaps.size ()) - throw std::invalid_argument ("gri_iir::set_taps"); - d_latest = 0; + + d_latest_n = 0; + d_latest_m = 0; d_fftaps = fftaps; d_fbtaps = fbtaps; int n = fftaps.size (); + int m = fbtaps.size (); d_prev_input.resize (2 * n); - d_prev_output.resize (2 * n); + d_prev_output.resize (2 * m); for (int i = 0; i < 2 * n; i++){ d_prev_input[i] = 0; + } + for (int i = 0; i < 2 * m; i++){ d_prev_output[i] = 0; } } @@ -108,7 +112,8 @@ public: protected: std::vector<tap_type> d_fftaps; std::vector<tap_type> d_fbtaps; - int d_latest; + int d_latest_n; + int d_latest_m; std::vector<tap_type> d_prev_output; std::vector<i_type> d_prev_input; }; @@ -123,29 +128,36 @@ gri_iir<i_type, o_type, tap_type>::filter (const i_type input) { tap_type acc; unsigned i = 0; - unsigned n = ntaps (); + unsigned n = ntaps_ff (); + unsigned m = ntaps_fb (); if (n == 0) return (o_type) 0; - int latest = d_latest; + int latest_n = d_latest_n; + int latest_m = d_latest_m; acc = d_fftaps[0] * input; for (i = 1; i < n; i ++) - acc += (d_fftaps[i] * d_prev_input[latest + i] - + d_fbtaps[i] * d_prev_output[latest + i]); + acc += (d_fftaps[i] * d_prev_input[latest_n + i]); + for (i = 1; i < m; i ++) + acc += (d_fbtaps[i] * d_prev_output[latest_m + i]); // store the values twice to avoid having to handle wrap-around in the loop - d_prev_output[latest] = acc; - d_prev_output[latest+n] = acc; - d_prev_input[latest] = input; - d_prev_input[latest+n] = input; - - latest--; - if (latest < 0) - latest += n; - - d_latest = latest; + d_prev_output[latest_m] = acc; + d_prev_output[latest_m+m] = acc; + d_prev_input[latest_n] = input; + d_prev_input[latest_n+n] = input; + + latest_n--; + latest_m--; + if (latest_n < 0) + latest_n += n; + if (latest_m < 0) + latest_m += m; + + d_latest_m = latest_m; + d_latest_n = latest_n; return (o_type) acc; } diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_iir.py b/gnuradio-core/src/python/gnuradio/gr/qa_iir.py index 43f2aa2191..426c73b58f 100755 --- a/gnuradio-core/src/python/gnuradio/gr/qa_iir.py +++ b/gnuradio-core/src/python/gnuradio/gr/qa_iir.py @@ -101,11 +101,6 @@ class test_iir (gr_unittest.TestCase): self.assertFloatTuplesAlmostEqual (expected_result, result_data) def test_iir_direct_006 (self): - fftaps = (2, 11, 0) - fbtaps = (0, -1) - self.assertRaises ((RuntimeError, ValueError), gr.iir_filter_ffd, fftaps, fbtaps) - - def test_iir_direct_007 (self): src_data = (1, 2, 3, 4, 5, 6, 7, 8) expected_result = (2, 13, 21, 59, 58, 186, 68, 583) fftaps = (2, 1) @@ -122,13 +117,42 @@ class test_iir (gr_unittest.TestCase): result_data = dst.data () self.assertFloatTuplesAlmostEqual (expected_result, result_data) - def test_iir_direct_008 (self): + def test_iir_direct_007 (self): + src_data = (1, 2, 3, 4, 5, 6, 7, 8) + expected_result = (2,2,5,5,8,8,11,11) fftaps = (2, 1) fbtaps = (0, -1) + src = gr.vector_source_f (src_data) op = gr.iir_filter_ffd (fftaps, fbtaps) - fftaps = (2, 11) - fbtaps = (0, -1, 3) - self.assertRaises ((RuntimeError, ValueError), op.set_taps, fftaps, fbtaps) + fftaps = (2,0,1) + fbtaps = (0, -1) + op.set_taps (fftaps, fbtaps) + dst = gr.vector_sink_f () + self.fg.connect (src, op) + self.fg.connect (op, dst) + self.fg.run () + result_data = dst.data () + self.assertFloatTuplesAlmostEqual (expected_result, result_data) + + def test_iir_direct_008 (self): + src_data = (1, 2, 3, 4, 5, 6, 7, 8) + expected_result = (2,4,4,10,18,14,26,56) + fftaps = (2,) + fbtaps = (0, 1) + src = gr.vector_source_f (src_data) + op = gr.iir_filter_ffd (fftaps, fbtaps) + fftaps_data = (1) + fbtaps = (0,0, -1,3) + op.set_taps (fftaps, fbtaps) + dst = gr.vector_sink_f () + self.fg.connect (src, op) + self.fg.connect (op, dst) + self.fg.run () + result_data = dst.data () + self.assertFloatTuplesAlmostEqual (expected_result, result_data) + + + if __name__ == '__main__': gr_unittest.main () |