summaryrefslogtreecommitdiff
path: root/gnuradio-core
diff options
context:
space:
mode:
Diffstat (limited to 'gnuradio-core')
-rw-r--r--gnuradio-core/src/lib/runtime/gr_hier_block2.cc2
-rw-r--r--gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc2
-rw-r--r--gnuradio-core/src/lib/runtime/gr_runtime_impl.cc2
-rw-r--r--gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.cc2
-rw-r--r--gnuradio-core/src/python/gnuradio/blksimpl2/Makefile.am4
-rw-r--r--gnuradio-core/src/python/gnuradio/blksimpl2/filterbank.py174
-rw-r--r--gnuradio-core/src/python/gnuradio/blksimpl2/rational_resampler.py131
7 files changed, 312 insertions, 5 deletions
diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2.cc b/gnuradio-core/src/lib/runtime/gr_hier_block2.cc
index 9811b9def..fc74ff431 100644
--- a/gnuradio-core/src/lib/runtime/gr_hier_block2.cc
+++ b/gnuradio-core/src/lib/runtime/gr_hier_block2.cc
@@ -29,7 +29,7 @@
#include <gr_hier_block2_detail.h>
#include <iostream>
-#define GR_HIER_BLOCK2_DEBUG 1
+#define GR_HIER_BLOCK2_DEBUG 0
gr_hier_block2_sptr gr_make_hier_block2(const std::string &name,
gr_io_signature_sptr input_signature,
diff --git a/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc
index 307cbabeb..4fefed28b 100644
--- a/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc
+++ b/gnuradio-core/src/lib/runtime/gr_hier_block2_detail.cc
@@ -30,7 +30,7 @@
#include <stdexcept>
#include <iostream>
-#define GR_HIER_BLOCK2_DETAIL_DEBUG 1
+#define GR_HIER_BLOCK2_DETAIL_DEBUG 0
gr_hier_block2_detail::gr_hier_block2_detail(gr_hier_block2 *owner) :
d_owner(owner),
diff --git a/gnuradio-core/src/lib/runtime/gr_runtime_impl.cc b/gnuradio-core/src/lib/runtime/gr_runtime_impl.cc
index 54fc7d19a..e792774b9 100644
--- a/gnuradio-core/src/lib/runtime/gr_runtime_impl.cc
+++ b/gnuradio-core/src/lib/runtime/gr_runtime_impl.cc
@@ -38,7 +38,7 @@
#include <stdexcept>
#include <iostream>
-#define GR_RUNTIME_IMPL_DEBUG 1
+#define GR_RUNTIME_IMPL_DEBUG 0
static gr_runtime_impl *s_runtime = 0;
diff --git a/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.cc b/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.cc
index a725adb6e..432cde0ae 100644
--- a/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.cc
+++ b/gnuradio-core/src/lib/runtime/gr_simple_flowgraph_detail.cc
@@ -33,7 +33,7 @@
#include <stdexcept>
#include <map>
-#define GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG 1
+#define GR_SIMPLE_FLOWGRAPH_DETAIL_DEBUG 0
gr_edge_sptr
gr_make_edge(const gr_endpoint &src, const gr_endpoint &dst)
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl2/Makefile.am b/gnuradio-core/src/python/gnuradio/blksimpl2/Makefile.am
index 4852ff3fb..201a85b39 100644
--- a/gnuradio-core/src/python/gnuradio/blksimpl2/Makefile.am
+++ b/gnuradio-core/src/python/gnuradio/blksimpl2/Makefile.am
@@ -31,9 +31,11 @@ grblkspython_PYTHON = \
dbpsk.py \
dqpsk.py \
d8psk.py \
+ filterbank.py \
gmsk.py \
pkt.py \
- psk.py
+ psk.py \
+ rational_resampler.py
noinst_PYTHON =
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl2/filterbank.py b/gnuradio-core/src/python/gnuradio/blksimpl2/filterbank.py
new file mode 100644
index 000000000..38587bae8
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blksimpl2/filterbank.py
@@ -0,0 +1,174 @@
+#
+# Copyright 2005 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 2, 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.
+#
+
+import sys
+from gnuradio import gr, gru
+
+def _generate_synthesis_taps(mpoints):
+ return [] # FIXME
+
+
+def _split_taps(taps, mpoints):
+ assert (len(taps) % mpoints) == 0
+ result = [list() for x in range(mpoints)]
+ for i in xrange(len(taps)):
+ (result[i % mpoints]).append(taps[i])
+ return [tuple(x) for x in result]
+
+
+class synthesis_filterbank(gr.hier_block2):
+ """
+ Uniformly modulated polyphase DFT filter bank: synthesis
+
+ See http://cnx.rice.edu/content/m10424/latest
+ """
+ def __init__(self, mpoints, taps=None):
+ """
+ Takes M complex streams in, produces single complex stream out
+ that runs at M times the input sample rate
+
+ @param fg: flow_graph
+ @param mpoints: number of freq bins/interpolation factor/subbands
+ @param taps: filter taps for subband filter
+
+ The channel spacing is equal to the input sample rate.
+ The total bandwidth and output sample rate are equal the input
+ sample rate * nchannels.
+
+ Output stream to frequency mapping:
+
+ channel zero is at zero frequency.
+
+ if mpoints is odd:
+
+ Channels with increasing positive frequencies come from
+ channels 1 through (N-1)/2.
+
+ Channel (N+1)/2 is the maximum negative frequency, and
+ frequency increases through N-1 which is one channel lower
+ than the zero frequency.
+
+ if mpoints is even:
+
+ Channels with increasing positive frequencies come from
+ channels 1 through (N/2)-1.
+
+ Channel (N/2) is evenly split between the max positive and
+ negative bins.
+
+ Channel (N/2)+1 is the maximum negative frequency, and
+ frequency increases through N-1 which is one channel lower
+ than the zero frequency.
+
+ Channels near the frequency extremes end up getting cut
+ off by subsequent filters and therefore have diminished
+ utility.
+ """
+ item_size = gr.sizeof_gr_complex
+ gr.hier_block2.__init__(self, "synthesis_filterbank",
+ gr.io_signature(mpoints, mpoints, item_size),
+ gr.io_signature(1, 1, item_size))
+
+ if taps is None:
+ taps = _generate_synthesis_taps(mpoints)
+
+ # pad taps to multiple of mpoints
+ r = len(taps) % mpoints
+ if r != 0:
+ taps = taps + (mpoints - r) * (0,)
+
+ # split in mpoints separate set of taps
+ sub_taps = _split_taps(taps, mpoints)
+
+ self.ss2v = gr.streams_to_vector(item_size, mpoints)
+ self.ifft = gr.fft_vcc(mpoints, False, [])
+ self.v2ss = gr.vector_to_streams(item_size, mpoints)
+ # mpoints filters go in here...
+ self.ss2s = gr.streams_to_stream(item_size, mpoints)
+
+ for i in range(mpoints):
+ self.connect((self, i), (self.ss2v, i))
+
+ self.connect(self.ss2v, self.ifft, self.v2ss, self)
+
+ # build mpoints fir filters...
+ for i in range(mpoints):
+ f = gr.fft_filter_ccc(1, sub_taps[i])
+ self.connect((self.v2ss, i), f)
+ self.connect(f, (self.ss2s, i))
+
+
+class analysis_filterbank(gr.hier_block2):
+ """
+ Uniformly modulated polyphase DFT filter bank: analysis
+
+ See http://cnx.rice.edu/content/m10424/latest
+ """
+ def __init__(self, mpoints, taps=None):
+ """
+ Takes 1 complex stream in, produces M complex streams out
+ that runs at 1/M times the input sample rate
+
+ @param fg: flow_graph
+ @param mpoints: number of freq bins/interpolation factor/subbands
+ @param taps: filter taps for subband filter
+
+ Same channel to frequency mapping as described above.
+ """
+ item_size = gr.sizeof_gr_complex
+ gr.hier_block2.__init__(self, "analysis_filterbank",
+ gr.io_signature(1, 1, item_size),
+ gr.io_signature(mpoints, mpoints, item_size))
+
+ if taps is None:
+ taps = _generate_synthesis_taps(mpoints)
+
+ # pad taps to multiple of mpoints
+ r = len(taps) % mpoints
+ if r != 0:
+ taps = taps + (mpoints - r) * (0,)
+
+ # split in mpoints separate set of taps
+ sub_taps = _split_taps(taps, mpoints)
+
+ # print >> sys.stderr, "mpoints =", mpoints, "len(sub_taps) =", len(sub_taps)
+
+ self.s2ss = gr.stream_to_streams(item_size, mpoints)
+ # filters here
+ self.ss2v = gr.streams_to_vector(item_size, mpoints)
+ self.fft = gr.fft_vcc(mpoints, True, [])
+ self.v2ss = gr.vector_to_streams(item_size, mpoints)
+
+ self.connect(self, self.s2ss)
+
+ # build mpoints fir filters...
+ for i in range(mpoints):
+ f = gr.fft_filter_ccc(1, sub_taps[mpoints-i-1])
+ self.connect((self.s2ss, i), f)
+ self.connect(f, (self.ss2v, i))
+
+ self.connect(self.ss2v, self.fft, self.v2ss)
+
+ for i in range(mpoints):
+ self.connect((self.v2ss, i), (self, i))
+
+
+
diff --git a/gnuradio-core/src/python/gnuradio/blksimpl2/rational_resampler.py b/gnuradio-core/src/python/gnuradio/blksimpl2/rational_resampler.py
new file mode 100644
index 000000000..93e90f346
--- /dev/null
+++ b/gnuradio-core/src/python/gnuradio/blksimpl2/rational_resampler.py
@@ -0,0 +1,131 @@
+#
+# Copyright 2005,2007 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 2, 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.
+#
+
+from gnuradio import gr, gru
+
+_plot = None
+
+def design_filter(interpolation, decimation, fractional_bw):
+ """
+ Given the interpolation rate, decimation rate and a fractional bandwidth,
+ design a set of taps.
+
+ @param interpolation: interpolation factor
+ @type interpolation: integer > 0
+ @param decimation: decimation factor
+ @type decimation: integer > 0
+ @param fractional_bw: fractional bandwidth in (0, 0.5) 0.4 works well.
+ @type fractional_bw: float
+ @returns: sequence of numbers
+ """
+
+ if fractional_bw >= 0.5 or fractional_bw <= 0:
+ raise ValueError, "Invalid fractional_bandwidth, must be in (0, 0.5)"
+
+ beta = 5.0
+ trans_width = 0.5 - fractional_bw
+ mid_transition_band = 0.5 - trans_width/2
+
+ taps = gr.firdes.low_pass(interpolation, # gain
+ 1, # Fs
+ mid_transition_band/interpolation, # trans mid point
+ trans_width/interpolation, # transition width
+ gr.firdes.WIN_KAISER,
+ beta # beta
+ )
+
+ return taps
+
+
+
+class _rational_resampler_base(gr.hier_block2):
+ """
+ base class for all rational resampler variants.
+ """
+ def __init__(self, resampler_base,
+ interpolation, decimation, taps=None, fractional_bw=None):
+ """
+ Rational resampling polyphase FIR filter.
+
+ Either taps or fractional_bw may be specified, but not both.
+ If neither is specified, a reasonable default, 0.4, is used as
+ the fractional_bw.
+
+ @param interpolation: interpolation factor
+ @type interpolation: integer > 0
+ @param decimation: decimation factor
+ @type decimation: integer > 0
+ @param taps: optional filter coefficients
+ @type taps: sequence
+ @param fractional_bw: fractional bandwidth in (0, 0.5), measured at final freq (use 0.4)
+ @type fractional_bw: float
+ """
+
+ if not isinstance(interpolation, int) or interpolation < 1:
+ raise ValueError, "interpolation must be an integer >= 1"
+
+ if not isinstance(decimation, int) or decimation < 1:
+ raise ValueError, "decimation must be an integer >= 1"
+
+ if taps is None and fractional_bw is None:
+ fractional_bw = 0.4
+
+ d = gru.gcd(interpolation, decimation)
+ interpolation = interpolation // d
+ decimation = decimation // d
+
+ if taps is None:
+ taps = design_filter(interpolation, decimation, fractional_bw)
+
+ resampler = resampler_base(interpolation, decimation, taps)
+ gr.hier_block2.__init__(self, resampler.name(),
+ gr.io_signature(1, 1, resampler.input_signature().sizeof_stream_item(0)),
+ gr.io_signature(1, 1, resampler.output_signature().sizeof_stream_item(1)))
+
+ self.connect(self, resampler, self)
+
+
+class rational_resampler_fff(_rational_resampler_base):
+ def __init__(self, interpolation, decimation, taps=None, fractional_bw=None):
+ """
+ Rational resampling polyphase FIR filter with
+ float input, float output and float taps.
+ """
+ _rational_resampler_base.__init__(self, gr.rational_resampler_base_fff,
+ interpolation, decimation, taps, fractional_bw)
+
+class rational_resampler_ccf(_rational_resampler_base):
+ def __init__(self, interpolation, decimation, taps=None, fractional_bw=None):
+ """
+ Rational resampling polyphase FIR filter with
+ complex input, complex output and float taps.
+ """
+ _rational_resampler_base.__init__(self, gr.rational_resampler_base_ccf,
+ interpolation, decimation, taps, fractional_bw)
+
+class rational_resampler_ccc(_rational_resampler_base):
+ def __init__(self, interpolation, decimation, taps=None, fractional_bw=None):
+ """
+ Rational resampling polyphase FIR filter with
+ complex input, complex output and complex taps.
+ """
+ _rational_resampler_base.__init__(self, gr.rational_resampler_base_ccc,
+ interpolation, decimation, taps, fractional_bw)