diff options
author | Tom Rondeau <trondeau@vt.edu> | 2012-06-10 19:33:52 -0400 |
---|---|---|
committer | Tom Rondeau <trondeau@vt.edu> | 2012-06-10 22:35:48 -0400 |
commit | 14532d8da0f40f2b58595bd7e217004bdbfc90e3 (patch) | |
tree | 5e52427340753129792bbe2b5984289376baf256 /gr-filter | |
parent | 511f351466e77fb49cc26d21fca3396f2213a44c (diff) |
filter: adding ccf version for adaptive filter.
Diffstat (limited to 'gr-filter')
-rw-r--r-- | gr-filter/include/filter/CMakeLists.txt | 1 | ||||
-rw-r--r-- | gr-filter/include/filter/adaptive_fir.h | 37 | ||||
-rw-r--r-- | gr-filter/include/filter/adaptive_fir_ccf.h | 53 | ||||
-rw-r--r-- | gr-filter/lib/CMakeLists.txt | 1 | ||||
-rw-r--r-- | gr-filter/lib/adaptive_fir.cc | 76 | ||||
-rw-r--r-- | gr-filter/lib/adaptive_fir_ccf_impl.cc | 94 | ||||
-rw-r--r-- | gr-filter/lib/adaptive_fir_ccf_impl.h | 58 |
7 files changed, 316 insertions, 4 deletions
diff --git a/gr-filter/include/filter/CMakeLists.txt b/gr-filter/include/filter/CMakeLists.txt index 98cd2161ea..5b209873c2 100644 --- a/gr-filter/include/filter/CMakeLists.txt +++ b/gr-filter/include/filter/CMakeLists.txt @@ -84,6 +84,7 @@ install(FILES polyphase_filterbank.h ${generated_includes} adaptive_fir_ccc.h + adaptive_fir_ccf.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 index 7468e6a058..75a5f57db7 100644 --- a/gr-filter/include/filter/adaptive_fir.h +++ b/gr-filter/include/filter/adaptive_fir.h @@ -33,11 +33,8 @@ namespace gr { class FILTER_API adaptive_fir_ccc { - private: - bool d_updated; - int d_decim; - protected: + int d_decim; unsigned int d_ntaps; gr_complex d_error; gr_complex *d_taps; @@ -62,6 +59,38 @@ namespace gr { void filterN(gr_complex *out, gr_complex *in, int nitems); }; + + /**************************************************************/ + + + class FILTER_API adaptive_fir_ccf + { + protected: + int d_decim; + unsigned int d_ntaps; + float d_error; + gr_complex *d_taps; + + // Override to calculate error signal per output + virtual float 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_ccf(int decimation, + const std::vector<float> &taps); + + void set_taps(const std::vector<float> &taps); + std::vector<float> 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 */ diff --git a/gr-filter/include/filter/adaptive_fir_ccf.h b/gr-filter/include/filter/adaptive_fir_ccf.h new file mode 100644 index 0000000000..8eb01c8776 --- /dev/null +++ b/gr-filter/include/filter/adaptive_fir_ccf.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_CCF_H +#define INCLUDED_FILTER_ADAPTIVE_FIR_CCF_H + +#include <filter/api.h> +#include <filter/adaptive_fir.h> +#include <gr_sync_decimator.h> + +namespace gr { + namespace filter { + + class FILTER_API adaptive_fir_ccf : virtual public gr_sync_decimator + { + public: + // gr::filter::adaptive_fir_ccf::sptr + typedef boost::shared_ptr<adaptive_fir_ccf> 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<float> &taps); + + void set_taps(const std::vector<float> &taps); + std::vector<float> taps(); + }; + + } /* namespace filter */ +} /* namespace gr */ + +#endif /* INCLUDED_FILTER_ADAPTIVE_FIR_CCF_H */ diff --git a/gr-filter/lib/CMakeLists.txt b/gr-filter/lib/CMakeLists.txt index 6f3e80d82f..b51a23bab5 100644 --- a/gr-filter/lib/CMakeLists.txt +++ b/gr-filter/lib/CMakeLists.txt @@ -114,6 +114,7 @@ list(APPEND filter_sources polyphase_filterbank.cc ${generated_sources} adaptive_fir_ccc_impl.cc + adaptive_fir_ccf_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 index 413133941f..9098e86ca1 100644 --- a/gr-filter/lib/adaptive_fir.cc +++ b/gr-filter/lib/adaptive_fir.cc @@ -104,6 +104,82 @@ namespace gr { } } + + /**************************************************************/ + + + adaptive_fir_ccf::adaptive_fir_ccf(int decimation, + const std::vector<float> &taps) + { + d_taps = NULL; + d_decim = decimation; + set_taps(taps); + } + + void + adaptive_fir_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[d_ntaps-i-1] = taps[i]; + } + } + + std::vector<float> + adaptive_fir_ccf::taps() const + { + std::vector<float> t; + for(unsigned int i = 0; i < d_ntaps; i++) + t.push_back(d_taps[d_ntaps-i-1].real()); + return t; + } + + int + adaptive_fir_ccf::decimation() const + { + return d_decim; + } + + unsigned int + adaptive_fir_ccf::ntaps() const + { + return d_ntaps; + } + + gr_complex + adaptive_fir_ccf::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_ccf::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_ccf_impl.cc b/gr-filter/lib/adaptive_fir_ccf_impl.cc new file mode 100644 index 0000000000..053facdc29 --- /dev/null +++ b/gr-filter/lib/adaptive_fir_ccf_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_ccf_impl.h" +#include <gr_io_signature.h> + +namespace gr { + namespace filter { + + adaptive_fir_ccf::sptr adaptive_fir_ccf::make(const char *name, int decimation, + const std::vector<float> &taps) + { + return gnuradio::get_initial_sptr(new adaptive_fir_ccf_impl + (name, decimation, taps)); + } + + adaptive_fir_ccf_impl::adaptive_fir_ccf_impl(const char *name, int decimation, + const std::vector<float> &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_ccf(decimation, taps), + d_updated(false) + { + set_history(d_ntaps); + } + + void + adaptive_fir_ccf_impl::set_taps(const std::vector<float> &taps) + { + d_new_taps = taps; + d_updated = true; + } + + float + adaptive_fir_ccf_impl::error(const gr_complex &out) + { + return 0; + } + + void + adaptive_fir_ccf_impl::update_tap(gr_complex &tap, const gr_complex &in) + { + tap = tap; + } + + int + adaptive_fir_ccf_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_ccf::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_ccf_impl.h b/gr-filter/lib/adaptive_fir_ccf_impl.h new file mode 100644 index 0000000000..fa9a421899 --- /dev/null +++ b/gr-filter/lib/adaptive_fir_ccf_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_CCF_IMPL_H +#define INCLUDED_FILTER_ADAPTIVE_FIR_CCF_IMPL_H + +#include <filter/adaptive_fir_ccf.h> +#include <gr_types.h> + +namespace gr { + namespace filter { + + class FILTER_API adaptive_fir_ccf_impl : public adaptive_fir_ccf, public kernel::adaptive_fir_ccf + { + private: + std::vector<float> d_new_taps; + bool d_updated; + + // Override to calculate error signal per output + float 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<float> &taps); + + adaptive_fir_ccf_impl(const char *name, int decimation, + const std::vector<float> &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_CCF_IMPL_H */ |