summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohnathan Corgan <johnathan@corganlabs.com>2015-03-28 18:50:23 -0700
committerJohnathan Corgan <johnathan@corganlabs.com>2015-03-28 18:50:23 -0700
commit4872549c9f07215b324c59edf909aac05d72c58a (patch)
treee40fc4e54e6eefa3b9ec690909769c89c608d429
parentdf6d6674d7206ca96cdc54d05d5b721d5a87cca1 (diff)
parentbe1ff60726e54eba576221993ac8de4ba094ea6e (diff)
Merge remote-tracking branch 'tom/iir_filter_stability'
-rw-r--r--gr-filter/include/gnuradio/filter/iir_filter.h68
-rw-r--r--gr-filter/lib/iir_filter.cc6
-rw-r--r--gr-filter/lib/iir_filter_ccc_impl.cc2
-rw-r--r--gr-filter/lib/iir_filter_ccc_impl.h2
-rw-r--r--gr-filter/lib/iir_filter_ccd_impl.cc2
-rw-r--r--gr-filter/lib/iir_filter_ccd_impl.h2
-rw-r--r--gr-filter/lib/iir_filter_ccf_impl.cc2
-rw-r--r--gr-filter/lib/iir_filter_ccf_impl.h2
-rw-r--r--gr-filter/lib/iir_filter_ccz_impl.cc2
-rw-r--r--gr-filter/lib/iir_filter_ccz_impl.h2
-rw-r--r--gr-filter/lib/iir_filter_ffd_impl.cc2
-rw-r--r--gr-filter/lib/iir_filter_ffd_impl.h2
12 files changed, 68 insertions, 26 deletions
diff --git a/gr-filter/include/gnuradio/filter/iir_filter.h b/gr-filter/include/gnuradio/filter/iir_filter.h
index bf87ce1d85..0f21472878 100644
--- a/gr-filter/include/gnuradio/filter/iir_filter.h
+++ b/gr-filter/include/gnuradio/filter/iir_filter.h
@@ -33,10 +33,53 @@ namespace gr {
namespace kernel {
/*!
- * \brief base class template for Infinite Impulse Response filter (IIR)
+ * \brief Base class template for Infinite Impulse Response filter (IIR)
+ *
+ * \details
+ *
+ * This class provides a templated kernel for IIR filters. These
+ * iir_filters can be instantiated with a set of feed-forward
+ * and feed-back taps in the constructor. We then call the
+ * iir_filter::filter function to add a new sample to the
+ * filter, or iir_filter::filter_n to add a vector of samples to
+ * be filtered.
+ *
+ * Instantiating a filter means defining the templates for the
+ * data types being processed by the filter. There are four templates:
+ *
+ * \li i_type the data type of the input data (i.e., float).
+ * \li o_type the data type of the output data (i.e., float).
+ * \li tap_type the data type of the filter taps (i.e., double).
+ * \li acc_type the data type of the internal accumulator (i.e., double).
+ *
+ * The acc_type is specified to control how data is handled
+ * internally in the filter. This should always be the highest
+ * precision data type of any of the first three. Often, IIR
+ * filters require double-precision values in the taps for
+ * stability, and so the internal accumulator should also be
+ * double precision.
+ *
+ * Example:
+ *
+ * \code
+ * gr::filter::kernel::iir_filter<float,float,double,double> iir_filt(fftaps, fbtaps);
+ * ...
+ * float y = iir_filt.filter(x);
+ *
+ * <or>
+ *
+ * iir_filt.filter(y, x, N); // y and x are float arrays
+ * \endcode
+ *
+ * Another example for handling complex samples with
+ * double-precision taps (see filter::iir_filter_ccz):
+ *
+ * \code
+ * gr:;filter::kernel::iir_filter<gr_complex, gr_complex, gr_complexd, gr_complexd> iir_filt(fftaps, fbtaps);
+ * \endcode
*/
- template<class i_type, class o_type, class tap_type>
- class iir_filter
+ template<class i_type, class o_type, class tap_type, class acc_type>
+ class FILTER_API iir_filter
{
public:
/*!
@@ -135,18 +178,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 +224,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,19 +236,18 @@ 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 */
} /* namespace gr */
#endif /* INCLUDED_IIR_FILTER_H */
-
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;