summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rondeau2011-05-25 16:29:22 +0100
committerTom Rondeau2011-05-25 16:29:22 +0100
commit09f5b9606b57631d27d3abd868dcf5fe7eca6d12 (patch)
treeb98845739bcbeeedc765b79a870672cc5e250f89
parentf5d6c321dcdba35189b120795dccad5b12ce8939 (diff)
downloadgnuradio-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.am7
-rw-r--r--gnuradio-core/src/lib/filter/filter.i2
-rw-r--r--gnuradio-core/src/lib/filter/gr_dc_blocker_cc.cc138
-rw-r--r--gnuradio-core/src/lib/filter/gr_dc_blocker_cc.h110
-rw-r--r--gnuradio-core/src/lib/filter/gr_dc_blocker_cc.i34
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 ();
+};