diff options
author | Tom Rondeau <tom@trondeau.com> | 2014-04-23 12:49:24 -0400 |
---|---|---|
committer | Tom Rondeau <tom@trondeau.com> | 2014-04-23 16:50:24 -0400 |
commit | e2afce984c606a1373150c5f6f51a4b00cd0b47a (patch) | |
tree | d288b0e5d8d6b0cf01bfb23280c54df037b2f49a | |
parent | d947f35405437e8efcd0111ef0bf1921444a9553 (diff) |
filter: adding ccc, ccz (complex double taps), ccf, and ccd IIR filters.
Renames grc file filter_iir_filter_ffd.xml to filter_iir_filter_xxx.xml
More proof that templates are practically worthless. complex<float> * complex<double> doesn't work and has to be specialized. Forced the creation of iir_filter.cc.
22 files changed, 1338 insertions, 42 deletions
diff --git a/gr-filter/grc/CMakeLists.txt b/gr-filter/grc/CMakeLists.txt index 1315b11c28..8c3dc64463 100644 --- a/gr-filter/grc/CMakeLists.txt +++ b/gr-filter/grc/CMakeLists.txt @@ -28,7 +28,7 @@ install(FILES filter_fractional_resampler_xx.xml filter_freq_xlating_fir_filter_xxx.xml filter_hilbert_fc.xml - filter_iir_filter_ffd.xml + filter_iir_filter_xxx.xml filter_interp_fir_filter_xxx.xml filter_pfb_arb_resampler.xml filter_pfb_channelizer.xml diff --git a/gr-filter/grc/filter_block_tree.xml b/gr-filter/grc/filter_block_tree.xml index 8fe0d17a78..f85f3f1921 100644 --- a/gr-filter/grc/filter_block_tree.xml +++ b/gr-filter/grc/filter_block_tree.xml @@ -43,7 +43,7 @@ <block>filterbank_vcvcf</block> <block>filter_delay_fc</block> <block>hilbert_fc</block> - <block>iir_filter_ffd</block> + <block>iir_filter_xxx</block> <block>interp_fir_filter_xxx</block> <block>single_pole_iir_filter_xx</block> </cat> diff --git a/gr-filter/grc/filter_iir_filter_ffd.xml b/gr-filter/grc/filter_iir_filter_ffd.xml deleted file mode 100644 index 514cd084de..0000000000 --- a/gr-filter/grc/filter_iir_filter_ffd.xml +++ /dev/null @@ -1,38 +0,0 @@ -<?xml version="1.0"?> -<!-- -################################################### -##IIR Filter -################################################### - --> -<block> - <name>IIR Filter</name> - <key>iir_filter_ffd</key> - <import>from gnuradio import filter</import> - <make>filter.iir_filter_ffd($fftaps, $fbtaps, $oldstyle)</make> - <callback>set_taps($fftaps, $fbtaps)</callback> - <param> - <name>Feed-forward Taps</name> - <key>fftaps</key> - <type>real_vector</type> - </param> - <param> - <name>Feedback Taps</name> - <key>fbtaps</key> - <type>real_vector</type> - </param> - <param> - <name>Old Style of Taps</name> - <key>oldstyle</key> - <value>True</value> - <type>bool</type> - <hide>part</hide> - </param> - <sink> - <name>in</name> - <type>float</type> - </sink> - <source> - <name>out</name> - <type>float</type> - </source> -</block> diff --git a/gr-filter/grc/filter_iir_filter_xxx.xml b/gr-filter/grc/filter_iir_filter_xxx.xml new file mode 100644 index 0000000000..cd41d47caf --- /dev/null +++ b/gr-filter/grc/filter_iir_filter_xxx.xml @@ -0,0 +1,93 @@ +<?xml version="1.0"?> +<!-- +################################################### +##IIR Filter +################################################### + --> +<block> + <name>IIR Filter</name> + <key>iir_filter_xxx</key> + <import>from gnuradio import filter</import> + <make>filter.iir_filter_$(type)($fftaps, $fbtaps, $oldstyle)</make> + <callback>set_taps($fftaps, $fbtaps)</callback> + + <param> + <name>Type</name> + <key>type</key> + <type>enum</type> + <option> + <name>Float->Float (Double Taps)</name> + <key>ffd</key> + <opt>input:float</opt> + <opt>output:float</opt> + <opt>taps:real_vector</opt> + </option> + <option> + <name>Complex->Complex (Float Taps)</name> + <key>ccf</key> + <opt>input:complex</opt> + <opt>output:complex</opt> + <opt>taps:real_vector</opt> + </option> + <option> + <name>Complex->Complex (Double Taps)</name> + <key>ccd</key> + <opt>input:complex</opt> + <opt>output:complex</opt> + <opt>taps:real_vector</opt> + </option> + <option> + <name>Complex->Complex (Complex Taps)</name> + <key>ccc</key> + <opt>input:complex</opt> + <opt>output:complex</opt> + <opt>taps:complex_vector</opt> + </option> + <option> + <name>Complex->Complex (Complex Double Taps)</name> + <key>ccz</key> + <opt>input:complex</opt> + <opt>output:complex</opt> + <opt>taps:complex_vector</opt> + </option> + </param> + + <param> + <name>Feed-forward Taps</name> + <key>fftaps</key> + <type>$type.taps</type> + </param> + + <param> + <name>Feedback Taps</name> + <key>fbtaps</key> + <type>$type.taps</type> + </param> + + <param> + <name>Old Style of Taps</name> + <key>oldstyle</key> + <value>True</value> + <type>enum</type> + <hide>part</hide> + <option> + <name>True</name> + <key>True</key> + </option> + <option> + <name>False</name> + <key>False</key> + </option> + </param> + + <sink> + <name>in</name> + <type>$type.input</type> + </sink> + + <source> + <name>out</name> + <type>$type.output</type> + </source> + +</block> diff --git a/gr-filter/include/gnuradio/filter/CMakeLists.txt b/gr-filter/include/gnuradio/filter/CMakeLists.txt index 1af91a6067..b5cc432c6a 100644 --- a/gr-filter/include/gnuradio/filter/CMakeLists.txt +++ b/gr-filter/include/gnuradio/filter/CMakeLists.txt @@ -104,6 +104,10 @@ install(FILES fractional_resampler_ff.h hilbert_fc.h iir_filter_ffd.h + iir_filter_ccc.h + iir_filter_ccf.h + iir_filter_ccd.h + iir_filter_ccz.h pfb_arb_resampler.h pfb_arb_resampler_ccf.h pfb_arb_resampler_ccc.h diff --git a/gr-filter/include/gnuradio/filter/iir_filter.h b/gr-filter/include/gnuradio/filter/iir_filter.h index 71ff73a03d..58694ff5c4 100644 --- a/gr-filter/include/gnuradio/filter/iir_filter.h +++ b/gr-filter/include/gnuradio/filter/iir_filter.h @@ -24,6 +24,7 @@ #define INCLUDED_IIR_FILTER_H #include <gnuradio/filter/api.h> +#include <gnuradio/gr_complex.h> #include <vector> #include <stdexcept> @@ -134,7 +135,7 @@ namespace gr { std::vector<tap_type> d_fbtaps; int d_latest_n; int d_latest_m; - std::vector<tap_type> d_prev_output; + std::vector<o_type> d_prev_output; std::vector<i_type> d_prev_input; }; @@ -145,7 +146,7 @@ namespace gr { o_type iir_filter<i_type, o_type, tap_type>::filter(const i_type input) { - tap_type acc; + o_type acc; unsigned i = 0; unsigned n = ntaps_ff(); unsigned m = ntaps_fb(); @@ -190,6 +191,18 @@ namespace gr { output[i] = filter(input[i]); } + template<> + gr_complex + iir_filter<gr_complex, gr_complex, float>::filter(const gr_complex input); + + template<> + gr_complex + iir_filter<gr_complex, gr_complex, double>::filter(const gr_complex input); + + template<> + gr_complex + iir_filter<gr_complex, gr_complex, gr_complexd>::filter(const gr_complex input); + } /* namespace kernel */ } /* namespace filter */ } /* namespace gr */ diff --git a/gr-filter/include/gnuradio/filter/iir_filter_ccc.h b/gr-filter/include/gnuradio/filter/iir_filter_ccc.h new file mode 100644 index 0000000000..7ca9108380 --- /dev/null +++ b/gr-filter/include/gnuradio/filter/iir_filter_ccc.h @@ -0,0 +1,85 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012,2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_IIR_FILTER_CCC_H +#define INCLUDED_IIR_FILTER_CCC_H + +#include <gnuradio/filter/api.h> +#include <gnuradio/sync_block.h> + +namespace gr { + namespace filter { + + /*! + * \brief IIR filter with complex input, complex output, and + * complex taps. + * \ingroup filter_blk + * + * \details + * This filter uses the Direct Form I implementation, where \p + * fftaps contains the feed-forward taps, and \p fbtaps the + * feedback ones. + * + * \p oldstyle: The old style of the IIR filter uses feedback + * taps that are negative of what most definitions use (scipy + * and Matlab among them). This parameter keeps using the old + * GNU Radio style and is set to TRUE by default. When taps + * generated from scipy, Matlab, or gr_filter_design, use the + * new style by setting this to FALSE. + * + * The input and output satisfy a difference equation of the form + \f[ + y[n] - \sum_{k=1}^{M} a_k y[n-k] = \sum_{k=0}^{N} b_k x[n-k] + \f] + + \xmlonly + y[n] - \sum_{k=1}^{M} a_k y[n-k] = \sum_{k=0}^{N} b_k x[n-k] + \endxmlonly + + * 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}} + \f] + + \xmlonly + H(z) = \ frac{\sum_{k=0}^{M} b_k z^{-k}}{1 - \sum_{k=1}^{N} a_k z^{-k}} + \endxmlonly + + */ + class FILTER_API iir_filter_ccc : virtual public sync_block + { + public: + // gr::filter::iir_filter_ccc::sptr + typedef boost::shared_ptr<iir_filter_ccc> sptr; + + static sptr make(const std::vector<gr_complex> &fftaps, + const std::vector<gr_complex> &fbtaps, + bool oldstyle=true); + + virtual void set_taps(const std::vector<gr_complex> &fftaps, + const std::vector<gr_complex> &fbtaps) = 0; + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_IIR_FILTER_CCC_H */ diff --git a/gr-filter/include/gnuradio/filter/iir_filter_ccd.h b/gr-filter/include/gnuradio/filter/iir_filter_ccd.h new file mode 100644 index 0000000000..c9565f6fec --- /dev/null +++ b/gr-filter/include/gnuradio/filter/iir_filter_ccd.h @@ -0,0 +1,85 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012,2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_IIR_FILTER_CCD_H +#define INCLUDED_IIR_FILTER_CCD_H + +#include <gnuradio/filter/api.h> +#include <gnuradio/sync_block.h> + +namespace gr { + namespace filter { + + /*! + * \brief IIR filter with complex input, complex output, and + * double taps. + * \ingroup filter_blk + * + * \details + * This filter uses the Direct Form I implementation, where \p + * fftaps contains the feed-forward taps, and \p fbtaps the + * feedback ones. + * + * \p oldstyle: The old style of the IIR filter uses feedback + * taps that are negative of what most definitions use (scipy + * and Matlab among them). This parameter keeps using the old + * GNU Radio style and is set to TRUE by default. When taps + * generated from scipy, Matlab, or gr_filter_design, use the + * new style by setting this to FALSE. + * + * The input and output satisfy a difference equation of the form + \f[ + y[n] - \sum_{k=1}^{M} a_k y[n-k] = \sum_{k=0}^{N} b_k x[n-k] + \f] + + \xmlonly + y[n] - \sum_{k=1}^{M} a_k y[n-k] = \sum_{k=0}^{N} b_k x[n-k] + \endxmlonly + + * 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}} + \f] + + \xmlonly + H(z) = \ frac{\sum_{k=0}^{M} b_k z^{-k}}{1 - \sum_{k=1}^{N} a_k z^{-k}} + \endxmlonly + + */ + class FILTER_API iir_filter_ccd : virtual public sync_block + { + public: + // gr::filter::iir_filter_ccd::sptr + typedef boost::shared_ptr<iir_filter_ccd> sptr; + + static sptr make(const std::vector<double> &fftaps, + const std::vector<double> &fbtaps, + bool oldstyle=true); + + virtual void set_taps(const std::vector<double> &fftaps, + const std::vector<double> &fbtaps) = 0; + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_IIR_FILTER_CCD_H */ diff --git a/gr-filter/include/gnuradio/filter/iir_filter_ccf.h b/gr-filter/include/gnuradio/filter/iir_filter_ccf.h new file mode 100644 index 0000000000..2a9a953719 --- /dev/null +++ b/gr-filter/include/gnuradio/filter/iir_filter_ccf.h @@ -0,0 +1,85 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012,2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_IIR_FILTER_CCF_H +#define INCLUDED_IIR_FILTER_CCF_H + +#include <gnuradio/filter/api.h> +#include <gnuradio/sync_block.h> + +namespace gr { + namespace filter { + + /*! + * \brief IIR filter with complex input, complex output, and + * float taps. + * \ingroup filter_blk + * + * \details + * This filter uses the Direct Form I implementation, where \p + * fftaps contains the feed-forward taps, and \p fbtaps the + * feedback ones. + * + * \p oldstyle: The old style of the IIR filter uses feedback + * taps that are negative of what most definitions use (scipy + * and Matlab among them). This parameter keeps using the old + * GNU Radio style and is set to TRUE by default. When taps + * generated from scipy, Matlab, or gr_filter_design, use the + * new style by setting this to FALSE. + * + * The input and output satisfy a difference equation of the form + \f[ + y[n] - \sum_{k=1}^{M} a_k y[n-k] = \sum_{k=0}^{N} b_k x[n-k] + \f] + + \xmlonly + y[n] - \sum_{k=1}^{M} a_k y[n-k] = \sum_{k=0}^{N} b_k x[n-k] + \endxmlonly + + * 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}} + \f] + + \xmlonly + H(z) = \ frac{\sum_{k=0}^{M} b_k z^{-k}}{1 - \sum_{k=1}^{N} a_k z^{-k}} + \endxmlonly + + */ + class FILTER_API iir_filter_ccf : virtual public sync_block + { + public: + // gr::filter::iir_filter_ccf::sptr + typedef boost::shared_ptr<iir_filter_ccf> sptr; + + static sptr make(const std::vector<float> &fftaps, + const std::vector<float> &fbtaps, + bool oldstyle=true); + + virtual void set_taps(const std::vector<float> &fftaps, + const std::vector<float> &fbtaps) = 0; + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_IIR_FILTER_CCF_H */ diff --git a/gr-filter/include/gnuradio/filter/iir_filter_ccz.h b/gr-filter/include/gnuradio/filter/iir_filter_ccz.h new file mode 100644 index 0000000000..061ab39715 --- /dev/null +++ b/gr-filter/include/gnuradio/filter/iir_filter_ccz.h @@ -0,0 +1,85 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012,2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_IIR_FILTER_CCZ_H +#define INCLUDED_IIR_FILTER_CCZ_H + +#include <gnuradio/filter/api.h> +#include <gnuradio/sync_block.h> + +namespace gr { + namespace filter { + + /*! + * \brief IIR filter with complex input, complex output, and + * complex (double) taps. + * \ingroup filter_blk + * + * \details + * This filter uses the Direct Form I implementation, where \p + * fftaps contains the feed-forward taps, and \p fbtaps the + * feedback ones. + * + * \p oldstyle: The old style of the IIR filter uses feedback + * taps that are negative of what most definitions use (scipy + * and Matlab among them). This parameter keeps using the old + * GNU Radio style and is set to TRUE by default. When taps + * generated from scipy, Matlab, or gr_filter_design, use the + * new style by setting this to FALSE. + * + * The input and output satisfy a difference equation of the form + \f[ + y[n] - \sum_{k=1}^{M} a_k y[n-k] = \sum_{k=0}^{N} b_k x[n-k] + \f] + + \xmlonly + y[n] - \sum_{k=1}^{M} a_k y[n-k] = \sum_{k=0}^{N} b_k x[n-k] + \endxmlonly + + * 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}} + \f] + + \xmlonly + H(z) = \ frac{\sum_{k=0}^{M} b_k z^{-k}}{1 - \sum_{k=1}^{N} a_k z^{-k}} + \endxmlonly + + */ + class FILTER_API iir_filter_ccz : virtual public sync_block + { + public: + // gr::filter::iir_filter_ccz::sptr + typedef boost::shared_ptr<iir_filter_ccz> sptr; + + static sptr make(const std::vector<gr_complexd> &fftaps, + const std::vector<gr_complexd> &fbtaps, + bool oldstyle=true); + + virtual void set_taps(const std::vector<gr_complexd> &fftaps, + const std::vector<gr_complexd> &fbtaps) = 0; + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_IIR_FILTER_CCZ_H */ diff --git a/gr-filter/lib/CMakeLists.txt b/gr-filter/lib/CMakeLists.txt index 0e444d5b5d..3d6aea5b52 100644 --- a/gr-filter/lib/CMakeLists.txt +++ b/gr-filter/lib/CMakeLists.txt @@ -119,6 +119,7 @@ list(APPEND filter_sources fir_filter_with_buffer.cc fft_filter.cc firdes.cc + iir_filter.cc mmse_fir_interpolator_cc.cc mmse_fir_interpolator_ff.cc pm_remez.cc @@ -138,6 +139,10 @@ list(APPEND filter_sources fractional_resampler_ff_impl.cc hilbert_fc_impl.cc iir_filter_ffd_impl.cc + iir_filter_ccc_impl.cc + iir_filter_ccf_impl.cc + iir_filter_ccd_impl.cc + iir_filter_ccz_impl.cc pfb_arb_resampler.cc pfb_arb_resampler_ccf_impl.cc pfb_arb_resampler_ccc_impl.cc diff --git a/gr-filter/lib/iir_filter.cc b/gr-filter/lib/iir_filter.cc new file mode 100644 index 0000000000..0f5ba00bb5 --- /dev/null +++ b/gr-filter/lib/iir_filter.cc @@ -0,0 +1,149 @@ +/* -*- c++ -*- */ +/* + * Copyright 2002,2012,2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#include <gnuradio/filter/iir_filter.h> + +namespace gr { + namespace filter { + namespace kernel { + + template<> + gr_complex + iir_filter<gr_complex, gr_complex, float>::filter(const gr_complex input) + { + gr_complex acc; + unsigned i = 0; + unsigned n = ntaps_ff(); + unsigned m = ntaps_fb(); + + if(n == 0) + return (gr_complex)0; + + 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_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_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 static_cast<gr_complex>(acc); + } + + template<> + gr_complex + iir_filter<gr_complex, gr_complex, double>::filter(const gr_complex input) + { + gr_complexd acc; + unsigned i = 0; + unsigned n = ntaps_ff(); + unsigned m = ntaps_fb(); + + if(n == 0) + return (gr_complex)0; + + int latest_n = d_latest_n; + int latest_m = d_latest_m; + + acc = d_fftaps[0] * static_cast<gr_complexd>(input); + for(i = 1; i < n; i ++) + acc += (d_fftaps[i] * static_cast<gr_complexd>(d_prev_input[latest_n + i])); + for(i = 1; i < m; i ++) + acc += (d_fbtaps[i] * static_cast<gr_complexd>(d_prev_output[latest_m + i])); + + // store the values twice to avoid having to handle wrap-around in the loop + 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 static_cast<gr_complex>(acc); + } + + template<> + gr_complex + iir_filter<gr_complex, gr_complex, gr_complexd>::filter(const gr_complex input) + { + gr_complexd acc; + unsigned i = 0; + unsigned n = ntaps_ff(); + unsigned m = ntaps_fb(); + + if(n == 0) + return (gr_complex)0; + + int latest_n = d_latest_n; + int latest_m = d_latest_m; + + acc = d_fftaps[0] * static_cast<gr_complexd>(input); + for(i = 1; i < n; i ++) + acc += (d_fftaps[i] * static_cast<gr_complexd>(d_prev_input[latest_n + i])); + for(i = 1; i < m; i ++) + acc += (d_fbtaps[i] * static_cast<gr_complexd>(d_prev_output[latest_m + i])); + + // store the values twice to avoid having to handle wrap-around in the loop + 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 static_cast<gr_complex>(acc); + } + + } /* namespace kernel */ + } /* namespace filter */ +} /* namespace gr */ + diff --git a/gr-filter/lib/iir_filter_ccc_impl.cc b/gr-filter/lib/iir_filter_ccc_impl.cc new file mode 100644 index 0000000000..f1f0dbe4ed --- /dev/null +++ b/gr-filter/lib/iir_filter_ccc_impl.cc @@ -0,0 +1,87 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010,2012,2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "iir_filter_ccc_impl.h" +#include <gnuradio/io_signature.h> + +namespace gr { + namespace filter { + + iir_filter_ccc::sptr + iir_filter_ccc::make(const std::vector<gr_complex> &fftaps, + const std::vector<gr_complex> &fbtaps, + bool oldstyle) + { + return gnuradio::get_initial_sptr + (new iir_filter_ccc_impl(fftaps, fbtaps, oldstyle)); + } + + iir_filter_ccc_impl::iir_filter_ccc_impl(const std::vector<gr_complex> &fftaps, + const std::vector<gr_complex> &fbtaps, + bool oldstyle) + + : sync_block("iir_filter_ccc", + io_signature::make(1, 1, sizeof(gr_complex)), + 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); + } + + iir_filter_ccc_impl::~iir_filter_ccc_impl() + { + delete d_iir; + } + + void + iir_filter_ccc_impl::set_taps(const std::vector<gr_complex> &fftaps, + const std::vector<gr_complex> &fbtaps) + { + d_new_fftaps = fftaps; + d_new_fbtaps = fbtaps; + d_updated = true; + } + + int + iir_filter_ccc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex*)input_items[0]; + gr_complex *out = (gr_complex*)output_items[0]; + + if(d_updated) { + d_iir->set_taps(d_new_fftaps, d_new_fbtaps); + d_updated = false; + } + + d_iir->filter_n(out, in, noutput_items); + return noutput_items; + }; + + } /* namespace filter */ +} /* namespace gr */ + diff --git a/gr-filter/lib/iir_filter_ccc_impl.h b/gr-filter/lib/iir_filter_ccc_impl.h new file mode 100644 index 0000000000..5b849f9ebd --- /dev/null +++ b/gr-filter/lib/iir_filter_ccc_impl.h @@ -0,0 +1,57 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012,2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_IIR_FILTER_CCC_IMPL_H +#define INCLUDED_IIR_FILTER_CCC_IMPL_H + +#include <gnuradio/filter/iir_filter.h> +#include <gnuradio/filter/iir_filter_ccc.h> + +namespace gr { + namespace filter { + + class FILTER_API iir_filter_ccc_impl : public iir_filter_ccc + { + private: + bool d_updated; + kernel::iir_filter<gr_complex, gr_complex, gr_complex> *d_iir; + std::vector<gr_complex> d_new_fftaps; + std::vector<gr_complex> d_new_fbtaps; + + public: + iir_filter_ccc_impl(const std::vector<gr_complex> &fftaps, + const std::vector<gr_complex> &fbtaps, + bool oldstyle=true); + ~iir_filter_ccc_impl(); + + void set_taps(const std::vector<gr_complex> &fftaps, + const std::vector<gr_complex> &fbtaps); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_IIR_FILTER_CCC_IMPL_H */ diff --git a/gr-filter/lib/iir_filter_ccd_impl.cc b/gr-filter/lib/iir_filter_ccd_impl.cc new file mode 100644 index 0000000000..8616b6deac --- /dev/null +++ b/gr-filter/lib/iir_filter_ccd_impl.cc @@ -0,0 +1,87 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010,2012,2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "iir_filter_ccd_impl.h" +#include <gnuradio/io_signature.h> + +namespace gr { + namespace filter { + + iir_filter_ccd::sptr + iir_filter_ccd::make(const std::vector<double> &fftaps, + const std::vector<double> &fbtaps, + bool oldstyle) + { + return gnuradio::get_initial_sptr + (new iir_filter_ccd_impl(fftaps, fbtaps, oldstyle)); + } + + iir_filter_ccd_impl::iir_filter_ccd_impl(const std::vector<double> &fftaps, + const std::vector<double> &fbtaps, + bool oldstyle) + + : sync_block("iir_filter_ccd", + io_signature::make(1, 1, sizeof(gr_complex)), + 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); + } + + iir_filter_ccd_impl::~iir_filter_ccd_impl() + { + delete d_iir; + } + + void + iir_filter_ccd_impl::set_taps(const std::vector<double> &fftaps, + const std::vector<double> &fbtaps) + { + d_new_fftaps = fftaps; + d_new_fbtaps = fbtaps; + d_updated = true; + } + + int + iir_filter_ccd_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex*)input_items[0]; + gr_complex *out = (gr_complex*)output_items[0]; + + if(d_updated) { + d_iir->set_taps(d_new_fftaps, d_new_fbtaps); + d_updated = false; + } + + d_iir->filter_n(out, in, noutput_items); + return noutput_items; + }; + + } /* namespace filter */ +} /* namespace gr */ + diff --git a/gr-filter/lib/iir_filter_ccd_impl.h b/gr-filter/lib/iir_filter_ccd_impl.h new file mode 100644 index 0000000000..2ae2504bb2 --- /dev/null +++ b/gr-filter/lib/iir_filter_ccd_impl.h @@ -0,0 +1,57 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012,2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_IIR_FILTER_CCD_IMPL_H +#define INCLUDED_IIR_FILTER_CCD_IMPL_H + +#include <gnuradio/filter/iir_filter.h> +#include <gnuradio/filter/iir_filter_ccd.h> + +namespace gr { + namespace filter { + + class FILTER_API iir_filter_ccd_impl : public iir_filter_ccd + { + private: + bool d_updated; + kernel::iir_filter<gr_complex, gr_complex, double> *d_iir; + std::vector<double> d_new_fftaps; + std::vector<double> d_new_fbtaps; + + public: + iir_filter_ccd_impl(const std::vector<double> &fftaps, + const std::vector<double> &fbtaps, + bool oldstyle=true); + ~iir_filter_ccd_impl(); + + void set_taps(const std::vector<double> &fftaps, + const std::vector<double> &fbtaps); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_IIR_FILTER_CCD_IMPL_H */ diff --git a/gr-filter/lib/iir_filter_ccf_impl.cc b/gr-filter/lib/iir_filter_ccf_impl.cc new file mode 100644 index 0000000000..5132bdfedf --- /dev/null +++ b/gr-filter/lib/iir_filter_ccf_impl.cc @@ -0,0 +1,87 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010,2012,2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "iir_filter_ccf_impl.h" +#include <gnuradio/io_signature.h> + +namespace gr { + namespace filter { + + iir_filter_ccf::sptr + iir_filter_ccf::make(const std::vector<float> &fftaps, + const std::vector<float> &fbtaps, + bool oldstyle) + { + return gnuradio::get_initial_sptr + (new iir_filter_ccf_impl(fftaps, fbtaps, oldstyle)); + } + + iir_filter_ccf_impl::iir_filter_ccf_impl(const std::vector<float> &fftaps, + const std::vector<float> &fbtaps, + bool oldstyle) + + : sync_block("iir_filter_ccf", + io_signature::make(1, 1, sizeof(gr_complex)), + 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); + } + + iir_filter_ccf_impl::~iir_filter_ccf_impl() + { + delete d_iir; + } + + void + iir_filter_ccf_impl::set_taps(const std::vector<float> &fftaps, + const std::vector<float> &fbtaps) + { + d_new_fftaps = fftaps; + d_new_fbtaps = fbtaps; + d_updated = true; + } + + int + iir_filter_ccf_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex*)input_items[0]; + gr_complex *out = (gr_complex*)output_items[0]; + + if(d_updated) { + d_iir->set_taps(d_new_fftaps, d_new_fbtaps); + d_updated = false; + } + + d_iir->filter_n(out, in, noutput_items); + return noutput_items; + }; + + } /* namespace filter */ +} /* namespace gr */ + diff --git a/gr-filter/lib/iir_filter_ccf_impl.h b/gr-filter/lib/iir_filter_ccf_impl.h new file mode 100644 index 0000000000..420e35ae0c --- /dev/null +++ b/gr-filter/lib/iir_filter_ccf_impl.h @@ -0,0 +1,57 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012,2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_IIR_FILTER_CCF_IMPL_H +#define INCLUDED_IIR_FILTER_CCF_IMPL_H + +#include <gnuradio/filter/iir_filter.h> +#include <gnuradio/filter/iir_filter_ccf.h> + +namespace gr { + namespace filter { + + class FILTER_API iir_filter_ccf_impl : public iir_filter_ccf + { + private: + bool d_updated; + kernel::iir_filter<gr_complex, gr_complex, float> *d_iir; + std::vector<float> d_new_fftaps; + std::vector<float> d_new_fbtaps; + + public: + iir_filter_ccf_impl(const std::vector<float> &fftaps, + const std::vector<float> &fbtaps, + bool oldstyle=true); + ~iir_filter_ccf_impl(); + + void set_taps(const std::vector<float> &fftaps, + const std::vector<float> &fbtaps); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_IIR_FILTER_CCF_IMPL_H */ diff --git a/gr-filter/lib/iir_filter_ccz_impl.cc b/gr-filter/lib/iir_filter_ccz_impl.cc new file mode 100644 index 0000000000..117aef5aa4 --- /dev/null +++ b/gr-filter/lib/iir_filter_ccz_impl.cc @@ -0,0 +1,87 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2010,2012,2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "iir_filter_ccz_impl.h" +#include <gnuradio/io_signature.h> + +namespace gr { + namespace filter { + + iir_filter_ccz::sptr + iir_filter_ccz::make(const std::vector<gr_complexd> &fftaps, + const std::vector<gr_complexd> &fbtaps, + bool oldstyle) + { + return gnuradio::get_initial_sptr + (new iir_filter_ccz_impl(fftaps, fbtaps, oldstyle)); + } + + iir_filter_ccz_impl::iir_filter_ccz_impl(const std::vector<gr_complexd> &fftaps, + const std::vector<gr_complexd> &fbtaps, + bool oldstyle) + + : sync_block("iir_filter_ccz", + io_signature::make(1, 1, sizeof(gr_complex)), + 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); + } + + iir_filter_ccz_impl::~iir_filter_ccz_impl() + { + delete d_iir; + } + + void + iir_filter_ccz_impl::set_taps(const std::vector<gr_complexd> &fftaps, + const std::vector<gr_complexd> &fbtaps) + { + d_new_fftaps = fftaps; + d_new_fbtaps = fbtaps; + d_updated = true; + } + + int + iir_filter_ccz_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + const gr_complex *in = (const gr_complex*)input_items[0]; + gr_complex *out = (gr_complex*)output_items[0]; + + if(d_updated) { + d_iir->set_taps(d_new_fftaps, d_new_fbtaps); + d_updated = false; + } + + d_iir->filter_n(out, in, noutput_items); + return noutput_items; + }; + + } /* namespace filter */ +} /* namespace gr */ + diff --git a/gr-filter/lib/iir_filter_ccz_impl.h b/gr-filter/lib/iir_filter_ccz_impl.h new file mode 100644 index 0000000000..1e2a984782 --- /dev/null +++ b/gr-filter/lib/iir_filter_ccz_impl.h @@ -0,0 +1,57 @@ +/* -*- c++ -*- */ +/* + * Copyright 2004,2012,2014 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNU Radio; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, + * Boston, MA 02110-1301, USA. + */ + +#ifndef INCLUDED_IIR_FILTER_CCZ_IMPL_H +#define INCLUDED_IIR_FILTER_CCZ_IMPL_H + +#include <gnuradio/filter/iir_filter.h> +#include <gnuradio/filter/iir_filter_ccz.h> + +namespace gr { + namespace filter { + + class FILTER_API iir_filter_ccz_impl : public iir_filter_ccz + { + private: + bool d_updated; + kernel::iir_filter<gr_complex, gr_complex, gr_complexd> *d_iir; + std::vector<gr_complexd> d_new_fftaps; + std::vector<gr_complexd> d_new_fbtaps; + + public: + iir_filter_ccz_impl(const std::vector<gr_complexd> &fftaps, + const std::vector<gr_complexd> &fbtaps, + bool oldstyle=true); + ~iir_filter_ccz_impl(); + + void set_taps(const std::vector<gr_complexd> &fftaps, + const std::vector<gr_complexd> &fbtaps); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_IIR_FILTER_CCZ_IMPL_H */ diff --git a/gr-filter/python/filter/qa_iir_filter.py b/gr-filter/python/filter/qa_iir_filter.py index cd66e82b69..0a89dc4d89 100755 --- a/gr-filter/python/filter/qa_iir_filter.py +++ b/gr-filter/python/filter/qa_iir_filter.py @@ -151,6 +151,148 @@ class test_iir_filter(gr_unittest.TestCase): result_data = dst.data() self.assertFloatTuplesAlmostEqual (expected_result, result_data) + def test_iir_ccf_001(self): + src_data = (1+1j, 2+2j, 3+3j, 4+4j, 5+5j, 6+6j, 7+7j, 8+8j) + expected_result = (2+2j, (6+6j), (12+12j), (20+20j), (30+30j), (42+42j), (56+56j), (72+72j)) + fftaps = (2,) + fbtaps = (0, 1) + src = blocks.vector_source_c(src_data) + op = filter.iir_filter_ccf(fftaps, fbtaps) + dst = blocks.vector_sink_c() + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + result_data = dst.data() + self.assertFloatTuplesAlmostEqual (expected_result, result_data) + + def test_iir_ccf_002(self): + src_data = (1+1j, 2+2j, 3+3j, 4+4j, 5+5j, 6+6j, 7+7j, 8+8j) + expected_result = (2+2j, (6+6j), (12+12j), (20+20j), (30+30j), (42+42j), (56+56j), (72+72j)) + + src = blocks.vector_source_c(src_data) + op = filter.iir_filter_ccf([1], [1]) + dst = blocks.vector_sink_c() + + fftaps = (2,) + fbtaps = (0, 1) + op.set_taps(fftaps, fbtaps) + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + result_data = dst.data() + self.assertFloatTuplesAlmostEqual (expected_result, result_data) + + + def test_iir_ccd_001(self): + src_data = (1+1j, 2+2j, 3+3j, 4+4j, 5+5j, 6+6j, 7+7j, 8+8j) + expected_result = (2+2j, (6+6j), (12+12j), (20+20j), (30+30j), (42+42j), (56+56j), (72+72j)) + fftaps = (2,) + fbtaps = (0, 1) + src = blocks.vector_source_c(src_data) + op = filter.iir_filter_ccd(fftaps, fbtaps) + dst = blocks.vector_sink_c() + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + result_data = dst.data() + self.assertFloatTuplesAlmostEqual (expected_result, result_data) + + def test_iir_ccd_002(self): + src_data = (1+1j, 2+2j, 3+3j, 4+4j, 5+5j, 6+6j, 7+7j, 8+8j) + expected_result = (2+2j, (6+6j), (12+12j), (20+20j), (30+30j), (42+42j), (56+56j), (72+72j)) + + src = blocks.vector_source_c(src_data) + op = filter.iir_filter_ccd([1], [1]) + dst = blocks.vector_sink_c() + + fftaps = (2,) + fbtaps = (0, 1) + op.set_taps(fftaps, fbtaps) + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + result_data = dst.data() + self.assertFloatTuplesAlmostEqual (expected_result, result_data) + + + def test_iir_ccc_001(self): + src_data = (1+1j, 2+2j, 3+3j, 4+4j, 5+5j, 6+6j, 7+7j, 8+8j) + expected_result = (4j, 12j, 24j, 40j, 60j, 84j, 112j, 144j) + fftaps = (2+2j,) + fbtaps = (0, 1) + src = blocks.vector_source_c(src_data) + op = filter.iir_filter_ccc(fftaps, fbtaps) + dst = blocks.vector_sink_c() + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + result_data = dst.data() + self.assertFloatTuplesAlmostEqual (expected_result, result_data) + + def test_iir_ccc_002(self): + src_data = (1+1j, 2+2j, 3+3j, 4+4j, 5+5j, 6+6j, 7+7j, 8+8j) + expected_result = (4j, 12j, 24j, 40j, 60j, 84j, 112j, 144j) + + src = blocks.vector_source_c(src_data) + op = filter.iir_filter_ccc([1], [1]) + dst = blocks.vector_sink_c() + + fftaps = (2+2j,) + fbtaps = (0, 1) + op.set_taps(fftaps, fbtaps) + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + result_data = dst.data() + self.assertFloatTuplesAlmostEqual (expected_result, result_data) + + def test_iir_ccz_001(self): + src_data = (1+1j, 2+2j, 3+3j, 4+4j, 5+5j, 6+6j, 7+7j, 8+8j) + expected_result = (4j, 12j, 24j, 40j, 60j, 84j, 112j, 144j) + fftaps = (2+2j,) + fbtaps = (0, 1) + src = blocks.vector_source_c(src_data) + op = filter.iir_filter_ccz(fftaps, fbtaps) + dst = blocks.vector_sink_c() + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + result_data = dst.data() + self.assertFloatTuplesAlmostEqual (expected_result, result_data) + + def test_iir_ccz_002(self): + src_data = (1+1j, 2+2j, 3+3j, 4+4j, 5+5j, 6+6j, 7+7j, 8+8j) + expected_result = (4j, 12j, 24j, 40j, 60j, 84j, 112j, 144j) + + src = blocks.vector_source_c(src_data) + op = filter.iir_filter_ccz([1], [1]) + dst = blocks.vector_sink_c() + + fftaps = (2+2j,) + fbtaps = (0, 1) + op.set_taps(fftaps, fbtaps) + + self.tb.connect(src, op) + self.tb.connect(op, dst) + self.tb.run() + + result_data = dst.data() + self.assertFloatTuplesAlmostEqual (expected_result, result_data) + if __name__ == '__main__': gr_unittest.run(test_iir_filter, "test_iir_filter.xml") diff --git a/gr-filter/swig/filter_swig.i b/gr-filter/swig/filter_swig.i index ec1f522117..b267fb591a 100644 --- a/gr-filter/swig/filter_swig.i +++ b/gr-filter/swig/filter_swig.i @@ -55,6 +55,10 @@ #include "gnuradio/filter/freq_xlating_fir_filter_scc.h" #include "gnuradio/filter/hilbert_fc.h" #include "gnuradio/filter/iir_filter_ffd.h" +#include "gnuradio/filter/iir_filter_ccc.h" +#include "gnuradio/filter/iir_filter_ccf.h" +#include "gnuradio/filter/iir_filter_ccd.h" +#include "gnuradio/filter/iir_filter_ccz.h" #include "gnuradio/filter/interp_fir_filter_ccc.h" #include "gnuradio/filter/interp_fir_filter_ccf.h" #include "gnuradio/filter/interp_fir_filter_fcc.h" @@ -105,6 +109,10 @@ %include "gnuradio/filter/freq_xlating_fir_filter_scc.h" %include "gnuradio/filter/hilbert_fc.h" %include "gnuradio/filter/iir_filter_ffd.h" +%include "gnuradio/filter/iir_filter_ccc.h" +%include "gnuradio/filter/iir_filter_ccf.h" +%include "gnuradio/filter/iir_filter_ccd.h" +%include "gnuradio/filter/iir_filter_ccz.h" %include "gnuradio/filter/interp_fir_filter_ccc.h" %include "gnuradio/filter/interp_fir_filter_ccf.h" %include "gnuradio/filter/interp_fir_filter_fcc.h" @@ -152,6 +160,10 @@ GR_SWIG_BLOCK_MAGIC2(filter, freq_xlating_fir_filter_scf); GR_SWIG_BLOCK_MAGIC2(filter, freq_xlating_fir_filter_scc); GR_SWIG_BLOCK_MAGIC2(filter, hilbert_fc); GR_SWIG_BLOCK_MAGIC2(filter, iir_filter_ffd); +GR_SWIG_BLOCK_MAGIC2(filter, iir_filter_ccc); +GR_SWIG_BLOCK_MAGIC2(filter, iir_filter_ccf); +GR_SWIG_BLOCK_MAGIC2(filter, iir_filter_ccd); +GR_SWIG_BLOCK_MAGIC2(filter, iir_filter_ccz); GR_SWIG_BLOCK_MAGIC2(filter, interp_fir_filter_ccc); GR_SWIG_BLOCK_MAGIC2(filter, interp_fir_filter_ccf); GR_SWIG_BLOCK_MAGIC2(filter, interp_fir_filter_fcc); |