summaryrefslogtreecommitdiff
path: root/gr-filter/include
diff options
context:
space:
mode:
authorTom Rondeau <trondeau@vt.edu>2012-06-15 15:58:28 -0400
committerTom Rondeau <trondeau@vt.edu>2012-06-15 16:05:51 -0400
commit76a6a4c668579ff2e17f8fa44ceb0db381b9053f (patch)
tree7327b7ffb742d9cadf25c2303a03a378cd45c8ca /gr-filter/include
parent05c117f359b831513bbf6c4f43dca9cb181e5920 (diff)
filter: adding single_pole_iir_filter blocks.
QA, docs, and GRC.
Diffstat (limited to 'gr-filter/include')
-rw-r--r--gr-filter/include/filter/CMakeLists.txt3
-rw-r--r--gr-filter/include/filter/single_pole_iir.h200
-rw-r--r--gr-filter/include/filter/single_pole_iir_filter_cc.h78
-rw-r--r--gr-filter/include/filter/single_pole_iir_filter_ff.h78
4 files changed, 359 insertions, 0 deletions
diff --git a/gr-filter/include/filter/CMakeLists.txt b/gr-filter/include/filter/CMakeLists.txt
index 24e63dc0ca..49e946536d 100644
--- a/gr-filter/include/filter/CMakeLists.txt
+++ b/gr-filter/include/filter/CMakeLists.txt
@@ -81,6 +81,7 @@ install(FILES
fft_filter.h
pm_remez.h
polyphase_filterbank.h
+ single_pole_iir.h
${generated_includes}
adaptive_fir_ccc.h
adaptive_fir_ccf.h
@@ -91,6 +92,8 @@ install(FILES
fft_filter_fff.h
hilbert_fc.h
pfb_channelizer_ccf.h
+ single_pole_iir_filter_cc.h
+ single_pole_iir_filter_ff.h
DESTINATION ${GR_INCLUDE_DIR}/gnuradio/filter
COMPONENT "fft_devel"
)
diff --git a/gr-filter/include/filter/single_pole_iir.h b/gr-filter/include/filter/single_pole_iir.h
new file mode 100644
index 0000000000..10d1b4791b
--- /dev/null
+++ b/gr-filter/include/filter/single_pole_iir.h
@@ -0,0 +1,200 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2002,2006,2012 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_SINGLE_POLE_IIR_H
+#define INCLUDED_SINGLE_POLE_IIR_H
+
+#include <filter/api.h>
+#include <stdexcept>
+#include <gr_complex.h>
+
+namespace gr {
+ namespace filter {
+
+ /*!
+ * \brief class template for single pole IIR filter
+ */
+ template<class o_type, class i_type, class tap_type>
+ class single_pole_iir
+ {
+ public:
+ /*!
+ * \brief construct new single pole IIR with given alpha
+ *
+ * computes y(i) = (1-alpha) * y(i-1) + alpha * x(i)
+ */
+ single_pole_iir(tap_type alpha = 1.0)
+ {
+ d_prev_output = 0;
+ set_taps(alpha);
+ }
+
+ /*!
+ * \brief compute a single output value.
+ * \returns the filtered input value.
+ */
+ o_type filter(const i_type input);
+
+ /*!
+ * \brief compute an array of N output values.
+ * \p input must have n valid entries.
+ */
+ void filterN(o_type output[], const i_type input[], unsigned long n);
+
+ /*!
+ * \brief install \p alpha as the current taps.
+ */
+ void set_taps(tap_type alpha)
+ {
+ if(alpha < 0 || alpha > 1)
+ throw std::out_of_range("Alpha must be in [0, 1]\n");
+
+ d_alpha = alpha;
+ d_one_minus_alpha = 1.0 - alpha;
+ }
+
+ //! reset state to zero
+ void reset()
+ {
+ d_prev_output = 0;
+ }
+
+ o_type prev_output() const { return d_prev_output; }
+
+ protected:
+ tap_type d_alpha;
+ tap_type d_one_minus_alpha;
+ o_type d_prev_output;
+ };
+
+ //
+ // general case. We may want to specialize this
+ //
+ template<class o_type, class i_type, class tap_type>
+ o_type
+ single_pole_iir<o_type, i_type, tap_type>::filter(const i_type input)
+ {
+ o_type output;
+
+ output = d_alpha * input + d_one_minus_alpha * d_prev_output;
+ d_prev_output = output;
+
+ return (o_type) output;
+ }
+
+
+ template<class o_type, class i_type, class tap_type>
+ void
+ single_pole_iir<o_type, i_type, tap_type>::filterN(o_type output[],
+ const i_type input[],
+ unsigned long n)
+ {
+ for(unsigned i = 0; i < n; i++)
+ output[i] = filter(input[i]);
+ }
+
+
+ //
+ // Specialized case for gr_complex output and double taps
+ // We need to have a gr_complexd type for the calculations and prev_output variable (in stead of double)
+
+ template<class i_type>
+ class single_pole_iir<gr_complex, i_type, double>
+ {
+ public:
+ /*!
+ * \brief construct new single pole IIR with given alpha
+ *
+ * computes y(i) = (1-alpha) * y(i-1) + alpha * x(i)
+ */
+ single_pole_iir(double alpha = 1.0)
+ {
+ d_prev_output = 0;
+ set_taps(alpha);
+ }
+
+ /*!
+ * \brief compute a single output value.
+ * \returns the filtered input value.
+ */
+ gr_complex filter(const i_type input);
+
+ /*!
+ * \brief compute an array of N output values.
+ * \p input must have n valid entries.
+ */
+ void filterN(gr_complex output[], const i_type input[], unsigned long n);
+
+ /*!
+ * \brief install \p alpha as the current taps.
+ */
+ void set_taps(double alpha)
+ {
+ if(alpha < 0 || alpha > 1)
+ throw std::out_of_range("Alpha must be in [0, 1]\n");
+
+ d_alpha = alpha;
+ d_one_minus_alpha = 1.0 - alpha;
+ }
+
+ //! reset state to zero
+ void reset()
+ {
+ d_prev_output = 0;
+ }
+
+ gr_complexd prev_output() const { return d_prev_output; }
+
+ protected:
+ double d_alpha;
+ double d_one_minus_alpha;
+ gr_complexd d_prev_output;
+ };
+
+ template< class i_type>
+ gr_complex
+ single_pole_iir<gr_complex, i_type, double>::filter(const i_type input)
+ {
+ gr_complexd output;
+
+ output = d_alpha * (gr_complexd)input + d_one_minus_alpha * d_prev_output;
+ d_prev_output = output;
+
+ return (gr_complex) output;
+ }
+
+ //Do we need to specialize this, although it is the same as the general case?
+
+ template<class i_type>
+ void
+ single_pole_iir<gr_complex, i_type, double>::filterN(gr_complex output[],
+ const i_type input[],
+ unsigned long n)
+ {
+ for(unsigned i = 0; i < n; i++)
+ output[i] = filter(input[i]);
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_SINGLE_POLE_IIR_H */
diff --git a/gr-filter/include/filter/single_pole_iir_filter_cc.h b/gr-filter/include/filter/single_pole_iir_filter_cc.h
new file mode 100644
index 0000000000..37db7c65fb
--- /dev/null
+++ b/gr-filter/include/filter/single_pole_iir_filter_cc.h
@@ -0,0 +1,78 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004-2006,2012 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_SINGLE_POLE_IIR_FILTER_CC_H
+#define INCLUDED_SINGLE_POLE_IIR_FILTER_CC_H
+
+#include <filter/api.h>
+#include <filter/single_pole_iir.h>
+#include <gr_sync_block.h>
+#include <gr_complex.h>
+
+namespace gr {
+ namespace filter {
+
+ /*!
+ * \brief single pole IIR filter with complex input, complex output
+ * \ingroup filter_blk
+ *
+ * The input and output satisfy a difference equation of the form
+ \htmlonly
+ \f{
+ y[n] - (1-alpha) y[n-1] = alpha x[n]
+ \f}
+ \endhtmlonly
+
+ \xmlonly
+ y[n] - (1-alpha) y[n-1] = alpha x[n]
+ \endxmlonly
+
+ * with the corresponding rational system function
+ \htmlonly
+ \f{
+ H(z) = \frac{alpha}{1 - (1-alpha) z^{-1}}
+ \f}
+ \endhtmlonly
+
+ \xmlonly
+ H(z) = \ frac{alpha}{1 - (1-alpha) z^{-1}}
+ \endxmlonly
+
+ * Note that some texts define the system function with a + in the
+ * denominator. If you're using that convention, you'll need to
+ * negate the feedback tap.
+ */
+ class FILTER_API single_pole_iir_filter_cc : virtual public gr_sync_block
+ {
+ public:
+ // gr::filter::single_pole_iir_filter_cc::sptr
+ typedef boost::shared_ptr<single_pole_iir_filter_cc> sptr;
+
+ static FILTER_API sptr make(double alpha, unsigned int vlen=1);
+
+ virtual void set_taps(double alpha) = 0;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_SINGLE_POLE_IIR_FILTER_CC_H */
diff --git a/gr-filter/include/filter/single_pole_iir_filter_ff.h b/gr-filter/include/filter/single_pole_iir_filter_ff.h
new file mode 100644
index 0000000000..8abce94c90
--- /dev/null
+++ b/gr-filter/include/filter/single_pole_iir_filter_ff.h
@@ -0,0 +1,78 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,2005 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_SINGLE_POLE_IIR_FILTER_FF_H
+#define INCLUDED_SINGLE_POLE_IIR_FILTER_FF_H
+
+#include <filter/api.h>
+#include <filter/single_pole_iir.h>
+#include <gr_sync_block.h>
+#include <gr_complex.h>
+
+namespace gr {
+ namespace filter {
+
+ /*!
+ * \brief single pole IIR filter with float input, float output
+ * \ingroup filter_blk
+ *
+ * The input and output satisfy a difference equation of the form
+ \htmlonly
+ \f{
+ y[n] - (1-alpha) y[n-1] = alpha x[n]
+ \f}
+ \endhtmlonly
+
+ \xmlonly
+ y[n] - (1-alpha) y[n-1] = alpha x[n]
+ \endxmlonly
+
+ * with the corresponding rational system function
+ \htmlonly
+ \f{
+ H(z) = \frac{alpha}{1 - (1-alpha) z^{-1}}
+ \f}
+ \endhtmlonly
+
+ \xmlonly
+ H(z) = \ frac{alpha}{1 - (1-alpha) z^{-1}}
+ \endxmlonly
+
+ * Note that some texts define the system function with a + in the
+ * denominator. If you're using that convention, you'll need to
+ * negate the feedback tap.
+ */
+ class FILTER_API single_pole_iir_filter_ff : virtual public gr_sync_block
+ {
+ public:
+ // gr::filter::single_pole_iir_filter_ff::sptr
+ typedef boost::shared_ptr<single_pole_iir_filter_ff> sptr;
+
+ static FILTER_API sptr make(double alpha, unsigned int vlen=1);
+
+ virtual void set_taps (double alpha) = 0;
+ };
+
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_SINGLE_POLE_IIR_FILTER_FF_H */