summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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_ff.cc138
-rw-r--r--gnuradio-core/src/lib/filter/gr_dc_blocker_ff.h110
-rw-r--r--gnuradio-core/src/lib/filter/gr_dc_blocker_ff.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 95489156f..0314079a2 100644
--- a/gnuradio-core/src/lib/filter/Makefile.am
+++ b/gnuradio-core/src/lib/filter/Makefile.am
@@ -217,7 +217,8 @@ libfilter_la_common_SOURCES = \
gr_pfb_arb_resampler_ccf.cc \
gr_pfb_clock_sync_ccf.cc \
gr_pfb_clock_sync_fff.cc \
- gr_dc_blocker_cc.cc
+ gr_dc_blocker_cc.cc \
+ gr_dc_blocker_ff.cc
libfilter_qa_la_common_SOURCES = \
qa_filter.cc \
@@ -308,7 +309,8 @@ grinclude_HEADERS = \
gr_pfb_arb_resampler_ccf.h \
gr_pfb_clock_sync_ccf.h \
gr_pfb_clock_sync_fff.h \
- gr_dc_blocker_cc.h
+ gr_dc_blocker_cc.h \
+ gr_dc_blocker_ff.h
noinst_HEADERS = \
assembly.h \
@@ -375,6 +377,7 @@ swiginclude_HEADERS = \
gr_pfb_clock_sync_ccf.i \
gr_pfb_clock_sync_fff.i \
gr_dc_blocker_cc.i \
+ gr_dc_blocker_ff.i \
$(GENERATED_I)
diff --git a/gnuradio-core/src/lib/filter/filter.i b/gnuradio-core/src/lib/filter/filter.i
index b8f4d06eb..58bb4f0d5 100644
--- a/gnuradio-core/src/lib/filter/filter.i
+++ b/gnuradio-core/src/lib/filter/filter.i
@@ -40,6 +40,7 @@
#include <gr_pfb_clock_sync_ccf.h>
#include <gr_pfb_clock_sync_fff.h>
#include <gr_dc_blocker_cc.h>
+#include <gr_dc_blocker_ff.h>
%}
%include "gr_iir_filter_ffd.i"
@@ -64,5 +65,6 @@
%include "gr_pfb_clock_sync_ccf.i"
%include "gr_pfb_clock_sync_fff.i"
%include "gr_dc_blocker_cc.i"
+%include "gr_dc_blocker_ff.i"
%include "filter_generated.i"
diff --git a/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.cc b/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.cc
new file mode 100644
index 000000000..d684bc7e8
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.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_ff.h>
+#include <gr_io_signature.h>
+#include <cstdio>
+
+moving_averager_f::moving_averager_f(int D)
+ : d_length(D), d_out(0), d_out_d1(0), d_out_d2(0)
+{
+ d_delay_line = std::deque<float>(d_length-1, 0);
+}
+
+moving_averager_f::~moving_averager_f()
+{
+}
+
+float
+moving_averager_f::filter(float x)
+{
+ d_out_d1 = d_out;
+ d_delay_line.push_back(x);
+ d_out = d_delay_line[0];
+ d_delay_line.pop_front();
+
+ float y = x - d_out_d1 + d_out_d2;
+ d_out_d2 = y;
+
+ return (y / (float)(d_length));
+}
+
+
+
+gr_dc_blocker_ff_sptr gr_make_dc_blocker_ff (int D, bool long_form)
+{
+ return gnuradio::get_initial_sptr(new gr_dc_blocker_ff(D, long_form));
+}
+
+
+gr_dc_blocker_ff::gr_dc_blocker_ff (int D, bool long_form)
+ : gr_sync_block ("dc_blocker_ff",
+ gr_make_io_signature (1, 1, sizeof(float)),
+ gr_make_io_signature (1, 1, sizeof(float))),
+ d_length(D), d_long_form(long_form)
+{
+ if(d_long_form) {
+ d_ma_0 = new moving_averager_f(D);
+ d_ma_1 = new moving_averager_f(D);
+ d_ma_2 = new moving_averager_f(D);
+ d_ma_3 = new moving_averager_f(D);
+ d_delay_line = std::deque<float>(d_length-1, 0);
+ }
+ else {
+ d_ma_0 = new moving_averager_f(D);
+ d_ma_1 = new moving_averager_f(D);
+ }
+}
+
+gr_dc_blocker_ff::~gr_dc_blocker_ff()
+{
+ 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_ff::get_group_delay()
+{
+ if(d_long_form)
+ return (2*d_length-2);
+ else
+ return d_length - 1;
+}
+
+int
+gr_dc_blocker_ff::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_long_form) {
+ float 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 {
+ float 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_ff.h b/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.h
new file mode 100644
index 000000000..adaaca1e2
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.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_FF_H
+#define INCLUDED_GR_DC_BLOCKER_FF_H
+
+#include <gr_sync_block.h>
+#include <deque>
+
+class gr_dc_blocker_ff;
+typedef boost::shared_ptr<gr_dc_blocker_ff> gr_dc_blocker_ff_sptr;
+gr_dc_blocker_ff_sptr gr_make_dc_blocker_ff (int D=32, bool long_form=true);
+
+/*!
+ * \class gr_dc_blocker_ff
+ * \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_f
+{
+public:
+ moving_averager_f(int D);
+ ~moving_averager_f();
+
+ float filter(float x);
+ float delayed_sig() { return d_out; }
+
+private:
+ int d_length;
+ float d_out, d_out_d1, d_out_d2;
+ std::deque<float> d_delay_line;
+};
+
+class gr_dc_blocker_ff : 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_ff_sptr gr_make_dc_blocker_ff (int D, bool long_form);
+
+ int d_length;
+ bool d_long_form;
+ moving_averager_f *d_ma_0;
+ moving_averager_f *d_ma_1;
+ moving_averager_f *d_ma_2;
+ moving_averager_f *d_ma_3;
+ std::deque<float> d_delay_line;
+
+ gr_dc_blocker_ff (int D, bool long_form);
+
+public:
+ ~gr_dc_blocker_ff ();
+
+ /*!
+ * 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_ff.i b/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.i
new file mode 100644
index 000000000..032145c9e
--- /dev/null
+++ b/gnuradio-core/src/lib/filter/gr_dc_blocker_ff.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_ff);
+
+gr_dc_blocker_ff_sptr gr_make_dc_blocker_ff (int D=32, bool long_form=true);
+
+class gr_dc_blocker_ff : public gr_sync_block
+{
+ private:
+ gr_dc_blocker_ff (int D, bool long_form);
+
+ public:
+ ~gr_dc_blocker_ff ();
+};