diff options
author | Brian Padalino <bpadalino@gmail.com> | 2015-03-22 08:51:04 -0400 |
---|---|---|
committer | Tom Rondeau <tom@trondeau.com> | 2015-03-22 08:51:04 -0400 |
commit | 81766fba0159fefdbc6526dea5b29d2f337e7dc8 (patch) | |
tree | 8d44f70de5814ed5169466bc3b565fc7c8510411 | |
parent | 8a3ad1a5a41f95c3b624a2a87e3285c44452c9a7 (diff) |
filter: fixes stability issue with IIR filters.
Addresses issue #773. IIR filters of some type combinations do not
appopriately handle the accumulator precision that can lead to
unstable results. This adds an accumulator data type template to
specify the precision that is needed internally here. The accumulator
should be of the highest precision data type used in the filter.
-rw-r--r-- | gr-filter/include/gnuradio/filter/iir_filter.h | 20 | ||||
-rw-r--r-- | gr-filter/lib/iir_filter.cc | 6 | ||||
-rw-r--r-- | gr-filter/lib/iir_filter_ccc_impl.cc | 2 | ||||
-rw-r--r-- | gr-filter/lib/iir_filter_ccc_impl.h | 2 | ||||
-rw-r--r-- | gr-filter/lib/iir_filter_ccd_impl.cc | 2 | ||||
-rw-r--r-- | gr-filter/lib/iir_filter_ccd_impl.h | 2 | ||||
-rw-r--r-- | gr-filter/lib/iir_filter_ccf_impl.cc | 2 | ||||
-rw-r--r-- | gr-filter/lib/iir_filter_ccf_impl.h | 2 | ||||
-rw-r--r-- | gr-filter/lib/iir_filter_ccz_impl.cc | 2 | ||||
-rw-r--r-- | gr-filter/lib/iir_filter_ccz_impl.h | 2 | ||||
-rw-r--r-- | gr-filter/lib/iir_filter_ffd_impl.cc | 2 | ||||
-rw-r--r-- | gr-filter/lib/iir_filter_ffd_impl.h | 2 |
12 files changed, 23 insertions, 23 deletions
diff --git a/gr-filter/include/gnuradio/filter/iir_filter.h b/gr-filter/include/gnuradio/filter/iir_filter.h index bf87ce1d85..5b1e5ee544 100644 --- a/gr-filter/include/gnuradio/filter/iir_filter.h +++ b/gr-filter/include/gnuradio/filter/iir_filter.h @@ -35,7 +35,7 @@ namespace gr { /*! * \brief base class template for Infinite Impulse Response filter (IIR) */ - template<class i_type, class o_type, class tap_type> + template<class i_type, class o_type, class tap_type, class acc_type> class iir_filter { public: @@ -135,18 +135,18 @@ namespace gr { std::vector<tap_type> d_fbtaps; int d_latest_n; int d_latest_m; - std::vector<o_type> d_prev_output; + std::vector<acc_type> d_prev_output; std::vector<i_type> d_prev_input; }; // // general case. We may want to specialize this // - template<class i_type, class o_type, class tap_type> + template<class i_type, class o_type, class tap_type, class acc_type> o_type - iir_filter<i_type, o_type, tap_type>::filter(const i_type input) + iir_filter<i_type, o_type, tap_type, acc_type>::filter(const i_type input) { - o_type acc; + acc_type acc; unsigned i = 0; unsigned n = ntaps_ff(); unsigned m = ntaps_fb(); @@ -181,9 +181,9 @@ namespace gr { return (o_type)acc; } - template<class i_type, class o_type, class tap_type> + template<class i_type, class o_type, class tap_type, class acc_type> void - iir_filter<i_type, o_type, tap_type>::filter_n(o_type output[], + iir_filter<i_type, o_type, tap_type, acc_type>::filter_n(o_type output[], const i_type input[], long n) { @@ -193,15 +193,15 @@ namespace gr { template<> gr_complex - iir_filter<gr_complex, gr_complex, float>::filter(const gr_complex input); + iir_filter<gr_complex, gr_complex, float, gr_complex>::filter(const gr_complex input); template<> gr_complex - iir_filter<gr_complex, gr_complex, double>::filter(const gr_complex input); + iir_filter<gr_complex, gr_complex, double, gr_complexd>::filter(const gr_complex input); template<> gr_complex - iir_filter<gr_complex, gr_complex, gr_complexd>::filter(const gr_complex input); + iir_filter<gr_complex, gr_complex, gr_complexd, gr_complexd>::filter(const gr_complex input); } /* namespace kernel */ } /* namespace filter */ diff --git a/gr-filter/lib/iir_filter.cc b/gr-filter/lib/iir_filter.cc index 0f5ba00bb5..52192827f4 100644 --- a/gr-filter/lib/iir_filter.cc +++ b/gr-filter/lib/iir_filter.cc @@ -28,7 +28,7 @@ namespace gr { template<> gr_complex - iir_filter<gr_complex, gr_complex, float>::filter(const gr_complex input) + iir_filter<gr_complex, gr_complex, float, gr_complex>::filter(const gr_complex input) { gr_complex acc; unsigned i = 0; @@ -67,7 +67,7 @@ namespace gr { template<> gr_complex - iir_filter<gr_complex, gr_complex, double>::filter(const gr_complex input) + iir_filter<gr_complex, gr_complex, double, gr_complexd>::filter(const gr_complex input) { gr_complexd acc; unsigned i = 0; @@ -106,7 +106,7 @@ namespace gr { template<> gr_complex - iir_filter<gr_complex, gr_complex, gr_complexd>::filter(const gr_complex input) + iir_filter<gr_complex, gr_complex, gr_complexd, gr_complexd>::filter(const gr_complex input) { gr_complexd acc; unsigned i = 0; diff --git a/gr-filter/lib/iir_filter_ccc_impl.cc b/gr-filter/lib/iir_filter_ccc_impl.cc index e813cd933d..7e8293cad1 100644 --- a/gr-filter/lib/iir_filter_ccc_impl.cc +++ b/gr-filter/lib/iir_filter_ccc_impl.cc @@ -48,7 +48,7 @@ namespace gr { io_signature::make(1, 1, sizeof(gr_complex))), d_updated(false) { - d_iir = new kernel::iir_filter<gr_complex, gr_complex, gr_complex>(fftaps, fbtaps, oldstyle); + d_iir = new kernel::iir_filter<gr_complex, gr_complex, gr_complex, gr_complex>(fftaps, fbtaps, oldstyle); } iir_filter_ccc_impl::~iir_filter_ccc_impl() diff --git a/gr-filter/lib/iir_filter_ccc_impl.h b/gr-filter/lib/iir_filter_ccc_impl.h index 5b849f9ebd..77e08fdce4 100644 --- a/gr-filter/lib/iir_filter_ccc_impl.h +++ b/gr-filter/lib/iir_filter_ccc_impl.h @@ -33,7 +33,7 @@ namespace gr { { private: bool d_updated; - kernel::iir_filter<gr_complex, gr_complex, gr_complex> *d_iir; + kernel::iir_filter<gr_complex, gr_complex, gr_complex, gr_complex> *d_iir; std::vector<gr_complex> d_new_fftaps; std::vector<gr_complex> d_new_fbtaps; diff --git a/gr-filter/lib/iir_filter_ccd_impl.cc b/gr-filter/lib/iir_filter_ccd_impl.cc index ebe53e925a..a090df0816 100644 --- a/gr-filter/lib/iir_filter_ccd_impl.cc +++ b/gr-filter/lib/iir_filter_ccd_impl.cc @@ -48,7 +48,7 @@ namespace gr { io_signature::make(1, 1, sizeof(gr_complex))), d_updated(false) { - d_iir = new kernel::iir_filter<gr_complex, gr_complex, double>(fftaps, fbtaps, oldstyle); + d_iir = new kernel::iir_filter<gr_complex, gr_complex, double, gr_complexd>(fftaps, fbtaps, oldstyle); } iir_filter_ccd_impl::~iir_filter_ccd_impl() diff --git a/gr-filter/lib/iir_filter_ccd_impl.h b/gr-filter/lib/iir_filter_ccd_impl.h index 2ae2504bb2..6a15d1aa2d 100644 --- a/gr-filter/lib/iir_filter_ccd_impl.h +++ b/gr-filter/lib/iir_filter_ccd_impl.h @@ -33,7 +33,7 @@ namespace gr { { private: bool d_updated; - kernel::iir_filter<gr_complex, gr_complex, double> *d_iir; + kernel::iir_filter<gr_complex, gr_complex, double, gr_complexd> *d_iir; std::vector<double> d_new_fftaps; std::vector<double> d_new_fbtaps; diff --git a/gr-filter/lib/iir_filter_ccf_impl.cc b/gr-filter/lib/iir_filter_ccf_impl.cc index bb19e4550d..9b15c2903d 100644 --- a/gr-filter/lib/iir_filter_ccf_impl.cc +++ b/gr-filter/lib/iir_filter_ccf_impl.cc @@ -48,7 +48,7 @@ namespace gr { io_signature::make(1, 1, sizeof(gr_complex))), d_updated(false) { - d_iir = new kernel::iir_filter<gr_complex, gr_complex, float>(fftaps, fbtaps, oldstyle); + d_iir = new kernel::iir_filter<gr_complex, gr_complex, float, gr_complex>(fftaps, fbtaps, oldstyle); } iir_filter_ccf_impl::~iir_filter_ccf_impl() diff --git a/gr-filter/lib/iir_filter_ccf_impl.h b/gr-filter/lib/iir_filter_ccf_impl.h index 420e35ae0c..67265e76fa 100644 --- a/gr-filter/lib/iir_filter_ccf_impl.h +++ b/gr-filter/lib/iir_filter_ccf_impl.h @@ -33,7 +33,7 @@ namespace gr { { private: bool d_updated; - kernel::iir_filter<gr_complex, gr_complex, float> *d_iir; + kernel::iir_filter<gr_complex, gr_complex, float, gr_complex> *d_iir; std::vector<float> d_new_fftaps; std::vector<float> d_new_fbtaps; diff --git a/gr-filter/lib/iir_filter_ccz_impl.cc b/gr-filter/lib/iir_filter_ccz_impl.cc index cb7b2300f5..4227a3004a 100644 --- a/gr-filter/lib/iir_filter_ccz_impl.cc +++ b/gr-filter/lib/iir_filter_ccz_impl.cc @@ -48,7 +48,7 @@ namespace gr { io_signature::make(1, 1, sizeof(gr_complex))), d_updated(false) { - d_iir = new kernel::iir_filter<gr_complex, gr_complex, gr_complexd>(fftaps, fbtaps, oldstyle); + d_iir = new kernel::iir_filter<gr_complex, gr_complex, gr_complexd, gr_complexd>(fftaps, fbtaps, oldstyle); } iir_filter_ccz_impl::~iir_filter_ccz_impl() diff --git a/gr-filter/lib/iir_filter_ccz_impl.h b/gr-filter/lib/iir_filter_ccz_impl.h index 1e2a984782..59bd53ffc7 100644 --- a/gr-filter/lib/iir_filter_ccz_impl.h +++ b/gr-filter/lib/iir_filter_ccz_impl.h @@ -33,7 +33,7 @@ namespace gr { { private: bool d_updated; - kernel::iir_filter<gr_complex, gr_complex, gr_complexd> *d_iir; + kernel::iir_filter<gr_complex, gr_complex, gr_complexd, gr_complexd> *d_iir; std::vector<gr_complexd> d_new_fftaps; std::vector<gr_complexd> d_new_fbtaps; diff --git a/gr-filter/lib/iir_filter_ffd_impl.cc b/gr-filter/lib/iir_filter_ffd_impl.cc index 5aee5175c1..f70e3a25af 100644 --- a/gr-filter/lib/iir_filter_ffd_impl.cc +++ b/gr-filter/lib/iir_filter_ffd_impl.cc @@ -48,7 +48,7 @@ namespace gr { io_signature::make(1, 1, sizeof (float))), d_updated(false) { - d_iir = new kernel::iir_filter<float,float,double>(fftaps, fbtaps, oldstyle); + d_iir = new kernel::iir_filter<float,float,double,double>(fftaps, fbtaps, oldstyle); } iir_filter_ffd_impl::~iir_filter_ffd_impl() diff --git a/gr-filter/lib/iir_filter_ffd_impl.h b/gr-filter/lib/iir_filter_ffd_impl.h index 5cad8eccdc..a74ac7a949 100644 --- a/gr-filter/lib/iir_filter_ffd_impl.h +++ b/gr-filter/lib/iir_filter_ffd_impl.h @@ -33,7 +33,7 @@ namespace gr { { private: bool d_updated; - kernel::iir_filter<float,float,double> *d_iir; + kernel::iir_filter<float,float,double,double> *d_iir; std::vector<double> d_new_fftaps; std::vector<double> d_new_fbtaps; |