summaryrefslogtreecommitdiff
path: root/gr-filter
diff options
context:
space:
mode:
authorTom Rondeau2012-05-06 22:42:22 -0400
committerTom Rondeau2012-05-06 22:42:22 -0400
commit0f6af7cf0ed1cad636a185fb951f026b85b49064 (patch)
tree55d92911313d8d3021ca0cff35051445095f87cf /gr-filter
parentfc98a2a9775ab8e091413a195ce2584e5b76de99 (diff)
downloadgnuradio-0f6af7cf0ed1cad636a185fb951f026b85b49064.tar.gz
gnuradio-0f6af7cf0ed1cad636a185fb951f026b85b49064.tar.bz2
gnuradio-0f6af7cf0ed1cad636a185fb951f026b85b49064.zip
filter: added fir_filter_with_buffer to gr-filter.
Only fff and ccc versions so far. Needs work on Volk to be followed from fir_filter.
Diffstat (limited to 'gr-filter')
-rw-r--r--gr-filter/include/filter/CMakeLists.txt1
-rw-r--r--gr-filter/include/filter/fir_filter_with_buffer.h218
-rw-r--r--gr-filter/lib/CMakeLists.txt1
-rw-r--r--gr-filter/lib/fir_filter_with_buffer.cc236
4 files changed, 456 insertions, 0 deletions
diff --git a/gr-filter/include/filter/CMakeLists.txt b/gr-filter/include/filter/CMakeLists.txt
index 75d44cb66..d5452a130 100644
--- a/gr-filter/include/filter/CMakeLists.txt
+++ b/gr-filter/include/filter/CMakeLists.txt
@@ -78,6 +78,7 @@ install(FILES
firdes.h
pm_remez.h
fir_filter.h
+ fir_filter_with_buffer.h
fft_filter.h
${generated_includes}
dc_blocker_cc.h
diff --git a/gr-filter/include/filter/fir_filter_with_buffer.h b/gr-filter/include/filter/fir_filter_with_buffer.h
new file mode 100644
index 000000000..feebb382f
--- /dev/null
+++ b/gr-filter/include/filter/fir_filter_with_buffer.h
@@ -0,0 +1,218 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010,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_FILTER_FIR_FILTER_WITH_BUFFER_H
+#define INCLUDED_FILTER_FIR_FILTER_WITH_BUFFER_H
+
+#include <filter/api.h>
+#include <vector>
+#include <gr_complex.h>
+
+namespace gr {
+ namespace filter {
+ namespace kernel {
+
+ /*!
+ * \brief FIR with internal buffer for float input, float output and float taps.
+ * \ingroup filter
+ */
+ class FILTER_API fir_filter_with_buffer_fff
+ {
+ private:
+ float *d_taps;
+ float *d_buffer;
+ unsigned int d_idx;
+ unsigned int d_ntaps;
+
+ public:
+
+ // CONSTRUCTORS
+
+ /*!
+ * \brief construct new FIR with given taps.
+ *
+ * Note that taps must be in forward order, e.g., coefficient 0 is
+ * stored in new_taps[0], coefficient 1 is stored in
+ * new_taps[1], etc.
+ */
+ fir_filter_with_buffer_fff(const std::vector<float> &taps);
+
+ ~fir_filter_with_buffer_fff();
+
+ // MANIPULATORS
+
+ /*!
+ * \brief compute a single output value.
+ *
+ * \p input is a single input value of the filter type
+ *
+ * \returns the filtered input value.
+ */
+ float filter(float input);
+
+ /*!
+ * \brief compute a single output value; designed for decimating filters.
+ *
+ * \p input is a single input value of the filter type. The value of dec is the
+ * decimating value of the filter, so input[] must have dec valid values.
+ * The filter pushes dec number of items onto the circ. buffer before computing
+ * a single output.
+ *
+ * \returns the filtered input value.
+ */
+ float filter(const float input[], unsigned long dec);
+
+ /*!
+ * \brief compute an array of N output values.
+ *
+ * \p input must have (n - 1 + ntaps()) valid entries.
+ * input[0] .. input[n - 1 + ntaps() - 1] are referenced to compute the output values.
+ */
+ void filterN(float output[],
+ const float input[],
+ unsigned long n);
+
+ /*!
+ * \brief compute an array of N output values, decimating the input
+ *
+ * \p input must have (decimate * (n - 1) + ntaps()) valid entries.
+ * input[0] .. input[decimate * (n - 1) + ntaps() - 1] are referenced to
+ * compute the output values.
+ */
+ void filterNdec(float output[], const float input[],
+ unsigned long n, unsigned long decimate);
+
+ // ACCESSORS
+
+ /*!
+ * \return number of taps in filter.
+ */
+ unsigned int ntaps() const { return d_ntaps; }
+
+ /*!
+ * \brief install \p new_taps as the current taps.
+ */
+ void set_taps(const std::vector<float> &taps);
+
+ /*!
+ * \return current taps
+ */
+ std::vector<float> taps() const;
+ };
+
+
+ /**************************************************************/
+
+
+ /*!
+ * \brief FIR with internal buffer for gr_complex input, gr_complex output and gr_complex taps.
+ * \ingroup filter
+ */
+ class FILTER_API fir_filter_with_buffer_ccc
+ {
+ private:
+ gr_complex *d_taps;
+ gr_complex *d_buffer;
+ unsigned int d_idx;
+ unsigned int d_ntaps;
+
+ public:
+
+ // CONSTRUCTORS
+
+ /*!
+ * \brief construct new FIR with given taps.
+ *
+ * Note that taps must be in forward order, e.g., coefficient 0 is
+ * stored in new_taps[0], coefficient 1 is stored in
+ * new_taps[1], etc.
+ */
+ fir_filter_with_buffer_ccc(const std::vector<gr_complex> &taps);
+
+ ~fir_filter_with_buffer_ccc();
+
+ // MANIPULATORS
+
+ /*!
+ * \brief compute a single output value.
+ *
+ * \p input is a single input value of the filter type
+ *
+ * \returns the filtered input value.
+ */
+ gr_complex filter(gr_complex input);
+
+ /*!
+ * \brief compute a single output value; designed for decimating filters.
+ *
+ * \p input is a single input value of the filter type. The value of dec is the
+ * decimating value of the filter, so input[] must have dec valid values.
+ * The filter pushes dec number of items onto the circ. buffer before computing
+ * a single output.
+ *
+ * \returns the filtered input value.
+ */
+ gr_complex filter(const gr_complex input[], unsigned long dec);
+
+ /*!
+ * \brief compute an array of N output values.
+ *
+ * \p input must have (n - 1 + ntaps()) valid entries.
+ * input[0] .. input[n - 1 + ntaps() - 1] are referenced to compute the output values.
+ */
+ void filterN(gr_complex output[],
+ const gr_complex input[],
+ unsigned long n);
+
+ /*!
+ * \brief compute an array of N output values, decimating the input
+ *
+ * \p input must have (decimate * (n - 1) + ntaps()) valid entries.
+ * input[0] .. input[decimate * (n - 1) + ntaps() - 1] are referenced to
+ * compute the output values.
+ */
+ void filterNdec(gr_complex output[], const gr_complex input[],
+ unsigned long n, unsigned long decimate);
+
+ // ACCESSORS
+
+ /*!
+ * \return number of taps in filter.
+ */
+ unsigned int ntaps() const { return d_ntaps; }
+
+ /*!
+ * \brief install \p new_taps as the current taps.
+ */
+ void set_taps(const std::vector<gr_complex> &taps);
+
+ /*!
+ * \return current taps
+ */
+ std::vector<gr_complex> taps() const;
+ };
+
+ } /* namespace kernel */
+ } /* namespace filter */
+} /* namespace gr */
+
+#endif /* INCLUDED_FILTER_FIR_FILTER_WITH_BUFFER_H */
diff --git a/gr-filter/lib/CMakeLists.txt b/gr-filter/lib/CMakeLists.txt
index c8e7b7e18..e1fae56a3 100644
--- a/gr-filter/lib/CMakeLists.txt
+++ b/gr-filter/lib/CMakeLists.txt
@@ -106,6 +106,7 @@ link_directories(${FFTW3F_LIBRARY_DIRS})
########################################################################
list(APPEND filter_sources
fir_filter.cc
+ fir_filter_with_buffer.cc
fft_filter.cc
firdes.cc
pm_remez.cc
diff --git a/gr-filter/lib/fir_filter_with_buffer.cc b/gr-filter/lib/fir_filter_with_buffer.cc
new file mode 100644
index 000000000..a2b804a08
--- /dev/null
+++ b/gr-filter/lib/fir_filter_with_buffer.cc
@@ -0,0 +1,236 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2010,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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <filter/fir_filter_with_buffer.h>
+#include <fft/fft.h>
+#include <volk/volk.h>
+
+namespace gr {
+ namespace filter {
+ namespace kernel {
+
+ fir_filter_with_buffer_fff::fir_filter_with_buffer_fff(const std::vector<float> &taps)
+ {
+ d_buffer = NULL;
+ set_taps(taps);
+ }
+
+ fir_filter_with_buffer_fff::~fir_filter_with_buffer_fff()
+ {
+ if(d_buffer != NULL)
+ fft::free(d_buffer);
+ }
+
+ void
+ fir_filter_with_buffer_fff::set_taps(const std::vector<float> &taps)
+ {
+ if(d_buffer != NULL) {
+ fft::free(d_buffer);
+ d_buffer = NULL;
+ }
+
+ d_ntaps = (int)taps.size();
+ d_taps = fft::malloc_float(d_ntaps);
+ for(unsigned int i = 0; i < d_ntaps; i++) {
+ d_taps[d_ntaps-i-1] = taps[i];
+ }
+ d_idx = 0;
+ }
+
+ std::vector<float>
+ fir_filter_with_buffer_fff::taps() const
+ {
+ std::vector<float> t;
+ for(unsigned int i = 0; i < d_ntaps; i++)
+ t.push_back(d_taps[d_ntaps-i-1]);
+ return t;
+ }
+
+ float
+ fir_filter_with_buffer_fff::filter(float input)
+ {
+ d_buffer[d_idx] = input;
+ d_buffer[d_idx+ntaps()] = input;
+
+ d_idx++;
+ if(d_idx >= ntaps())
+ d_idx = 0;
+
+ float output = 0;
+ volk_32f_x2_dot_prod_32f_u(&output, &d_buffer[d_idx],
+ d_taps, d_ntaps);
+
+ return output;
+ }
+
+ float
+ fir_filter_with_buffer_fff::filter(const float input[],
+ unsigned long dec)
+ {
+ unsigned int i;
+
+ for(i = 0; i < dec; i++) {
+ d_buffer[d_idx] = input[i];
+ d_buffer[d_idx+ntaps()] = input[i];
+ d_idx++;
+ if(d_idx >= ntaps())
+ d_idx = 0;
+ }
+
+ float output = 0;
+ volk_32f_x2_dot_prod_32f_u(&output, &d_buffer[d_idx],
+ d_taps, d_ntaps);
+ return output;
+ }
+
+ void
+ fir_filter_with_buffer_fff::filterN(float output[],
+ const float input[],
+ unsigned long n)
+ {
+ for(unsigned long i = 0; i < n; i++) {
+ output[i] = filter(input[i]);
+ }
+ }
+
+ void
+ fir_filter_with_buffer_fff::filterNdec(float output[],
+ const float input[],
+ unsigned long n,
+ unsigned long decimate)
+ {
+ unsigned long j = 0;
+ for(unsigned long i = 0; i < n; i++) {
+ output[i] = filter(&input[j], decimate);
+ j += decimate;
+ }
+ }
+
+
+ /**************************************************************/
+
+
+ fir_filter_with_buffer_ccc::fir_filter_with_buffer_ccc(const std::vector<gr_complex> &taps)
+ {
+ d_buffer = NULL;
+ set_taps(taps);
+ }
+
+ fir_filter_with_buffer_ccc::~fir_filter_with_buffer_ccc()
+ {
+ if(d_buffer != NULL)
+ fft::free(d_buffer);
+ }
+
+ void
+ fir_filter_with_buffer_ccc::set_taps(const std::vector<gr_complex> &taps)
+ {
+ if(d_buffer != NULL) {
+ fft::free(d_buffer);
+ d_buffer = NULL;
+ }
+
+ d_ntaps = (int)taps.size();
+ d_taps = fft::malloc_complex(d_ntaps);
+ for(unsigned int i = 0; i < d_ntaps; i++) {
+ d_taps[d_ntaps-i-1] = taps[i];
+ }
+ d_idx = 0;
+ }
+
+ std::vector<gr_complex>
+ fir_filter_with_buffer_ccc::taps() const
+ {
+ std::vector<gr_complex> t;
+ for(unsigned int i = 0; i < d_ntaps; i++)
+ t.push_back(d_taps[d_ntaps-i-1]);
+ return t;
+ }
+
+ gr_complex
+ fir_filter_with_buffer_ccc::filter(gr_complex input)
+ {
+ d_buffer[d_idx] = input;
+ d_buffer[d_idx+ntaps()] = input;
+
+ d_idx++;
+ if(d_idx >= ntaps())
+ d_idx = 0;
+
+ gr_complex output = 0;
+ volk_32fc_x2_dot_prod_32fc_u(&output, &d_buffer[d_idx],
+ d_taps, d_ntaps);
+
+ return output;
+ }
+
+ gr_complex
+ fir_filter_with_buffer_ccc::filter(const gr_complex input[],
+ unsigned long dec)
+ {
+ unsigned int i;
+
+ for(i = 0; i < dec; i++) {
+ d_buffer[d_idx] = input[i];
+ d_buffer[d_idx+ntaps()] = input[i];
+ d_idx++;
+ if(d_idx >= ntaps())
+ d_idx = 0;
+ }
+
+ gr_complex output = 0;
+ volk_32fc_x2_dot_prod_32fc_u(&output, &d_buffer[d_idx],
+ d_taps, d_ntaps);
+ return output;
+ }
+
+ void
+ fir_filter_with_buffer_ccc::filterN(gr_complex output[],
+ const gr_complex input[],
+ unsigned long n)
+ {
+ for(unsigned long i = 0; i < n; i++) {
+ output[i] = filter(input[i]);
+ }
+ }
+
+ void
+ fir_filter_with_buffer_ccc::filterNdec(gr_complex output[],
+ const gr_complex input[],
+ unsigned long n,
+ unsigned long decimate)
+ {
+ unsigned long j = 0;
+ for(unsigned long i = 0; i < n; i++) {
+ output[i] = filter(&input[j], decimate);
+ j += decimate;
+ }
+ }
+
+
+ } /* namespace kernel */
+ } /* namespace filter */
+} /* namespace gr */