diff options
author | Tom Rondeau | 2011-05-25 16:29:22 +0100 |
---|---|---|
committer | Tom Rondeau | 2011-05-25 16:29:22 +0100 |
commit | 09f5b9606b57631d27d3abd868dcf5fe7eca6d12 (patch) | |
tree | b98845739bcbeeedc765b79a870672cc5e250f89 | |
parent | f5d6c321dcdba35189b120795dccad5b12ce8939 (diff) | |
download | gnuradio-09f5b9606b57631d27d3abd868dcf5fe7eca6d12.tar.gz gnuradio-09f5b9606b57631d27d3abd868dcf5fe7eca6d12.tar.bz2 gnuradio-09f5b9606b57631d27d3abd868dcf5fe7eca6d12.zip |
filter: adding a DC blocker algorithm.
-rw-r--r-- | gnuradio-core/src/lib/filter/Makefile.am | 7 | ||||
-rw-r--r-- | gnuradio-core/src/lib/filter/filter.i | 2 | ||||
-rw-r--r-- | gnuradio-core/src/lib/filter/gr_dc_blocker_cc.cc | 138 | ||||
-rw-r--r-- | gnuradio-core/src/lib/filter/gr_dc_blocker_cc.h | 110 | ||||
-rw-r--r-- | gnuradio-core/src/lib/filter/gr_dc_blocker_cc.i | 34 |
5 files changed, 289 insertions, 2 deletions
diff --git a/gnuradio-core/src/lib/filter/Makefile.am b/gnuradio-core/src/lib/filter/Makefile.am index dee13e239..95489156f 100644 --- a/gnuradio-core/src/lib/filter/Makefile.am +++ b/gnuradio-core/src/lib/filter/Makefile.am @@ -216,7 +216,8 @@ libfilter_la_common_SOURCES = \ gr_pfb_interpolator_ccf.cc \ gr_pfb_arb_resampler_ccf.cc \ gr_pfb_clock_sync_ccf.cc \ - gr_pfb_clock_sync_fff.cc + gr_pfb_clock_sync_fff.cc \ + gr_dc_blocker_cc.cc libfilter_qa_la_common_SOURCES = \ qa_filter.cc \ @@ -306,7 +307,8 @@ grinclude_HEADERS = \ gr_pfb_interpolator_ccf.h \ gr_pfb_arb_resampler_ccf.h \ gr_pfb_clock_sync_ccf.h \ - gr_pfb_clock_sync_fff.h + gr_pfb_clock_sync_fff.h \ + gr_dc_blocker_cc.h noinst_HEADERS = \ assembly.h \ @@ -372,6 +374,7 @@ swiginclude_HEADERS = \ gr_pfb_arb_resampler_ccf.i \ gr_pfb_clock_sync_ccf.i \ gr_pfb_clock_sync_fff.i \ + gr_dc_blocker_cc.i \ $(GENERATED_I) diff --git a/gnuradio-core/src/lib/filter/filter.i b/gnuradio-core/src/lib/filter/filter.i index 645607cba..b8f4d06eb 100644 --- a/gnuradio-core/src/lib/filter/filter.i +++ b/gnuradio-core/src/lib/filter/filter.i @@ -39,6 +39,7 @@ #include <gr_pfb_arb_resampler_ccf.h> #include <gr_pfb_clock_sync_ccf.h> #include <gr_pfb_clock_sync_fff.h> +#include <gr_dc_blocker_cc.h> %} %include "gr_iir_filter_ffd.i" @@ -62,5 +63,6 @@ %include "gr_pfb_arb_resampler_ccf.i" %include "gr_pfb_clock_sync_ccf.i" %include "gr_pfb_clock_sync_fff.i" +%include "gr_dc_blocker_cc.i" %include "filter_generated.i" diff --git a/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.cc b/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.cc new file mode 100644 index 000000000..66f59f240 --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.cc @@ -0,0 +1,138 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011 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 <gr_dc_blocker_cc.h> +#include <gr_io_signature.h> +#include <cstdio> + +moving_averager::moving_averager(int D) + : d_length(D), d_out(0), d_out_d1(0), d_out_d2(0) +{ + d_delay_line = std::deque<gr_complex>(d_length-1, gr_complex(0,0)); +} + +moving_averager::~moving_averager() +{ +} + +gr_complex +moving_averager::filter(gr_complex x) +{ + d_out_d1 = d_out; + d_delay_line.push_back(x); + d_out = d_delay_line[0]; + d_delay_line.pop_front(); + + gr_complex y = x - d_out_d1 + d_out_d2; + d_out_d2 = y; + + return (y / (float)(d_length)); +} + + + +gr_dc_blocker_cc_sptr gr_make_dc_blocker_cc (int D, bool long_form) +{ + return gnuradio::get_initial_sptr(new gr_dc_blocker_cc(D, long_form)); +} + + +gr_dc_blocker_cc::gr_dc_blocker_cc (int D, bool long_form) + : gr_sync_block ("dc_blocker_cc", + gr_make_io_signature (1, 1, sizeof(gr_complex)), + gr_make_io_signature (1, 1, sizeof(gr_complex))), + d_length(D), d_long_form(long_form) +{ + if(d_long_form) { + d_ma_0 = new moving_averager(D); + d_ma_1 = new moving_averager(D); + d_ma_2 = new moving_averager(D); + d_ma_3 = new moving_averager(D); + d_delay_line = std::deque<gr_complex>(d_length-1, gr_complex(0,0)); + } + else { + d_ma_0 = new moving_averager(D); + d_ma_1 = new moving_averager(D); + } +} + +gr_dc_blocker_cc::~gr_dc_blocker_cc() +{ + if(d_long_form) { + delete d_ma_0; + delete d_ma_1; + delete d_ma_2; + delete d_ma_3; + } + else { + delete d_ma_0; + delete d_ma_1; + } +} + +int +gr_dc_blocker_cc::get_group_delay() +{ + if(d_long_form) + return (2*d_length-2); + else + return d_length - 1; +} + +int +gr_dc_blocker_cc::work(int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items) +{ + const gr_complex *in = (const gr_complex*)input_items[0]; + gr_complex *out = (gr_complex*)output_items[0]; + + if(d_long_form) { + gr_complex y1, y2, y3, y4, d; + for(int i = 0; i < noutput_items; i++) { + y1 = d_ma_0->filter(in[i]); + y2 = d_ma_1->filter(y1); + y3 = d_ma_2->filter(y2); + y4 = d_ma_3->filter(y3); + + d_delay_line.push_back(d_ma_0->delayed_sig()); + d = d_delay_line[0]; + d_delay_line.pop_front(); + + out[i] = d - y4; + } + } + else { + gr_complex y1, y2; + for(int i = 0; i < noutput_items; i++) { + y1 = d_ma_0->filter(in[i]); + y2 = d_ma_1->filter(y1); + out[i] = d_ma_0->delayed_sig() - y2; + } + } + + return noutput_items; +} diff --git a/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.h b/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.h new file mode 100644 index 000000000..26a2247ea --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.h @@ -0,0 +1,110 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011 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_GR_DC_BLOCKER_CC_H +#define INCLUDED_GR_DC_BLOCKER_CC_H + +#include <gr_sync_block.h> +#include <deque> + +class gr_dc_blocker_cc; +typedef boost::shared_ptr<gr_dc_blocker_cc> gr_dc_blocker_cc_sptr; +gr_dc_blocker_cc_sptr gr_make_dc_blocker_cc (int D=32, bool long_form=true); + +/*! + * \class gr_dc_blocker_cc + * \brief a computationally efficient controllabel DC blocker + * + * \ingroup filter_blk + * + * This block implements a computationally efficient DC blocker that produces + * a tigher notch filter around DC for a smaller group delay than an + * equivalent FIR filter or using a single pole IIR filter. + * + * The block defaults to using a delay line of length 32 and the long form + * of the filter. Optionally, the delay line length can be changed to alter + * the width of the DC notch (longer lines will decrease the width). + * + * The long form of the filter produces a nearly flat response outside of + * the notch but at the cost of a group delay of 2D-2. + * + * The short form of the filter does not have a flat a response in the + * passband but has a group delay of only D-1 and is cheaper to compute. + * + * The theory behind this block can be found in the paper: + * + * <B><EM>R. Yates, "DC Blocker Algorithms," IEEE Signal Processing Magazine, + * Mar. 2008, pp 132-134.</EM></B> + */ +class moving_averager +{ +public: + moving_averager(int D); + ~moving_averager(); + + gr_complex filter(gr_complex x); + gr_complex delayed_sig() { return d_out; } + +private: + int d_length; + gr_complex d_out, d_out_d1, d_out_d2; + std::deque<gr_complex> d_delay_line; +}; + +class gr_dc_blocker_cc : public gr_sync_block +{ + private: + /*! + * Build the DC blocker. + * \param D (int) the length of the delay line + * \param long_form (bool) whether to use long (true, default) or short form + * \param channel (unsigned integer) Selects the channel to return [default=0]. + */ + friend gr_dc_blocker_cc_sptr gr_make_dc_blocker_cc (int D, bool long_form); + + int d_length; + bool d_long_form; + moving_averager *d_ma_0; + moving_averager *d_ma_1; + moving_averager *d_ma_2; + moving_averager *d_ma_3; + std::deque<gr_complex> d_delay_line; + + gr_dc_blocker_cc (int D, bool long_form); + +public: + ~gr_dc_blocker_cc (); + + /*! + * Get the blocker's group delay that is based on length of delay lines + */ + int get_group_delay(); + + //int set_length(int D); + + int work (int noutput_items, + gr_vector_const_void_star &input_items, + gr_vector_void_star &output_items); +}; + +#endif diff --git a/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.i b/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.i new file mode 100644 index 000000000..b88fecbde --- /dev/null +++ b/gnuradio-core/src/lib/filter/gr_dc_blocker_cc.i @@ -0,0 +1,34 @@ +/* -*- c++ -*- */ +/* + * Copyright 2011 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. + */ + +GR_SWIG_BLOCK_MAGIC(gr,dc_blocker_cc); + +gr_dc_blocker_cc_sptr gr_make_dc_blocker_cc (int D=32, bool long_form=true); + +class gr_dc_blocker_cc : public gr_sync_block +{ + private: + gr_dc_blocker_cc (int D, bool long_form); + + public: + ~gr_dc_blocker_cc (); +}; |