From 511f351466e77fb49cc26d21fca3396f2213a44c Mon Sep 17 00:00:00 2001 From: Tom Rondeau Date: Wed, 9 May 2012 20:17:39 -0400 Subject: filter: wip: working on adaptive FIR filter. Moved ccc and created parent class that is not a gr_block. --- gr-filter/include/filter/CMakeLists.txt | 2 + gr-filter/include/filter/adaptive_fir.h | 69 ++++++++++++++++++ gr-filter/include/filter/adaptive_fir_ccc.h | 53 ++++++++++++++ gr-filter/lib/CMakeLists.txt | 2 + gr-filter/lib/adaptive_fir.cc | 109 ++++++++++++++++++++++++++++ gr-filter/lib/adaptive_fir_ccc_impl.cc | 94 ++++++++++++++++++++++++ gr-filter/lib/adaptive_fir_ccc_impl.h | 58 +++++++++++++++ 7 files changed, 387 insertions(+) create mode 100644 gr-filter/include/filter/adaptive_fir.h create mode 100644 gr-filter/include/filter/adaptive_fir_ccc.h create mode 100644 gr-filter/lib/adaptive_fir.cc create mode 100644 gr-filter/lib/adaptive_fir_ccc_impl.cc create mode 100644 gr-filter/lib/adaptive_fir_ccc_impl.h diff --git a/gr-filter/include/filter/CMakeLists.txt b/gr-filter/include/filter/CMakeLists.txt index 0c067fcba..98cd2161e 100644 --- a/gr-filter/include/filter/CMakeLists.txt +++ b/gr-filter/include/filter/CMakeLists.txt @@ -75,6 +75,7 @@ add_custom_target(filter_generated_includes DEPENDS ######################################################################## install(FILES api.h + adaptive_fir.h firdes.h fir_filter.h fir_filter_with_buffer.h @@ -82,6 +83,7 @@ install(FILES pm_remez.h polyphase_filterbank.h ${generated_includes} + adaptive_fir_ccc.h dc_blocker_cc.h dc_blocker_ff.h filter_delay_fc.h diff --git a/gr-filter/include/filter/adaptive_fir.h b/gr-filter/include/filter/adaptive_fir.h new file mode 100644 index 000000000..7468e6a05 --- /dev/null +++ b/gr-filter/include/filter/adaptive_fir.h @@ -0,0 +1,69 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011,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_ADAPTIVE_FIR_H +#define INCLUDED_FILTER_ADAPTIVE_FIR_H + +#include +#include +#include + +namespace gr { + namespace filter { + namespace kernel { + + class FILTER_API adaptive_fir_ccc + { + private: + bool d_updated; + int d_decim; + + protected: + unsigned int d_ntaps; + gr_complex d_error; + gr_complex *d_taps; + + // Override to calculate error signal per output + virtual gr_complex error(const gr_complex &out) = 0; + + // Override to calculate new weight from old, corresponding input + virtual void update_tap(gr_complex &tap, const gr_complex &in) = 0; + + public: + adaptive_fir_ccc(int decimation, + const std::vector &taps); + + void set_taps(const std::vector &taps); + std::vector taps() const; + + int decimation() const; + unsigned int ntaps() const; + + gr_complex filter(gr_complex *input); + void filterN(gr_complex *out, gr_complex *in, int nitems); + }; + + } /* namespace kernel */ + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_FILTER_ADAPTIVE_FIR_H */ diff --git a/gr-filter/include/filter/adaptive_fir_ccc.h b/gr-filter/include/filter/adaptive_fir_ccc.h new file mode 100644 index 000000000..14e9f6f53 --- /dev/null +++ b/gr-filter/include/filter/adaptive_fir_ccc.h @@ -0,0 +1,53 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011,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_ADAPTIVE_FIR_CCC_H +#define INCLUDED_FILTER_ADAPTIVE_FIR_CCC_H + +#include +#include +#include + +namespace gr { + namespace filter { + + class FILTER_API adaptive_fir_ccc : virtual public gr_sync_decimator + { + public: + // gr::filter::adaptive_fir_ccc::sptr + typedef boost::shared_ptr sptr; + + /*! + * \brief Adaptive FIR filter with gr_complex input, gr_complex output and float taps + * \ingroup filter_blk + */ + static FILTER_API sptr make(const char *name, int decimation, + const std::vector &taps); + + void set_taps(const std::vector &taps); + std::vector taps(); + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_FILTER_ADAPTIVE_FIR_CCC_H */ diff --git a/gr-filter/lib/CMakeLists.txt b/gr-filter/lib/CMakeLists.txt index b7577ad5e..6f3e80d82 100644 --- a/gr-filter/lib/CMakeLists.txt +++ b/gr-filter/lib/CMakeLists.txt @@ -105,6 +105,7 @@ link_directories(${FFTW3F_LIBRARY_DIRS}) # Setup library ######################################################################## list(APPEND filter_sources + adaptive_fir.cc fir_filter.cc fir_filter_with_buffer.cc fft_filter.cc @@ -112,6 +113,7 @@ list(APPEND filter_sources pm_remez.cc polyphase_filterbank.cc ${generated_sources} + adaptive_fir_ccc_impl.cc dc_blocker_cc_impl.cc dc_blocker_ff_impl.cc filter_delay_fc_impl.cc diff --git a/gr-filter/lib/adaptive_fir.cc b/gr-filter/lib/adaptive_fir.cc new file mode 100644 index 000000000..413133941 --- /dev/null +++ b/gr-filter/lib/adaptive_fir.cc @@ -0,0 +1,109 @@ +/* -*- c++ -*- */ +/* + * Copyright 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 +#include +#include + +namespace gr { + namespace filter { + namespace kernel { + + adaptive_fir_ccc::adaptive_fir_ccc(int decimation, + const std::vector &taps) + { + d_taps = NULL; + d_decim = decimation; + set_taps(taps); + } + + void + adaptive_fir_ccc::set_taps(const std::vector &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[d_ntaps-i-1] = taps[i]; + } + } + + std::vector + adaptive_fir_ccc::taps() const + { + std::vector t; + for(unsigned int i = 0; i < d_ntaps; i++) + t.push_back(d_taps[d_ntaps-i-1]); + return t; + } + + int + adaptive_fir_ccc::decimation() const + { + return d_decim; + } + + unsigned int + adaptive_fir_ccc::ntaps() const + { + return d_ntaps; + } + + gr_complex + adaptive_fir_ccc::filter(gr_complex *input) + { + gr_complex output; + volk_32fc_x2_dot_prod_32fc_u(&output, input, d_taps, d_ntaps); + return output; + } + + void + adaptive_fir_ccc::filterN(gr_complex *out, gr_complex *in, + int nitems) + { + int j = 0; + unsigned int k; + for(int i = 0; i < nitems; i++) { + out[i] = filter(&in[j]); + + // Adjust taps + d_error = error(out[i]); + for(k = 0; k < d_ntaps; k++) { + update_tap(d_taps[d_ntaps-k-1], in[j+k]); + } + + j += decimation(); + } + } + + } /* namespace kernel */ + } /* namespace filter */ +} /* namespace gr */ diff --git a/gr-filter/lib/adaptive_fir_ccc_impl.cc b/gr-filter/lib/adaptive_fir_ccc_impl.cc new file mode 100644 index 000000000..06736ae6f --- /dev/null +++ b/gr-filter/lib/adaptive_fir_ccc_impl.cc @@ -0,0 +1,94 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011,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 "adaptive_fir_ccc_impl.h" +#include + +namespace gr { + namespace filter { + + adaptive_fir_ccc::sptr adaptive_fir_ccc::make(const char *name, int decimation, + const std::vector &taps) + { + return gnuradio::get_initial_sptr(new adaptive_fir_ccc_impl + (name, decimation, taps)); + } + + adaptive_fir_ccc_impl::adaptive_fir_ccc_impl(const char *name, int decimation, + const std::vector &taps) + : gr_sync_decimator(name, + gr_make_io_signature(1, 1, sizeof(gr_complex)), + gr_make_io_signature(1, 1, sizeof(gr_complex)), + decimation), + kernel::adaptive_fir_ccc(decimation, taps), + d_updated(false) + { + set_history(d_ntaps); + } + + void + adaptive_fir_ccc_impl::set_taps(const std::vector &taps) + { + d_new_taps = taps; + d_updated = true; + } + + gr_complex + adaptive_fir_ccc_impl::error(const gr_complex &out) + { + return 0; + } + + void + adaptive_fir_ccc_impl::update_tap(gr_complex &tap, const gr_complex &in) + { + tap = tap; + } + + int + adaptive_fir_ccc_impl::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) + { + gr_complex *in = (gr_complex *)input_items[0]; + gr_complex *out = (gr_complex *)output_items[0]; + + if (d_updated) { + kernel::adaptive_fir_ccc::set_taps(d_new_taps); + set_history(d_ntaps); + d_updated = false; + return 0; // history requirements may have changed. + } + + // Call base class filtering function that uses + // overloaded error and update_tap functions. + filterN(out, in, noutput_items); + + return noutput_items; + } + + } /* namespace filter */ +} /* namespace gr */ diff --git a/gr-filter/lib/adaptive_fir_ccc_impl.h b/gr-filter/lib/adaptive_fir_ccc_impl.h new file mode 100644 index 000000000..f145ceeaa --- /dev/null +++ b/gr-filter/lib/adaptive_fir_ccc_impl.h @@ -0,0 +1,58 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011,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_ADAPTIVE_FIR_CCC_IMPL_H +#define INCLUDED_FILTER_ADAPTIVE_FIR_CCC_IMPL_H + +#include +#include + +namespace gr { + namespace filter { + + class FILTER_API adaptive_fir_ccc_impl : public adaptive_fir_ccc, public kernel::adaptive_fir_ccc + { + private: + std::vector d_new_taps; + bool d_updated; + + // Override to calculate error signal per output + gr_complex error(const gr_complex &out); + + // Override to calculate new weight from old, corresponding input + void update_tap(gr_complex &tap, const gr_complex &in); + + public: + void set_taps(const std::vector &taps); + + adaptive_fir_ccc_impl(const char *name, int decimation, + const std::vector &taps); + + int work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_FILTER_ADAPTIVE_FIR_CCC_IMPL_H */ -- cgit