summaryrefslogtreecommitdiff
path: root/gr-filter/lib
diff options
context:
space:
mode:
authorTom Rondeau2012-05-02 16:14:09 -0400
committerTom Rondeau2012-05-02 16:14:09 -0400
commit32f807a8c8f1bcadfd8f8ad4c5a46c1b099f8c8f (patch)
tree9b310ec42d0532831e20e6c6f2f184e9d2463a54 /gr-filter/lib
parenta247889d7ad212cf3a69df8ec95dc2436e4cc400 (diff)
downloadgnuradio-32f807a8c8f1bcadfd8f8ad4c5a46c1b099f8c8f.tar.gz
gnuradio-32f807a8c8f1bcadfd8f8ad4c5a46c1b099f8c8f.tar.bz2
gnuradio-32f807a8c8f1bcadfd8f8ad4c5a46c1b099f8c8f.zip
filter: Reworking filter to have a set of basic implementation classes for filters of different kinds.
The GR blocks are templated now and call from fir_filters for the volk-specific implemenation. Note the modification to build_utils.py to accomodate these changes.
Diffstat (limited to 'gr-filter/lib')
-rw-r--r--gr-filter/lib/CMakeLists.txt69
-rw-r--r--gr-filter/lib/fir_filter.cc268
-rw-r--r--gr-filter/lib/fir_filter_XXX_impl.cc.t98
-rw-r--r--gr-filter/lib/fir_filter_XXX_impl.h.t (renamed from gr-filter/lib/fir_filter_fff_impl.h)27
-rw-r--r--gr-filter/lib/fir_filter_fff_impl.cc123
5 files changed, 448 insertions, 137 deletions
diff --git a/gr-filter/lib/CMakeLists.txt b/gr-filter/lib/CMakeLists.txt
index 2850b6925..784a3c109 100644
--- a/gr-filter/lib/CMakeLists.txt
+++ b/gr-filter/lib/CMakeLists.txt
@@ -18,6 +18,72 @@
# Boston, MA 02110-1301, USA.
########################################################################
+# generate helper scripts to expand templated files
+########################################################################
+include(GrPython)
+
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py "
+#!${PYTHON_EXECUTABLE}
+
+import sys, os, re
+sys.path.append('${GR_CORE_PYTHONPATH}')
+os.environ['srcdir'] = '${CMAKE_CURRENT_SOURCE_DIR}'
+os.chdir('${CMAKE_CURRENT_BINARY_DIR}')
+
+if __name__ == '__main__':
+ import build_utils
+ root, inp = sys.argv[1:3]
+ for sig in sys.argv[3:]:
+ name = re.sub ('X+', sig, root)
+ d = build_utils.standard_impl_dict2(name, sig, 'filter')
+ build_utils.expand_template(d, inp)
+")
+
+macro(expand_cc root)
+ #make a list of all the generated files
+ unset(expanded_files_cc)
+ unset(expanded_files_h)
+ foreach(sig ${ARGN})
+ string(REGEX REPLACE "X+" ${sig} name ${root})
+ list(APPEND expanded_files_cc ${CMAKE_CURRENT_BINARY_DIR}/${name}.cc)
+ list(APPEND expanded_files_h ${CMAKE_CURRENT_BINARY_DIR}/${name}.h)
+ endforeach(sig)
+
+ #create a command to generate the source files
+ add_custom_command(
+ OUTPUT ${expanded_files_cc}
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.cc.t
+ COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
+ ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
+ ${root} ${root}.cc.t ${ARGN}
+ )
+
+ #create a command to generate the header file
+ add_custom_command(
+ OUTPUT ${expanded_files_h}
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${root}.h.t
+ COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
+ ${CMAKE_CURRENT_BINARY_DIR}/generate_helper.py
+ ${root} ${root}.h.t ${ARGN}
+ )
+
+ #make source files depends on headers to force generation
+ set_source_files_properties(${expanded_files_cc}
+ PROPERTIES OBJECT_DEPENDS "${expanded_files_h}"
+ )
+
+ #install rules for the generated cc files
+ list(APPEND generated_sources ${expanded_files_cc})
+ list(APPEND generated_headers ${expanded_files_h})
+endmacro(expand_cc)
+
+########################################################################
+# Invoke macro to generate various sources
+########################################################################
+expand_cc(fir_filter_XXX_impl fff ccf ccc)
+
+
+########################################################################
# Setup the include and linker paths
########################################################################
include_directories(
@@ -39,7 +105,8 @@ link_directories(${FFTW3F_LIBRARY_DIRS})
# Setup library
########################################################################
list(APPEND filter_sources
- fir_filter_fff_impl.cc
+ fir_filter.cc
+ ${generated_sources}
)
list(APPEND filter_libs
diff --git a/gr-filter/lib/fir_filter.cc b/gr-filter/lib/fir_filter.cc
new file mode 100644
index 000000000..5f0e0912d
--- /dev/null
+++ b/gr-filter/lib/fir_filter.cc
@@ -0,0 +1,268 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,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.
+ */
+
+#include <filter/fir_filter.h>
+#include <fft/fft.h>
+#include <volk/volk.h>
+
+namespace gr {
+ namespace filter {
+ namespace impl {
+
+ fir_filter_fff::fir_filter_fff(int decimation,
+ const std::vector<float> &taps)
+ {
+ d_taps = NULL;
+ set_taps(taps);
+ }
+
+ fir_filter_fff::~fir_filter_fff()
+ {
+ if(d_taps != NULL) {
+ fft::free(d_taps);
+ d_taps = NULL;
+ }
+ }
+
+ void
+ fir_filter_fff::set_taps(const std::vector<float> &taps)
+ {
+ // Free the taps if already allocated
+ if(d_taps != NULL) {
+ fft::free(d_taps);
+ d_taps = NULL;
+ }
+
+ d_ntaps = (int)taps.size();
+ d_taps = fft::malloc_float(d_ntaps);
+ for(unsigned int i = 0; i < d_ntaps; i++) {
+ d_taps[i] = taps[i];
+ }
+ }
+
+ std::vector<float>
+ fir_filter_fff::taps() const
+ {
+ std::vector<float> t;
+ for(unsigned int i = 0; i < d_ntaps; i++)
+ t.push_back(d_taps[i]);
+ return t;
+ }
+
+ unsigned int
+ fir_filter_fff::ntaps() const
+ {
+ return d_ntaps;
+ }
+
+ float
+ fir_filter_fff::filter(const float input[])
+ {
+ float output;
+ volk_32f_x2_dot_prod_32f_u(&output, input, d_taps, d_ntaps);
+ return output;
+ }
+
+ void
+ fir_filter_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_fff::filterNdec(float output[],
+ const float input[],
+ unsigned long n,
+ unsigned int decimate)
+ {
+ unsigned long j = 0;
+ for(unsigned long i = 0; i < n; i++){
+ output[i] = filter(&input[j]);
+ j += decimate;
+ }
+ }
+
+ /**************************************************************/
+
+ fir_filter_ccf::fir_filter_ccf(int decimation,
+ const std::vector<float> &taps)
+ {
+ d_taps = NULL;
+ set_taps(taps);
+ }
+
+ fir_filter_ccf::~fir_filter_ccf()
+ {
+ if(d_taps != NULL) {
+ fft::free(d_taps);
+ d_taps = NULL;
+ }
+ }
+
+ void
+ fir_filter_ccf::set_taps(const std::vector<float> &taps)
+ {
+ // Free the taps if already allocated
+ if(d_taps != NULL) {
+ fft::free(d_taps);
+ d_taps = NULL;
+ }
+
+ d_ntaps = (int)taps.size();
+ d_taps = fft::malloc_complex(d_ntaps);
+ for(unsigned int i = 0; i < d_ntaps; i++) {
+ d_taps[i] = gr_complex(taps[i],0);
+ }
+ }
+
+ std::vector<float>
+ fir_filter_ccf::taps() const
+ {
+ std::vector<float> t;
+ for(unsigned int i = 0; i < d_ntaps; i++)
+ t.push_back(d_taps[i].real());
+ return t;
+ }
+
+ unsigned int
+ fir_filter_ccf::ntaps() const
+ {
+ return d_ntaps;
+ }
+
+ gr_complex
+ fir_filter_ccf::filter(const gr_complex input[])
+ {
+ gr_complex output;
+ volk_32fc_x2_dot_prod_32fc_u(&output, input, d_taps, d_ntaps);
+ return output;
+ }
+
+ void
+ fir_filter_ccf::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_ccf::filterNdec(gr_complex output[],
+ const gr_complex input[],
+ unsigned long n,
+ unsigned int decimate)
+ {
+ unsigned long j = 0;
+ for(unsigned long i = 0; i < n; i++){
+ output[i] = filter(&input[j]);
+ j += decimate;
+ }
+ }
+
+ /**************************************************************/
+
+ fir_filter_ccc::fir_filter_ccc(int decimation,
+ const std::vector<gr_complex> &taps)
+ {
+ d_taps = NULL;
+ set_taps(taps);
+ }
+
+ fir_filter_ccc::~fir_filter_ccc()
+ {
+ if(d_taps != NULL) {
+ fft::free(d_taps);
+ d_taps = NULL;
+ }
+ }
+
+ void
+ fir_filter_ccc::set_taps(const std::vector<gr_complex> &taps)
+ {
+ // Free the taps if already allocated
+ if(d_taps != NULL) {
+ fft::free(d_taps);
+ d_taps = NULL;
+ }
+
+ d_ntaps = (int)taps.size();
+ d_taps = fft::malloc_complex(d_ntaps);
+ for(unsigned int i = 0; i < d_ntaps; i++) {
+ d_taps[i] = taps[i];
+ }
+ }
+
+ std::vector<gr_complex>
+ fir_filter_ccc::taps() const
+ {
+ std::vector<gr_complex> t;
+ for(unsigned int i = 0; i < d_ntaps; i++)
+ t.push_back(d_taps[i]);
+ return t;
+ }
+
+ unsigned int
+ fir_filter_ccc::ntaps() const
+ {
+ return d_ntaps;
+ }
+
+ gr_complex
+ fir_filter_ccc::filter(const gr_complex input[])
+ {
+ gr_complex output;
+ volk_32fc_x2_dot_prod_32fc_u(&output, input, d_taps, d_ntaps);
+ return output;
+ }
+
+ void
+ fir_filter_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_ccc::filterNdec(gr_complex output[],
+ const gr_complex input[],
+ unsigned long n,
+ unsigned int decimate)
+ {
+ unsigned long j = 0;
+ for(unsigned long i = 0; i < n; i++){
+ output[i] = filter(&input[j]);
+ j += decimate;
+ }
+ }
+
+ } /* namespace impl */
+ } /* namespace filter */
+} /* namespace gr */
diff --git a/gr-filter/lib/fir_filter_XXX_impl.cc.t b/gr-filter/lib/fir_filter_XXX_impl.cc.t
new file mode 100644
index 000000000..70c3fba3f
--- /dev/null
+++ b/gr-filter/lib/fir_filter_XXX_impl.cc.t
@@ -0,0 +1,98 @@
+/* -*- c++ -*- */
+/*
+ * Copyright 2004,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 "@IMPL_NAME@.h"
+#include <gr_io_signature.h>
+#include <volk/volk.h>
+#include <fft/fft.h>
+
+namespace gr {
+ namespace filter {
+
+ @BASE_NAME@::sptr
+ @BASE_NAME@::make(int decimation, const std::vector<@TAP_TYPE@> &taps)
+ {
+ return gnuradio::get_initial_sptr(new @IMPL_NAME@
+ (decimation, taps));
+ }
+
+
+ @IMPL_NAME@::@IMPL_NAME@(int decimation, const std::vector<@TAP_TYPE@> &taps)
+ : gr_sync_decimator("fir_filter_fff",
+ gr_make_io_signature(1, 1, sizeof(@I_TYPE@)),
+ gr_make_io_signature(1, 1, sizeof(@O_TYPE@)),
+ decimation)
+ {
+ d_fir = new impl::@BASE_NAME@(decimation, taps);
+ d_updated = false;
+ set_history(d_fir->ntaps()+1);
+ }
+
+ @IMPL_NAME@::~@IMPL_NAME@()
+ {
+ delete d_fir;
+ }
+
+ void
+ @IMPL_NAME@::set_taps(const std::vector<@TAP_TYPE@> &taps)
+ {
+ d_fir->set_taps(taps);
+ d_updated = true;
+ }
+
+ std::vector<@TAP_TYPE@>
+ @IMPL_NAME@::taps() const
+ {
+ return d_fir->taps();
+ }
+
+ int
+ @IMPL_NAME@::work(int noutput_items,
+ gr_vector_const_void_star &input_items,
+ gr_vector_void_star &output_items)
+ {
+ const @I_TYPE@ *in = (const @I_TYPE@*)input_items[0];
+ @O_TYPE@ *out = (@O_TYPE@*)output_items[0];
+
+ if (d_updated) {
+ set_history(d_fir->ntaps()+1);
+ d_updated = false;
+ return 0; // history requirements may have changed.
+ }
+
+ if (decimation() == 1) {
+ d_fir->filterN(out, in, noutput_items);
+ }
+ else {
+ d_fir->filterNdec(out, in, noutput_items, decimation());
+ }
+
+ return noutput_items;
+ }
+
+ } /* namespace filter */
+} /* namespace gr */
+
diff --git a/gr-filter/lib/fir_filter_fff_impl.h b/gr-filter/lib/fir_filter_XXX_impl.h.t
index 962781466..a40c49bf2 100644
--- a/gr-filter/lib/fir_filter_fff_impl.h
+++ b/gr-filter/lib/fir_filter_XXX_impl.h.t
@@ -20,30 +20,31 @@
* Boston, MA 02110-1301, USA.
*/
-#ifndef FILTER_FIR_FILTER_FFF_IMPL_H
-#define FILTER_FIR_FILTER_FFF_IMPL_H
+/* @WARNING@ */
+
+#ifndef @GUARD_NAME@
+#define @GUARD_NAME@
#include <filter/api.h>
-#include <filter/fir_filter_fff.h>
+#include <filter/fir_filter.h>
+#include <filter/@BASE_NAME@.h>
namespace gr {
namespace filter {
- class FILTER_API fir_filter_fff_impl : public fir_filter_fff
+ class FILTER_API @IMPL_NAME@ : public @BASE_NAME@
{
private:
- float *d_taps;
- int d_ntaps;
- bool d_updated;
+ impl::@BASE_NAME@ *d_fir;
+ bool d_updated;
public:
- fir_filter_fff_impl(int decimation,
- const std::vector<float> &taps);
+ @IMPL_NAME@(int decimation, const std::vector<@TAP_TYPE@> &taps);
- ~fir_filter_fff_impl();
+ ~@IMPL_NAME@();
- void set_taps(const std::vector<float> &taps);
- std::vector<float> taps() const;
+ void set_taps(const std::vector<@TAP_TYPE@> &taps);
+ std::vector<@TAP_TYPE@> taps() const;
int work(int noutput_items,
gr_vector_const_void_star &input_items,
@@ -53,4 +54,4 @@ namespace gr {
} /* namespace filter */
} /* namespace gr */
-#endif /* FILTER_FIR_FILTER_FFF_IMPL_H */
+#endif /* @GUARD_NAME@ */
diff --git a/gr-filter/lib/fir_filter_fff_impl.cc b/gr-filter/lib/fir_filter_fff_impl.cc
deleted file mode 100644
index 15ccb4d07..000000000
--- a/gr-filter/lib/fir_filter_fff_impl.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-/* -*- c++ -*- */
-/*
- * Copyright 2004,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 "fir_filter_fff_impl.h"
-#include <gr_io_signature.h>
-#include <volk/volk.h>
-#include <fft/fft.h>
-#include <gr_math.h>
-
-namespace gr {
- namespace filter {
-
- fir_filter_fff::sptr
- fir_filter_fff::make(int decimation, const std::vector<float> &taps)
- {
- return gnuradio::get_initial_sptr(new fir_filter_fff_impl
- (decimation, taps));
- }
-
-
- fir_filter_fff_impl::fir_filter_fff_impl(int decimation,
- const std::vector<float> &taps)
- : gr_sync_decimator("fir_filter_fff",
- gr_make_io_signature (1, 1, sizeof(float)),
- gr_make_io_signature (1, 1, sizeof(float)),
- decimation)
- {
- d_taps = NULL;
- set_taps(taps);
- d_updated = false;
- set_history(d_ntaps+1);
- }
-
- fir_filter_fff_impl::~fir_filter_fff_impl()
- {
- if(d_taps != NULL) {
- fft::free(d_taps);
- d_taps = NULL;
- }
- }
-
- void
- fir_filter_fff_impl::set_taps(const std::vector<float> &taps)
- {
- // Free the taps if already allocated
- if(d_taps != NULL) {
- fft::free(d_taps);
- d_taps = NULL;
- }
-
- d_ntaps = (int)taps.size();
- d_taps = fft::malloc_float(d_ntaps);
- for(int i = 0; i < d_ntaps; i++) {
- d_taps[i] = taps[i];
- }
- d_updated = true;
- }
-
- std::vector<float>
- fir_filter_fff_impl::taps() const
- {
- std::vector<float> t;
- for(int i = 0; i < d_ntaps; i++)
- t.push_back(d_taps[i]);
- return t;
- }
-
- int
- fir_filter_fff_impl::work(int noutput_items,
- gr_vector_const_void_star &input_items,
- gr_vector_void_star &output_items)
- {
- const float *in = (const float*)input_items[0];
- float *out = (float*)output_items[0];
-
- if (d_updated) {
- set_history((unsigned int)d_ntaps+1);
- d_updated = false;
- return 0; // history requirements may have changed.
- }
-
- if (decimation() == 1) {
- for(int i = 0; i < noutput_items; i++) {
- volk_32f_x2_dot_prod_32f_u(&out[i], &in[i], d_taps, d_ntaps);
- }
- }
- else {
- int j = 0;
- for(int i = 0; i < noutput_items; i++) {
- volk_32f_x2_dot_prod_32f_u(&out[i], &in[j], d_taps, d_ntaps);
- j += decimation();
- }
- }
-
- return noutput_items;
- }
-
- } /* namespace filter */
-} /* namespace gr */
-