diff options
Diffstat (limited to 'gnuradio-core/src/python')
13 files changed, 135 insertions, 130 deletions
diff --git a/gnuradio-core/src/python/Makefile.am b/gnuradio-core/src/python/Makefile.am index e50af8944..a90aaba5c 100644 --- a/gnuradio-core/src/python/Makefile.am +++ b/gnuradio-core/src/python/Makefile.am @@ -21,9 +21,10 @@ include $(top_srcdir)/Makefile.common +if PYTHON SUBDIRS = gnuradio bin noinst_PYTHON = \ build_utils.py \ build_utils_codes.py - +endif diff --git a/gnuradio-core/src/python/bin/Makefile.am b/gnuradio-core/src/python/bin/Makefile.am index 0afd32767..6f9f162f1 100644 --- a/gnuradio-core/src/python/bin/Makefile.am +++ b/gnuradio-core/src/python/bin/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2005,2009 Free Software Foundation, Inc. +# Copyright 2005,2009,2010 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -22,7 +22,7 @@ include $(top_srcdir)/Makefile.common -EXTRA_DIST = microtune.py +EXTRA_DIST += microtune.py noinst_SCRIPTS = \ microtune.py diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/pfb_arb_resampler.py b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_arb_resampler.py index 74eae58dc..62f40582e 100644 --- a/gnuradio-core/src/python/gnuradio/blks2impl/pfb_arb_resampler.py +++ b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_arb_resampler.py @@ -20,7 +20,7 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr +from gnuradio import gr, optfir class pfb_arb_resampler_ccf(gr.hier_block2): ''' @@ -31,7 +31,7 @@ class pfb_arb_resampler_ccf(gr.hier_block2): streams. This block is provided to be consistent with the interface to the other PFB block. ''' - def __init__(self, rate, taps=None, flt_size=32, atten=80): + def __init__(self, rate, taps=None, flt_size=32, atten=100): gr.hier_block2.__init__(self, "pfb_arb_resampler_ccf", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature @@ -43,9 +43,23 @@ class pfb_arb_resampler_ccf(gr.hier_block2): self._taps = taps else: # Create a filter that covers the full bandwidth of the input signal - bw = 0.5 - tb = 0.1 - self._taps = gr.firdes.low_pass_2(self._size, self._size, bw, tb, atten) + bw = 0.4 + tb = 0.2 + ripple = 0.1 + #self._taps = gr.firdes.low_pass_2(self._size, self._size, bw, tb, atten) + made = False + while not made: + try: + self._taps = optfir.low_pass(self._size, self._size, bw, bw+tb, ripple, atten) + made = True + except RuntimeError: + ripple += 0.01 + made = False + print("Warning: set ripple to %.4f dB. If this is a problem, adjust the attenuation or create your own filter taps." % (ripple)) + + # Build in an exit strategy; if we've come this far, it ain't working. + if(ripple >= 1.0): + raise RuntimeError("optfir could not generate an appropriate filter.") self.pfb = gr.pfb_arb_resampler_ccf(self._rate, self._taps, self._size) #print "PFB has %d taps\n" % (len(self._taps),) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/pfb_channelizer.py b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_channelizer.py index a479ed48e..3ddc1749a 100644 --- a/gnuradio-core/src/python/gnuradio/blks2impl/pfb_channelizer.py +++ b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_channelizer.py @@ -20,7 +20,7 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr +from gnuradio import gr, optfir class pfb_channelizer_ccf(gr.hier_block2): ''' @@ -29,15 +29,35 @@ class pfb_channelizer_ccf(gr.hier_block2): This simplifies the interface by allowing a single input stream to connect to this block. It will then output a stream for each channel. ''' - def __init__(self, numchans, taps, oversample_rate=1): + def __init__(self, numchans, taps=None, oversample_rate=1, atten=100): gr.hier_block2.__init__(self, "pfb_channelizer_ccf", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(numchans, numchans, gr.sizeof_gr_complex)) # Output signature self._numchans = numchans - self._taps = taps self._oversample_rate = oversample_rate + if taps is not None: + self._taps = taps + else: + # Create a filter that covers the full bandwidth of the input signal + bw = 0.4 + tb = 0.2 + ripple = 0.1 + made = False + while not made: + try: + self._taps = optfir.low_pass(1, self._numchans, bw, bw+tb, ripple, atten) + made = True + except RuntimeError: + ripple += 0.01 + made = False + print("Warning: set ripple to %.4f dB. If this is a problem, adjust the attenuation or create your own filter taps." % (ripple)) + + # Build in an exit strategy; if we've come this far, it ain't working. + if(ripple >= 1.0): + raise RuntimeError("optfir could not generate an appropriate filter.") + self.s2ss = gr.stream_to_streams(gr.sizeof_gr_complex, self._numchans) self.pfb = gr.pfb_channelizer_ccf(self._numchans, self._taps, self._oversample_rate) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/pfb_decimator.py b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_decimator.py index 176d0473e..2e36e7bc1 100644 --- a/gnuradio-core/src/python/gnuradio/blks2impl/pfb_decimator.py +++ b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_decimator.py @@ -20,7 +20,7 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr +from gnuradio import gr, optfir class pfb_decimator_ccf(gr.hier_block2): ''' @@ -29,15 +29,35 @@ class pfb_decimator_ccf(gr.hier_block2): This simplifies the interface by allowing a single input stream to connect to this block. It will then output a stream that is the decimated output stream. ''' - def __init__(self, decim, taps, channel=0): + def __init__(self, decim, taps=None, channel=0, atten=100): gr.hier_block2.__init__(self, "pfb_decimator_ccf", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature self._decim = decim - self._taps = taps self._channel = channel + if taps is not None: + self._taps = taps + else: + # Create a filter that covers the full bandwidth of the input signal + bw = 0.4 + tb = 0.2 + ripple = 0.1 + made = False + while not made: + try: + self._taps = optfir.low_pass(1, self._decim, bw, bw+tb, ripple, atten) + made = True + except RuntimeError: + ripple += 0.01 + made = False + print("Warning: set ripple to %.4f dB. If this is a problem, adjust the attenuation or create your own filter taps." % (ripple)) + + # Build in an exit strategy; if we've come this far, it ain't working. + if(ripple >= 1.0): + raise RuntimeError("optfir could not generate an appropriate filter.") + self.s2ss = gr.stream_to_streams(gr.sizeof_gr_complex, self._decim) self.pfb = gr.pfb_decimator_ccf(self._decim, self._taps, self._channel) diff --git a/gnuradio-core/src/python/gnuradio/blks2impl/pfb_interpolator.py b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_interpolator.py index db2944042..a6094f7f4 100644 --- a/gnuradio-core/src/python/gnuradio/blks2impl/pfb_interpolator.py +++ b/gnuradio-core/src/python/gnuradio/blks2impl/pfb_interpolator.py @@ -20,7 +20,7 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr +from gnuradio import gr, optfir class pfb_interpolator_ccf(gr.hier_block2): ''' @@ -31,7 +31,7 @@ class pfb_interpolator_ccf(gr.hier_block2): streams. This block is provided to be consistent with the interface to the other PFB block. ''' - def __init__(self, interp, taps): + def __init__(self, interp, taps=None, atten=100): gr.hier_block2.__init__(self, "pfb_interpolator_ccf", gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature @@ -39,6 +39,27 @@ class pfb_interpolator_ccf(gr.hier_block2): self._interp = interp self._taps = taps + if taps is not None: + self._taps = taps + else: + # Create a filter that covers the full bandwidth of the input signal + bw = 0.4 + tb = 0.2 + ripple = 0.99 + made = False + while not made: + try: + self._taps = optfir.low_pass(self._interp, self._interp, bw, bw+tb, ripple, atten) + made = True + except RuntimeError: + ripple += 0.01 + made = False + print("Warning: set ripple to %.4f dB. If this is a problem, adjust the attenuation or create your own filter taps." % (ripple)) + + # Build in an exit strategy; if we've come this far, it ain't working. + if(ripple >= 1.0): + raise RuntimeError("optfir could not generate an appropriate filter.") + self.pfb = gr.pfb_interpolator_ccf(self._interp, self._taps) self.connect(self, self.pfb) diff --git a/gnuradio-core/src/python/gnuradio/gr/Makefile.am b/gnuradio-core/src/python/gnuradio/gr/Makefile.am index 341f58812..b8da9cf48 100644 --- a/gnuradio-core/src/python/gnuradio/gr/Makefile.am +++ b/gnuradio-core/src/python/gnuradio/gr/Makefile.am @@ -21,12 +21,11 @@ include $(top_srcdir)/Makefile.common -EXTRA_DIST = \ +EXTRA_DIST += \ run_tests.in \ test_16bit_1chunk.wav -TESTS = \ - run_tests +TESTS = run_tests grgrpythondir = $(grpythondir)/gr @@ -39,7 +38,6 @@ grgrpython_PYTHON = \ gr_threading_24.py \ hier_block2.py \ prefs.py \ - scheduler.py \ top_block.py \ pubsub.py diff --git a/gnuradio-core/src/python/gnuradio/gr/__init__.py b/gnuradio-core/src/python/gnuradio/gr/__init__.py index 6f939c470..73ca8e08f 100644 --- a/gnuradio-core/src/python/gnuradio/gr/__init__.py +++ b/gnuradio-core/src/python/gnuradio/gr/__init__.py @@ -1,5 +1,5 @@ # -# Copyright 2003,2004,2006,2008,2009 Free Software Foundation, Inc. +# Copyright 2003,2004,2006,2008,2009,2010 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -40,7 +40,7 @@ if _RTLD_GLOBAL != 0: _dlopenflags = sys.getdlopenflags() sys.setdlopenflags(_dlopenflags|_RTLD_GLOBAL) -from gnuradio_swig_python import * +from gnuradio_core import * from exceptions import * from hier_block2 import * from top_block import * diff --git a/gnuradio-core/src/python/gnuradio/gr/hier_block2.py b/gnuradio-core/src/python/gnuradio/gr/hier_block2.py index b43c5feda..debb65d91 100644 --- a/gnuradio-core/src/python/gnuradio/gr/hier_block2.py +++ b/gnuradio-core/src/python/gnuradio/gr/hier_block2.py @@ -19,7 +19,7 @@ # Boston, MA 02110-1301, USA. # -from gnuradio_swig_python import hier_block2_swig +from gnuradio_core import hier_block2_swig # # This hack forces a 'has-a' relationship to look like an 'is-a' one. @@ -66,7 +66,7 @@ class hier_block2(object): raise ValueError, ("connect requires at least one endpoint; %d provided." % (len (points),)) else: if len(points) == 1: - self._hb.connect(points[0].basic_block()) + self._hb.primitive_connect(points[0].to_basic_block()) else: for i in range (1, len (points)): self._connect(points[i-1], points[i]) @@ -74,11 +74,11 @@ class hier_block2(object): def _connect(self, src, dst): (src_block, src_port) = self._coerce_endpoint(src) (dst_block, dst_port) = self._coerce_endpoint(dst) - self._hb.connect(src_block.basic_block(), src_port, - dst_block.basic_block(), dst_port) + self._hb.primitive_connect(src_block.to_basic_block(), src_port, + dst_block.to_basic_block(), dst_port) def _coerce_endpoint(self, endp): - if hasattr(endp, 'basic_block'): + if hasattr(endp, 'to_basic_block'): return (endp, 0) else: if hasattr(endp, "__getitem__") and len(endp) == 2: @@ -97,10 +97,10 @@ class hier_block2(object): """ if len (points) < 1: - raise ValueError, ("disconnect requires at least two endpoints; %d provided." % (len (points),)) + raise ValueError, ("disconnect requires at least one endpoint; %d provided." % (len (points),)) else: if len (points) == 1: - self._hb.disconnect(points[0].basic_block()) + self._hb.primitive_disconnect(points[0].to_basic_block()) else: for i in range (1, len (points)): self._disconnect(points[i-1], points[i]) @@ -108,6 +108,6 @@ class hier_block2(object): def _disconnect(self, src, dst): (src_block, src_port) = self._coerce_endpoint(src) (dst_block, dst_port) = self._coerce_endpoint(dst) - self._hb.disconnect(src_block.basic_block(), src_port, - dst_block.basic_block(), dst_port) + self._hb.primitive_disconnect(src_block.to_basic_block(), src_port, + dst_block.to_basic_block(), dst_port) diff --git a/gnuradio-core/src/python/gnuradio/gr/prefs.py b/gnuradio-core/src/python/gnuradio/gr/prefs.py index 9b31b772b..40347a2f4 100644 --- a/gnuradio-core/src/python/gnuradio/gr/prefs.py +++ b/gnuradio-core/src/python/gnuradio/gr/prefs.py @@ -19,7 +19,7 @@ # Boston, MA 02110-1301, USA. # -import gnuradio_swig_python as gsp +import gnuradio_core as gsp _prefs_base = gsp.gr_prefs diff --git a/gnuradio-core/src/python/gnuradio/gr/scheduler.py b/gnuradio-core/src/python/gnuradio/gr/scheduler.py deleted file mode 100644 index 4694d48b2..000000000 --- a/gnuradio-core/src/python/gnuradio/gr/scheduler.py +++ /dev/null @@ -1,70 +0,0 @@ -# -# Copyright 2004 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. -# - -from gnuradio.gr.exceptions import * -from gnuradio_swig_python import single_threaded_scheduler, sts_pyrun -import gr_threading as _threading -#import threading as _threading - -class scheduler_thread(_threading.Thread): - def __init__(self, sts): - _threading.Thread.__init__(self) - self.sts = sts - def run(self): - # Invoke the single threaded scheduler's run method - # - # Note that we're in a new thread, and that sts_pyrun - # releases the global interpreter lock. This has the - # effect of evaluating the graph in parallel to the - # main line control code. - sts_pyrun(self.sts) - self.sts = None - -class scheduler(object): - def __init__(self, fg): - graphs = fg.partition_graph(fg.blocks) - # print "@@@ # graphs = %d" % (len(graphs)) - - self.state = [] - - for g in graphs: - list_of_blocks = [x.block() for x in g] - sts = single_threaded_scheduler(list_of_blocks) - thread = scheduler_thread(sts) - thread.setDaemon(1) - self.state.append((sts, thread)) - - def start(self): - for (sts, thread) in self.state: - thread.start() - - def stop(self): - for (sts, thread) in self.state: - sts.stop() - self.wait() - - def wait(self): - for (sts, thread) in self.state: - timeout = 0.100 - while True: - thread.join(timeout) - if not thread.isAlive(): - break diff --git a/gnuradio-core/src/python/gnuradio/gr/top_block.py b/gnuradio-core/src/python/gnuradio/gr/top_block.py index 71e401424..1e36d3b48 100644 --- a/gnuradio-core/src/python/gnuradio/gr/top_block.py +++ b/gnuradio-core/src/python/gnuradio/gr/top_block.py @@ -19,7 +19,7 @@ # Boston, MA 02110-1301, USA. # -from gnuradio_swig_python import top_block_swig, \ +from gnuradio_core import top_block_swig, \ top_block_wait_unlocked, top_block_run_unlocked #import gnuradio.gr.gr_threading as _threading @@ -118,7 +118,7 @@ class top_block(object): raise ValueError, ("connect requires at least one endpoint; %d provided." % (len (points),)) else: if len(points) == 1: - self._tb.connect(points[0].basic_block()) + self._tb.primitive_connect(points[0].to_basic_block()) else: for i in range (1, len (points)): self._connect(points[i-1], points[i]) @@ -126,11 +126,11 @@ class top_block(object): def _connect(self, src, dst): (src_block, src_port) = self._coerce_endpoint(src) (dst_block, dst_port) = self._coerce_endpoint(dst) - self._tb.connect(src_block.basic_block(), src_port, - dst_block.basic_block(), dst_port) + self._tb.primitive_connect(src_block.to_basic_block(), src_port, + dst_block.to_basic_block(), dst_port) def _coerce_endpoint(self, endp): - if hasattr(endp, 'basic_block'): + if hasattr(endp, 'to_basic_block'): return (endp, 0) else: if hasattr(endp, "__getitem__") and len(endp) == 2: @@ -139,14 +139,14 @@ class top_block(object): raise ValueError("unable to coerce endpoint") def disconnect(self, *points): - '''connect requires one or more arguments that can be coerced to endpoints. + '''disconnect requires one or more arguments that can be coerced to endpoints. If more than two arguments are provided, they are disconnected successively. ''' if len (points) < 1: - raise ValueError, ("disconnect requires at least two endpoints; %d provided." % (len (points),)) + raise ValueError, ("disconnect requires at least one endpoint; %d provided." % (len (points),)) else: if len(points) == 1: - self._tb.disconnect(points[0].basic_block()) + self._tb.primitive_disconnect(points[0].to_basic_block()) else: for i in range (1, len (points)): self._disconnect(points[i-1], points[i]) @@ -154,6 +154,6 @@ class top_block(object): def _disconnect(self, src, dst): (src_block, src_port) = self._coerce_endpoint(src) (dst_block, dst_port) = self._coerce_endpoint(dst) - self._tb.disconnect(src_block.basic_block(), src_port, - dst_block.basic_block(), dst_port) + self._tb.primitive_disconnect(src_block.to_basic_block(), src_port, + dst_block.to_basic_block(), dst_port) diff --git a/gnuradio-core/src/python/gnuradio/gr_unittest.py b/gnuradio-core/src/python/gnuradio/gr_unittest.py index 50d484a76..c2c4df2ba 100755 --- a/gnuradio-core/src/python/gnuradio/gr_unittest.py +++ b/gnuradio-core/src/python/gnuradio/gr_unittest.py @@ -38,7 +38,7 @@ class TestCase(unittest.TestCase): Note that decimal places (from zero) is usually not the same as significant digits (measured from the most signficant digit). - """ + """ if round(second.real-first.real, places) != 0: raise self.failureException, \ (msg or '%s != %s within %s places' % (`first`, `second`, `places` )) @@ -112,30 +112,31 @@ def run(PUT, filename=None): Runs the unittest on a TestCase and produces an optional XML report PUT: the program under test and should be a gr_unittest.TestCase filename: an optional filename to save the XML report of the tests - this will live in $HOME/.gnuradio/unittests/python + this will live in ./.unittests/python ''' # Run this is given a file name if(filename is not None): - homepath = os.getenv("HOME") - basepath = homepath + "/.gnuradio" - path = homepath + "/.gnuradio/unittests/python" + basepath = "./.unittests" + path = basepath + "/python" + + if not os.path.exists(basepath): + os.makedirs(basepath, 0750) xmlrunner = None - if os.path.exists(basepath): - # only proceed if $HOME/.gnuradio is writable - st = os.stat(basepath)[stat.ST_MODE] + # only proceed if .unittests is writable + st = os.stat(basepath)[stat.ST_MODE] + if(st & stat.S_IWUSR > 0): + # Test if path exists; if not, build it + if not os.path.exists(path): + os.makedirs(path, 0750) + + # Just for safety: make sure we can write here, too + st = os.stat(path)[stat.ST_MODE] if(st & stat.S_IWUSR > 0): - # Test if path exists; if not, build it - if not os.path.exists(path): - os.makedirs(path, 0750) - - # Just for safety: make sure we can write here, too - st = os.stat(path)[stat.ST_MODE] - if(st & stat.S_IWUSR > 0): - # Create an XML runner to filename - fout = file(path+"/"+filename, "w") - xmlrunner = gr_xmlrunner.XMLTestRunner(fout) + # Create an XML runner to filename + fout = file(path+"/"+filename, "w") + xmlrunner = gr_xmlrunner.XMLTestRunner(fout) txtrunner = TextTestRunner(verbosity=1) |