diff options
author | Tom Rondeau | 2012-05-02 16:14:09 -0400 |
---|---|---|
committer | Tom Rondeau | 2012-05-02 16:14:09 -0400 |
commit | 32f807a8c8f1bcadfd8f8ad4c5a46c1b099f8c8f (patch) | |
tree | 9b310ec42d0532831e20e6c6f2f184e9d2463a54 /gr-filter/lib | |
parent | a247889d7ad212cf3a69df8ec95dc2436e4cc400 (diff) | |
download | gnuradio-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.txt | 69 | ||||
-rw-r--r-- | gr-filter/lib/fir_filter.cc | 268 | ||||
-rw-r--r-- | gr-filter/lib/fir_filter_XXX_impl.cc.t | 98 | ||||
-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.cc | 123 |
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 */ - |