From 05005e3d3fad3c9baee9906714510b5d12e0fa6f Mon Sep 17 00:00:00 2001 From: eb Date: Fri, 8 Feb 2008 04:36:24 +0000 Subject: [PATCH] Removed gr.flow_graph, gr.hier_block and friends. From here on out all work on the trunk must use gr.top_block and gr.hier_block2. Merged eb/fg-no-more -r7602:7606 into trunk. git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@7607 221aa14e-8319-0410-a670-987f0aec2ac5 --- config/grc_gnuradio_core.m4 | 4 +- gnuradio-core/src/python/gnuradio/Makefile.am | 4 +- .../src/python/gnuradio/blks/Makefile.am | 35 - .../src/python/gnuradio/blks/__init__.py | 37 - .../src/python/gnuradio/blksimpl/Makefile.am | 59 -- .../src/python/gnuradio/blksimpl/__init__.py | 1 - .../src/python/gnuradio/blksimpl/am_demod.py | 75 -- .../python/gnuradio/blksimpl/channel_model.py | 59 -- .../src/python/gnuradio/blksimpl/cpm.py | 249 ------- .../src/python/gnuradio/blksimpl/d8psk.py | 363 ---------- .../src/python/gnuradio/blksimpl/dbpsk.py | 364 ---------- .../gnuradio/blksimpl/digital_voice.py.real | 102 --- .../src/python/gnuradio/blksimpl/dqpsk.py | 363 ---------- .../python/gnuradio/blksimpl/filterbank.py | 160 ----- .../src/python/gnuradio/blksimpl/fm_demod.py | 122 ---- .../src/python/gnuradio/blksimpl/fm_emph.py | 145 ---- .../src/python/gnuradio/blksimpl/gmsk.py | 292 -------- .../src/python/gnuradio/blksimpl/nbfm_rx.py | 87 --- .../src/python/gnuradio/blksimpl/nbfm_tx.py | 95 --- .../src/python/gnuradio/blksimpl/pkt.py | 161 ----- .../src/python/gnuradio/blksimpl/psk.py | 94 --- .../src/python/gnuradio/blksimpl/qam.py | 113 --- .../src/python/gnuradio/blksimpl/qam16.py | 205 ------ .../src/python/gnuradio/blksimpl/qam256.py | 205 ------ .../src/python/gnuradio/blksimpl/qam64.py | 205 ------ .../src/python/gnuradio/blksimpl/qam8.py | 205 ------ .../gnuradio/blksimpl/rational_resampler.py | 137 ---- .../gnuradio/blksimpl/standard_squelch.py | 73 -- .../src/python/gnuradio/blksimpl/wfm_rcv.py | 72 -- .../python/gnuradio/blksimpl/wfm_rcv_pll.py | 206 ------ .../src/python/gnuradio/blksimpl/wfm_tx.py | 79 --- .../src/python/gnuradio/gr/Makefile.am | 7 +- .../src/python/gnuradio/gr/__init__.py | 5 +- .../python/gnuradio/gr/basic_flow_graph.py | 270 -------- .../src/python/gnuradio/gr/flow_graph.py | 234 ------- .../src/python/gnuradio/gr/hier_block.py | 132 ---- .../python/gnuradio/gr/qa_basic_flow_graph.py | 190 ----- .../src/python/gnuradio/gr/qa_flow_graph.py | 356 ---------- .../python/gnuradio/gr/qa_kludged_imports.py | 4 +- gnuradio-core/src/tests/test_buffers.py | 4 +- .../python/apps/hf_radio/README.TXT | 7 + .../python/multi-antenna/multi_fft.py | 14 +- .../python/multi-antenna/multi_file.py | 6 +- .../python/multi-antenna/multi_scope.py | 11 +- gnuradio-examples/python/multi_usrp/README | 6 + .../python/multi_usrp/multi_usrp_rx_cfile.py | 12 +- gnuradio-examples/python/ofdm/fftshift.py | 10 +- .../python/ofdm/ofdm_mod_demod_test.py | 12 +- .../python/usrp/limbo/siggen_min2.py | 62 -- gr-howto-write-a-block/doc/qa_howto_1.py | 10 +- gr-wxgui/src/python/Makefile.am | 7 +- gr-wxgui/src/python/fftsink.py | 488 ------------- gr-wxgui/src/python/numbersink.py | 614 ----------------- gr-wxgui/src/python/scopesink.py | 650 ------------------ gr-wxgui/src/python/stdgui.py | 90 --- gr-wxgui/src/python/waterfallsink.py | 475 ------------- 56 files changed, 60 insertions(+), 7987 deletions(-) delete mode 100644 gnuradio-core/src/python/gnuradio/blks/Makefile.am delete mode 100644 gnuradio-core/src/python/gnuradio/blks/__init__.py delete mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/Makefile.am delete mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/__init__.py delete mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/am_demod.py delete mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/channel_model.py delete mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/cpm.py delete mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/d8psk.py delete mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/dbpsk.py delete mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/digital_voice.py.real delete mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/dqpsk.py delete mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/filterbank.py delete mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/fm_demod.py delete mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/fm_emph.py delete mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/gmsk.py delete mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/nbfm_rx.py delete mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/nbfm_tx.py delete mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/pkt.py delete mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/psk.py delete mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/qam.py delete mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/qam16.py delete mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/qam256.py delete mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/qam64.py delete mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/qam8.py delete mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/rational_resampler.py delete mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/standard_squelch.py delete mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/wfm_rcv.py delete mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/wfm_rcv_pll.py delete mode 100644 gnuradio-core/src/python/gnuradio/blksimpl/wfm_tx.py delete mode 100644 gnuradio-core/src/python/gnuradio/gr/basic_flow_graph.py delete mode 100644 gnuradio-core/src/python/gnuradio/gr/flow_graph.py delete mode 100644 gnuradio-core/src/python/gnuradio/gr/hier_block.py delete mode 100755 gnuradio-core/src/python/gnuradio/gr/qa_basic_flow_graph.py delete mode 100755 gnuradio-core/src/python/gnuradio/gr/qa_flow_graph.py delete mode 100755 gnuradio-examples/python/usrp/limbo/siggen_min2.py delete mode 100755 gr-wxgui/src/python/fftsink.py delete mode 100755 gr-wxgui/src/python/numbersink.py delete mode 100755 gr-wxgui/src/python/scopesink.py delete mode 100644 gr-wxgui/src/python/stdgui.py delete mode 100755 gr-wxgui/src/python/waterfallsink.py diff --git a/config/grc_gnuradio_core.m4 b/config/grc_gnuradio_core.m4 index a005645c..37849929 100644 --- a/config/grc_gnuradio_core.m4 +++ b/config/grc_gnuradio_core.m4 @@ -1,4 +1,4 @@ -dnl Copyright 2001,2002,2003,2004,2005,2006,2007 Free Software Foundation, Inc. +dnl Copyright 2001,2002,2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc. dnl dnl This file is part of GNU Radio dnl @@ -43,8 +43,6 @@ AC_DEFUN([GRC_GNURADIO_CORE],[ gnuradio-core/src/python/Makefile \ gnuradio-core/src/python/bin/Makefile \ gnuradio-core/src/python/gnuradio/Makefile \ - gnuradio-core/src/python/gnuradio/blks/Makefile \ - gnuradio-core/src/python/gnuradio/blksimpl/Makefile \ gnuradio-core/src/python/gnuradio/blks2/Makefile \ gnuradio-core/src/python/gnuradio/blks2impl/Makefile \ gnuradio-core/src/python/gnuradio/gr/Makefile \ diff --git a/gnuradio-core/src/python/gnuradio/Makefile.am b/gnuradio-core/src/python/gnuradio/Makefile.am index 388681e5..d0188215 100644 --- a/gnuradio-core/src/python/gnuradio/Makefile.am +++ b/gnuradio-core/src/python/gnuradio/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2004,2007 Free Software Foundation, Inc. +# Copyright 2004,2007,2008 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -21,7 +21,7 @@ include $(top_srcdir)/Makefile.common -SUBDIRS = gr gru gruimpl blks blksimpl blks2 blks2impl vocoder +SUBDIRS = gr gru gruimpl blks2 blks2impl vocoder grpython_PYTHON = \ __init__.py \ diff --git a/gnuradio-core/src/python/gnuradio/blks/Makefile.am b/gnuradio-core/src/python/gnuradio/blks/Makefile.am deleted file mode 100644 index 48cfff0e..00000000 --- a/gnuradio-core/src/python/gnuradio/blks/Makefile.am +++ /dev/null @@ -1,35 +0,0 @@ -# -# 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 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. -# - -include $(top_srcdir)/Makefile.common - -# EXTRA_DIST = run_tests.in -# TESTS = run_tests - -grblkspythondir = $(grpythondir)/blks - -grblkspython_PYTHON = \ - __init__.py - - -noinst_PYTHON = - -CLEANFILES = *.pyc *.pyo diff --git a/gnuradio-core/src/python/gnuradio/blks/__init__.py b/gnuradio-core/src/python/gnuradio/blks/__init__.py deleted file mode 100644 index 08836bbc..00000000 --- a/gnuradio-core/src/python/gnuradio/blks/__init__.py +++ /dev/null @@ -1,37 +0,0 @@ -# -# 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 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. -# - -import glob -import os.path - -# Semi-hideous kludge to import everything in the blksimpl directory -# into the gnuradio.blks namespace. This keeps us from having to remember -# to manually update this file. - -for p in __path__: - filenames = glob.glob (os.path.join (p, "..", "blksimpl", "*.py")) - for f in filenames: - f = os.path.basename(f).lower() - f = f[:-3] - if f == '__init__': - continue - # print f - exec "from gnuradio.blksimpl.%s import *" % (f,) diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/Makefile.am b/gnuradio-core/src/python/gnuradio/blksimpl/Makefile.am deleted file mode 100644 index 74fa098d..00000000 --- a/gnuradio-core/src/python/gnuradio/blksimpl/Makefile.am +++ /dev/null @@ -1,59 +0,0 @@ -# -# 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 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. -# - -include $(top_srcdir)/Makefile.common - -# EXTRA_DIST = run_tests.in -# TESTS = run_tests - -grblkspythondir = $(grpythondir)/blksimpl - -grblkspython_PYTHON = \ - __init__.py \ - am_demod.py \ - channel_model.py \ - dbpsk.py \ - dqpsk.py \ - d8psk.py \ - filterbank.py \ - fm_demod.py \ - fm_emph.py \ - gmsk.py \ - cpm.py \ - nbfm_rx.py \ - nbfm_tx.py \ - pkt.py \ - psk.py \ - qam.py \ - qam8.py \ - qam16.py \ - qam64.py \ - qam256.py \ - rational_resampler.py \ - standard_squelch.py \ - wfm_rcv.py \ - wfm_rcv_pll.py \ - wfm_tx.py - - -noinst_PYTHON = - -CLEANFILES = *.pyc *.pyo diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/__init__.py b/gnuradio-core/src/python/gnuradio/blksimpl/__init__.py deleted file mode 100644 index a4917cf6..00000000 --- a/gnuradio-core/src/python/gnuradio/blksimpl/__init__.py +++ /dev/null @@ -1 +0,0 @@ -# make this a package diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/am_demod.py b/gnuradio-core/src/python/gnuradio/blksimpl/am_demod.py deleted file mode 100644 index d449d74f..00000000 --- a/gnuradio-core/src/python/gnuradio/blksimpl/am_demod.py +++ /dev/null @@ -1,75 +0,0 @@ -# -# Copyright 2006 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 import gr, optfir - -class am_demod_cf(gr.hier_block): - """ - Generalized AM demodulation block with audio filtering. - - This block demodulates a band-limited, complex down-converted AM - channel into the the original baseband signal, applying low pass - filtering to the audio output. It produces a float stream in the - range [-1.0, +1.0]. - - @param fg: flowgraph - @param channel_rate: incoming sample rate of the AM baseband - @type sample_rate: integer - @param audio_decim: input to output decimation rate - @type audio_decim: integer - @param audio_pass: audio low pass filter passband frequency - @type audio_pass: float - @param audio_stop: audio low pass filter stop frequency - @type audio_stop: float - """ - def __init__(self, fg, channel_rate, audio_decim, audio_pass, audio_stop): - MAG = gr.complex_to_mag() - DCR = gr.add_const_ff(-1.0) - - audio_taps = optfir.low_pass(0.5, # Filter gain - channel_rate, # Sample rate - audio_pass, # Audio passband - audio_stop, # Audio stopband - 0.1, # Passband ripple - 60) # Stopband attenuation - LPF = gr.fir_filter_fff(audio_decim, audio_taps) - - fg.connect(MAG, DCR, LPF) - gr.hier_block.__init__(self, fg, MAG, LPF) - -class demod_10k0a3e_cf(am_demod_cf): - """ - AM demodulation block, 10 KHz channel. - - This block demodulates an AM channel conformant to 10K0A3E emission - standards, such as broadcast band AM transmissions. - - @param fg: flowgraph - @param channel_rate: incoming sample rate of the AM baseband - @type sample_rate: integer - @param audio_decim: input to output decimation rate - @type audio_decim: integer - """ - def __init__(self, fg, channel_rate, audio_decim): - am_demod_cf.__init__(self, fg, channel_rate, audio_decim, - 5000, # Audio passband - 5500) # Audio stopband - \ No newline at end of file diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/channel_model.py b/gnuradio-core/src/python/gnuradio/blksimpl/channel_model.py deleted file mode 100644 index 21980a22..00000000 --- a/gnuradio-core/src/python/gnuradio/blksimpl/channel_model.py +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 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 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 import gr - -class channel_model(gr.hier_block): - def __init__(self, fg, noise_voltage=0.0, frequency_offset=0.0, epsilon=1.0, taps=[1.0,0.0]): - ''' Creates a channel model that includes: - - AWGN noise power in terms of noise voltage - - A frequency offest in the channel in ratio - - A timing offset ratio to model clock difference (epsilon) - - Multipath taps - ''' - - print epsilon - self.timing_offset = gr.fractional_interpolator_cc(0, epsilon) - - self.multipath = gr.fir_filter_ccc(1, taps) - - self.noise_adder = gr.add_cc() - self.noise = gr.noise_source_c(gr.GR_GAUSSIAN,noise_voltage) - self.freq_offset = gr.sig_source_c(1, gr.GR_SIN_WAVE, frequency_offset, 1.0, 0.0) - self.mixer_offset = gr.multiply_cc() - - fg.connect(self.timing_offset, self.multipath) - fg.connect(self.multipath, (self.mixer_offset,0)) - fg.connect(self.freq_offset,(self.mixer_offset,1)) - fg.connect(self.mixer_offset, (self.noise_adder,1)) - fg.connect(self.noise, (self.noise_adder,0)) - - gr.hier_block.__init__(self, fg, self.timing_offset, self.noise_adder) - - def set_noise_voltage(noise_voltage): - self.noise.set_amplitude(noise_voltage) - - def set_frequency_offset(frequency_offset): - self.freq_offset.set_frequency(frequency_offset) - - def set_taps(taps): - self.multipath.set_taps(taps) diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/cpm.py b/gnuradio-core/src/python/gnuradio/blksimpl/cpm.py deleted file mode 100644 index dc9526e9..00000000 --- a/gnuradio-core/src/python/gnuradio/blksimpl/cpm.py +++ /dev/null @@ -1,249 +0,0 @@ -# -# CPM modulation and demodulation. -# -# -# Copyright 2005,2006,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 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. -# - -# See gnuradio-examples/python/digital for examples - -from gnuradio import gr -from gnuradio import modulation_utils -from math import pi -import numpy -from pprint import pprint -import inspect - -# default values (used in __init__ and add_options) -_def_samples_per_symbol = 2 -_def_bits_per_symbol = 1 -_def_h_numerator = 1 -_def_h_denominator = 2 -_def_cpm_type = 0 # 0=CPFSK, 1=GMSK, 2=RC, 3=GENERAL -_def_bt = 0.35 -_def_symbols_per_pulse = 1 -_def_generic_taps = numpy.empty(1) -_def_verbose = False -_def_log = False - - -# ///////////////////////////////////////////////////////////////////////////// -# CPM modulator -# ///////////////////////////////////////////////////////////////////////////// - -class cpm_mod(gr.hier_block): - def __init__(self, fg, - samples_per_symbol=_def_samples_per_symbol, - bits_per_symbol=_def_bits_per_symbol, - h_numerator=_def_h_numerator, - h_denominator=_def_h_denominator, - cpm_type=_def_cpm_type, - bt=_def_bt, - symbols_per_pulse=_def_symbols_per_pulse, - generic_taps=_def_generic_taps, - verbose=_def_verbose, - log=_def_log): - """ - Hierarchical block for Continuous Phase - modulation. - - The input is a byte stream (unsigned char) - representing packed bits and the - output is the complex modulated signal at baseband. - - See Proakis for definition of generic CPM signals: - s(t)=exp(j phi(t)) - phi(t)= 2 pi h int_0^t f(t') dt' - f(t)=sum_k a_k g(t-kT) - (normalizing assumption: int_0^infty g(t) dt = 1/2) - - @param fg: flow graph - @type fg: flow graph - @param samples_per_symbol: samples per baud >= 2 - @type samples_per_symbol: integer - @param bits_per_symbol: bits per symbol - @type bits_per_symbol: integer - @param h_numerator: numerator of modulation index - @type h_numerator: integer - @param h_denominator: denominator of modulation index (numerator and denominator must be relative primes) - @type h_denominator: integer - @param cpm_type: supported types are: 0=CPFSK, 1=GMSK, 2=RC, 3=GENERAL - @type cpm_type: integer - @param bt: bandwidth symbol time product for GMSK - @type bt: float - @param symbols_per_pulse: shaping pulse duration in symbols - @type symbols_per_pulse: integer - @param generic_taps: define a generic CPM pulse shape (sum = samples_per_symbol/2) - @type generic_taps: array of floats - - @param verbose: Print information about modulator? - @type verbose: bool - @param debug: Print modulation data to files? - @type debug: bool - """ - - self._fg = fg - self._samples_per_symbol = samples_per_symbol - self._bits_per_symbol = bits_per_symbol - self._h_numerator = h_numerator - self._h_denominator = h_denominator - self._cpm_type = cpm_type - self._bt=bt - if cpm_type == 0 or cpm_type == 2 or cpm_type == 3: # CPFSK, RC, Generic - self._symbols_per_pulse = symbols_per_pulse - elif cpm_type == 1: # GMSK - self._symbols_per_pulse = 4 - else: - raise TypeError, ("cpm_type must be an integer in {0,1,2,3}, is %r" % (cpm_type,)) - - self._generic_taps=numpy.array(generic_taps) - - if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2: - raise TypeError, ("samples_per_symbol must be an integer >= 2, is %r" % (samples_per_symbol,)) - - self.nsymbols = 2**bits_per_symbol - self.sym_alphabet=numpy.arange(-(self.nsymbols-1),self.nsymbols,2) - - - self.ntaps = self._symbols_per_pulse * samples_per_symbol - sensitivity = 2 * pi * h_numerator / h_denominator / samples_per_symbol - - # Unpack Bytes into bits_per_symbol groups - self.B2s = gr.packed_to_unpacked_bb(bits_per_symbol,gr.GR_MSB_FIRST) - - - # Turn it into symmetric PAM data. - self.pam = gr.chunks_to_symbols_bf(self.sym_alphabet,1) - - # Generate pulse (sum of taps = samples_per_symbol/2) - if cpm_type == 0: # CPFSK - self.taps= (1.0/self._symbols_per_pulse/2,) * self.ntaps - elif cpm_type == 1: # GMSK - gaussian_taps = gr.firdes.gaussian( - 1.0/2, # gain - samples_per_symbol, # symbol_rate - bt, # bandwidth * symbol time - self.ntaps # number of taps - ) - sqwave = (1,) * samples_per_symbol # rectangular window - self.taps = numpy.convolve(numpy.array(gaussian_taps),numpy.array(sqwave)) - elif cpm_type == 2: # Raised Cosine - # generalize it for arbitrary roll-off factor - self.taps = (1-numpy.cos(2*pi*numpy.arange(0,self.ntaps)/samples_per_symbol/self._symbols_per_pulse))/(2*self._symbols_per_pulse) - elif cpm_type == 3: # Generic CPM - self.taps = generic_taps - else: - raise TypeError, ("cpm_type must be an integer in {0,1,2,3}, is %r" % (cpm_type,)) - - self.filter = gr.interp_fir_filter_fff(samples_per_symbol, self.taps) - - # FM modulation - self.fmmod = gr.frequency_modulator_fc(sensitivity) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect & Initialize base class - self._fg.connect(self.B2s, self.pam, self.filter, self.fmmod) - gr.hier_block.__init__(self, self._fg, self.B2s, self.fmmod) - - #def samples_per_symbol(self): - #return self._samples_per_symbol - - #def bits_per_symbol(self): - #return self._bits_per_symbol - - #def h_numerator(self): - #return self._h_numerator - - #def h_denominator(self): - #return self._h_denominator - - #def cpm_type(self): - #return self._cpm_type - - #def bt(self): - #return self._bt - - #def symbols_per_pulse(self): - #return self._symbols_per_pulse - - - def _print_verbage(self): - print "Samples per symbol = %d" % self._samples_per_symbol - print "Bits per symbol = %d" % self._bits_per_symbol - print "h = " , self._h_numerator , " / " , self._h_denominator - print "Symbol alphabet = " , self.sym_alphabet - print "Symbols per pulse = %d" % self._symbols_per_pulse - print "taps = " , self.taps - - print "CPM type = %d" % self._cpm_type - if self._cpm_type == 1: - print "Gaussian filter BT = %.2f" % self._bt - - - def _setup_logging(self): - print "Modulation logging turned on." - self._fg.connect(self.B2s, - gr.file_sink(gr.sizeof_float, "symbols.dat")) - self._fg.connect(self.pam, - gr.file_sink(gr.sizeof_float, "pam.dat")) - self._fg.connect(self.filter, - gr.file_sink(gr.sizeof_float, "filter.dat")) - self._fg.connect(self.fmmod, - gr.file_sink(gr.sizeof_gr_complex, "fmmod.dat")) - - - def add_options(parser): - """ - Adds CPM modulation-specific options to the standard parser - """ - parser.add_option("", "--bt", type="float", default=_def_bt, - help="set bandwidth-time product [default=%default] (GMSK)") - add_options=staticmethod(add_options) - - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils.extract_kwargs_from_options(cpm_mod.__init__, - ('self', 'fg'), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - - -# ///////////////////////////////////////////////////////////////////////////// -# CPM demodulator -# ///////////////////////////////////////////////////////////////////////////// -# -# Not yet implemented -# - - - -# -# Add these to the mod/demod registry -# -modulation_utils.add_type_1_mod('cpm', cpm_mod) -#modulation_utils.add_type_1_demod('cpm', cpm_demod) diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/d8psk.py b/gnuradio-core/src/python/gnuradio/blksimpl/d8psk.py deleted file mode 100644 index b7451d47..00000000 --- a/gnuradio-core/src/python/gnuradio/blksimpl/d8psk.py +++ /dev/null @@ -1,363 +0,0 @@ -# -# Copyright 2005,2006,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 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. -# - -# See gnuradio-examples/python/digital for examples - -""" -differential 8PSK modulation and demodulation. -""" - -from gnuradio import gr, gru, modulation_utils -from math import pi, sqrt -import psk -import cmath -from pprint import pprint - -# default values (used in __init__ and add_options) -_def_samples_per_symbol = 3 -_def_excess_bw = 0.35 -_def_gray_code = True -_def_verbose = False -_def_log = False - -_def_costas_alpha = 0.175 -_def_gain_mu = 0.175 -_def_mu = 0.5 -_def_omega_relative_limit = 0.005 - - -# ///////////////////////////////////////////////////////////////////////////// -# D8PSK modulator -# ///////////////////////////////////////////////////////////////////////////// - -class d8psk_mod(gr.hier_block): - - def __init__(self, fg, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - """ - Hierarchical block for RRC-filtered QPSK modulation. - - The input is a byte stream (unsigned char) and the - output is the complex modulated signal at baseband. - - @param fg: flow graph - @type fg: flow graph - @param samples_per_symbol: samples per symbol >= 2 - @type samples_per_symbol: integer - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param debug: Print modualtion data to files? - @type debug: bool - """ - - self._fg = fg - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._gray_code = gray_code - - if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2: - raise TypeError, ("sbp must be an integer >= 2, is %d" % samples_per_symbol) - - ntaps = 11 * samples_per_symbol - - arity = pow(2,self.bits_per_symbol()) - - # turn bytes into k-bit vectors - self.bytes2chunks = \ - gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(psk.binary_to_gray[arity]) - else: - self.symbol_mapper = gr.map_bb(psk.binary_to_ungray[arity]) - - self.diffenc = gr.diff_encoder_bb(arity) - - rot = 1 - rotated_const = map(lambda pt: pt * rot, psk.constellation[arity]) - self.chunks2symbols = gr.chunks_to_symbols_bc(rotated_const) - - # pulse shaping filter - self.rrc_taps = gr.firdes.root_raised_cosine( - self._samples_per_symbol, # gain (sps since we're interpolating by sps) - self._samples_per_symbol, # sampling rate - 1.0, # symbol rate - self._excess_bw, # excess bandwidth (roll-off factor) - ntaps) - - self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol, self.rrc_taps) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect & Initialize base class - self._fg.connect(self.bytes2chunks, self.symbol_mapper, self.diffenc, - self.chunks2symbols, self.rrc_filter) - gr.hier_block.__init__(self, self._fg, self.bytes2chunks, self.rrc_filter) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 3 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def _print_verbage(self): - print "bits per symbol = %d" % self.bits_per_symbol() - print "Gray code = %s" % self._gray_code - print "RS roll-off factor = %f" % self._excess_bw - - def _setup_logging(self): - print "Modulation logging turned on." - self._fg.connect(self.bytes2chunks, - gr.file_sink(gr.sizeof_char, "tx_bytes2chunks.dat")) - self._fg.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "tx_graycoder.dat")) - self._fg.connect(self.diffenc, - gr.file_sink(gr.sizeof_char, "tx_diffenc.dat")) - self._fg.connect(self.chunks2symbols, - gr.file_sink(gr.sizeof_gr_complex, "tx_chunks2symbols.dat")) - self._fg.connect(self.rrc_filter, - gr.file_sink(gr.sizeof_gr_complex, "tx_rrc_filter.dat")) - - def add_options(parser): - """ - Adds 8PSK modulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default] (PSK)") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=_def_gray_code, - help="disable gray coding on modulated bits (PSK)") - add_options=staticmethod(add_options) - - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils.extract_kwargs_from_options(d8psk_mod.__init__, - ('self', 'fg'), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - -# ///////////////////////////////////////////////////////////////////////////// -# D8PSK demodulator -# -# Differentially coherent detection of differentially encoded 8psk -# ///////////////////////////////////////////////////////////////////////////// - -class d8psk_demod(gr.hier_block): - - def __init__(self, fg, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - costas_alpha=_def_costas_alpha, - gain_mu=_def_gain_mu, - mu=_def_mu, - omega_relative_limit=_def_omega_relative_limit, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - """ - Hierarchical block for RRC-filtered DQPSK demodulation - - The input is the complex modulated signal at baseband. - The output is a stream of bits packed 1 bit per byte (LSB) - - @param fg: flow graph - @type fg: flow graph - @param samples_per_symbol: samples per symbol >= 2 - @type samples_per_symbol: float - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param costas_alpha: loop filter gain - @type costas_alphas: float - @param gain_mu: for M&M block - @type gain_mu: float - @param mu: for M&M block - @type mu: float - @param omega_relative_limit: for M&M block - @type omega_relative_limit: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param debug: Print modualtion data to files? - @type debug: bool - """ - - self._fg = fg - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._costas_alpha = costas_alpha - self._mm_gain_mu = gain_mu - self._mm_mu = mu - self._mm_omega_relative_limit = omega_relative_limit - self._gray_code = gray_code - - if samples_per_symbol < 2: - raise TypeError, "sbp must be >= 2, is %d" % samples_per_symbol - - arity = pow(2,self.bits_per_symbol()) - - # Automatic gain control - scale = (1.0/16384.0) - self.pre_scaler = gr.multiply_const_cc(scale) # scale the signal from full-range to +-1 - #self.agc = gr.agc_cc(1e-2, 1, 1, 100) - self.agc = gr.agc2_cc(1e-1, 1e-2, 1, 1, 100) - #self.agc = gr.feedforward_agc_cc(16, 1.0) - - # RRC data filter - ntaps = 11 * samples_per_symbol - self.rrc_taps = gr.firdes.root_raised_cosine( - 1.0, # gain - self._samples_per_symbol, # sampling rate - 1.0, # symbol rate - self._excess_bw, # excess bandwidth (roll-off factor) - ntaps) - self.rrc_filter=gr.interp_fir_filter_ccf(1, self.rrc_taps) - - # symbol clock recovery - self._mm_omega = self._samples_per_symbol - self._mm_gain_omega = .25 * self._mm_gain_mu * self._mm_gain_mu - self._costas_beta = 0.25 * self._costas_alpha * self._costas_alpha - fmin = -0.025 - fmax = 0.025 - - self.receiver=gr.mpsk_receiver_cc(arity, 0, - self._costas_alpha, self._costas_beta, - fmin, fmax, - self._mm_mu, self._mm_gain_mu, - self._mm_omega, self._mm_gain_omega, - self._mm_omega_relative_limit) - - # Perform Differential decoding on the constellation - self.diffdec = gr.diff_phasor_cc() - - # find closest constellation point - rot = 1 - rotated_const = map(lambda pt: pt * rot, psk.constellation[arity]) - self.slicer = gr.constellation_decoder_cb(rotated_const, range(arity)) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(psk.gray_to_binary[arity]) - else: - self.symbol_mapper = gr.map_bb(psk.ungray_to_binary[arity]) - - - # unpack the k bit vector into a stream of bits - self.unpack = gr.unpack_k_bits_bb(self.bits_per_symbol()) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect & Initialize base class - self._fg.connect(self.pre_scaler, self.agc, self.rrc_filter, self.receiver, - self.diffdec, self.slicer, self.symbol_mapper, self.unpack) - gr.hier_block.__init__(self, self._fg, self.pre_scaler, self.unpack) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 3 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def _print_verbage(self): - print "\nDemodulator:" - print "bits per symbol: %d" % self.bits_per_symbol() - print "Gray code: %s" % self._gray_code - print "RRC roll-off factor: %.2f" % self._excess_bw - print "Costas Loop alpha: %.2e" % self._costas_alpha - print "Costas Loop beta: %.2e" % self._costas_beta - print "M&M mu: %.2f" % self._mm_mu - print "M&M mu gain: %.2e" % self._mm_gain_mu - print "M&M omega: %.2f" % self._mm_omega - print "M&M omega gain: %.2e" % self._mm_gain_omega - print "M&M omega limit: %.2f" % self._mm_omega_relative_limit - - - def _setup_logging(self): - print "Modulation logging turned on." - self._fg.connect(self.pre_scaler, - gr.file_sink(gr.sizeof_gr_complex, "rx_prescaler.dat")) - self._fg.connect(self.agc, - gr.file_sink(gr.sizeof_gr_complex, "rx_agc.dat")) - self._fg.connect(self.rrc_filter, - gr.file_sink(gr.sizeof_gr_complex, "rx_rrc_filter.dat")) - self._fg.connect(self.receiver, - gr.file_sink(gr.sizeof_gr_complex, "rx_receiver.dat")) - self._fg.connect(self.diffdec, - gr.file_sink(gr.sizeof_gr_complex, "rx_diffdec.dat")) - self._fg.connect(self.slicer, - gr.file_sink(gr.sizeof_char, "rx_slicer.dat")) - self._fg.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "rx_gray_decoder.dat")) - self._fg.connect(self.unpack, - gr.file_sink(gr.sizeof_char, "rx_unpack.dat")) - - def add_options(parser): - """ - Adds modulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default] (PSK)") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=_def_gray_code, - help="disable gray coding on modulated bits (PSK)") - parser.add_option("", "--costas-alpha", type="float", default=_def_costas_alpha, - help="set Costas loop alpha value [default=%default] (PSK)") - parser.add_option("", "--gain-mu", type="float", default=_def_gain_mu, - help="set M&M symbol sync loop gain mu value [default=%default] (PSK)") - parser.add_option("", "--mu", type="float", default=_def_mu, - help="set M&M symbol sync loop mu value [default=%default] (PSK)") - add_options=staticmethod(add_options) - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils.extract_kwargs_from_options( - d8psk_demod.__init__, ('self', 'fg'), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - -# -# Add these to the mod/demod registry -# -# NOT READY TO BE USED YET -- ENABLE AT YOUR OWN RISK -#modulation_utils.add_type_1_mod('d8psk', d8psk_mod) -#modulation_utils.add_type_1_demod('d8psk', d8psk_demod) diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/dbpsk.py b/gnuradio-core/src/python/gnuradio/blksimpl/dbpsk.py deleted file mode 100644 index 635ad1db..00000000 --- a/gnuradio-core/src/python/gnuradio/blksimpl/dbpsk.py +++ /dev/null @@ -1,364 +0,0 @@ -# -# Copyright 2005,2006 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. -# - -# See gnuradio-examples/python/digital for examples - -""" -differential BPSK modulation and demodulation. -""" - -from gnuradio import gr, gru, modulation_utils -from math import pi, sqrt -import psk -import cmath -from pprint import pprint - -# default values (used in __init__ and add_options) -_def_samples_per_symbol = 2 -_def_excess_bw = 0.35 -_def_gray_code = True -_def_verbose = False -_def_log = False - -_def_costas_alpha = 0.1 -_def_gain_mu = None -_def_mu = 0.5 -_def_omega_relative_limit = 0.005 - - -# ///////////////////////////////////////////////////////////////////////////// -# DBPSK modulator -# ///////////////////////////////////////////////////////////////////////////// - -class dbpsk_mod(gr.hier_block): - - def __init__(self, fg, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - """ - Hierarchical block for RRC-filtered differential BPSK modulation. - - The input is a byte stream (unsigned char) and the - output is the complex modulated signal at baseband. - - @param fg: flow graph - @type fg: flow graph - @param samples_per_symbol: samples per baud >= 2 - @type samples_per_symbol: integer - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param log: Log modulation data to files? - @type log: bool - """ - - self._fg = fg - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._gray_code = gray_code - - if not isinstance(self._samples_per_symbol, int) or self._samples_per_symbol < 2: - raise TypeError, ("sbp must be an integer >= 2, is %d" % self._samples_per_symbol) - - ntaps = 11 * self._samples_per_symbol - - arity = pow(2,self.bits_per_symbol()) - - # turn bytes into k-bit vectors - self.bytes2chunks = \ - gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(psk.binary_to_gray[arity]) - else: - self.symbol_mapper = gr.map_bb(psk.binary_to_ungray[arity]) - - self.diffenc = gr.diff_encoder_bb(arity) - - self.chunks2symbols = gr.chunks_to_symbols_bc(psk.constellation[arity]) - - # pulse shaping filter - self.rrc_taps = gr.firdes.root_raised_cosine( - self._samples_per_symbol, # gain (samples_per_symbol since we're - # interpolating by samples_per_symbol) - self._samples_per_symbol, # sampling rate - 1.0, # symbol rate - self._excess_bw, # excess bandwidth (roll-off factor) - ntaps) - self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol, - self.rrc_taps) - - # Connect - fg.connect(self.bytes2chunks, self.symbol_mapper, self.diffenc, - self.chunks2symbols, self.rrc_filter) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Initialize base class - gr.hier_block.__init__(self, self._fg, self.bytes2chunks, self.rrc_filter) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # static method that's also callable on an instance - return 1 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def add_options(parser): - """ - Adds DBPSK modulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default]") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=True, - help="disable gray coding on modulated bits (PSK)") - add_options=staticmethod(add_options) - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils.extract_kwargs_from_options(dbpsk_mod.__init__, - ('self', 'fg'), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - - def _print_verbage(self): - print "\nModulator:" - print "bits per symbol: %d" % self.bits_per_symbol() - print "Gray code: %s" % self._gray_code - print "RRC roll-off factor: %.2f" % self._excess_bw - - def _setup_logging(self): - print "Modulation logging turned on." - self._fg.connect(self.bytes2chunks, - gr.file_sink(gr.sizeof_char, "tx_bytes2chunks.dat")) - self._fg.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "tx_graycoder.dat")) - self._fg.connect(self.diffenc, - gr.file_sink(gr.sizeof_char, "tx_diffenc.dat")) - self._fg.connect(self.chunks2symbols, - gr.file_sink(gr.sizeof_gr_complex, "tx_chunks2symbols.dat")) - self._fg.connect(self.rrc_filter, - gr.file_sink(gr.sizeof_gr_complex, "tx_rrc_filter.dat")) - - -# ///////////////////////////////////////////////////////////////////////////// -# DBPSK demodulator -# -# Differentially coherent detection of differentially encoded BPSK -# ///////////////////////////////////////////////////////////////////////////// - -class dbpsk_demod(gr.hier_block): - - def __init__(self, fg, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - costas_alpha=_def_costas_alpha, - gain_mu=_def_gain_mu, - mu=_def_mu, - omega_relative_limit=_def_omega_relative_limit, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - """ - Hierarchical block for RRC-filtered differential BPSK demodulation - - The input is the complex modulated signal at baseband. - The output is a stream of bits packed 1 bit per byte (LSB) - - @param fg: flow graph - @type fg: flow graph - @param samples_per_symbol: samples per symbol >= 2 - @type samples_per_symbol: float - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param costas_alpha: loop filter gain - @type costas_alphas: float - @param gain_mu: for M&M block - @type gain_mu: float - @param mu: for M&M block - @type mu: float - @param omega_relative_limit: for M&M block - @type omega_relative_limit: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param debug: Print modualtion data to files? - @type debug: bool - """ - - self._fg = fg - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._costas_alpha = costas_alpha - self._mm_gain_mu = gain_mu - self._mm_mu = mu - self._mm_omega_relative_limit = omega_relative_limit - self._gray_code = gray_code - - if samples_per_symbol < 2: - raise TypeError, "samples_per_symbol must be >= 2, is %r" % (samples_per_symbol,) - - arity = pow(2,self.bits_per_symbol()) - - # Automatic gain control - scale = (1.0/16384.0) - self.pre_scaler = gr.multiply_const_cc(scale) # scale the signal from full-range to +-1 - #self.agc = gr.agc2_cc(0.6e-1, 1e-3, 1, 1, 100) - self.agc = gr.feedforward_agc_cc(16, 2.0) - - # RRC data filter - ntaps = 11 * samples_per_symbol - self.rrc_taps = gr.firdes.root_raised_cosine( - 1.0, # gain - self._samples_per_symbol, # sampling rate - 1.0, # symbol rate - self._excess_bw, # excess bandwidth (roll-off factor) - ntaps) - self.rrc_filter=gr.interp_fir_filter_ccf(1, self.rrc_taps) - - # symbol clock recovery - if not self._mm_gain_mu: - self._mm_gain_mu = 0.1 - - self._mm_omega = self._samples_per_symbol - self._mm_gain_omega = .25 * self._mm_gain_mu * self._mm_gain_mu - self._costas_beta = 0.25 * self._costas_alpha * self._costas_alpha - fmin = -0.025 - fmax = 0.025 - - self.receiver=gr.mpsk_receiver_cc(arity, 0, - self._costas_alpha, self._costas_beta, - fmin, fmax, - self._mm_mu, self._mm_gain_mu, - self._mm_omega, self._mm_gain_omega, - self._mm_omega_relative_limit) - - # Do differential decoding based on phase change of symbols - self.diffdec = gr.diff_phasor_cc() - - # find closest constellation point - rot = 1 - rotated_const = map(lambda pt: pt * rot, psk.constellation[arity]) - self.slicer = gr.constellation_decoder_cb(rotated_const, range(arity)) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(psk.gray_to_binary[arity]) - else: - self.symbol_mapper = gr.map_bb(psk.ungray_to_binary[arity]) - - # unpack the k bit vector into a stream of bits - self.unpack = gr.unpack_k_bits_bb(self.bits_per_symbol()) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect and Initialize base class - self._fg.connect(self.pre_scaler, self.agc, self.rrc_filter, self.receiver, - self.diffdec, self.slicer, self.symbol_mapper, self.unpack) - gr.hier_block.__init__(self, self._fg, self.pre_scaler, self.unpack) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 1 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def _print_verbage(self): - print "\nDemodulator:" - print "bits per symbol: %d" % self.bits_per_symbol() - print "Gray code: %s" % self._gray_code - print "RRC roll-off factor: %.2f" % self._excess_bw - print "Costas Loop alpha: %.2e" % self._costas_alpha - print "Costas Loop beta: %.2e" % self._costas_beta - print "M&M mu: %.2f" % self._mm_mu - print "M&M mu gain: %.2e" % self._mm_gain_mu - print "M&M omega: %.2f" % self._mm_omega - print "M&M omega gain: %.2e" % self._mm_gain_omega - print "M&M omega limit: %.2f" % self._mm_omega_relative_limit - - def _setup_logging(self): - print "Modulation logging turned on." - self._fg.connect(self.pre_scaler, - gr.file_sink(gr.sizeof_gr_complex, "rx_prescaler.dat")) - self._fg.connect(self.agc, - gr.file_sink(gr.sizeof_gr_complex, "rx_agc.dat")) - self._fg.connect(self.rrc_filter, - gr.file_sink(gr.sizeof_gr_complex, "rx_rrc_filter.dat")) - self._fg.connect(self.receiver, - gr.file_sink(gr.sizeof_gr_complex, "rx_receiver.dat")) - self._fg.connect(self.diffdec, - gr.file_sink(gr.sizeof_gr_complex, "rx_diffdec.dat")) - self._fg.connect(self.slicer, - gr.file_sink(gr.sizeof_char, "rx_slicer.dat")) - self._fg.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "rx_symbol_mapper.dat")) - self._fg.connect(self.unpack, - gr.file_sink(gr.sizeof_char, "rx_unpack.dat")) - - def add_options(parser): - """ - Adds DBPSK demodulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default] (PSK)") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=_def_gray_code, - help="disable gray coding on modulated bits (PSK)") - parser.add_option("", "--costas-alpha", type="float", default=None, - help="set Costas loop alpha value [default=%default] (PSK)") - parser.add_option("", "--gain-mu", type="float", default=_def_gain_mu, - help="set M&M symbol sync loop gain mu value [default=%default] (GMSK/PSK)") - parser.add_option("", "--mu", type="float", default=_def_mu, - help="set M&M symbol sync loop mu value [default=%default] (GMSK/PSK)") - parser.add_option("", "--omega-relative-limit", type="float", default=_def_omega_relative_limit, - help="M&M clock recovery omega relative limit [default=%default] (GMSK/PSK)") - add_options=staticmethod(add_options) - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils.extract_kwargs_from_options( - dbpsk_demod.__init__, ('self', 'fg'), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) -# -# Add these to the mod/demod registry -# -modulation_utils.add_type_1_mod('dbpsk', dbpsk_mod) -modulation_utils.add_type_1_demod('dbpsk', dbpsk_demod) diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/digital_voice.py.real b/gnuradio-core/src/python/gnuradio/blksimpl/digital_voice.py.real deleted file mode 100644 index 6ec66825..00000000 --- a/gnuradio-core/src/python/gnuradio/blksimpl/digital_voice.py.real +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/env python -# -# 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 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. -# - -""" -Digital voice Tx and Rx using GSM 13kbit vocoder and GMSK. - -Runs channel at 32kbit/sec. Currently uses fake channel coding, -but there's room for a rate 1/2 coder. -""" - -from gnuradio import gr, gru -from gnuradio.blksimpl.gmsk import gmsk_mod, gmsk_demod - -from gnuradio.vocoder import gsm_full_rate - -# Size of gsm full rate speech encoder output packet in bytes - -GSM_FRAME_SIZE = 33 - -# Size of packet in bytes that we send to GMSK modulator: -# -# Target: 256kS/sec air rate. -# -# 256kS 1 sym 1 bit 1 byte 0.020 sec 80 bytes -# ---- * ----- * ----- * ------ * --------- = -------- -# sec 8 S 1 sym 8 bits frame frame -# -# gr_simple_framer add 10 bytes of overhead. - -AIR_FRAME_SIZE = 70 - - -class digital_voice_tx(gr.hier_block): - """ - Hierarchical block for digital voice tranmission. - - The input is 8kS/sec floating point audio in the range [-1,+1] - The output is 256kS/sec GMSK modulated complex baseband signal in the range [-1,+1]. - """ - def __init__(self, fg): - samples_per_symbol = 8 - symbol_rate = 32000 - bt = 0.3 # Gaussian filter bandwidth * symbol time - - src_scale = gr.multiply_const_ff(32767) - f2s = gr.float_to_short() - voice_coder = gsm_full_rate.encode_sp() - - channel_coder = gr.fake_channel_encoder_pp(GSM_FRAME_SIZE, AIR_FRAME_SIZE) - p2s = gr.parallel_to_serial(gr.sizeof_char, AIR_FRAME_SIZE) - - mod = gmsk_mod(fg, sps=samples_per_symbol, - symbol_rate=symbol_rate, bt=bt, - p_size=AIR_FRAME_SIZE) - - fg.connect(src_scale, f2s, voice_coder, channel_coder, p2s, mod) - gr.hier_block.__init__(self, fg, src_scale, mod) - - -class digital_voice_rx(gr.hier_block): - """ - Hierarchical block for digital voice reception. - - The input is 256kS/sec GMSK modulated complex baseband signal. - The output is 8kS/sec floating point audio in the range [-1,+1] - """ - def __init__(self, fg): - samples_per_symbol = 8 - symbol_rate = 32000 - - demod = gmsk_demod(fg, sps=samples_per_symbol, - symbol_rate=symbol_rate, - p_size=AIR_FRAME_SIZE) - - s2p = gr.serial_to_parallel(gr.sizeof_char, AIR_FRAME_SIZE) - channel_decoder = gr.fake_channel_decoder_pp(AIR_FRAME_SIZE, GSM_FRAME_SIZE) - - voice_decoder = gsm_full_rate.decode_ps() - s2f = gr.short_to_float () - sink_scale = gr.multiply_const_ff(1.0/32767.) - - fg.connect(demod, s2p, channel_decoder, voice_decoder, s2f, sink_scale) - gr.hier_block.__init__(self, fg, demod, sink_scale) diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/dqpsk.py b/gnuradio-core/src/python/gnuradio/blksimpl/dqpsk.py deleted file mode 100644 index fcf7d8eb..00000000 --- a/gnuradio-core/src/python/gnuradio/blksimpl/dqpsk.py +++ /dev/null @@ -1,363 +0,0 @@ -# -# Copyright 2005,2006 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. -# - -# See gnuradio-examples/python/digital for examples - -""" -differential QPSK modulation and demodulation. -""" - -from gnuradio import gr, gru, modulation_utils -from math import pi, sqrt -import psk -import cmath -from pprint import pprint - -# default values (used in __init__ and add_options) -_def_samples_per_symbol = 2 -_def_excess_bw = 0.35 -_def_gray_code = True -_def_verbose = False -_def_log = False - -_def_costas_alpha = 0.15 -_def_gain_mu = None -_def_mu = 0.5 -_def_omega_relative_limit = 0.005 - - -# ///////////////////////////////////////////////////////////////////////////// -# DQPSK modulator -# ///////////////////////////////////////////////////////////////////////////// - -class dqpsk_mod(gr.hier_block): - - def __init__(self, fg, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - """ - Hierarchical block for RRC-filtered QPSK modulation. - - The input is a byte stream (unsigned char) and the - output is the complex modulated signal at baseband. - - @param fg: flow graph - @type fg: flow graph - @param samples_per_symbol: samples per symbol >= 2 - @type samples_per_symbol: integer - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param debug: Print modualtion data to files? - @type debug: bool - """ - - self._fg = fg - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._gray_code = gray_code - - if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2: - raise TypeError, ("sbp must be an integer >= 2, is %d" % samples_per_symbol) - - ntaps = 11 * samples_per_symbol - - arity = pow(2,self.bits_per_symbol()) - - # turn bytes into k-bit vectors - self.bytes2chunks = \ - gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(psk.binary_to_gray[arity]) - else: - self.symbol_mapper = gr.map_bb(psk.binary_to_ungray[arity]) - - self.diffenc = gr.diff_encoder_bb(arity) - - rot = .707 + .707j - rotated_const = map(lambda pt: pt * rot, psk.constellation[arity]) - self.chunks2symbols = gr.chunks_to_symbols_bc(rotated_const) - - # pulse shaping filter - self.rrc_taps = gr.firdes.root_raised_cosine( - self._samples_per_symbol, # gain (sps since we're interpolating by sps) - self._samples_per_symbol, # sampling rate - 1.0, # symbol rate - self._excess_bw, # excess bandwidth (roll-off factor) - ntaps) - - self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol, self.rrc_taps) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect & Initialize base class - self._fg.connect(self.bytes2chunks, self.symbol_mapper, self.diffenc, - self.chunks2symbols, self.rrc_filter) - gr.hier_block.__init__(self, self._fg, self.bytes2chunks, self.rrc_filter) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 2 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def _print_verbage(self): - print "\nModulator:" - print "bits per symbol: %d" % self.bits_per_symbol() - print "Gray code: %s" % self._gray_code - print "RRS roll-off factor: %f" % self._excess_bw - - def _setup_logging(self): - print "Modulation logging turned on." - self._fg.connect(self.bytes2chunks, - gr.file_sink(gr.sizeof_char, "tx_bytes2chunks.dat")) - self._fg.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "tx_graycoder.dat")) - self._fg.connect(self.diffenc, - gr.file_sink(gr.sizeof_char, "tx_diffenc.dat")) - self._fg.connect(self.chunks2symbols, - gr.file_sink(gr.sizeof_gr_complex, "tx_chunks2symbols.dat")) - self._fg.connect(self.rrc_filter, - gr.file_sink(gr.sizeof_gr_complex, "tx_rrc_filter.dat")) - - def add_options(parser): - """ - Adds QPSK modulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default] (PSK)") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=_def_gray_code, - help="disable gray coding on modulated bits (PSK)") - add_options=staticmethod(add_options) - - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils.extract_kwargs_from_options(dqpsk_mod.__init__, - ('self', 'fg'), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - -# ///////////////////////////////////////////////////////////////////////////// -# DQPSK demodulator -# -# Differentially coherent detection of differentially encoded qpsk -# ///////////////////////////////////////////////////////////////////////////// - -class dqpsk_demod(gr.hier_block): - - def __init__(self, fg, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - costas_alpha=_def_costas_alpha, - gain_mu=_def_gain_mu, - mu=_def_mu, - omega_relative_limit=_def_omega_relative_limit, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - """ - Hierarchical block for RRC-filtered DQPSK demodulation - - The input is the complex modulated signal at baseband. - The output is a stream of bits packed 1 bit per byte (LSB) - - @param fg: flow graph - @type fg: flow graph - @param samples_per_symbol: samples per symbol >= 2 - @type samples_per_symbol: float - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param costas_alpha: loop filter gain - @type costas_alphas: float - @param gain_mu: for M&M block - @type gain_mu: float - @param mu: for M&M block - @type mu: float - @param omega_relative_limit: for M&M block - @type omega_relative_limit: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param debug: Print modualtion data to files? - @type debug: bool - """ - - self._fg = fg - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._costas_alpha = costas_alpha - self._mm_gain_mu = gain_mu - self._mm_mu = mu - self._mm_omega_relative_limit = omega_relative_limit - self._gray_code = gray_code - - if samples_per_symbol < 2: - raise TypeError, "sbp must be >= 2, is %d" % samples_per_symbol - - arity = pow(2,self.bits_per_symbol()) - - # Automatic gain control - scale = (1.0/16384.0) - self.pre_scaler = gr.multiply_const_cc(scale) # scale the signal from full-range to +-1 - #self.agc = gr.agc2_cc(0.6e-1, 1e-3, 1, 1, 100) - self.agc = gr.feedforward_agc_cc(16, 2.0) - - # RRC data filter - ntaps = 11 * samples_per_symbol - self.rrc_taps = gr.firdes.root_raised_cosine( - 1.0, # gain - self._samples_per_symbol, # sampling rate - 1.0, # symbol rate - self._excess_bw, # excess bandwidth (roll-off factor) - ntaps) - self.rrc_filter=gr.interp_fir_filter_ccf(1, self.rrc_taps) - - if not self._mm_gain_mu: - sbs_to_mm = {2: 0.050, 3: 0.075, 4: 0.11, 5: 0.125, 6: 0.15, 7: 0.15} - self._mm_gain_mu = sbs_to_mm[samples_per_symbol] - - self._mm_omega = self._samples_per_symbol - self._mm_gain_omega = .25 * self._mm_gain_mu * self._mm_gain_mu - self._costas_beta = 0.25 * self._costas_alpha * self._costas_alpha - fmin = -0.025 - fmax = 0.025 - - self.receiver=gr.mpsk_receiver_cc(arity, pi/4.0, - self._costas_alpha, self._costas_beta, - fmin, fmax, - self._mm_mu, self._mm_gain_mu, - self._mm_omega, self._mm_gain_omega, - self._mm_omega_relative_limit) - - # Perform Differential decoding on the constellation - self.diffdec = gr.diff_phasor_cc() - - # find closest constellation point - rot = 1 - rotated_const = map(lambda pt: pt * rot, psk.constellation[arity]) - self.slicer = gr.constellation_decoder_cb(rotated_const, range(arity)) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(psk.gray_to_binary[arity]) - else: - self.symbol_mapper = gr.map_bb(psk.ungray_to_binary[arity]) - - # unpack the k bit vector into a stream of bits - self.unpack = gr.unpack_k_bits_bb(self.bits_per_symbol()) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect & Initialize base class - self._fg.connect(self.pre_scaler, self.agc, self.rrc_filter, self.receiver, - self.diffdec, self.slicer, self.symbol_mapper, self.unpack) - gr.hier_block.__init__(self, self._fg, self.pre_scaler, self.unpack) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 2 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def _print_verbage(self): - print "\nDemodulator:" - print "bits per symbol: %d" % self.bits_per_symbol() - print "Gray code: %s" % self._gray_code - print "RRC roll-off factor: %.2f" % self._excess_bw - print "Costas Loop alpha: %.2e" % self._costas_alpha - print "Costas Loop beta: %.2e" % self._costas_beta - print "M&M mu: %.2f" % self._mm_mu - print "M&M mu gain: %.2e" % self._mm_gain_mu - print "M&M omega: %.2f" % self._mm_omega - print "M&M omega gain: %.2e" % self._mm_gain_omega - print "M&M omega limit: %.2f" % self._mm_omega_relative_limit - - def _setup_logging(self): - print "Modulation logging turned on." - self._fg.connect(self.pre_scaler, - gr.file_sink(gr.sizeof_gr_complex, "rx_prescaler.dat")) - self._fg.connect(self.agc, - gr.file_sink(gr.sizeof_gr_complex, "rx_agc.dat")) - self._fg.connect(self.rrc_filter, - gr.file_sink(gr.sizeof_gr_complex, "rx_rrc_filter.dat")) - self._fg.connect(self.receiver, - gr.file_sink(gr.sizeof_gr_complex, "rx_receiver.dat")) - self._fg.connect(self.diffdec, - gr.file_sink(gr.sizeof_gr_complex, "rx_diffdec.dat")) - self._fg.connect(self.slicer, - gr.file_sink(gr.sizeof_char, "rx_slicer.dat")) - self._fg.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "rx_gray_decoder.dat")) - self._fg.connect(self.unpack, - gr.file_sink(gr.sizeof_char, "rx_unpack.dat")) - - def add_options(parser): - """ - Adds modulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default] (PSK)") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=_def_gray_code, - help="disable gray coding on modulated bits (PSK)") - parser.add_option("", "--costas-alpha", type="float", default=_def_costas_alpha, - help="set Costas loop alpha value [default=%default] (PSK)") - parser.add_option("", "--gain-mu", type="float", default=_def_gain_mu, - help="set M&M symbol sync loop gain mu value [default=%default] (PSK)") - parser.add_option("", "--mu", type="float", default=_def_mu, - help="set M&M symbol sync loop mu value [default=%default] (PSK)") - add_options=staticmethod(add_options) - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils.extract_kwargs_from_options( - dqpsk_demod.__init__, ('self', 'fg'), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - -# -# Add these to the mod/demod registry -# -modulation_utils.add_type_1_mod('dqpsk', dqpsk_mod) -modulation_utils.add_type_1_demod('dqpsk', dqpsk_demod) diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/filterbank.py b/gnuradio-core/src/python/gnuradio/blksimpl/filterbank.py deleted file mode 100644 index a7ba2459..00000000 --- a/gnuradio-core/src/python/gnuradio/blksimpl/filterbank.py +++ /dev/null @@ -1,160 +0,0 @@ -# -# 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 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. -# - -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_block): - """ - Uniformly modulated polyphase DFT filter bank: synthesis - - See http://cnx.rice.edu/content/m10424/latest - """ - def __init__(self, fg, 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 - - 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) - - fg.connect(self.ss2v, self.ifft, self.v2ss) - - # build mpoints fir filters... - for i in range(mpoints): - f = gr.fft_filter_ccc(1, sub_taps[i]) - fg.connect((self.v2ss, i), f) - fg.connect(f, (self.ss2s, i)) - - gr.hier_block.__init__(self, fg, self.ss2v, self.ss2s) - - -class analysis_filterbank(gr.hier_block): - """ - Uniformly modulated polyphase DFT filter bank: analysis - - See http://cnx.rice.edu/content/m10424/latest - """ - def __init__(self, fg, 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 - - 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) - - # build mpoints fir filters... - for i in range(mpoints): - f = gr.fft_filter_ccc(1, sub_taps[mpoints-i-1]) - fg.connect((self.s2ss, i), f) - fg.connect(f, (self.ss2v, i)) - - fg.connect(self.ss2v, self.fft, self.v2ss) - gr.hier_block.__init__(self, fg, self.s2ss, self.v2ss) diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/fm_demod.py b/gnuradio-core/src/python/gnuradio/blksimpl/fm_demod.py deleted file mode 100644 index 344d84d9..00000000 --- a/gnuradio-core/src/python/gnuradio/blksimpl/fm_demod.py +++ /dev/null @@ -1,122 +0,0 @@ -# -# Copyright 2006 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 import gr, optfir -from gnuradio.blksimpl.fm_emph import fm_deemph -from math import pi - -class fm_demod_cf(gr.hier_block): - """ - Generalized FM demodulation block with deemphasis and audio - filtering. - - This block demodulates a band-limited, complex down-converted FM - channel into the the original baseband signal, optionally applying - deemphasis. Low pass filtering is done on the resultant signal. It - produces an output float strem in the range of [-1.0, +1.0]. - - @param fg: flowgraph - @param channel_rate: incoming sample rate of the FM baseband - @type sample_rate: integer - @param deviation: maximum FM deviation (default = 5000) - @type deviation: float - @param audio_decim: input to output decimation rate - @type audio_decim: integer - @param audio_pass: audio low pass filter passband frequency - @type audio_pass: float - @param audio_stop: audio low pass filter stop frequency - @type audio_stop: float - @param gain: gain applied to audio output (default = 1.0) - @type gain: float - @param tau: deemphasis time constant (default = 75e-6), specify 'None' - to prevent deemphasis - """ - def __init__(self, fg, channel_rate, audio_decim, deviation, - audio_pass, audio_stop, gain=1.0, tau=75e-6): - - """ - # Equalizer for ~100 us delay - delay = 100e-6 - num_taps = int(channel_rate*delay) - - mu = 1e-4/num_taps - print "CMA: delay =", delay, "n =", num_taps, "mu =", mu - CMA = gr.cma_equalizer_cc(num_taps, 1.0, mu) - """ - k = channel_rate/(2*pi*deviation) - QUAD = gr.quadrature_demod_cf(k) - - audio_taps = optfir.low_pass(gain, # Filter gain - channel_rate, # Sample rate - audio_pass, # Audio passband - audio_stop, # Audio stopband - 0.1, # Passband ripple - 60) # Stopband attenuation - LPF = gr.fir_filter_fff(audio_decim, audio_taps) - - if tau is not None: - DEEMPH = fm_deemph(fg, channel_rate, tau) - fg.connect(QUAD, DEEMPH, LPF) - else: - fg.connect(QUAD, LPF) - - gr.hier_block.__init__(self, fg, QUAD, LPF) - -class demod_20k0f3e_cf(fm_demod_cf): - """ - NBFM demodulation block, 20 KHz channels - - This block demodulates a complex, downconverted, narrowband FM - channel conforming to 20K0F3E emission standards, outputting - floats in the range [-1.0, +1.0]. - - @param fg: flowgraph - @param sample_rate: incoming sample rate of the FM baseband - @type sample_rate: integer - @param audio_decim: input to output decimation rate - @type audio_decim: integer - """ - def __init__(self, fg, channel_rate, audio_decim): - fm_demod_cf.__init__(self, fg, channel_rate, audio_decim, - 5000, # Deviation - 3000, # Audio passband frequency - 4000) # Audio stopband frequency - -class demod_200kf3e_cf(fm_demod_cf): - """ - WFM demodulation block, mono. - - This block demodulates a complex, downconverted, wideband FM - channel conforming to 200KF3E emission standards, outputting - floats in the range [-1.0, +1.0]. - - @param fg: flowgraph - @param sample_rate: incoming sample rate of the FM baseband - @type sample_rate: integer - @param audio_decim: input to output decimation rate - @type audio_decim: integer - """ - def __init__(self, fg, channel_rate, audio_decim): - fm_demod_cf.__init__(self, fg, channel_rate, audio_decim, - 75000, # Deviation - 15000, # Audio passband - 16000, # Audio stopband - 20.0) # Audio gain diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/fm_emph.py b/gnuradio-core/src/python/gnuradio/blksimpl/fm_emph.py deleted file mode 100644 index 473a70af..00000000 --- a/gnuradio-core/src/python/gnuradio/blksimpl/fm_emph.py +++ /dev/null @@ -1,145 +0,0 @@ -# -# 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 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 import gr -import math - - -# -# 1 -# H(s) = ------- -# 1 + s -# -# tau is the RC time constant. -# critical frequency: w_p = 1/tau -# -# We prewarp and use the bilinear z-transform to get our IIR coefficients. -# See "Digital Signal Processing: A Practical Approach" by Ifeachor and Jervis -# - -class fm_deemph(gr.hier_block): - """ - FM Deemphasis IIR filter. - """ - def __init__(self, fg, fs, tau=75e-6): - """ - @param fg: flow graph - @type fg: gr.flow_graph - @param fs: sampling frequency in Hz - @type fs: float - @param tau: Time constant in seconds (75us in US, 50us in EUR) - @type tau: float - """ - w_p = 1/tau - w_pp = math.tan (w_p / (fs * 2)) # prewarped analog freq - - a1 = (w_pp - 1)/(w_pp + 1) - b0 = w_pp/(1 + w_pp) - b1 = b0 - - btaps = [b0, b1] - ataps = [1, a1] - - if 0: - print "btaps =", btaps - print "ataps =", ataps - global plot1 - plot1 = gru.gnuplot_freqz (gru.freqz (btaps, ataps), fs, True) - - deemph = gr.iir_filter_ffd(btaps, ataps) - gr.hier_block.__init__(self, fg, deemph, deemph) - -# -# 1 + s*t1 -# H(s) = ---------- -# 1 + s*t2 -# -# I think this is the right transfer function. -# -# -# This fine ASCII rendition is based on Figure 5-15 -# in "Digital and Analog Communication Systems", Leon W. Couch II -# -# -# R1 -# +-----||------+ -# | | -# o------+ +-----+--------o -# | C1 | | -# +----/\/\/\/--+ \ -# / -# \ R2 -# / -# \ -# | -# o--------------------------+--------o -# -# f1 = 1/(2*pi*t1) = 1/(2*pi*R1*C) -# -# 1 R1 + R2 -# f2 = ------- = ------------ -# 2*pi*t2 2*pi*R1*R2*C -# -# t1 is 75us in US, 50us in EUR -# f2 should be higher than our audio bandwidth. -# -# -# The Bode plot looks like this: -# -# -# /---------------- -# / -# / <-- slope = 20dB/decade -# / -# -------------/ -# f1 f2 -# -# We prewarp and use the bilinear z-transform to get our IIR coefficients. -# See "Digital Signal Processing: A Practical Approach" by Ifeachor and Jervis -# - -class fm_preemph(gr.hier_block): - """ - FM Preemphasis IIR filter. - """ - def __init__(self, fg, fs, tau=75e-6): - """ - @param fg: flow graph - @type fg: gr.flow_graph - @param fs: sampling frequency in Hz - @type fs: float - @param tau: Time constant in seconds (75us in US, 50us in EUR) - @type tau: float - """ - - # FIXME make this compute the right answer - - btaps = [1] - ataps = [1] - - if 0: - print "btaps =", btaps - print "ataps =", ataps - global plot2 - plot2 = gru.gnuplot_freqz (gru.freqz (btaps, ataps), fs, True) - - preemph = gr.iir_filter_ffd(btaps, ataps) - gr.hier_block.__init__(self, fg, preemph, preemph) diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/gmsk.py b/gnuradio-core/src/python/gnuradio/blksimpl/gmsk.py deleted file mode 100644 index 5cc86527..00000000 --- a/gnuradio-core/src/python/gnuradio/blksimpl/gmsk.py +++ /dev/null @@ -1,292 +0,0 @@ -# -# GMSK modulation and demodulation. -# -# -# Copyright 2005,2006 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. -# - -# See gnuradio-examples/python/digital for examples - -from gnuradio import gr -from gnuradio import modulation_utils -from math import pi -import numpy -from pprint import pprint -import inspect - -# default values (used in __init__ and add_options) -_def_samples_per_symbol = 2 -_def_bt = 0.35 -_def_verbose = False -_def_log = False - -_def_gain_mu = None -_def_mu = 0.5 -_def_freq_error = 0.0 -_def_omega_relative_limit = 0.005 - - -# ///////////////////////////////////////////////////////////////////////////// -# GMSK modulator -# ///////////////////////////////////////////////////////////////////////////// - -class gmsk_mod(gr.hier_block): - - def __init__(self, fg, - samples_per_symbol=_def_samples_per_symbol, - bt=_def_bt, - verbose=_def_verbose, - log=_def_log): - """ - Hierarchical block for Gaussian Minimum Shift Key (GMSK) - modulation. - - The input is a byte stream (unsigned char) and the - output is the complex modulated signal at baseband. - - @param fg: flow graph - @type fg: flow graph - @param samples_per_symbol: samples per baud >= 2 - @type samples_per_symbol: integer - @param bt: Gaussian filter bandwidth * symbol time - @type bt: float - @param verbose: Print information about modulator? - @type verbose: bool - @param debug: Print modualtion data to files? - @type debug: bool - """ - - self._fg = fg - self._samples_per_symbol = samples_per_symbol - self._bt = bt - - if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2: - raise TypeError, ("samples_per_symbol must be an integer >= 2, is %r" % (samples_per_symbol,)) - - ntaps = 4 * samples_per_symbol # up to 3 bits in filter at once - sensitivity = (pi / 2) / samples_per_symbol # phase change per bit = pi / 2 - - # Turn it into NRZ data. - self.nrz = gr.bytes_to_syms() - - # Form Gaussian filter - # Generate Gaussian response (Needs to be convolved with window below). - self.gaussian_taps = gr.firdes.gaussian( - 1, # gain - samples_per_symbol, # symbol_rate - bt, # bandwidth * symbol time - ntaps # number of taps - ) - - self.sqwave = (1,) * samples_per_symbol # rectangular window - self.taps = numpy.convolve(numpy.array(self.gaussian_taps),numpy.array(self.sqwave)) - self.gaussian_filter = gr.interp_fir_filter_fff(samples_per_symbol, self.taps) - - # FM modulation - self.fmmod = gr.frequency_modulator_fc(sensitivity) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect & Initialize base class - self._fg.connect(self.nrz, self.gaussian_filter, self.fmmod) - gr.hier_block.__init__(self, self._fg, self.nrz, self.fmmod) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 1 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. - - - def _print_verbage(self): - print "bits per symbol = %d" % self.bits_per_symbol() - print "Gaussian filter bt = %.2f" % self._bt - - - def _setup_logging(self): - print "Modulation logging turned on." - self._fg.connect(self.nrz, - gr.file_sink(gr.sizeof_float, "nrz.dat")) - self._fg.connect(self.gaussian_filter, - gr.file_sink(gr.sizeof_float, "gaussian_filter.dat")) - self._fg.connect(self.fmmod, - gr.file_sink(gr.sizeof_gr_complex, "fmmod.dat")) - - - def add_options(parser): - """ - Adds GMSK modulation-specific options to the standard parser - """ - parser.add_option("", "--bt", type="float", default=_def_bt, - help="set bandwidth-time product [default=%default] (GMSK)") - add_options=staticmethod(add_options) - - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils.extract_kwargs_from_options(gmsk_mod.__init__, - ('self', 'fg'), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - - -# ///////////////////////////////////////////////////////////////////////////// -# GMSK demodulator -# ///////////////////////////////////////////////////////////////////////////// - -class gmsk_demod(gr.hier_block): - - def __init__(self, fg, - samples_per_symbol=_def_samples_per_symbol, - gain_mu=_def_gain_mu, - mu=_def_mu, - omega_relative_limit=_def_omega_relative_limit, - freq_error=_def_freq_error, - verbose=_def_verbose, - log=_def_log): - """ - Hierarchical block for Gaussian Minimum Shift Key (GMSK) - demodulation. - - The input is the complex modulated signal at baseband. - The output is a stream of bits packed 1 bit per byte (the LSB) - - @param fg: flow graph - @type fg: flow graph - @param samples_per_symbol: samples per baud - @type samples_per_symbol: integer - @param verbose: Print information about modulator? - @type verbose: bool - @param log: Print modualtion data to files? - @type log: bool - - Clock recovery parameters. These all have reasonble defaults. - - @param gain_mu: controls rate of mu adjustment - @type gain_mu: float - @param mu: fractional delay [0.0, 1.0] - @type mu: float - @param omega_relative_limit: sets max variation in omega - @type omega_relative_limit: float, typically 0.000200 (200 ppm) - @param freq_error: bit rate error as a fraction - @param float - """ - - self._fg = fg - self._samples_per_symbol = samples_per_symbol - self._gain_mu = gain_mu - self._mu = mu - self._omega_relative_limit = omega_relative_limit - self._freq_error = freq_error - - if samples_per_symbol < 2: - raise TypeError, "samples_per_symbol >= 2, is %f" % samples_per_symbol - - self._omega = samples_per_symbol*(1+self._freq_error) - - if not self._gain_mu: - self._gain_mu = 0.175 - - self._gain_omega = .25 * self._gain_mu * self._gain_mu # critically damped - - # Demodulate FM - sensitivity = (pi / 2) / samples_per_symbol - self.fmdemod = gr.quadrature_demod_cf(1.0 / sensitivity) - - # the clock recovery block tracks the symbol clock and resamples as needed. - # the output of the block is a stream of soft symbols (float) - self.clock_recovery = gr.clock_recovery_mm_ff(self._omega, self._gain_omega, - self._mu, self._gain_mu, - self._omega_relative_limit) - - # slice the floats at 0, outputting 1 bit (the LSB of the output byte) per sample - self.slicer = gr.binary_slicer_fb() - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect & Initialize base class - self._fg.connect(self.fmdemod, self.clock_recovery, self.slicer) - gr.hier_block.__init__(self, self._fg, self.fmdemod, self.slicer) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 1 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. - - - def _print_verbage(self): - print "bits per symbol = %d" % self.bits_per_symbol() - print "M&M clock recovery omega = %f" % self._omega - print "M&M clock recovery gain mu = %f" % self._gain_mu - print "M&M clock recovery mu = %f" % self._mu - print "M&M clock recovery omega rel. limit = %f" % self._omega_relative_limit - print "frequency error = %f" % self._freq_error - - - def _setup_logging(self): - print "Demodulation logging turned on." - self._fg.connect(self.fmdemod, - gr.file_sink(gr.sizeof_float, "fmdemod.dat")) - self._fg.connect(self.clock_recovery, - gr.file_sink(gr.sizeof_float, "clock_recovery.dat")) - self._fg.connect(self.slicer, - gr.file_sink(gr.sizeof_char, "slicer.dat")) - - def add_options(parser): - """ - Adds GMSK demodulation-specific options to the standard parser - """ - parser.add_option("", "--gain-mu", type="float", default=_def_gain_mu, - help="M&M clock recovery gain mu [default=%default] (GMSK/PSK)") - parser.add_option("", "--mu", type="float", default=_def_mu, - help="M&M clock recovery mu [default=%default] (GMSK/PSK)") - parser.add_option("", "--omega-relative-limit", type="float", default=_def_omega_relative_limit, - help="M&M clock recovery omega relative limit [default=%default] (GMSK/PSK)") - parser.add_option("", "--freq-error", type="float", default=_def_freq_error, - help="M&M clock recovery frequency error [default=%default] (GMSK)") - add_options=staticmethod(add_options) - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils.extract_kwargs_from_options(gmsk_demod.__init__, - ('self', 'fg'), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - -# -# Add these to the mod/demod registry -# -modulation_utils.add_type_1_mod('gmsk', gmsk_mod) -modulation_utils.add_type_1_demod('gmsk', gmsk_demod) diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/nbfm_rx.py b/gnuradio-core/src/python/gnuradio/blksimpl/nbfm_rx.py deleted file mode 100644 index 6ec06356..00000000 --- a/gnuradio-core/src/python/gnuradio/blksimpl/nbfm_rx.py +++ /dev/null @@ -1,87 +0,0 @@ -# -# 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 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. -# - -import math -from gnuradio import gr, optfir -from gnuradio.blksimpl.fm_emph import fm_deemph -from gnuradio.blksimpl.standard_squelch import standard_squelch - -class nbfm_rx(gr.hier_block): - def __init__(self, fg, audio_rate, quad_rate, tau=75e-6, max_dev=5e3): - """ - Narrow Band FM Receiver. - - Takes a single complex baseband input stream and produces a single - float output stream of audio sample in the range [-1, +1]. - - @param fg: flow graph - @param audio_rate: sample rate of audio stream, >= 16k - @type audio_rate: integer - @param quad_rate: sample rate of output stream - @type quad_rate: integer - @param tau: preemphasis time constant (default 75e-6) - @type tau: float - @param max_dev: maximum deviation in Hz (default 5e3) - @type max_dev: float - - quad_rate must be an integer multiple of audio_rate. - - Exported sub-blocks (attributes): - squelch - quad_demod - deemph - audio_filter - """ - - # FIXME audio_rate and quad_rate ought to be exact rationals - audio_rate = int(audio_rate) - quad_rate = int(quad_rate) - - if quad_rate % audio_rate != 0: - raise ValueError, "quad_rate is not an integer multiple of audio_rate" - - squelch_threshold = 20 # dB - #self.squelch = gr.simple_squelch_cc(squelch_threshold, 0.001) - - # FM Demodulator input: complex; output: float - k = quad_rate/(2*math.pi*max_dev) - self.quad_demod = gr.quadrature_demod_cf(k) - - # FM Deemphasis IIR filter - self.deemph = fm_deemph (fg, quad_rate, tau=tau) - - # compute FIR taps for audio filter - audio_decim = quad_rate // audio_rate - audio_taps = gr.firdes.low_pass (1.0, # gain - quad_rate, # sampling rate - 4.5e3, # Audio LPF cutoff - 2.5e3, # Transition band - gr.firdes.WIN_HAMMING) # filter type - - print "len(audio_taps) =", len(audio_taps) - - # Decimating audio filter - # input: float; output: float; taps: float - self.audio_filter = gr.fir_filter_fff(audio_decim, audio_taps) - - fg.connect(self.quad_demod, self.deemph, self.audio_filter) - - gr.hier_block.__init__(self, fg, self.quad_demod, self.audio_filter) diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/nbfm_tx.py b/gnuradio-core/src/python/gnuradio/blksimpl/nbfm_tx.py deleted file mode 100644 index 49b052bc..00000000 --- a/gnuradio-core/src/python/gnuradio/blksimpl/nbfm_tx.py +++ /dev/null @@ -1,95 +0,0 @@ -# -# 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 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. -# - -import math -from gnuradio import gr, optfir -from gnuradio.blksimpl.fm_emph import fm_preemph - -#from gnuradio import ctcss - -class nbfm_tx(gr.hier_block): - def __init__(self, fg, audio_rate, quad_rate, tau=75e-6, max_dev=5e3): - """ - Narrow Band FM Transmitter. - - Takes a single float input stream of audio samples in the range [-1,+1] - and produces a single FM modulated complex baseband output. - - @param fg: flow graph - @param audio_rate: sample rate of audio stream, >= 16k - @type audio_rate: integer - @param quad_rate: sample rate of output stream - @type quad_rate: integer - @param tau: preemphasis time constant (default 75e-6) - @type tau: float - @param max_dev: maximum deviation in Hz (default 5e3) - @type max_dev: float - - quad_rate must be an integer multiple of audio_rate. - """ - - # FIXME audio_rate and quad_rate ought to be exact rationals - audio_rate = int(audio_rate) - quad_rate = int(quad_rate) - - if quad_rate % audio_rate != 0: - raise ValueError, "quad_rate is not an integer multiple of audio_rate" - - - do_interp = audio_rate != quad_rate - - if do_interp: - interp_factor = quad_rate / audio_rate - interp_taps = optfir.low_pass (interp_factor, # gain - quad_rate, # Fs - 4500, # passband cutoff - 7000, # stopband cutoff - 0.1, # passband ripple dB - 40) # stopband atten dB - - #print "len(interp_taps) =", len(interp_taps) - self.interpolator = gr.interp_fir_filter_fff (interp_factor, interp_taps) - - self.preemph = fm_preemph (fg, quad_rate, tau=tau) - - k = 2 * math.pi * max_dev / quad_rate - self.modulator = gr.frequency_modulator_fc (k) - - if do_interp: - fg.connect (self.interpolator, self.preemph, self.modulator) - gr.hier_block.__init__(self, fg, self.interpolator, self.modulator) - else: - fg.connect(self.preemph, self.modulator) - gr.hier_block.__init__(self, fg, self.preemph, self.modulator) - - -#class ctcss_gen_f(gr.sig_source_f): -# def __init__(self, sample_rate, tone_freq): -# gr.sig_source_f.__init__(self, sample_rate, gr.SIN_WAVE, tone_freq, 0.1, 0.0) -# -# def set_tone (self, tone): -# gr.sig_source_f.set_frequency(self,tone) - -class ctcss_gen_f(gr.hier_block): - def __init__(self, fg, sample_rate, tone_freq): - self.plgen = gr.sig_source_f(sample_rate, gr.GR_SIN_WAVE, tone_freq, 0.1, 0.0) - - gr.hier_block.__init__(self, fg, self.plgen, self.plgen) diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/pkt.py b/gnuradio-core/src/python/gnuradio/blksimpl/pkt.py deleted file mode 100644 index d5e677ee..00000000 --- a/gnuradio-core/src/python/gnuradio/blksimpl/pkt.py +++ /dev/null @@ -1,161 +0,0 @@ -# -# Copyright 2005,2006 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 math import pi -from gnuradio import gr, packet_utils -import gnuradio.gr.gr_threading as _threading - - -# ///////////////////////////////////////////////////////////////////////////// -# mod/demod with packets as i/o -# ///////////////////////////////////////////////////////////////////////////// - -class mod_pkts(gr.hier_block): - """ - Wrap an arbitrary digital modulator in our packet handling framework. - - Send packets by calling send_pkt - """ - def __init__(self, fg, modulator, access_code=None, msgq_limit=2, pad_for_usrp=True, use_whitener_offset=False): - """ - Hierarchical block for sending packets - - Packets to be sent are enqueued by calling send_pkt. - The output is the complex modulated signal at baseband. - - @param fg: flow graph - @type fg: flow graph - @param modulator: instance of modulator class (gr_block or hier_block) - @type modulator: complex baseband out - @param access_code: AKA sync vector - @type access_code: string of 1's and 0's between 1 and 64 long - @param msgq_limit: maximum number of messages in message queue - @type msgq_limit: int - @param pad_for_usrp: If true, packets are padded such that they end up a multiple of 128 samples - @param use_whitener_offset: If true, start of whitener XOR string is incremented each packet - - See gmsk_mod for remaining parameters - """ - self._modulator = modulator - self._pad_for_usrp = pad_for_usrp - self._use_whitener_offset = use_whitener_offset - self._whitener_offset = 0 - - if access_code is None: - access_code = packet_utils.default_access_code - if not packet_utils.is_1_0_string(access_code): - raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,) - self._access_code = access_code - - # accepts messages from the outside world - self._pkt_input = gr.message_source(gr.sizeof_char, msgq_limit) - fg.connect(self._pkt_input, self._modulator) - gr.hier_block.__init__(self, fg, None, self._modulator) - - def send_pkt(self, payload='', eof=False): - """ - Send the payload. - - @param payload: data to send - @type payload: string - """ - if eof: - msg = gr.message(1) # tell self._pkt_input we're not sending any more packets - else: - # print "original_payload =", string_to_hex_list(payload) - pkt = packet_utils.make_packet(payload, - self._modulator.samples_per_symbol(), - self._modulator.bits_per_symbol(), - self._access_code, - self._pad_for_usrp, - self._whitener_offset) - #print "pkt =", string_to_hex_list(pkt) - msg = gr.message_from_string(pkt) - if self._use_whitener_offset is True: - self._whitener_offset = (self._whitener_offset + 1) % 16 - - self._pkt_input.msgq().insert_tail(msg) - - - -class demod_pkts(gr.hier_block): - """ - Wrap an arbitrary digital demodulator in our packet handling framework. - - The input is complex baseband. When packets are demodulated, they are passed to the - app via the callback. - """ - - def __init__(self, fg, demodulator, access_code=None, callback=None, threshold=-1): - """ - Hierarchical block for demodulating and deframing packets. - - The input is the complex modulated signal at baseband. - Demodulated packets are sent to the handler. - - @param fg: flow graph - @type fg: flow graph - @param demodulator: instance of demodulator class (gr_block or hier_block) - @type demodulator: complex baseband in - @param access_code: AKA sync vector - @type access_code: string of 1's and 0's - @param callback: function of two args: ok, payload - @type callback: ok: bool; payload: string - @param threshold: detect access_code with up to threshold bits wrong (-1 -> use default) - @type threshold: int - """ - - self._demodulator = demodulator - if access_code is None: - access_code = packet_utils.default_access_code - if not packet_utils.is_1_0_string(access_code): - raise ValueError, "Invalid access_code %r. Must be string of 1's and 0's" % (access_code,) - self._access_code = access_code - - if threshold == -1: - threshold = 12 # FIXME raise exception - - self._rcvd_pktq = gr.msg_queue() # holds packets from the PHY - self.correlator = gr.correlate_access_code_bb(access_code, threshold) - - self.framer_sink = gr.framer_sink_1(self._rcvd_pktq) - fg.connect(self._demodulator, self.correlator, self.framer_sink) - - gr.hier_block.__init__(self, fg, self._demodulator, None) - self._watcher = _queue_watcher_thread(self._rcvd_pktq, callback) - - -class _queue_watcher_thread(_threading.Thread): - def __init__(self, rcvd_pktq, callback): - _threading.Thread.__init__(self) - self.setDaemon(1) - self.rcvd_pktq = rcvd_pktq - self.callback = callback - self.keep_running = True - self.start() - - - def run(self): - while self.keep_running: - msg = self.rcvd_pktq.delete_head() - ok, payload = packet_utils.unmake_packet(msg.to_string(), int(msg.arg1())) - if self.callback: - self.callback(ok, payload) diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/psk.py b/gnuradio-core/src/python/gnuradio/blksimpl/psk.py deleted file mode 100644 index acedf3b6..00000000 --- a/gnuradio-core/src/python/gnuradio/blksimpl/psk.py +++ /dev/null @@ -1,94 +0,0 @@ -# -# Copyright 2005,2006 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 math import pi, sqrt, log10 -import math, cmath - -# The following algorithm generates Gray coded constellations for M-PSK for M=[2,4,8] -def make_gray_constellation(m): - # number of bits/symbol (log2(M)) - k = int(log10(m) / log10(2.0)) - - coeff = 1 - const_map = [] - bits = [0]*3 - for i in range(m): - # get a vector of the k bits to use in this mapping - bits[3-k:3] = [((i&(0x01 << k-j-1)) >> k-j-1) for j in range(k)] - - theta = -(2*bits[0]-1)*(2*pi/m)*(bits[0]+abs(bits[1]-bits[2])+2*bits[1]) - re = math.cos(theta) - im = math.sin(theta) - const_map.append(complex(re, im)) # plug it into the constellation - - # return the constellation; by default, it is normalized - return const_map - -# This makes a constellation that increments around the unit circle -def make_constellation(m): - return [cmath.exp(i * 2 * pi / m * 1j) for i in range(m)] - -# Common definition of constellations for Tx and Rx -constellation = { - 2 : make_constellation(2), # BPSK - 4 : make_constellation(4), # QPSK - 8 : make_constellation(8) # 8PSK - } - -gray_constellation = { - 2 : make_gray_constellation(2), # BPSK - 4 : make_gray_constellation(4), # QPSK - 8 : make_gray_constellation(8) # 8PSK - } - -# ----------------------- -# Do Gray code -# ----------------------- -# binary to gray coding -- constellation does Gray coding -binary_to_gray = { - 2 : range(2), - 4 : [0,1,3,2], - 8 : [0, 1, 3, 2, 7, 6, 4, 5] - } - -# gray to binary -gray_to_binary = { - 2 : range(2), - 4 : [0,1,3,2], - 8 : [0, 1, 3, 2, 6, 7, 5, 4] - } - -# ----------------------- -# Don't Gray code -# ----------------------- -# identity mapping -binary_to_ungray = { - 2 : range(2), - 4 : range(4), - 8 : range(8) - } - -# identity mapping -ungray_to_binary = { - 2 : range(2), - 4 : range(4), - 8 : range(8) - } diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/qam.py b/gnuradio-core/src/python/gnuradio/blksimpl/qam.py deleted file mode 100644 index 22b1e1da..00000000 --- a/gnuradio-core/src/python/gnuradio/blksimpl/qam.py +++ /dev/null @@ -1,113 +0,0 @@ -# -# Copyright 2005,2006 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 math import pi, sqrt -import math - -# These constellations are generated for Gray coding when symbos [1, ..., m] are used -# Mapping to Gray coding is therefore unnecessary - -def make_constellation(m): - # number of bits/symbol (log2(M)) - k = int(math.log10(m) / math.log10(2.0)) - - coeff = 1 - const_map = [] - for i in range(m): - a = (i&(0x01 << k-1)) >> k-1 - b = (i&(0x01 << k-2)) >> k-2 - bits_i = [((i&(0x01 << k-j-1)) >> k-j-1) for j in range(2, k, 2)] - bits_q = [((i&(0x01 << k-j-1)) >> k-j-1) for j in range(3, k, 2)] - - ss = 0 - ll = len(bits_i) - for ii in range(ll): - rr = 0 - for jj in range(ll-ii): - rr = abs(bits_i[jj] - rr) - ss += rr*pow(2.0, ii+1) - re = (2*a-1)*(ss+1) - - ss = 0 - ll = len(bits_q) - for ii in range(ll): - rr = 0 - for jj in range(ll-ii): - rr = abs(bits_q[jj] - rr) - ss += rr*pow(2.0, ii+1) - im = (2*b-1)*(ss+1) - - a = max(re, im) - if a > coeff: - coeff = a - const_map.append(complex(re, im)) - - norm_map = [complex(i.real/coeff, i.imag/coeff) for i in const_map] - return norm_map - -# Common definition of constellations for Tx and Rx -constellation = { - 4 : make_constellation(4), # QAM4 (QPSK) - 8 : make_constellation(8), # QAM8 - 16: make_constellation(16), # QAM16 - 64: make_constellation(64), # QAM64 - 256: make_constellation(256) # QAM256 - } - -# ----------------------- -# Do Gray code -# ----------------------- -# binary to gray coding -binary_to_gray = { - 4 : range(4), - 8 : range(8), - 16: range(16), - 64: range(64), - 256: range(256) - } - -# gray to binary -gray_to_binary = { - 4 : range(4), - 8 : range(8), - 16: range(16), - 64: range(64), - 256: range(256) - } - -# ----------------------- -# Don't Gray code -# ----------------------- -# identity mapping -binary_to_ungray = { - 4 : range(4), - 8 : range(8), - 16: range(16), - 64: range(64) - } - -# identity mapping -ungray_to_binary = { - 4 : range(4), - 8 : range(8), - 16: range(16), - 64: range(64) - } diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/qam16.py b/gnuradio-core/src/python/gnuradio/blksimpl/qam16.py deleted file mode 100644 index 7a724068..00000000 --- a/gnuradio-core/src/python/gnuradio/blksimpl/qam16.py +++ /dev/null @@ -1,205 +0,0 @@ -# -# Copyright 2005,2006 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. -# - -# See gnuradio-examples/python/digital for examples - -""" -QAM16 modulation and demodulation. -""" - -from gnuradio import gr, gru, modulation_utils -from math import pi, sqrt -import qam -import cmath -from pprint import pprint - -# default values (used in __init__ and add_options) -_def_samples_per_symbol = 2 -_def_excess_bw = 0.35 -_def_gray_code = True -_def_verbose = False -_def_log = False - -_def_costas_alpha = None -_def_gain_mu = 0.03 -_def_mu = 0.05 -_def_omega_relative_limit = 0.005 - - -# ///////////////////////////////////////////////////////////////////////////// -# QAM16 modulator -# ///////////////////////////////////////////////////////////////////////////// - -class qam16_mod(gr.hier_block): - - def __init__(self, fg, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - - """ - Hierarchical block for RRC-filtered QPSK modulation. - - The input is a byte stream (unsigned char) and the - output is the complex modulated signal at baseband. - - @param fg: flow graph - @type fg: flow graph - @param samples_per_symbol: samples per symbol >= 2 - @type samples_per_symbol: integer - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param debug: Print modualtion data to files? - @type debug: bool - """ - - self._fg = fg - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._gray_code = gray_code - - if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2: - raise TypeError, ("sbp must be an integer >= 2, is %d" % samples_per_symbol) - - ntaps = 11 * samples_per_symbol - - arity = pow(2, self.bits_per_symbol()) - - # turn bytes into k-bit vectors - self.bytes2chunks = \ - gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(qam.binary_to_gray[arity]) - else: - self.symbol_mapper = gr.map_bb(qam.binary_to_ungray[arity]) - - self.diffenc = gr.diff_encoder_bb(arity) - - rot = 1.0 - print "constellation with %d arity" % arity - rotated_const = map(lambda pt: pt * rot, qam.constellation[arity]) - self.chunks2symbols = gr.chunks_to_symbols_bc(rotated_const) - - # pulse shaping filter - self.rrc_taps = gr.firdes.root_raised_cosine( - self._samples_per_symbol, # gain (sps since we're interpolating by sps) - self._samples_per_symbol, # sampling rate - 1.0, # symbol rate - self._excess_bw, # excess bandwidth (roll-off factor) - ntaps) - - self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol, self.rrc_taps) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect & Initialize base class - self._fg.connect(self.bytes2chunks, self.symbol_mapper, self.diffenc, - self.chunks2symbols, self.rrc_filter) - gr.hier_block.__init__(self, self._fg, self.bytes2chunks, self.rrc_filter) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 4 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def _print_verbage(self): - print "bits per symbol = %d" % self.bits_per_symbol() - print "Gray code = %s" % self._gray_code - print "RRS roll-off factor = %f" % self._excess_bw - - def _setup_logging(self): - print "Modulation logging turned on." - self._fg.connect(self.bytes2chunks, - gr.file_sink(gr.sizeof_char, "bytes2chunks.dat")) - self._fg.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "graycoder.dat")) - self._fg.connect(self.diffenc, - gr.file_sink(gr.sizeof_char, "diffenc.dat")) - self._fg.connect(self.chunks2symbols, - gr.file_sink(gr.sizeof_gr_complex, "chunks2symbols.dat")) - self._fg.connect(self.rrc_filter, - gr.file_sink(gr.sizeof_gr_complex, "rrc_filter.dat")) - - def add_options(parser): - """ - Adds QAM modulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default] (PSK)") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=_def_gray_code, - help="disable gray coding on modulated bits (PSK)") - add_options=staticmethod(add_options) - - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils.extract_kwargs_from_options(qam16_mod.__init__, - ('self', 'fg'), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - -# ///////////////////////////////////////////////////////////////////////////// -# QAM16 demodulator -# -# ///////////////////////////////////////////////////////////////////////////// - -class qam16_demod(gr.hier_block): - - def __init__(self, fg, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - costas_alpha=_def_costas_alpha, - gain_mu=_def_gain_mu, - mu=_def_mu, - omega_relative_limit=_def_omega_relative_limit, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - - # do this - pass - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 4 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - -# -# Add these to the mod/demod registry -# -# NOT READY TO BE USED YET -- ENABLE AT YOUR OWN RISK -#modulation_utils.add_type_1_mod('qam16', qam16_mod) -#modulation_utils.add_type_1_demod('qam16', qam16_demod) diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/qam256.py b/gnuradio-core/src/python/gnuradio/blksimpl/qam256.py deleted file mode 100644 index 7ccb5afc..00000000 --- a/gnuradio-core/src/python/gnuradio/blksimpl/qam256.py +++ /dev/null @@ -1,205 +0,0 @@ -# -# Copyright 2005,2006 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. -# - -# See gnuradio-examples/python/digital for examples - -""" -QAM256 modulation and demodulation. -""" - -from gnuradio import gr, gru, modulation_utils -from math import pi, sqrt -import qam -import cmath -from pprint import pprint - -# default values (used in __init__ and add_options) -_def_samples_per_symbol = 2 -_def_excess_bw = 0.35 -_def_gray_code = True -_def_verbose = False -_def_log = False - -_def_costas_alpha = None -_def_gain_mu = 0.03 -_def_mu = 0.05 -_def_omega_relative_limit = 0.005 - - -# ///////////////////////////////////////////////////////////////////////////// -# QAM256 modulator -# ///////////////////////////////////////////////////////////////////////////// - -class qam256_mod(gr.hier_block): - - def __init__(self, fg, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - - """ - Hierarchical block for RRC-filtered QPSK modulation. - - The input is a byte stream (unsigned char) and the - output is the complex modulated signal at baseband. - - @param fg: flow graph - @type fg: flow graph - @param samples_per_symbol: samples per symbol >= 2 - @type samples_per_symbol: integer - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param debug: Print modualtion data to files? - @type debug: bool - """ - - self._fg = fg - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._gray_code = gray_code - - if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2: - raise TypeError, ("sbp must be an integer >= 2, is %d" % samples_per_symbol) - - ntaps = 11 * samples_per_symbol - - arity = pow(2, self.bits_per_symbol()) - - # turn bytes into k-bit vectors - self.bytes2chunks = \ - gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(qam.binary_to_gray[arity]) - else: - self.symbol_mapper = gr.map_bb(qam.binary_to_ungray[arity]) - - self.diffenc = gr.diff_encoder_bb(arity) - - rot = 1.0 - print "constellation with %d arity" % arity - rotated_const = map(lambda pt: pt * rot, qam.constellation[arity]) - self.chunks2symbols = gr.chunks_to_symbols_bc(rotated_const) - - # pulse shaping filter - self.rrc_taps = gr.firdes.root_raised_cosine( - self._samples_per_symbol, # gain (sps since we're interpolating by sps) - self._samples_per_symbol, # sampling rate - 1.0, # symbol rate - self._excess_bw, # excess bandwidth (roll-off factor) - ntaps) - - self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol, self.rrc_taps) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect & Initialize base class - self._fg.connect(self.bytes2chunks, self.symbol_mapper, self.diffenc, - self.chunks2symbols, self.rrc_filter) - gr.hier_block.__init__(self, self._fg, self.bytes2chunks, self.rrc_filter) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 8 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def _print_verbage(self): - print "bits per symbol = %d" % self.bits_per_symbol() - print "Gray code = %s" % self._gray_code - print "RRS roll-off factor = %f" % self._excess_bw - - def _setup_logging(self): - print "Modulation logging turned on." - self._fg.connect(self.bytes2chunks, - gr.file_sink(gr.sizeof_char, "bytes2chunks.dat")) - self._fg.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "graycoder.dat")) - self._fg.connect(self.diffenc, - gr.file_sink(gr.sizeof_char, "diffenc.dat")) - self._fg.connect(self.chunks2symbols, - gr.file_sink(gr.sizeof_gr_complex, "chunks2symbols.dat")) - self._fg.connect(self.rrc_filter, - gr.file_sink(gr.sizeof_gr_complex, "rrc_filter.dat")) - - def add_options(parser): - """ - Adds QAM modulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default] (PSK)") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=_def_gray_code, - help="disable gray coding on modulated bits (PSK)") - add_options=staticmethod(add_options) - - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils.extract_kwargs_from_options(qam256_mod.__init__, - ('self', 'fg'), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - -# ///////////////////////////////////////////////////////////////////////////// -# QAM256 demodulator -# -# ///////////////////////////////////////////////////////////////////////////// - -class qam256_demod(gr.hier_block): - - def __init__(self, fg, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - costas_alpha=_def_costas_alpha, - gain_mu=_def_gain_mu, - mu=_def_mu, - omega_relative_limit=_def_omega_relative_limit, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - - # do this - pass - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 8 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - -# -# Add these to the mod/demod registry -# -# NOT READY TO BE USED YET -- ENABLE AT YOUR OWN RISK -#modulation_utils.add_type_1_mod('qam256', qam256_mod) -#modulation_utils.add_type_1_demod('qam256', qam256_demod) diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/qam64.py b/gnuradio-core/src/python/gnuradio/blksimpl/qam64.py deleted file mode 100644 index 76b24cd9..00000000 --- a/gnuradio-core/src/python/gnuradio/blksimpl/qam64.py +++ /dev/null @@ -1,205 +0,0 @@ -# -# Copyright 2005,2006 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. -# - -# See gnuradio-examples/python/digital for examples - -""" -differential QPSK modulation and demodulation. -""" - -from gnuradio import gr, gru, modulation_utils -from math import pi, sqrt -import qam -import cmath -from pprint import pprint - -# default values (used in __init__ and add_options) -_def_samples_per_symbol = 2 -_def_excess_bw = 0.35 -_def_gray_code = True -_def_verbose = False -_def_log = False - -_def_costas_alpha = None -_def_gain_mu = 0.03 -_def_mu = 0.05 -_def_omega_relative_limit = 0.005 - - -# ///////////////////////////////////////////////////////////////////////////// -# QAM64 modulator -# ///////////////////////////////////////////////////////////////////////////// - -class qam64_mod(gr.hier_block): - - def __init__(self, fg, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - - """ - Hierarchical block for RRC-filtered QPSK modulation. - - The input is a byte stream (unsigned char) and the - output is the complex modulated signal at baseband. - - @param fg: flow graph - @type fg: flow graph - @param samples_per_symbol: samples per symbol >= 2 - @type samples_per_symbol: integer - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param debug: Print modualtion data to files? - @type debug: bool - """ - - self._fg = fg - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._gray_code = gray_code - - if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2: - raise TypeError, ("sbp must be an integer >= 2, is %d" % samples_per_symbol) - - ntaps = 11 * samples_per_symbol - - arity = pow(2, self.bits_per_symbol()) - - # turn bytes into k-bit vectors - self.bytes2chunks = \ - gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(qam.binary_to_gray[arity]) - else: - self.symbol_mapper = gr.map_bb(qam.binary_to_ungray[arity]) - - self.diffenc = gr.diff_encoder_bb(arity) - - rot = 1.0 - print "constellation with %d arity" % arity - rotated_const = map(lambda pt: pt * rot, qam.constellation[arity]) - self.chunks2symbols = gr.chunks_to_symbols_bc(rotated_const) - - # pulse shaping filter - self.rrc_taps = gr.firdes.root_raised_cosine( - self._samples_per_symbol, # gain (sps since we're interpolating by sps) - self._samples_per_symbol, # sampling rate - 1.0, # symbol rate - self._excess_bw, # excess bandwidth (roll-off factor) - ntaps) - - self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol, self.rrc_taps) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect & Initialize base class - self._fg.connect(self.bytes2chunks, self.symbol_mapper, self.diffenc, - self.chunks2symbols, self.rrc_filter) - gr.hier_block.__init__(self, self._fg, self.bytes2chunks, self.rrc_filter) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 6 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def _print_verbage(self): - print "bits per symbol = %d" % self.bits_per_symbol() - print "Gray code = %s" % self._gray_code - print "RRS roll-off factor = %f" % self._excess_bw - - def _setup_logging(self): - print "Modulation logging turned on." - self._fg.connect(self.bytes2chunks, - gr.file_sink(gr.sizeof_char, "bytes2chunks.dat")) - self._fg.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "graycoder.dat")) - self._fg.connect(self.diffenc, - gr.file_sink(gr.sizeof_char, "diffenc.dat")) - self._fg.connect(self.chunks2symbols, - gr.file_sink(gr.sizeof_gr_complex, "chunks2symbols.dat")) - self._fg.connect(self.rrc_filter, - gr.file_sink(gr.sizeof_gr_complex, "rrc_filter.dat")) - - def add_options(parser): - """ - Adds QAM modulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default] (PSK)") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=_def_gray_code, - help="disable gray coding on modulated bits (PSK)") - add_options=staticmethod(add_options) - - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils.extract_kwargs_from_options(qam64_mod.__init__, - ('self', 'fg'), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - -# ///////////////////////////////////////////////////////////////////////////// -# QAM16 demodulator -# -# ///////////////////////////////////////////////////////////////////////////// - -class qam64_demod(gr.hier_block): - - def __init__(self, fg, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - costas_alpha=_def_costas_alpha, - gain_mu=_def_gain_mu, - mu=_def_mu, - omega_relative_limit=_def_omega_relative_limit, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - - # do this - pass - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 6 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - -# -# Add these to the mod/demod registry -# -# NOT READY TO BE USED YET -- ENABLE AT YOUR OWN RISK -#modulation_utils.add_type_1_mod('qam64', qam64_mod) -#modulation_utils.add_type_1_demod('qam16', qam16_demod) diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/qam8.py b/gnuradio-core/src/python/gnuradio/blksimpl/qam8.py deleted file mode 100644 index 604e5c88..00000000 --- a/gnuradio-core/src/python/gnuradio/blksimpl/qam8.py +++ /dev/null @@ -1,205 +0,0 @@ -# -# Copyright 2005,2006 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. -# - -# See gnuradio-examples/python/digital for examples - -""" -QAM8 modulation and demodulation. -""" - -from gnuradio import gr, gru, modulation_utils -from math import pi, sqrt -import qam -import cmath -from pprint import pprint - -# default values (used in __init__ and add_options) -_def_samples_per_symbol = 2 -_def_excess_bw = 0.35 -_def_gray_code = True -_def_verbose = False -_def_log = False - -_def_costas_alpha = None -_def_gain_mu = 0.03 -_def_mu = 0.05 -_def_omega_relative_limit = 0.005 - - -# ///////////////////////////////////////////////////////////////////////////// -# QAM8 modulator -# ///////////////////////////////////////////////////////////////////////////// - -class qam8_mod(gr.hier_block): - - def __init__(self, fg, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - - """ - Hierarchical block for RRC-filtered QPSK modulation. - - The input is a byte stream (unsigned char) and the - output is the complex modulated signal at baseband. - - @param fg: flow graph - @type fg: flow graph - @param samples_per_symbol: samples per symbol >= 2 - @type samples_per_symbol: integer - @param excess_bw: Root-raised cosine filter excess bandwidth - @type excess_bw: float - @param gray_code: Tell modulator to Gray code the bits - @type gray_code: bool - @param verbose: Print information about modulator? - @type verbose: bool - @param debug: Print modualtion data to files? - @type debug: bool - """ - - self._fg = fg - self._samples_per_symbol = samples_per_symbol - self._excess_bw = excess_bw - self._gray_code = gray_code - - if not isinstance(samples_per_symbol, int) or samples_per_symbol < 2: - raise TypeError, ("sbp must be an integer >= 2, is %d" % samples_per_symbol) - - ntaps = 11 * samples_per_symbol - - arity = pow(2, self.bits_per_symbol()) - - # turn bytes into k-bit vectors - self.bytes2chunks = \ - gr.packed_to_unpacked_bb(self.bits_per_symbol(), gr.GR_MSB_FIRST) - - if self._gray_code: - self.symbol_mapper = gr.map_bb(qam.binary_to_gray[arity]) - else: - self.symbol_mapper = gr.map_bb(qam.binary_to_ungray[arity]) - - self.diffenc = gr.diff_encoder_bb(arity) - - rot = 1.0 - print "constellation with %d arity" % arity - rotated_const = map(lambda pt: pt * rot, qam.constellation[arity]) - self.chunks2symbols = gr.chunks_to_symbols_bc(rotated_const) - - # pulse shaping filter - self.rrc_taps = gr.firdes.root_raised_cosine( - self._samples_per_symbol, # gain (sps since we're interpolating by sps) - self._samples_per_symbol, # sampling rate - 1.0, # symbol rate - self._excess_bw, # excess bandwidth (roll-off factor) - ntaps) - - self.rrc_filter = gr.interp_fir_filter_ccf(self._samples_per_symbol, self.rrc_taps) - - if verbose: - self._print_verbage() - - if log: - self._setup_logging() - - # Connect & Initialize base class - self._fg.connect(self.bytes2chunks, self.symbol_mapper, self.diffenc, - self.chunks2symbols, self.rrc_filter) - gr.hier_block.__init__(self, self._fg, self.bytes2chunks, self.rrc_filter) - - def samples_per_symbol(self): - return self._samples_per_symbol - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 3 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - - def _print_verbage(self): - print "bits per symbol = %d" % self.bits_per_symbol() - print "Gray code = %s" % self._gray_code - print "RRS roll-off factor = %f" % self._excess_bw - - def _setup_logging(self): - print "Modulation logging turned on." - self._fg.connect(self.bytes2chunks, - gr.file_sink(gr.sizeof_char, "bytes2chunks.dat")) - self._fg.connect(self.symbol_mapper, - gr.file_sink(gr.sizeof_char, "graycoder.dat")) - self._fg.connect(self.diffenc, - gr.file_sink(gr.sizeof_char, "diffenc.dat")) - self._fg.connect(self.chunks2symbols, - gr.file_sink(gr.sizeof_gr_complex, "chunks2symbols.dat")) - self._fg.connect(self.rrc_filter, - gr.file_sink(gr.sizeof_gr_complex, "rrc_filter.dat")) - - def add_options(parser): - """ - Adds QAM modulation-specific options to the standard parser - """ - parser.add_option("", "--excess-bw", type="float", default=_def_excess_bw, - help="set RRC excess bandwith factor [default=%default] (PSK)") - parser.add_option("", "--no-gray-code", dest="gray_code", - action="store_false", default=_def_gray_code, - help="disable gray coding on modulated bits (PSK)") - add_options=staticmethod(add_options) - - - def extract_kwargs_from_options(options): - """ - Given command line options, create dictionary suitable for passing to __init__ - """ - return modulation_utils.extract_kwargs_from_options(qam8_mod.__init__, - ('self', 'fg'), options) - extract_kwargs_from_options=staticmethod(extract_kwargs_from_options) - - -# ///////////////////////////////////////////////////////////////////////////// -# QAM8 demodulator -# -# ///////////////////////////////////////////////////////////////////////////// - -class qam8_demod(gr.hier_block): - - def __init__(self, fg, - samples_per_symbol=_def_samples_per_symbol, - excess_bw=_def_excess_bw, - costas_alpha=_def_costas_alpha, - gain_mu=_def_gain_mu, - mu=_def_mu, - omega_relative_limit=_def_omega_relative_limit, - gray_code=_def_gray_code, - verbose=_def_verbose, - log=_def_log): - - # do this - pass - - def bits_per_symbol(self=None): # staticmethod that's also callable on an instance - return 3 - bits_per_symbol = staticmethod(bits_per_symbol) # make it a static method. RTFM - -# -# Add these to the mod/demod registry -# -# NOT READY TO BE USED YET -- ENABLE AT YOUR OWN RISK -#modulation_utils.add_type_1_mod('qam8', qam8_mod) -#modulation_utils.add_type_1_demod('qam8', qam8_demod) diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/rational_resampler.py b/gnuradio-core/src/python/gnuradio/blksimpl/rational_resampler.py deleted file mode 100644 index b3e8ad7a..00000000 --- a/gnuradio-core/src/python/gnuradio/blksimpl/rational_resampler.py +++ /dev/null @@ -1,137 +0,0 @@ -# -# 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 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 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 - """ - - global _plot - - 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 - ) - # print "len(resampler_taps) =", len(taps) - # _plot = gru.gnuplot_freqz(gru.freqz(taps, 1), 1) - - return taps - - - -class _rational_resampler_base(gr.hier_block): - """ - base class for all rational resampler variants. - """ - def __init__(self, resampler_base, fg, - 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 fg: flow graph - @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_block.__init__(self, fg, resampler, resampler) - - - -class rational_resampler_fff(_rational_resampler_base): - def __init__(self, fg, 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, fg, - interpolation, decimation, - taps, fractional_bw) - -class rational_resampler_ccf(_rational_resampler_base): - def __init__(self, fg, 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, fg, - interpolation, decimation, - taps, fractional_bw) - -class rational_resampler_ccc(_rational_resampler_base): - def __init__(self, fg, 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, fg, - interpolation, decimation, - taps, fractional_bw) - diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/standard_squelch.py b/gnuradio-core/src/python/gnuradio/blksimpl/standard_squelch.py deleted file mode 100644 index b2b9451c..00000000 --- a/gnuradio-core/src/python/gnuradio/blksimpl/standard_squelch.py +++ /dev/null @@ -1,73 +0,0 @@ -# -# 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 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. -# - -import math -from gnuradio import gr, optfir - -class standard_squelch(gr.hier_block): - def __init__(self, fg, audio_rate): - - self.input_node = gr.add_const_ff(0) # FIXME kludge - - self.low_iir = gr.iir_filter_ffd((0.0193,0,-0.0193),(1,1.9524,-0.9615)) - self.low_square = gr.multiply_ff() - self.low_smooth = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate)) # 100ms time constant - - self.hi_iir = gr.iir_filter_ffd((0.0193,0,-0.0193),(1,1.3597,-0.9615)) - self.hi_square = gr.multiply_ff() - self.hi_smooth = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate)) - - self.sub = gr.sub_ff(); - self.add = gr.add_ff(); - self.gate = gr.threshold_ff(0.3,0.43,0) - self.squelch_lpf = gr.single_pole_iir_filter_ff(1/(0.01*audio_rate)) - - self.div = gr.divide_ff() - self.squelch_mult = gr.multiply_ff() - - fg.connect (self.input_node, (self.squelch_mult, 0)) - - fg.connect (self.input_node,self.low_iir) - fg.connect (self.low_iir,(self.low_square,0)) - fg.connect (self.low_iir,(self.low_square,1)) - fg.connect (self.low_square,self.low_smooth,(self.sub,0)) - fg.connect (self.low_smooth, (self.add,0)) - - fg.connect (self.input_node,self.hi_iir) - fg.connect (self.hi_iir,(self.hi_square,0)) - fg.connect (self.hi_iir,(self.hi_square,1)) - fg.connect (self.hi_square,self.hi_smooth,(self.sub,1)) - fg.connect (self.hi_smooth, (self.add,1)) - - fg.connect (self.sub, (self.div, 0)) - fg.connect (self.add, (self.div, 1)) - fg.connect (self.div, self.gate, self.squelch_lpf, (self.squelch_mult,1)) - - gr.hier_block.__init__(self, fg, self.input_node, self.squelch_mult) - - def set_threshold(self, threshold): - self.gate.set_hi(threshold) - - def threshold(self): - return self.gate.hi() - - def squelch_range(self): - return (0.0, 1.0, 1.0/100) diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/wfm_rcv.py b/gnuradio-core/src/python/gnuradio/blksimpl/wfm_rcv.py deleted file mode 100644 index ffcdc144..00000000 --- a/gnuradio-core/src/python/gnuradio/blksimpl/wfm_rcv.py +++ /dev/null @@ -1,72 +0,0 @@ -# -# 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 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 import gr -from gnuradio.blksimpl.fm_emph import fm_deemph -import math - -class wfm_rcv(gr.hier_block): - def __init__ (self, fg, quad_rate, audio_decimation): - """ - Hierarchical block for demodulating a broadcast FM signal. - - The input is the downconverted complex baseband signal (gr_complex). - The output is the demodulated audio (float). - - @param fg: flow graph. - @type fg: flow graph - @param quad_rate: input sample rate of complex baseband input. - @type quad_rate: float - @param audio_decimation: how much to decimate quad_rate to get to audio. - @type audio_decimation: integer - """ - volume = 20. - - max_dev = 75e3 - fm_demod_gain = quad_rate/(2*math.pi*max_dev) - audio_rate = quad_rate / audio_decimation - - - # We assign to self so that outsiders can grab the demodulator - # if they need to. E.g., to plot its output. - # - # input: complex; output: float - self.fm_demod = gr.quadrature_demod_cf (fm_demod_gain) - - # input: float; output: float - self.deemph = fm_deemph (fg, audio_rate) - - # compute FIR filter taps for audio filter - width_of_transition_band = audio_rate / 32 - audio_coeffs = gr.firdes.low_pass (1.0, # gain - quad_rate, # sampling rate - audio_rate/2 - width_of_transition_band, - width_of_transition_band, - gr.firdes.WIN_HAMMING) - # input: float; output: float - self.audio_filter = gr.fir_filter_fff (audio_decimation, audio_coeffs) - - fg.connect (self.fm_demod, self.audio_filter, self.deemph) - - gr.hier_block.__init__(self, - fg, - self.fm_demod, # head of the pipeline - self.deemph) # tail of the pipeline diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/wfm_rcv_pll.py b/gnuradio-core/src/python/gnuradio/blksimpl/wfm_rcv_pll.py deleted file mode 100644 index 5ee49cea..00000000 --- a/gnuradio-core/src/python/gnuradio/blksimpl/wfm_rcv_pll.py +++ /dev/null @@ -1,206 +0,0 @@ -# -# Copyright 2005,2006 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 import gr -from gnuradio.blksimpl.fm_emph import fm_deemph -import math - -class wfm_rcv_pll(gr.hier_block): - def __init__ (self, fg, demod_rate, audio_decimation): - """ - Hierarchical block for demodulating a broadcast FM signal. - - The input is the downconverted complex baseband signal (gr_complex). - The output is two streams of the demodulated audio (float) 0=Left, 1=Right. - - @param fg: flow graph. - @type fg: flow graph - @param demod_rate: input sample rate of complex baseband input. - @type demod_rate: float - @param audio_decimation: how much to decimate demod_rate to get to audio. - @type audio_decimation: integer - """ - - bandwidth = 200e3 - audio_rate = demod_rate / audio_decimation - - - # We assign to self so that outsiders can grab the demodulator - # if they need to. E.g., to plot its output. - # - # input: complex; output: float - alpha = 0.25*bandwidth * math.pi / demod_rate - beta = alpha * alpha / 4.0 - max_freq = 2.0*math.pi*100e3/demod_rate - - self.fm_demod = gr.pll_freqdet_cf (alpha,beta,max_freq,-max_freq) - - # input: float; output: float - self.deemph_Left = fm_deemph (fg, audio_rate) - self.deemph_Right = fm_deemph (fg, audio_rate) - - # compute FIR filter taps for audio filter - width_of_transition_band = audio_rate / 32 - audio_coeffs = gr.firdes.low_pass (1.0 , # gain - demod_rate, # sampling rate - 15000 , - width_of_transition_band, - gr.firdes.WIN_HAMMING) - # input: float; output: float - self.audio_filter = gr.fir_filter_fff (audio_decimation, audio_coeffs) - if 1: - # Pick off the stereo carrier/2 with this filter. It attenuated 10 dB so apply 10 dB gain - # We pick off the negative frequency half because we want to base band by it! - ## NOTE THIS WAS HACKED TO OFFSET INSERTION LOSS DUE TO DEEMPHASIS - - stereo_carrier_filter_coeffs = gr.firdes.complex_band_pass(10.0, - demod_rate, - -19020, - -18980, - width_of_transition_band, - gr.firdes.WIN_HAMMING) - - #print "len stereo carrier filter = ",len(stereo_carrier_filter_coeffs) - #print "stereo carrier filter ", stereo_carrier_filter_coeffs - #print "width of transition band = ",width_of_transition_band, " audio rate = ", audio_rate - - # Pick off the double side band suppressed carrier Left-Right audio. It is attenuated 10 dB so apply 10 dB gain - - stereo_dsbsc_filter_coeffs = gr.firdes.complex_band_pass(20.0, - demod_rate, - 38000-15000/2, - 38000+15000/2, - width_of_transition_band, - gr.firdes.WIN_HAMMING) - #print "len stereo dsbsc filter = ",len(stereo_dsbsc_filter_coeffs) - #print "stereo dsbsc filter ", stereo_dsbsc_filter_coeffs - # construct overlap add filter system from coefficients for stereo carrier - - self.stereo_carrier_filter = gr.fir_filter_fcc(audio_decimation, stereo_carrier_filter_coeffs) - - # carrier is twice the picked off carrier so arrange to do a commplex multiply - - self.stereo_carrier_generator = gr.multiply_cc(); - - # Pick off the rds signal - - stereo_rds_filter_coeffs = gr.firdes.complex_band_pass(30.0, - demod_rate, - 57000 - 1500, - 57000 + 1500, - width_of_transition_band, - gr.firdes.WIN_HAMMING) - #print "len stereo dsbsc filter = ",len(stereo_dsbsc_filter_coeffs) - #print "stereo dsbsc filter ", stereo_dsbsc_filter_coeffs - # construct overlap add filter system from coefficients for stereo carrier - - self.stereo_carrier_filter = gr.fir_filter_fcc(audio_decimation, stereo_carrier_filter_coeffs) - self.rds_signal_filter = gr.fir_filter_fcc(audio_decimation, stereo_rds_filter_coeffs) - - - - - - - self.rds_carrier_generator = gr.multiply_cc(); - self.rds_signal_generator = gr.multiply_cc(); - self_rds_signal_processor = gr.null_sink(gr.sizeof_gr_complex); - - - - alpha = 5 * 0.25 * math.pi / (audio_rate) - beta = alpha * alpha / 4.0 - max_freq = -2.0*math.pi*18990/audio_rate; - min_freq = -2.0*math.pi*19010/audio_rate; - - self.stereo_carrier_pll_recovery = gr.pll_refout_cc(alpha,beta,max_freq,min_freq); - #self.stereo_carrier_pll_recovery.squelch_enable(False) #pll_refout does not have squelch yet, so disabled for now - - - # set up mixer (multiplier) to get the L-R signal at baseband - - self.stereo_basebander = gr.multiply_cc(); - - # pick off the real component of the basebanded L-R signal. The imaginary SHOULD be zero - - self.LmR_real = gr.complex_to_real(); - self.Make_Left = gr.add_ff(); - self.Make_Right = gr.sub_ff(); - - self.stereo_dsbsc_filter = gr.fir_filter_fcc(audio_decimation, stereo_dsbsc_filter_coeffs) - - - if 1: - - # send the real signal to complex filter to pick off the carrier and then to one side of a multiplier - fg.connect (self.fm_demod,self.stereo_carrier_filter,self.stereo_carrier_pll_recovery, (self.stereo_carrier_generator,0)) - # send the already filtered carrier to the otherside of the carrier - fg.connect (self.stereo_carrier_pll_recovery, (self.stereo_carrier_generator,1)) - # the resulting signal from this multiplier is the carrier with correct phase but at -38000 Hz. - - # send the new carrier to one side of the mixer (multiplier) - fg.connect (self.stereo_carrier_generator, (self.stereo_basebander,0)) - # send the demphasized audio to the DSBSC pick off filter, the complex - # DSBSC signal at +38000 Hz is sent to the other side of the mixer/multiplier - fg.connect (self.fm_demod,self.stereo_dsbsc_filter, (self.stereo_basebander,1)) - # the result is BASEBANDED DSBSC with phase zero! - - # Pick off the real part since the imaginary is theoretically zero and then to one side of a summer - fg.connect (self.stereo_basebander, self.LmR_real, (self.Make_Left,0)) - #take the same real part of the DSBSC baseband signal and send it to negative side of a subtracter - fg.connect (self.LmR_real,(self.Make_Right,1)) - - # Make rds carrier by taking the squared pilot tone and multiplying by pilot tone - fg.connect (self.stereo_basebander,(self.rds_carrier_generator,0)) - fg.connect (self.stereo_carrier_pll_recovery,(self.rds_carrier_generator,1)) - # take signal, filter off rds, send into mixer 0 channel - fg.connect (self.fm_demod,self.rds_signal_filter,(self.rds_signal_generator,0)) - # take rds_carrier_generator output and send into mixer 1 channel - fg.connect (self.rds_carrier_generator,(self.rds_signal_generator,1)) - # send basebanded rds signal and send into "processor" which for now is a null sink - fg.connect (self.rds_signal_generator,self_rds_signal_processor) - - - if 1: - # pick off the audio, L+R that is what we used to have and send it to the summer - fg.connect(self.fm_demod, self.audio_filter, (self.Make_Left, 1)) - # take the picked off L+R audio and send it to the PLUS side of the subtractor - fg.connect(self.audio_filter,(self.Make_Right, 0)) - # The result of Make_Left gets (L+R) + (L-R) and results in 2*L - # The result of Make_Right gets (L+R) - (L-R) and results in 2*R - - - # kludge the signals into a stereo channel - kludge = gr.kludge_copy(gr.sizeof_float) - fg.connect(self.Make_Left , self.deemph_Left, (kludge, 0)) - fg.connect(self.Make_Right, self.deemph_Right, (kludge, 1)) - - #send it to the audio system - gr.hier_block.__init__(self, - fg, - self.fm_demod, # head of the pipeline - kludge) # tail of the pipeline - else: - fg.connect (self.fm_demod, self.audio_filter) - gr.hier_block.__init__(self, - fg, - self.fm_demod, # head of the pipeline - self.audio_filter) # tail of the pipeline diff --git a/gnuradio-core/src/python/gnuradio/blksimpl/wfm_tx.py b/gnuradio-core/src/python/gnuradio/blksimpl/wfm_tx.py deleted file mode 100644 index 89528a82..00000000 --- a/gnuradio-core/src/python/gnuradio/blksimpl/wfm_tx.py +++ /dev/null @@ -1,79 +0,0 @@ -# -# 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 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. -# - -import math -from gnuradio import gr, optfir -from gnuradio.blksimpl.fm_emph import fm_preemph - -class wfm_tx(gr.hier_block): - def __init__(self, fg, audio_rate, quad_rate, tau=75e-6, max_dev=75e3): - """ - Wide Band FM Transmitter. - - Takes a single float input stream of audio samples in the range [-1,+1] - and produces a single FM modulated complex baseband output. - - @param fg: flow graph - @param audio_rate: sample rate of audio stream, >= 16k - @type audio_rate: integer - @param quad_rate: sample rate of output stream - @type quad_rate: integer - @param tau: preemphasis time constant (default 75e-6) - @type tau: float - @param max_dev: maximum deviation in Hz (default 75e3) - @type max_dev: float - - quad_rate must be an integer multiple of audio_rate. - """ - - # FIXME audio_rate and quad_rate ought to be exact rationals - audio_rate = int(audio_rate) - quad_rate = int(quad_rate) - - if quad_rate % audio_rate != 0: - raise ValueError, "quad_rate is not an integer multiple of audio_rate" - - - do_interp = audio_rate != quad_rate - - if do_interp: - interp_factor = quad_rate / audio_rate - interp_taps = optfir.low_pass (interp_factor, # gain - quad_rate, # Fs - 16000, # passband cutoff - 18000, # stopband cutoff - 0.1, # passband ripple dB - 40) # stopband atten dB - - print "len(interp_taps) =", len(interp_taps) - self.interpolator = gr.interp_fir_filter_fff (interp_factor, interp_taps) - - self.preemph = fm_preemph (fg, quad_rate, tau=tau) - - k = 2 * math.pi * max_dev / quad_rate - self.modulator = gr.frequency_modulator_fc (k) - - if do_interp: - fg.connect (self.interpolator, self.preemph, self.modulator) - gr.hier_block.__init__(self, fg, self.interpolator, self.modulator) - else: - fg.connect(self.preemph, self.modulator) - gr.hier_block.__init__(self, fg, self.preemph, self.modulator) diff --git a/gnuradio-core/src/python/gnuradio/gr/Makefile.am b/gnuradio-core/src/python/gnuradio/gr/Makefile.am index 77cc53e3..7406d062 100644 --- a/gnuradio-core/src/python/gnuradio/gr/Makefile.am +++ b/gnuradio-core/src/python/gnuradio/gr/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2004,2005,2006 Free Software Foundation, Inc. +# Copyright 2004,2005,2006,2008 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -32,13 +32,10 @@ grgrpythondir = $(grpythondir)/gr grgrpython_PYTHON = \ __init__.py \ - basic_flow_graph.py \ exceptions.py \ - flow_graph.py \ gr_threading.py \ gr_threading_23.py \ gr_threading_24.py \ - hier_block.py \ hier_block2.py \ prefs.py \ scheduler.py \ @@ -50,7 +47,6 @@ noinst_PYTHON = \ qa_add_v_and_friends.py \ qa_agc.py \ qa_argmax.py \ - qa_basic_flow_graph.py \ qa_bin_statistics.py \ qa_cma_equalizer.py \ qa_complex_to_xxx.py \ @@ -62,7 +58,6 @@ noinst_PYTHON = \ qa_feval.py \ qa_fft_filter.py \ qa_filter_delay_fc.py \ - qa_flow_graph.py \ qa_fractional_interpolator.py \ qa_frequency_modulator.py \ qa_fsk_stuff.py \ diff --git a/gnuradio-core/src/python/gnuradio/gr/__init__.py b/gnuradio-core/src/python/gnuradio/gr/__init__.py index 774996be..15ff17d7 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 Free Software Foundation, Inc. +# Copyright 2003,2004,2006,2008 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -40,10 +40,7 @@ _dlopenflags = sys.getdlopenflags() sys.setdlopenflags(_dlopenflags|_RTLD_GLOBAL) from gnuradio_swig_python import * -from basic_flow_graph import * -from flow_graph import * from exceptions import * -from hier_block import * from hier_block2 import * from top_block import * diff --git a/gnuradio-core/src/python/gnuradio/gr/basic_flow_graph.py b/gnuradio-core/src/python/gnuradio/gr/basic_flow_graph.py deleted file mode 100644 index 13152dd2..00000000 --- a/gnuradio-core/src/python/gnuradio/gr/basic_flow_graph.py +++ /dev/null @@ -1,270 +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_swig_python import gr_block_sptr -import types -import hier_block - -def remove_duplicates (seq): - new = [] - for x in seq: - if not x in new: - new.append (x) - return new - - -class endpoint (object): - __slots__ = ['block', 'port'] - def __init__ (self, block, port): - self.block = block - self.port = port - - def __cmp__ (self, other): - if self.block == other.block and self.port == other.port: - return 0 - return 1 - - def __str__ (self): - return '' % (self.block, self.port) - -def expand_src_endpoint (src_endpoint): - # A src_endpoint is an output of a block - src_endpoint = coerce_endpoint (src_endpoint) - if isinstance (src_endpoint.block, hier_block.hier_block_base): - return expand_src_endpoint ( - coerce_endpoint (src_endpoint.block.resolve_output_port(src_endpoint.port))) - else: - return src_endpoint - -def expand_dst_endpoint (dst_endpoint): - # a dst_endpoint is the input to a block - dst_endpoint = coerce_endpoint (dst_endpoint) - if isinstance (dst_endpoint.block, hier_block.hier_block_base): - exp = [coerce_endpoint(x) for x in - dst_endpoint.block.resolve_input_port(dst_endpoint.port)] - return expand_dst_endpoints (exp) - else: - return [dst_endpoint] - -def expand_dst_endpoints (endpoint_list): - r = [] - for e in endpoint_list: - r.extend (expand_dst_endpoint (e)) - return r - - -def coerce_endpoint (x): - if isinstance (x, endpoint): - return x - elif isinstance (x, types.TupleType) and len (x) == 2: - return endpoint (x[0], x[1]) - elif hasattr (x, 'block'): # assume it's a block - return endpoint (x, 0) - elif isinstance(x, hier_block.hier_block_base): - return endpoint (x, 0) - else: - raise ValueError, "Not coercible to endpoint: %s" % (x,) - - -class edge (object): - __slots__ = ['src', 'dst'] - def __init__ (self, src_endpoint, dst_endpoint): - self.src = src_endpoint - self.dst = dst_endpoint - - def __cmp__ (self, other): - if self.src == other.src and self.dst == other.dst: - return 0 - return 1 - - def __repr__ (self): - return '' % (self.src, self.dst) - -class basic_flow_graph (object): - '''basic_flow_graph -- describe connections between blocks''' - # __slots__ is incompatible with weakrefs (for some reason!) - # __slots__ = ['edge_list'] - def __init__ (self): - self.edge_list = [] - - def connect (self, *points): - '''connect requires two or more arguments that can be coerced to endpoints. - If more than two arguments are provided, they are connected together successively. - ''' - if len (points) < 2: - raise ValueError, ("connect requires at least two endpoints; %d provided." % (len (points),)) - for i in range (1, len (points)): - self._connect (points[i-1], points[i]) - - def _connect (self, src_endpoint, dst_endpoint): - s = expand_src_endpoint (src_endpoint) - for d in expand_dst_endpoint (dst_endpoint): - self._connect_prim (s, d) - - def _connect_prim (self, src_endpoint, dst_endpoint): - src_endpoint = coerce_endpoint (src_endpoint) - dst_endpoint = coerce_endpoint (dst_endpoint) - self._check_valid_src_port (src_endpoint) - self._check_valid_dst_port (dst_endpoint) - self._check_dst_in_use (dst_endpoint) - self._check_type_match (src_endpoint, dst_endpoint) - self.edge_list.append (edge (src_endpoint, dst_endpoint)) - - def disconnect (self, src_endpoint, dst_endpoint): - s = expand_src_endpoint (src_endpoint) - for d in expand_dst_endpoint (dst_endpoint): - self._disconnect_prim (s, d) - - def _disconnect_prim (self, src_endpoint, dst_endpoint): - src_endpoint = coerce_endpoint (src_endpoint) - dst_endpoint = coerce_endpoint (dst_endpoint) - e = edge (src_endpoint, dst_endpoint) - self.edge_list.remove (e) - - def disconnect_all (self): - self.edge_list = [] - - def validate (self): - # check all blocks to ensure: - # (1a) their input ports are contiguously assigned - # (1b) the number of input ports is between min and max - # (2a) their output ports are contiguously assigned - # (2b) the number of output ports is between min and max - # (3) check_topology returns true - - for m in self.all_blocks (): - # print m - - edges = self.in_edges (m) - used_ports = [e.dst.port for e in edges] - ninputs = self._check_contiguity (m, m.input_signature (), used_ports, "input") - - edges = self.out_edges (m) - used_ports = [e.src.port for e in edges] - noutputs = self._check_contiguity (m, m.output_signature (), used_ports, "output") - - if not m.check_topology (ninputs, noutputs): - raise ValueError, ("%s::check_topology (%d, %d) failed" % (m, ninputs, noutputs)) - - - # --- public utilities --- - - def all_blocks (self): - '''return list of all blocks in the graph''' - all_blocks = [] - for edge in self.edge_list: - m = edge.src.block - if not m in all_blocks: - all_blocks.append (m) - m = edge.dst.block - if not m in all_blocks: - all_blocks.append (m) - return all_blocks - - def in_edges (self, m): - '''return list of all edges that have M as a destination''' - return [e for e in self.edge_list if e.dst.block == m] - - def out_edges (self, m): - '''return list of all edges that have M as a source''' - return [e for e in self.edge_list if e.src.block == m] - - def downstream_verticies (self, m): - return [e.dst.block for e in self.out_edges (m)] - - def downstream_verticies_port (self, m, port): - return [e.dst.block for e in self.out_edges(m) if e.src.port == port] - - def upstream_verticies (self, m): - return [e.src.block for e in self.in_edges (m)] - - def adjacent_verticies (self, m): - '''return list of all verticies adjacent to M''' - return self.downstream_verticies (m) + self.upstream_verticies (m) - - def sink_p (self, m): - '''return True iff this block is a sink''' - e = self.out_edges (m) - return len (e) == 0 - - def source_p (self, m): - '''return True iff this block is a source''' - e = self.in_edges (m) - return len (e) == 0 - - # --- internal methods --- - - def _check_dst_in_use (self, dst_endpoint): - '''Ensure that there is not already an endpoint that terminates at dst_endpoint.''' - x = [ep for ep in self.edge_list if ep.dst == dst_endpoint] - if x: # already in use - raise ValueError, ("destination endpoint already in use: %s" % (dst_endpoint)) - - def _check_valid_src_port (self, src_endpoint): - self._check_port (src_endpoint.block.output_signature(), src_endpoint.port) - - def _check_valid_dst_port (self, dst_endpoint): - self._check_port (dst_endpoint.block.input_signature(), dst_endpoint.port) - - def _check_port (self, signature, port): - if port < 0: - raise ValueError, 'port number out of range.' - if signature.max_streams () == -1: # infinite - return # OK - if port >= signature.max_streams (): - raise ValueError, 'port number out of range.' - - def _check_type_match (self, src_endpoint, dst_endpoint): - # for now, we just ensure that the stream item sizes match - src_sig = src_endpoint.block.output_signature () - dst_sig = dst_endpoint.block.input_signature () - src_size = src_sig.sizeof_stream_item (src_endpoint.port) - dst_size = dst_sig.sizeof_stream_item (dst_endpoint.port) - if src_size != dst_size: - raise ValueError, ( -' '.join(('source and destination data sizes are different:', -src_endpoint.block.name(), -dst_endpoint.block.name()))) - - def _check_contiguity (self, m, sig, used_ports, dir): - used_ports.sort () - used_ports = remove_duplicates (used_ports) - min_s = sig.min_streams () - - l = len (used_ports) - if l == 0: - if min_s == 0: - return l - raise ValueError, ("%s requires %d %s connections. It has none." % - (m, min_s, dir)) - - if used_ports[-1] + 1 < min_s: - raise ValueError, ("%s requires %d %s connections. It has %d." % - (m, min_s, dir, used_ports[-1] + 1)) - - if used_ports[-1] + 1 != l: - for i in range (l): - if used_ports[i] != i: - raise ValueError, ("%s %s port %d is not connected" % - (m, dir, i)) - - # print "%s ports: %s" % (dir, used_ports) - return l diff --git a/gnuradio-core/src/python/gnuradio/gr/flow_graph.py b/gnuradio-core/src/python/gnuradio/gr/flow_graph.py deleted file mode 100644 index 39e479b2..00000000 --- a/gnuradio-core/src/python/gnuradio/gr/flow_graph.py +++ /dev/null @@ -1,234 +0,0 @@ -# -# Copyright 2004,2006 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.basic_flow_graph import remove_duplicates, endpoint, edge, \ - basic_flow_graph - -from gnuradio.gr.exceptions import * -from gnuradio_swig_python import buffer, buffer_add_reader, block_detail, \ - single_threaded_scheduler - -from gnuradio.gr.scheduler import scheduler - -_WHITE = 0 # graph coloring tags -_GRAY = 1 -_BLACK = 2 - -_flow_graph_debug = False - -def set_flow_graph_debug(on): - global _flow_graph_debug - _flow_graph_debug = on - - -class buffer_sizes (object): - """compute buffer sizes to use""" - def __init__ (self, flow_graph): - # We could scan the graph here and determine individual sizes - # based on relative_rate, number of readers, etc. - - # The simplest thing that could possibly work: all buffers same size - self.flow_graph = flow_graph - self.fixed_buffer_size = 32*1024 - - def allocate (self, m, index): - """allocate buffer for output index of block m""" - item_size = m.output_signature().sizeof_stream_item (index) - nitems = self.fixed_buffer_size / item_size - if nitems < 2 * m.output_multiple (): - nitems = 2 * m.output_multiple () - - # if any downstream blocks is a decimator and/or has a large output_multiple, - # ensure that we have a buffer at least 2 * their decimation_factor*output_multiple - for mdown in self.flow_graph.downstream_verticies_port(m, index): - decimation = int(1.0 / mdown.relative_rate()) - nitems = max(nitems, 2 * (decimation * mdown.output_multiple() + mdown.history())) - - return buffer (nitems, item_size) - - -class flow_graph (basic_flow_graph): - """add physical connection info to simple_flow_graph - """ - # __slots__ is incompatible with weakrefs (for some reason!) - # __slots__ = ['blocks', 'scheduler'] - - def __init__ (self): - basic_flow_graph.__init__ (self); - self.blocks = None - self.scheduler = None - - def __del__(self): - # print "\nflow_graph.__del__" - # this ensures that i/o devices such as the USRP get shutdown gracefully - self.stop() - - def start (self): - '''start graph, forking thread(s), return immediately''' - if self.scheduler: - raise RuntimeError, "Scheduler already running" - self._setup_connections () - - # cast down to gr_module_sptr - # t = [x.block () for x in self.topological_sort (self.blocks)] - self.scheduler = scheduler (self) - self.scheduler.start () - - def stop (self): - '''tells scheduler to stop and waits for it to happen''' - if self.scheduler: - self.scheduler.stop () - self.scheduler = None - - def wait (self): - '''waits for scheduler to stop''' - if self.scheduler: - self.scheduler.wait () - self.scheduler = None - - def is_running (self): - return not not self.scheduler - - def run (self): - '''start graph, wait for completion''' - self.start () - self.wait () - - def _setup_connections (self): - """given the basic flow graph, setup all the physical connections""" - self.validate () - self.blocks = self.all_blocks () - self._assign_details () - self._assign_buffers () - self._connect_inputs () - - def _assign_details (self): - for m in self.blocks: - edges = self.in_edges (m) - used_ports = remove_duplicates ([e.dst.port for e in edges]) - ninputs = len (used_ports) - - edges = self.out_edges (m) - used_ports = remove_duplicates ([e.src.port for e in edges]) - noutputs = len (used_ports) - - m.set_detail (block_detail (ninputs, noutputs)) - - def _assign_buffers (self): - """determine the buffer sizes to use, allocate them and attach to detail""" - sizes = buffer_sizes (self) - for m in self.blocks: - d = m.detail () - for index in range (d.noutputs ()): - d.set_output (index, sizes.allocate (m, index)) - - def _connect_inputs (self): - """connect all block inputs to appropriate upstream buffers""" - for m in self.blocks: - d = m.detail () - # print "%r history = %d" % (m, m.history()) - for e in self.in_edges(m): - # FYI, sources don't have any in_edges - our_port = e.dst.port - upstream_block = e.src.block - upstream_port = e.src.port - upstream_buffer = upstream_block.detail().output(upstream_port) - d.set_input(our_port, buffer_add_reader(upstream_buffer, m.history()-1)) - - - def topological_sort (self, all_v): - ''' - Return a topologically sorted list of vertices. - This is basically a depth-first search with checks - for back edges (the non-DAG condition) - - ''' - - # it's correct without this sort, but this - # should give better ordering for cache utilization - all_v = self._sort_sources_first (all_v) - - output = [] - for v in all_v: - v.ts_color = _WHITE - for v in all_v: - if v.ts_color == _WHITE: - self._dfs_visit (v, output) - output.reverse () - return output - - def _dfs_visit (self, u, output): - # print "dfs_visit (enter): ", u - u.ts_color = _GRAY - for v in self.downstream_verticies (u): - if v.ts_color == _WHITE: # (u, v) is a tree edge - self._dfs_visit (v, output) - elif v.ts_color == _GRAY: # (u, v) is a back edge - raise NotDAG, "The graph is not an acyclic graph (It's got a loop)" - elif v.ts_color == _BLACK: # (u, v) is a cross or forward edge - pass - else: - raise CantHappen, "Invalid color on vertex" - u.ts_color = _BLACK - output.append (u) - # print "dfs_visit (exit): ", u, output - - def _sort_sources_first (self, all_v): - # the sort function is not guaranteed to be stable. - # We add the unique_id in to the key so we're guaranteed - # of reproducible results. This is important for the test - # code. There is often more than one valid topological sort. - # We want to force a reproducible choice. - x = [(not self.source_p(v), v.unique_id(), v) for v in all_v] - x.sort () - x = [v[2] for v in x] - # print "sorted: ", x - return x - - def partition_graph (self, all_v): - '''Return a list of lists of nodes that are connected. - The result is a list of disjoint graphs. - The sublists are topologically sorted. - ''' - result = [] - working_v = all_v[:] # make copy - while working_v: - rv = self._reachable_verticies (working_v[0], working_v) - result.append (self.topological_sort (rv)) - for v in rv: - working_v.remove (v) - if _flow_graph_debug: - print "partition_graph:", result - return result - - def _reachable_verticies (self, start, all_v): - for v in all_v: - v.ts_color = _WHITE - - self._reachable_dfs_visit (start) - return [v for v in all_v if v.ts_color == _BLACK] - - def _reachable_dfs_visit (self, u): - u.ts_color = _BLACK - for v in self.adjacent_verticies (u): - if v.ts_color == _WHITE: - self._reachable_dfs_visit (v) - return None diff --git a/gnuradio-core/src/python/gnuradio/gr/hier_block.py b/gnuradio-core/src/python/gnuradio/gr/hier_block.py deleted file mode 100644 index 8bcf6421..00000000 --- a/gnuradio-core/src/python/gnuradio/gr/hier_block.py +++ /dev/null @@ -1,132 +0,0 @@ -# -# 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 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_swig_python import io_signature -import weakref - -class hier_block_base(object): - """ - Abstract base class for hierarchical signal processing blocks. - """ - def __init__(self, fg): - """ - @param fg: The flow graph that contains this hierarchical block. - @type fg: gr.flow_graph - """ - self.fg = weakref.proxy(fg) - - def input_signature(self): - """ - @return input signature of hierarchical block. - @rtype gr.io_signature - """ - raise NotImplemented - - def output_signature(self): - """ - @return output signature of hierarchical block. - @rtype gr.io_signature - """ - raise NotImplemented - - def resolve_input_port(self, port_number): - """ - @param port_number: which input port number to resolve to an endpoint. - @type port_number: int - @return: sequence of endpoints - @rtype: sequence of endpoint - - Note that an input port can resolve to more than one endpoint. - """ - raise NotImplemented - - def resolve_output_port(self, port_number): - """ - @param port_number: which output port number to resolve to an endpoint. - @type port_number: int - @return: endpoint - @rtype: endpoint - - Output ports resolve to a single endpoint. - """ - raise NotImplemented - - -class hier_block(hier_block_base): - """ - Simple concrete class for building hierarchical blocks. - - This class assumes that there is at most a single block at the - head of the chain and a single block at the end of the chain. - Either head or tail may be None indicating a sink or source respectively. - - If you needs something more elaborate than this, derive a new class from - hier_block_base. - """ - def __init__(self, fg, head_block, tail_block): - """ - @param fg: The flow graph that contains this hierarchical block. - @type fg: flow_graph - @param head_block: the first block in the signal processing chain. - @type head_block: None or subclass of gr.block or gr.hier_block_base - @param tail_block: the last block in the signal processing chain. - @type tail_block: None or subclass of gr.block or gr.hier_block_base - """ - hier_block_base.__init__(self, fg) - # FIXME add type checks here for easier debugging of misuse - self.head = head_block - self.tail = tail_block - - def input_signature(self): - if self.head: - return self.head.input_signature() - else: - return io_signature(0,0,0) - - def output_signature(self): - if self.tail: - return self.tail.output_signature() - else: - return io_signature(0,0,0) - - def resolve_input_port(self, port_number): - return ((self.head, port_number),) - - def resolve_output_port(self, port_number): - return (self.tail, port_number) - - -class compose(hier_block): - """ - Compose one or more blocks (primitive or hierarchical) into a new hierarchical block. - """ - def __init__(self, fg, *blocks): - """ - @param fg: flow graph - @type fg: gr.flow_graph - @param *blocks: list of blocks - @type *blocks: list of blocks - """ - if len(blocks) < 1: - raise ValueError, ("compose requires at least one block; none provided.") - if len(blocks) > 1: - fg.connect(*blocks) - hier_block.__init__(self, fg, blocks[0], blocks[-1]) diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_basic_flow_graph.py b/gnuradio-core/src/python/gnuradio/gr/qa_basic_flow_graph.py deleted file mode 100755 index 0799c72e..00000000 --- a/gnuradio-core/src/python/gnuradio/gr/qa_basic_flow_graph.py +++ /dev/null @@ -1,190 +0,0 @@ -#!/usr/bin/env python - -from gnuradio import gr, gr_unittest - - -# ---------------------------------------------------------------- - - -class test_basic_flow_graph (gr_unittest.TestCase): - - def setUp (self): - self.fg = gr.basic_flow_graph () - - def tearDown (self): - self.fg = None - - def test_000_create_delete (self): - pass - - def test_001a_insert_1 (self): - fg = self.fg - src1 = gr.null_source (gr.sizeof_int) - dst1 = gr.null_sink (gr.sizeof_int) - fg.connect (gr.endpoint (src1, 0), gr.endpoint (dst1, 0)) - - def test_001b_insert_1 (self): - fg = self.fg - src1 = gr.null_source (gr.sizeof_int) - dst1 = gr.null_sink (gr.sizeof_int) - fg.connect (src1, gr.endpoint (dst1, 0)) - - def test_001c_insert_1 (self): - fg = self.fg - src1 = gr.null_source (gr.sizeof_int) - dst1 = gr.null_sink (gr.sizeof_int) - fg.connect (gr.endpoint (src1, 0), dst1) - - def test_001d_insert_1 (self): - fg = self.fg - src1 = gr.null_source (gr.sizeof_int) - dst1 = gr.null_sink (gr.sizeof_int) - fg.connect (src1, dst1) - - def test_001e_insert_1 (self): - fg = self.fg - src1 = gr.null_source (gr.sizeof_int) - dst1 = gr.null_sink (gr.sizeof_int) - fg.connect ((src1, 0), (dst1, 0)) - - def test_002_dst_in_use (self): - fg = self.fg - src1 = gr.null_source (gr.sizeof_int) - src2 = gr.null_source (gr.sizeof_int) - dst1 = gr.null_sink (gr.sizeof_int) - fg.connect ((src1, 0), (dst1, 0)) - self.assertRaises (ValueError, - lambda : fg.connect ((src2, 0), - (dst1, 0))) - - def test_003_no_such_src_port (self): - fg = self.fg - src1 = gr.null_source (gr.sizeof_int) - dst1 = gr.null_sink (gr.sizeof_int) - self.assertRaises (ValueError, - lambda : fg.connect ((src1, 1), - (dst1, 0))) - - def test_004_no_such_dst_port (self): - fg = self.fg - src1 = gr.null_source (gr.sizeof_int) - dst1 = gr.null_sink (gr.sizeof_int) - self.assertRaises (ValueError, - lambda : fg.connect ((src1, 0), - (dst1, 1))) - - def test_005_one_src_two_dst (self): - fg = self.fg - src1 = gr.null_source (gr.sizeof_int) - dst1 = gr.null_sink (gr.sizeof_int) - dst2 = gr.null_sink (gr.sizeof_int) - fg.connect ((src1, 0), (dst1, 0)) - fg.connect ((src1, 0), (dst2, 0)) - - def test_006_check_item_sizes (self): - fg = self.fg - src1 = gr.null_source (gr.sizeof_int) - dst1 = gr.null_sink (gr.sizeof_char) - self.assertRaises (ValueError, - lambda : fg.connect ((src1, 0), - (dst1, 0))) - - def test_007_validate (self): - fg = self.fg - src1 = gr.null_source (gr.sizeof_int) - dst1 = gr.null_sink (gr.sizeof_int) - dst2 = gr.null_sink (gr.sizeof_int) - fg.connect ((src1, 0), (dst1, 0)) - fg.connect ((src1, 0), (dst2, 0)) - fg.validate () - - def test_008_validate (self): - fg = self.fg - src1 = gr.null_source (gr.sizeof_int) - nop1 = gr.nop (gr.sizeof_int) - dst1 = gr.null_sink (gr.sizeof_int) - dst2 = gr.null_sink (gr.sizeof_int) - fg.connect ((src1, 0), (nop1, 0)) - fg.connect ((src1, 0), (nop1, 1)) - fg.connect ((nop1, 0), (dst1, 0)) - fg.connect ((nop1, 1), (dst2, 0)) - fg.validate () - - def test_009_validate (self): - fg = self.fg - src1 = gr.null_source (gr.sizeof_int) - nop1 = gr.nop (gr.sizeof_int) - dst1 = gr.null_sink (gr.sizeof_int) - dst2 = gr.null_sink (gr.sizeof_int) - fg.connect ((src1, 0), (nop1, 0)) - fg.connect ((src1, 0), (nop1, 2)) - fg.connect ((nop1, 0), (dst1, 0)) - fg.connect ((nop1, 1), (dst2, 0)) - self.assertRaises (ValueError, - lambda : fg.validate ()) - - - def test_010_validate (self): - fg = self.fg - src1 = gr.null_source (gr.sizeof_int) - nop1 = gr.nop (gr.sizeof_int) - dst1 = gr.null_sink (gr.sizeof_int) - dst2 = gr.null_sink (gr.sizeof_int) - fg.connect ((src1, 0), (nop1, 0)) - fg.connect ((src1, 0), (nop1, 1)) - fg.connect ((nop1, 0), (dst1, 0)) - fg.connect ((nop1, 2), (dst2, 0)) - self.assertRaises (ValueError, - lambda : fg.validate ()) - - - def test_011_disconnect (self): - fg = self.fg - src1 = gr.null_source (gr.sizeof_int) - nop1 = gr.nop (gr.sizeof_int) - dst1 = gr.null_sink (gr.sizeof_int) - dst2 = gr.null_sink (gr.sizeof_int) - fg.connect ((src1, 0), (nop1, 0)) - fg.connect ((src1, 0), (nop1, 1)) - fg.connect ((nop1, 0), (dst1, 0)) - fg.connect ((nop1, 1), (dst2, 0)) - fg.validate () - fg.disconnect ((src1, 0), (nop1, 1)) - fg.validate () - self.assertRaises (ValueError, - lambda : fg.disconnect ((src1, 0), - (nop1, 1))) - - def test_012_connect (self): - fg = self.fg - src_data = (0, 1, 2, 3) - expected_result = (2, 3, 4, 5) - src1 = gr.vector_source_i (src_data) - op = gr.add_const_ii (2) - dst1 = gr.vector_sink_i () - fg.connect (src1, op) - fg.connect (op, dst1) - # print "edge_list:", fg.edge_list - fg.validate () - - def test_013_connect_varargs (self): - fg = self.fg - src1 = gr.null_source (gr.sizeof_int) - nop1 = gr.nop (gr.sizeof_int) - dst1 = gr.null_sink (gr.sizeof_int) - self.assertRaises (ValueError, - lambda : fg.connect ()) - self.assertRaises (ValueError, - lambda : fg.connect (src1)) - - def test_014_connect_varargs (self): - fg = self.fg - src1 = gr.null_source (gr.sizeof_int) - nop1 = gr.nop (gr.sizeof_int) - dst1 = gr.null_sink (gr.sizeof_int) - fg.connect (src1, nop1, dst1) - fg.validate () - -if __name__ == '__main__': - gr_unittest.main () - diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_flow_graph.py b/gnuradio-core/src/python/gnuradio/gr/qa_flow_graph.py deleted file mode 100755 index 5c84d5fe..00000000 --- a/gnuradio-core/src/python/gnuradio/gr/qa_flow_graph.py +++ /dev/null @@ -1,356 +0,0 @@ -#!/usr/bin/env python -# -# 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 import gr, gr_unittest -import qa_basic_flow_graph - - -def all_counts (): - return (gr.block_ncurrently_allocated (), - gr.block_detail_ncurrently_allocated (), - gr.buffer_ncurrently_allocated (), - gr.buffer_reader_ncurrently_allocated ()) - - -class wrap_add(gr.hier_block): - def __init__(self, fg, a): - add = gr.add_const_ii (a) - gr.hier_block.__init__ (self, fg, add, add) - -class mult_add(gr.hier_block): - def __init__(self, fg, m, a): - mult = gr.multiply_const_ii (m) - add = gr.add_const_ii (a) - fg.connect (mult, add) - gr.hier_block.__init__ (self, fg, mult, add) - - -class test_flow_graph (qa_basic_flow_graph.test_basic_flow_graph): - - def setUp (self): - ''' override qa_basic_flow_graph setUp in order to use our class''' - self.fg = gr.flow_graph () - - def tearDown (self): - qa_basic_flow_graph.test_basic_flow_graph.tearDown (self) - - - # we inherit all their tests, so we can be sure we don't break - # any of the underlying code - - - def leak_check (self, fct): - begin = all_counts () - fct () - # tear down early so we can check for leaks - self.tearDown () - end = all_counts () - self.assertEqual (begin, end) - - def test_100_tsort_null (self): - self.assertEqual ([], self.fg.topological_sort (self.fg.all_blocks ())) - - def test_101_tsort_two (self): - fg = self.fg - src1 = gr.null_source (gr.sizeof_int) - dst1 = gr.null_sink (gr.sizeof_int) - fg.connect ((src1, 0), (dst1, 0)) - fg.validate () - self.assertEqual ([src1, dst1], fg.topological_sort (fg.all_blocks ())) - - def test_102_tsort_three_a (self): - fg = self.fg - src1 = gr.null_source (gr.sizeof_int) - nop1 = gr.nop (gr.sizeof_int) - dst1 = gr.null_sink (gr.sizeof_int) - fg.connect (src1, nop1) - fg.connect (nop1, dst1) - fg.validate () - self.assertEqual ([src1, nop1, dst1], fg.topological_sort (fg.all_blocks ())) - - def test_103_tsort_three_b (self): - fg = self.fg - src1 = gr.null_source (gr.sizeof_int) - nop1 = gr.nop (gr.sizeof_int) - dst1 = gr.null_sink (gr.sizeof_int) - fg.connect (nop1, dst1) - fg.connect (src1, nop1) - fg.validate () - self.assertEqual ([src1, nop1, dst1], fg.topological_sort (fg.all_blocks ())) - - def test_104_trivial_dag_check (self): - fg = self.fg - nop1 = gr.nop (gr.sizeof_int) - fg.connect (nop1, nop1) - fg.validate () - self.assertRaises (gr.NotDAG, - lambda : fg.topological_sort (fg.all_blocks ())) - - def test_105 (self): - fg = self.fg - src1 = gr.null_source (gr.sizeof_int) - src2 = gr.null_source (gr.sizeof_int) - nop1 = gr.nop (gr.sizeof_int) - nop2 = gr.nop (gr.sizeof_int) - nop3 = gr.nop (gr.sizeof_int) - dst1 = gr.null_sink (gr.sizeof_int) - - fg.connect (src1, nop1) - fg.connect (src2, nop2) - fg.connect (nop1, (nop3, 0)) - fg.connect (nop2, (nop3, 1)) - fg.connect (nop3, dst1) - fg.validate () - ts = fg.topological_sort (fg.all_blocks ()) - self.assertEqual ([src2, nop2, src1, nop1, nop3, dst1], ts) - - - def test_106 (self): - fg = self.fg - src1 = gr.null_source (gr.sizeof_int) - src2 = gr.null_source (gr.sizeof_int) - nop1 = gr.nop (gr.sizeof_int) - nop2 = gr.nop (gr.sizeof_int) - nop3 = gr.nop (gr.sizeof_int) - dst1 = gr.null_sink (gr.sizeof_int) - - fg.connect (nop3, dst1) - fg.connect (nop2, (nop3, 1)) - fg.connect (nop1, (nop3, 0)) - fg.connect (src2, nop2) - fg.connect (src1, nop1) - fg.validate () - ts = fg.topological_sort (fg.all_blocks ()) - self.assertEqual ([src2, nop2, src1, nop1, nop3, dst1], ts) - - def test_107 (self): - fg = self.fg - src1 = gr.null_source (gr.sizeof_int) - src2 = gr.null_source (gr.sizeof_int) - nop1 = gr.nop (gr.sizeof_int) - nop2 = gr.nop (gr.sizeof_int) - dst1 = gr.null_sink (gr.sizeof_int) - dst2 = gr.null_sink (gr.sizeof_int) - - fg.connect (src1, nop1) - fg.connect (nop1, dst1) - fg.connect (src2, nop2) - fg.connect (nop2, dst2) - fg.validate () - ts = fg.topological_sort (fg.all_blocks ()) - self.assertEqual ([src2, nop2, dst2, src1, nop1, dst1], ts) - - def test_108 (self): - self.leak_check (self.body_108) - - def body_108 (self): - fg = self.fg - src1 = gr.null_source (gr.sizeof_int) - src2 = gr.null_source (gr.sizeof_int) - nop1 = gr.nop (gr.sizeof_int) - nop2 = gr.nop (gr.sizeof_int) - dst1 = gr.null_sink (gr.sizeof_int) - dst2 = gr.null_sink (gr.sizeof_int) - - fg.connect (nop2, dst2) - fg.connect (src1, nop1) - fg.connect (src2, nop2) - fg.connect (nop1, dst1) - fg.validate () - ts = fg.topological_sort (fg.all_blocks ()) - self.assertEqual ([src2, nop2, dst2, src1, nop1, dst1], ts) - self.assertEqual ((6,0,0,0), all_counts ()) - - def test_109__setup_connections (self): - self.leak_check (self.body_109) - - def body_109 (self): - fg = self.fg - src1 = gr.null_source (gr.sizeof_int) - dst1 = gr.null_sink (gr.sizeof_int) - fg.connect (src1, dst1) - fg._setup_connections () - self.assertEqual ((2,2,1,1), all_counts ()) - - def test_110_scheduler (self): - self.leak_check (self.body_110) - - def body_110 (self): - fg = self.fg - src_data = (0, 1, 2, 3) - src1 = gr.vector_source_i (src_data) - dst1 = gr.vector_sink_i () - fg.connect ((src1, 0), (dst1, 0)) - fg.run () - dst_data = dst1.data () - self.assertEqual (src_data, dst_data) - - def test_111_scheduler (self): - self.leak_check (self.body_111) - - def body_111 (self): - fg = self.fg - src_data = (0, 1, 2, 3) - expected_result = (2, 3, 4, 5) - src1 = gr.vector_source_i (src_data) - op = gr.add_const_ii (2) - dst1 = gr.vector_sink_i () - fg.connect (src1, op) - fg.connect (op, dst1) - fg.run () - dst_data = dst1.data () - self.assertEqual (expected_result, dst_data) - - def test_111v_scheduler (self): - self.leak_check (self.body_111v) - - def body_111v (self): - fg = self.fg - src_data = (0, 1, 2, 3) - expected_result = (2, 3, 4, 5) - src1 = gr.vector_source_i (src_data) - op = gr.add_const_ii (2) - dst1 = gr.vector_sink_i () - fg.connect (src1, op, dst1) - fg.run () - dst_data = dst1.data () - self.assertEqual (expected_result, dst_data) - - def test_112 (self): - fg = self.fg - nop1 = gr.nop (gr.sizeof_int) - nop2 = gr.nop (gr.sizeof_int) - nop3 = gr.nop (gr.sizeof_int) - fg.connect ((nop1, 0), (nop2, 0)) - fg.connect ((nop1, 1), (nop3, 0)) - fg._setup_connections () - self.assertEqual (2, nop1.detail().noutputs()) - - def test_113 (self): - fg = self.fg - nop1 = gr.nop (gr.sizeof_int) - nop2 = gr.nop (gr.sizeof_int) - nop3 = gr.nop (gr.sizeof_int) - fg.connect ((nop1, 0), (nop2, 0)) - fg.connect ((nop1, 0), (nop3, 0)) - fg._setup_connections () - self.assertEqual (1, nop1.detail().noutputs()) - - def test_200_partition (self): - self.leak_check (self.body_200) - - def body_200 (self): - fg = self.fg - src1 = gr.null_source (gr.sizeof_int) - nop1 = gr.nop (gr.sizeof_int) - dst1 = gr.null_sink (gr.sizeof_int) - fg.connect (nop1, dst1) - fg.connect (src1, nop1) - fg.validate () - p = fg.partition_graph (fg.all_blocks ()) - self.assertEqual ([[src1, nop1, dst1]], p) - self.assertEqual ((3,0,0,0), all_counts ()) - - def test_201_partition (self): - self.leak_check (self.body_201) - - def body_201 (self): - fg = self.fg - src1 = gr.null_source (gr.sizeof_int) - src2 = gr.null_source (gr.sizeof_int) - nop1 = gr.nop (gr.sizeof_int) - nop2 = gr.nop (gr.sizeof_int) - dst1 = gr.null_sink (gr.sizeof_int) - dst2 = gr.null_sink (gr.sizeof_int) - - fg.connect (nop2, dst2) - fg.connect (src1, nop1) - fg.connect (src2, nop2) - fg.connect (nop1, dst1) - fg.validate () - p = fg.partition_graph (fg.all_blocks ()) - self.assertEqual ([[src2, nop2, dst2], [src1, nop1, dst1]], p) - self.assertEqual ((6,0,0,0), all_counts ()) - - def test_300_hier (self): - self.leak_check (self.body_300_hier) - - def body_300_hier (self): - fg = self.fg - src_data = (0, 1, 2, 3) - expected_result = (10, 11, 12, 13) - src1 = gr.vector_source_i (src_data) - op = wrap_add (fg, 10) - dst1 = gr.vector_sink_i () - fg.connect (src1, op, dst1) - fg.run () - dst_data = dst1.data () - self.assertEqual (expected_result, dst_data) - - def test_301_hier (self): - self.leak_check (self.body_301_hier) - - def body_301_hier (self): - fg = self.fg - src_data = (0, 1, 2, 3) - expected_result = (5, 8, 11, 14) - src1 = gr.vector_source_i (src_data) - op = mult_add (fg, 3, 5) - dst1 = gr.vector_sink_i () - fg.connect (src1, op, dst1) - fg.run () - dst_data = dst1.data () - self.assertEqual (expected_result, dst_data) - - def test_302_hier (self): - self.leak_check (self.body_302_hier) - - def body_302_hier (self): - fg = self.fg - src_data = (0, 1, 2, 3) - expected_result = (10, 11, 12, 13) - src1 = gr.vector_source_i (src_data) - op = gr.compose (fg, gr.add_const_ii (10)) - dst1 = gr.vector_sink_i () - fg.connect (src1, op, dst1) - fg.run () - dst_data = dst1.data () - self.assertEqual (expected_result, dst_data) - - def test_303_hier (self): - self.leak_check (self.body_303_hier) - - def body_303_hier (self): - fg = self.fg - src_data = (0, 1, 2, 3) - expected_result = (35, 38, 41, 44) - src1 = gr.vector_source_i (src_data) - op = gr.compose (fg, gr.add_const_ii (10), mult_add (fg, 3, 5)) - dst1 = gr.vector_sink_i () - fg.connect (src1, op, dst1) - fg.run () - dst_data = dst1.data () - self.assertEqual (expected_result, dst_data) - - -if __name__ == '__main__': - gr_unittest.main () diff --git a/gnuradio-core/src/python/gnuradio/gr/qa_kludged_imports.py b/gnuradio-core/src/python/gnuradio/gr/qa_kludged_imports.py index c2f1698c..91ddf7cd 100755 --- a/gnuradio-core/src/python/gnuradio/gr/qa_kludged_imports.py +++ b/gnuradio-core/src/python/gnuradio/gr/qa_kludged_imports.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2005 Free Software Foundation, Inc. +# Copyright 2005,2008 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -32,7 +32,7 @@ class test_head (gr_unittest.TestCase): def test_blks_import(self): # make sure that this somewhat magic import works - from gnuradio import blks + from gnuradio import blks2 def test_gru_import(self): # make sure that this somewhat magic import works diff --git a/gnuradio-core/src/tests/test_buffers.py b/gnuradio-core/src/tests/test_buffers.py index 49250ad9..186a60bb 100755 --- a/gnuradio-core/src/tests/test_buffers.py +++ b/gnuradio-core/src/tests/test_buffers.py @@ -43,10 +43,10 @@ import sys #$ cat /proc/sys/kernel/shmmax #300000000 -class my_graph(gr.flow_graph): +class my_graph(gr.top_block): def __init__(self, seconds,history,output_multiple): - gr.flow_graph.__init__(self) + gr.top_block.__init__(self) parser = OptionParser(option_class=eng_option) parser.add_option("-O", "--audio-output", type="string", default="", diff --git a/gnuradio-examples/python/apps/hf_radio/README.TXT b/gnuradio-examples/python/apps/hf_radio/README.TXT index df8a901e..7c7edf5e 100644 --- a/gnuradio-examples/python/apps/hf_radio/README.TXT +++ b/gnuradio-examples/python/apps/hf_radio/README.TXT @@ -1,3 +1,10 @@ +# 2008-02-07 +# +# These files have not yet been update to use the new top_block/hier_block2 +# interfaces. Until someone does that, this files will no longer run. +# + + The files in this directory implement a fairly simple HF radio that works with the basic rx daughter board on the USRP. diff --git a/gnuradio-examples/python/multi-antenna/multi_fft.py b/gnuradio-examples/python/multi-antenna/multi_fft.py index 3a8d4819..0f1dbb10 100755 --- a/gnuradio-examples/python/multi-antenna/multi_fft.py +++ b/gnuradio-examples/python/multi-antenna/multi_fft.py @@ -6,7 +6,7 @@ from gnuradio.eng_option import eng_option from gnuradio import eng_notation from gnuradio import optfir from optparse import OptionParser -from gnuradio.wxgui import stdgui, fftsink, waterfallsink, scopesink, form, slider +from gnuradio.wxgui import stdgui2, fftsink2, waterfallsink2, scopesink2, form, slider import wx from usrpm import usrp_dbid import time @@ -16,10 +16,10 @@ import sys # required FPGA that can do 4 rx channels. -class my_graph(stdgui.gui_flow_graph): +class my_graph(stdgui2.std_top_block): def __init__(self, frame, panel, vbox, argv): - stdgui.gui_flow_graph.__init__(self) + stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) self.frame = frame self.panel = panel @@ -89,9 +89,9 @@ class my_graph(stdgui.gui_flow_graph): #print len(chan_filt_coeffs) for i in range(nchan): - scope = fftsink.fft_sink_c(self, panel, sample_rate=input_rate/sw_decim, - title="Input %d" % (i,), - ref_level=80, y_per_div=20) + scope = fftsink2.fft_sink_c(panel, sample_rate=input_rate/sw_decim, + title="Input %d" % (i,), + ref_level=80, y_per_div=20) vbox.Add(scope.win, 10, wx.EXPAND) if options.filter: @@ -121,7 +121,7 @@ class my_graph(stdgui.gui_flow_graph): def main (): - app = stdgui.stdapp(my_graph, "Multi Scope", nstatus=1) + app = stdgui2.stdapp(my_graph, "Multi Scope", nstatus=1) app.MainLoop() if __name__ == '__main__': diff --git a/gnuradio-examples/python/multi-antenna/multi_file.py b/gnuradio-examples/python/multi-antenna/multi_file.py index d5a5d872..f887b9cf 100755 --- a/gnuradio-examples/python/multi-antenna/multi_file.py +++ b/gnuradio-examples/python/multi-antenna/multi_file.py @@ -6,8 +6,6 @@ from gnuradio.eng_option import eng_option from gnuradio import eng_notation from gnuradio import optfir from optparse import OptionParser -from gnuradio.wxgui import stdgui, fftsink, waterfallsink, scopesink, form, slider -import wx from usrpm import usrp_dbid import time import os.path @@ -16,10 +14,10 @@ import sys # required FPGA that can do 4 rx channels. -class my_graph(gr.flow_graph): +class my_graph(gr.top_block): def __init__(self): - gr.flow_graph.__init__(self) + gr.top_block.__init__(self) parser = OptionParser (option_class=eng_option) #parser.add_option("-S", "--subdev", type="subdev", default=(0, None), diff --git a/gnuradio-examples/python/multi-antenna/multi_scope.py b/gnuradio-examples/python/multi-antenna/multi_scope.py index b35e9165..8db183d6 100755 --- a/gnuradio-examples/python/multi-antenna/multi_scope.py +++ b/gnuradio-examples/python/multi-antenna/multi_scope.py @@ -6,7 +6,7 @@ from gnuradio.eng_option import eng_option from gnuradio import eng_notation from gnuradio import optfir from optparse import OptionParser -from gnuradio.wxgui import stdgui, fftsink, waterfallsink, scopesink, form, slider +from gnuradio.wxgui import stdgui2, fftsink2, waterfallsink2, scopesink2, form, slider import wx from usrpm import usrp_dbid import time @@ -16,10 +16,10 @@ import sys # required FPGA that can do 4 rx channels. -class my_graph(stdgui.gui_flow_graph): +class my_top_block(stdgui2.std_top_block): def __init__(self, frame, panel, vbox, argv): - stdgui.gui_flow_graph.__init__(self) + stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) self.frame = frame self.panel = panel @@ -78,7 +78,8 @@ class my_graph(stdgui.gui_flow_graph): self.connect(self.u, di) # our destination (8 float inputs) - self.scope = scopesink.scope_sink_f(self, panel, sample_rate=input_rate/sw_decim) + self.scope = scopesink2.scope_sink_f(panel, sample_rate=input_rate/sw_decim, + num_inputs=2*nchan) # taps for channel filter chan_filt_coeffs = optfir.low_pass (1, # gain @@ -131,7 +132,7 @@ class my_graph(stdgui.gui_flow_graph): def main (): - app = stdgui.stdapp(my_graph, "Multi Scope", nstatus=1) + app = stdgui2.stdapp(my_top_block, "Multi Scope", nstatus=1) app.MainLoop() if __name__ == '__main__': diff --git a/gnuradio-examples/python/multi_usrp/README b/gnuradio-examples/python/multi_usrp/README index 982f02d9..05723910 100644 --- a/gnuradio-examples/python/multi_usrp/README +++ b/gnuradio-examples/python/multi_usrp/README @@ -1,3 +1,9 @@ +# +# N.B., these files have not been converted to top_block/hier_block2 because +# those of doing the conversion don't have the setup to test this. +# As a result, these programs will no longer run until updated. +# + Quick start multi-usrp: Unpack, build and install usrp, gnuradio-core and gr-usrp diff --git a/gnuradio-examples/python/multi_usrp/multi_usrp_rx_cfile.py b/gnuradio-examples/python/multi_usrp/multi_usrp_rx_cfile.py index 6084aba3..ca0ec97c 100755 --- a/gnuradio-examples/python/multi_usrp/multi_usrp_rx_cfile.py +++ b/gnuradio-examples/python/multi_usrp/multi_usrp_rx_cfile.py @@ -17,10 +17,10 @@ import sys import time from gnuradio import usrp_multi -class my_graph(gr.flow_graph): +class my_top_block(gr.top_block): def __init__(self): - gr.flow_graph.__init__(self) + gr.top_block.__init__(self) usage="%prog: [options] output_filename" parser = OptionParser(option_class=eng_option, usage=usage) @@ -118,12 +118,12 @@ class my_graph(gr.flow_graph): if __name__ == '__main__': - fg=my_graph() - fg.start() + tb=my_top_block() + tb.start() #time.sleep(0.5) - fg.sync_usrps() + tb.sync_usrps() raw_input ('Press Enter to quit: ') - fg.stop() + tb.stop() #try: # fg.start() # fg.sync_usrps() diff --git a/gnuradio-examples/python/ofdm/fftshift.py b/gnuradio-examples/python/ofdm/fftshift.py index 6b355326..98abf5d4 100755 --- a/gnuradio-examples/python/ofdm/fftshift.py +++ b/gnuradio-examples/python/ofdm/fftshift.py @@ -2,9 +2,9 @@ from gnuradio import gr -class my_graph(gr.flow_graph): +class my_top_block(gr.top_block): def __init__(self): - gr.flow_graph.__init__(self) + gr.top_block.__init__(self) length = 101 @@ -32,9 +32,9 @@ class my_graph(gr.flow_graph): def main(): - fg = my_graph() - fg.start() - fg.wait() + tb = my_top_block() + tb.start() + tb.wait() if __name__ == "__main__": try: diff --git a/gnuradio-examples/python/ofdm/ofdm_mod_demod_test.py b/gnuradio-examples/python/ofdm/ofdm_mod_demod_test.py index 0c7857b2..b1521da6 100755 --- a/gnuradio-examples/python/ofdm/ofdm_mod_demod_test.py +++ b/gnuradio-examples/python/ofdm/ofdm_mod_demod_test.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2005, 2006 Free Software Foundation, Inc. +# Copyright 2005,2006,2008 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -28,9 +28,9 @@ from optparse import OptionParser import random, time, struct, sys, math, os -class my_graph(gr.flow_graph): +class my_top_block(gr.top_block): def __init__(self, callback, options): - gr.flow_graph.__init__(self) + gr.top_block.__init__(self) # hard-coded known symbol ks1 = known_symbols_4512_1[0:options.occupied_tones] @@ -143,9 +143,9 @@ def main(): (options, args) = parser.parse_args () # build the graph - fg = my_graph(rx_callback, options) + tb = my_top_block(rx_callback, options) - fg.start() # start flow graph + tb.start() # start flow graph # generate and send packets nbytes = int(1e6 * options.megabytes) @@ -164,7 +164,7 @@ def main(): pktno += 1 send_pkt(eof=True) - fg.wait() # wait for it to finish + tb.wait() # wait for it to finish known_symbols_4512_1 = [-1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, 1, -1, -1, -1, 1, 1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, 1, -1, 1, -1, 1, 1, 1, -1, 1, 1, -1, 1, -1, 1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, -1, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, 1, -1, -1, -1, -1, -1, 1, -1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, 1, 1, -1, 1, -1, 1, -1, 1, -1, -1, 1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, 1, -1, -1, 1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, 1, -1, 1, -1, -1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, -1, 1, 1, -1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, -1, 1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, 1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, -1, 1, -1, 1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -1, 1, 1, 1, 1, -1, -1, 1, 1, 1, 1, 1, -1, -1, 1, 1, 1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, 1, 1, 1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1, -1, 1, 1, 1, 1, -1, -1, 1] diff --git a/gnuradio-examples/python/usrp/limbo/siggen_min2.py b/gnuradio-examples/python/usrp/limbo/siggen_min2.py deleted file mode 100755 index 8709e337..00000000 --- a/gnuradio-examples/python/usrp/limbo/siggen_min2.py +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env python - -from gnuradio import gr -from gnuradio import usrp -from gnuradio import eng_notation -from gnuradio.eng_option import eng_option -from optparse import OptionParser - - - -def build_graph (): - - # interp = 32 - interp = 64 - nchan = 2 - - if nchan == 1: - mux = 0x0098 - #mux = 0x9800 - else: - mux = 0xba98 - - f0 = 100e3 - a0 = 16e3 - duc0 = 5e6 - - f1 = 50e3 - a1 = 16e3 - duc1 = 7e6 - - fg = gr.flow_graph () - - u = usrp.sink_c (0, interp, nchan, mux) - sample_rate = u.dac_freq () / interp - print "sample_rate = ", eng_notation.num_to_str (sample_rate) - print "usb_sample_rate = ", eng_notation.num_to_str (sample_rate * nchan) - - u.set_tx_freq (0, duc0) - u.set_tx_freq (1, duc1) - - interleave = gr.interleave (gr.sizeof_gr_complex) - fg.connect (interleave, u) - - src0 = gr.sig_source_c (sample_rate, gr.GR_SIN_WAVE, f0, a0, 0) - fg.connect (src0, (interleave, 0)) - - if nchan == 2: - if 1: - src1 = gr.sig_source_c (sample_rate, gr.GR_SIN_WAVE, f1, a1, 0) - else: - src1 = gr.noise_source_c (gr.GR_UNIFORM, a1) - fg.connect (src1, (interleave, 1)) - - return fg - - -if __name__ == '__main__': - fg = build_graph () - fg.start () - raw_input ('Press Enter to quit: ') - fg.stop () - diff --git a/gr-howto-write-a-block/doc/qa_howto_1.py b/gr-howto-write-a-block/doc/qa_howto_1.py index aa84908d..3173110f 100755 --- a/gr-howto-write-a-block/doc/qa_howto_1.py +++ b/gr-howto-write-a-block/doc/qa_howto_1.py @@ -6,10 +6,10 @@ import howto class qa_howto (gr_unittest.TestCase): def setUp (self): - self.fg = gr.flow_graph () + self.tb = gr.top_block () def tearDown (self): - self.fg = None + self.tb = None def test_001_square_ff (self): src_data = (-3, 4, -5.5, 2, 3) @@ -17,9 +17,9 @@ class qa_howto (gr_unittest.TestCase): src = gr.vector_source_f (src_data) sqr = howto.square_ff () dst = gr.vector_sink_f () - self.fg.connect (src, sqr) - self.fg.connect (sqr, dst) - self.fg.run () + self.tb.connect (src, sqr) + self.tb.connect (sqr, dst) + self.tb.run () result_data = dst.data () self.assertFloatTuplesAlmostEqual (expected_result, result_data, 6) diff --git a/gr-wxgui/src/python/Makefile.am b/gr-wxgui/src/python/Makefile.am index f466db16..bda7c362 100644 --- a/gr-wxgui/src/python/Makefile.am +++ b/gr-wxgui/src/python/Makefile.am @@ -1,5 +1,5 @@ # -# Copyright 2004,2005 Free Software Foundation, Inc. +# Copyright 2004,2005,2008 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -31,16 +31,11 @@ ourlibdir = $(grpyexecdir)/wxgui ourpython_PYTHON = \ __init__.py \ form.py \ - fftsink.py \ fftsink2.py \ plot.py \ powermate.py \ - scopesink.py \ scopesink2.py \ - waterfallsink.py \ waterfallsink2.py \ slider.py \ - stdgui.py \ stdgui2.py \ - numbersink.py \ numbersink2.py diff --git a/gr-wxgui/src/python/fftsink.py b/gr-wxgui/src/python/fftsink.py deleted file mode 100755 index 85e3a1f9..00000000 --- a/gr-wxgui/src/python/fftsink.py +++ /dev/null @@ -1,488 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2003,2004,2005,2006,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 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 import gr, gru, window -from gnuradio.wxgui import stdgui -import wx -import gnuradio.wxgui.plot as plot -import numpy -import threading -import math - -default_fftsink_size = (640,240) -default_fft_rate = gr.prefs().get_long('wxgui', 'fft_rate', 15) - -class fft_sink_base(object): - def __init__(self, input_is_real=False, baseband_freq=0, y_per_div=10, ref_level=50, - sample_rate=1, fft_size=512, - fft_rate=default_fft_rate, - average=False, avg_alpha=None, title='', peak_hold=False): - - # initialize common attributes - self.baseband_freq = baseband_freq - self.y_divs = 8 - self.y_per_div=y_per_div - self.ref_level = ref_level - self.sample_rate = sample_rate - self.fft_size = fft_size - self.fft_rate = fft_rate - self.average = average - if avg_alpha is None: - self.avg_alpha = 2.0 / fft_rate - else: - self.avg_alpha = avg_alpha - self.title = title - self.peak_hold = peak_hold - self.input_is_real = input_is_real - self.msgq = gr.msg_queue(2) # queue that holds a maximum of 2 messages - - def set_y_per_div(self, y_per_div): - self.y_per_div = y_per_div - - def set_ref_level(self, ref_level): - self.ref_level = ref_level - - def set_average(self, average): - self.average = average - if average: - self.avg.set_taps(self.avg_alpha) - self.set_peak_hold(False) - else: - self.avg.set_taps(1.0) - - def set_peak_hold(self, enable): - self.peak_hold = enable - if enable: - self.set_average(False) - self.win.set_peak_hold(enable) - - def set_avg_alpha(self, avg_alpha): - self.avg_alpha = avg_alpha - - def set_baseband_freq(self, baseband_freq): - self.baseband_freq = baseband_freq - - def set_sample_rate(self, sample_rate): - self.sample_rate = sample_rate - self._set_n() - - def _set_n(self): - self.one_in_n.set_n(max(1, int(self.sample_rate/self.fft_size/self.fft_rate))) - - -class fft_sink_f(gr.hier_block, fft_sink_base): - def __init__(self, fg, parent, baseband_freq=0, - y_per_div=10, ref_level=50, sample_rate=1, fft_size=512, - fft_rate=default_fft_rate, average=False, avg_alpha=None, - title='', size=default_fftsink_size, peak_hold=False): - - fft_sink_base.__init__(self, input_is_real=True, baseband_freq=baseband_freq, - y_per_div=y_per_div, ref_level=ref_level, - sample_rate=sample_rate, fft_size=fft_size, - fft_rate=fft_rate, - average=average, avg_alpha=avg_alpha, title=title, - peak_hold=peak_hold) - - s2p = gr.stream_to_vector(gr.sizeof_float, self.fft_size) - self.one_in_n = gr.keep_one_in_n(gr.sizeof_float * self.fft_size, - max(1, int(self.sample_rate/self.fft_size/self.fft_rate))) - - mywindow = window.blackmanharris(self.fft_size) - fft = gr.fft_vfc(self.fft_size, True, mywindow) - power = 0 - for tap in mywindow: - power += tap*tap - - c2mag = gr.complex_to_mag(self.fft_size) - self.avg = gr.single_pole_iir_filter_ff(1.0, self.fft_size) - - # FIXME We need to add 3dB to all bins but the DC bin - log = gr.nlog10_ff(20, self.fft_size, - -20*math.log10(self.fft_size)-10*math.log10(power/self.fft_size)) - sink = gr.message_sink(gr.sizeof_float * self.fft_size, self.msgq, True) - - fg.connect (s2p, self.one_in_n, fft, c2mag, self.avg, log, sink) - gr.hier_block.__init__(self, fg, s2p, sink) - - self.win = fft_window(self, parent, size=size) - self.set_average(self.average) - - -class fft_sink_c(gr.hier_block, fft_sink_base): - def __init__(self, fg, parent, baseband_freq=0, - y_per_div=10, ref_level=50, sample_rate=1, fft_size=512, - fft_rate=default_fft_rate, average=False, avg_alpha=None, - title='', size=default_fftsink_size, peak_hold=False): - - fft_sink_base.__init__(self, input_is_real=False, baseband_freq=baseband_freq, - y_per_div=y_per_div, ref_level=ref_level, - sample_rate=sample_rate, fft_size=fft_size, - fft_rate=fft_rate, - average=average, avg_alpha=avg_alpha, title=title, - peak_hold=peak_hold) - - s2p = gr.stream_to_vector(gr.sizeof_gr_complex, self.fft_size) - self.one_in_n = gr.keep_one_in_n(gr.sizeof_gr_complex * self.fft_size, - max(1, int(self.sample_rate/self.fft_size/self.fft_rate))) - mywindow = window.blackmanharris(self.fft_size) - power = 0 - for tap in mywindow: - power += tap*tap - - fft = gr.fft_vcc(self.fft_size, True, mywindow) - c2mag = gr.complex_to_mag(fft_size) - self.avg = gr.single_pole_iir_filter_ff(1.0, fft_size) - log = gr.nlog10_ff(20, self.fft_size, - -20*math.log10(self.fft_size)-10*math.log10(power/self.fft_size)) - sink = gr.message_sink(gr.sizeof_float * fft_size, self.msgq, True) - - fg.connect(s2p, self.one_in_n, fft, c2mag, self.avg, log, sink) - gr.hier_block.__init__(self, fg, s2p, sink) - - self.win = fft_window(self, parent, size=size) - self.set_average(self.average) - - -# ------------------------------------------------------------------------ - -myDATA_EVENT = wx.NewEventType() -EVT_DATA_EVENT = wx.PyEventBinder (myDATA_EVENT, 0) - - -class DataEvent(wx.PyEvent): - def __init__(self, data): - wx.PyEvent.__init__(self) - self.SetEventType (myDATA_EVENT) - self.data = data - - def Clone (self): - self.__class__ (self.GetId()) - - -class input_watcher (threading.Thread): - def __init__ (self, msgq, fft_size, event_receiver, **kwds): - threading.Thread.__init__ (self, **kwds) - self.setDaemon (1) - self.msgq = msgq - self.fft_size = fft_size - self.event_receiver = event_receiver - self.keep_running = True - self.start () - - def run (self): - while (self.keep_running): - msg = self.msgq.delete_head() # blocking read of message queue - itemsize = int(msg.arg1()) - nitems = int(msg.arg2()) - - s = msg.to_string() # get the body of the msg as a string - - # There may be more than one FFT frame in the message. - # If so, we take only the last one - if nitems > 1: - start = itemsize * (nitems - 1) - s = s[start:start+itemsize] - - complex_data = numpy.fromstring (s, numpy.float32) - de = DataEvent (complex_data) - wx.PostEvent (self.event_receiver, de) - del de - - -class fft_window (plot.PlotCanvas): - def __init__ (self, fftsink, parent, id = -1, - pos = wx.DefaultPosition, size = wx.DefaultSize, - style = wx.DEFAULT_FRAME_STYLE, name = ""): - plot.PlotCanvas.__init__ (self, parent, id, pos, size, style, name) - - self.y_range = None - self.fftsink = fftsink - self.peak_hold = False - self.peak_vals = None - - self.SetEnableGrid (True) - # self.SetEnableZoom (True) - # self.SetBackgroundColour ('black') - - self.build_popup_menu() - - EVT_DATA_EVENT (self, self.set_data) - wx.EVT_CLOSE (self, self.on_close_window) - self.Bind(wx.EVT_RIGHT_UP, self.on_right_click) - - self.input_watcher = input_watcher(fftsink.msgq, fftsink.fft_size, self) - - - def on_close_window (self, event): - print "fft_window:on_close_window" - self.keep_running = False - - - def set_data (self, evt): - dB = evt.data - L = len (dB) - - if self.peak_hold: - if self.peak_vals is None: - self.peak_vals = dB - else: - self.peak_vals = numpy.maximum(dB, self.peak_vals) - dB = self.peak_vals - - x = max(abs(self.fftsink.sample_rate), abs(self.fftsink.baseband_freq)) - if x >= 1e9: - sf = 1e-9 - units = "GHz" - elif x >= 1e6: - sf = 1e-6 - units = "MHz" - else: - sf = 1e-3 - units = "kHz" - - if self.fftsink.input_is_real: # only plot 1/2 the points - x_vals = ((numpy.arange (L/2) - * (self.fftsink.sample_rate * sf / L)) - + self.fftsink.baseband_freq * sf) - points = numpy.zeros((len(x_vals), 2), numpy.float64) - points[:,0] = x_vals - points[:,1] = dB[0:L/2] - else: - # the "negative freqs" are in the second half of the array - x_vals = ((numpy.arange (-L/2, L/2) - * (self.fftsink.sample_rate * sf / L)) - + self.fftsink.baseband_freq * sf) - points = numpy.zeros((len(x_vals), 2), numpy.float64) - points[:,0] = x_vals - points[:,1] = numpy.concatenate ((dB[L/2:], dB[0:L/2])) - - - lines = plot.PolyLine (points, colour='BLUE') - - graphics = plot.PlotGraphics ([lines], - title=self.fftsink.title, - xLabel = units, yLabel = "dB") - - self.Draw (graphics, xAxis=None, yAxis=self.y_range) - self.update_y_range () - - def set_peak_hold(self, enable): - self.peak_hold = enable - self.peak_vals = None - - def update_y_range (self): - ymax = self.fftsink.ref_level - ymin = self.fftsink.ref_level - self.fftsink.y_per_div * self.fftsink.y_divs - self.y_range = self._axisInterval ('min', ymin, ymax) - - def on_average(self, evt): - # print "on_average" - self.fftsink.set_average(evt.IsChecked()) - - def on_peak_hold(self, evt): - # print "on_peak_hold" - self.fftsink.set_peak_hold(evt.IsChecked()) - - def on_incr_ref_level(self, evt): - # print "on_incr_ref_level" - self.fftsink.set_ref_level(self.fftsink.ref_level - + self.fftsink.y_per_div) - - def on_decr_ref_level(self, evt): - # print "on_decr_ref_level" - self.fftsink.set_ref_level(self.fftsink.ref_level - - self.fftsink.y_per_div) - - def on_incr_y_per_div(self, evt): - # print "on_incr_y_per_div" - self.fftsink.set_y_per_div(next_up(self.fftsink.y_per_div, (1,2,5,10,20))) - - def on_decr_y_per_div(self, evt): - # print "on_decr_y_per_div" - self.fftsink.set_y_per_div(next_down(self.fftsink.y_per_div, (1,2,5,10,20))) - - def on_y_per_div(self, evt): - # print "on_y_per_div" - Id = evt.GetId() - if Id == self.id_y_per_div_1: - self.fftsink.set_y_per_div(1) - elif Id == self.id_y_per_div_2: - self.fftsink.set_y_per_div(2) - elif Id == self.id_y_per_div_5: - self.fftsink.set_y_per_div(5) - elif Id == self.id_y_per_div_10: - self.fftsink.set_y_per_div(10) - elif Id == self.id_y_per_div_20: - self.fftsink.set_y_per_div(20) - - - def on_right_click(self, event): - menu = self.popup_menu - for id, pred in self.checkmarks.items(): - item = menu.FindItemById(id) - item.Check(pred()) - self.PopupMenu(menu, event.GetPosition()) - - - def build_popup_menu(self): - self.id_incr_ref_level = wx.NewId() - self.id_decr_ref_level = wx.NewId() - self.id_incr_y_per_div = wx.NewId() - self.id_decr_y_per_div = wx.NewId() - self.id_y_per_div_1 = wx.NewId() - self.id_y_per_div_2 = wx.NewId() - self.id_y_per_div_5 = wx.NewId() - self.id_y_per_div_10 = wx.NewId() - self.id_y_per_div_20 = wx.NewId() - self.id_average = wx.NewId() - self.id_peak_hold = wx.NewId() - - self.Bind(wx.EVT_MENU, self.on_average, id=self.id_average) - self.Bind(wx.EVT_MENU, self.on_peak_hold, id=self.id_peak_hold) - self.Bind(wx.EVT_MENU, self.on_incr_ref_level, id=self.id_incr_ref_level) - self.Bind(wx.EVT_MENU, self.on_decr_ref_level, id=self.id_decr_ref_level) - self.Bind(wx.EVT_MENU, self.on_incr_y_per_div, id=self.id_incr_y_per_div) - self.Bind(wx.EVT_MENU, self.on_decr_y_per_div, id=self.id_decr_y_per_div) - self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_1) - self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_2) - self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_5) - self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_10) - self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_20) - - - # make a menu - menu = wx.Menu() - self.popup_menu = menu - menu.AppendCheckItem(self.id_average, "Average") - menu.AppendCheckItem(self.id_peak_hold, "Peak Hold") - menu.Append(self.id_incr_ref_level, "Incr Ref Level") - menu.Append(self.id_decr_ref_level, "Decr Ref Level") - # menu.Append(self.id_incr_y_per_div, "Incr dB/div") - # menu.Append(self.id_decr_y_per_div, "Decr dB/div") - menu.AppendSeparator() - # we'd use RadioItems for these, but they're not supported on Mac - menu.AppendCheckItem(self.id_y_per_div_1, "1 dB/div") - menu.AppendCheckItem(self.id_y_per_div_2, "2 dB/div") - menu.AppendCheckItem(self.id_y_per_div_5, "5 dB/div") - menu.AppendCheckItem(self.id_y_per_div_10, "10 dB/div") - menu.AppendCheckItem(self.id_y_per_div_20, "20 dB/div") - - self.checkmarks = { - self.id_average : lambda : self.fftsink.average, - self.id_peak_hold : lambda : self.fftsink.peak_hold, - self.id_y_per_div_1 : lambda : self.fftsink.y_per_div == 1, - self.id_y_per_div_2 : lambda : self.fftsink.y_per_div == 2, - self.id_y_per_div_5 : lambda : self.fftsink.y_per_div == 5, - self.id_y_per_div_10 : lambda : self.fftsink.y_per_div == 10, - self.id_y_per_div_20 : lambda : self.fftsink.y_per_div == 20, - } - - -def next_up(v, seq): - """ - Return the first item in seq that is > v. - """ - for s in seq: - if s > v: - return s - return v - -def next_down(v, seq): - """ - Return the last item in seq that is < v. - """ - rseq = list(seq[:]) - rseq.reverse() - - for s in rseq: - if s < v: - return s - return v - - -# ---------------------------------------------------------------- -# Deprecated interfaces -# ---------------------------------------------------------------- - -# returns (block, win). -# block requires a single input stream of float -# win is a subclass of wxWindow - -def make_fft_sink_f(fg, parent, title, fft_size, input_rate, ymin = 0, ymax=50): - - block = fft_sink_f(fg, parent, title=title, fft_size=fft_size, sample_rate=input_rate, - y_per_div=(ymax - ymin)/8, ref_level=ymax) - return (block, block.win) - -# returns (block, win). -# block requires a single input stream of gr_complex -# win is a subclass of wxWindow - -def make_fft_sink_c(fg, parent, title, fft_size, input_rate, ymin=0, ymax=50): - block = fft_sink_c(fg, parent, title=title, fft_size=fft_size, sample_rate=input_rate, - y_per_div=(ymax - ymin)/8, ref_level=ymax) - return (block, block.win) - - -# ---------------------------------------------------------------- -# Standalone test app -# ---------------------------------------------------------------- - -class test_app_flow_graph (stdgui.gui_flow_graph): - def __init__(self, frame, panel, vbox, argv): - stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv) - - fft_size = 256 - - # build our flow graph - input_rate = 20.48e3 - - # Generate a complex sinusoid - #src1 = gr.sig_source_c (input_rate, gr.GR_SIN_WAVE, 2e3, 1) - src1 = gr.sig_source_c (input_rate, gr.GR_CONST_WAVE, 5.75e3, 1) - - # We add these throttle blocks so that this demo doesn't - # suck down all the CPU available. Normally you wouldn't use these. - thr1 = gr.throttle(gr.sizeof_gr_complex, input_rate) - - sink1 = fft_sink_c (self, panel, title="Complex Data", fft_size=fft_size, - sample_rate=input_rate, baseband_freq=100e3, - ref_level=0, y_per_div=20) - vbox.Add (sink1.win, 1, wx.EXPAND) - self.connect (src1, thr1, sink1) - - #src2 = gr.sig_source_f (input_rate, gr.GR_SIN_WAVE, 2e3, 1) - src2 = gr.sig_source_f (input_rate, gr.GR_CONST_WAVE, 5.75e3, 1) - thr2 = gr.throttle(gr.sizeof_float, input_rate) - sink2 = fft_sink_f (self, panel, title="Real Data", fft_size=fft_size*2, - sample_rate=input_rate, baseband_freq=100e3, - ref_level=0, y_per_div=20) - vbox.Add (sink2.win, 1, wx.EXPAND) - self.connect (src2, thr2, sink2) - -def main (): - app = stdgui.stdapp (test_app_flow_graph, - "FFT Sink Test App") - app.MainLoop () - -if __name__ == '__main__': - main () diff --git a/gr-wxgui/src/python/numbersink.py b/gr-wxgui/src/python/numbersink.py deleted file mode 100755 index 5427d2a4..00000000 --- a/gr-wxgui/src/python/numbersink.py +++ /dev/null @@ -1,614 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2003,2004,2005,2006,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 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., 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. -# - -from gnuradio import gr, gru, window -from gnuradio.wxgui import stdgui -import wx -#from wx import StaticText -import gnuradio.wxgui.plot as plot -import numpy -import threading -import math - -default_numbersink_size = (640,240) -default_number_rate = gr.prefs().get_long('wxgui', 'number_rate', 15) - -class number_sink_base(object): - def __init__(self, input_is_real=False, unit='',base_value=0, minval=-100.0,maxval=100.0,factor=1.0,decimal_places=10, ref_level=50, - sample_rate=1, - number_rate=default_number_rate, - average=False, avg_alpha=None, label='', peak_hold=False): - - # initialize common attributes - self.unit=unit - self.base_value = base_value - self.minval=minval - self.maxval=maxval - self.factor=factor - self.y_divs = 8 - self.decimal_places=decimal_places - self.ref_level = ref_level - self.sample_rate = sample_rate - number_size=1 - self.number_size = number_size - self.number_rate = number_rate - self.average = average - if avg_alpha is None: - self.avg_alpha = 2.0 / number_rate - else: - self.avg_alpha = avg_alpha - self.label = label - self.peak_hold = peak_hold - self.show_gauge = True - self.input_is_real = input_is_real - self.msgq = gr.msg_queue(2) # queue that holds a maximum of 2 messages - - def set_decimal_places(self, decimal_places): - self.decimal_places = decimal_places - - def set_ref_level(self, ref_level): - self.ref_level = ref_level - - def print_current_value(self, comment): - print comment,self.win.current_value - - def set_average(self, average): - self.average = average - if average: - self.avg.set_taps(self.avg_alpha) - self.set_peak_hold(False) - else: - self.avg.set_taps(1.0) - - def set_peak_hold(self, enable): - self.peak_hold = enable - if enable: - self.set_average(False) - self.win.set_peak_hold(enable) - - def set_show_gauge(self, enable): - self.show_gauge = enable - self.win.set_show_gauge(enable) - - def set_avg_alpha(self, avg_alpha): - self.avg_alpha = avg_alpha - - def set_base_value(self, base_value): - self.base_value = base_value - - -class number_sink_f(gr.hier_block, number_sink_base): - def __init__(self, fg, parent, unit='',base_value=0,minval=-100.0,maxval=100.0,factor=1.0, - decimal_places=10, ref_level=50, sample_rate=1, #number_size=512, - number_rate=default_number_rate, average=False, avg_alpha=None, - label='', size=default_numbersink_size, peak_hold=False): - - number_sink_base.__init__(self, unit=unit, input_is_real=True, base_value=base_value, - minval=minval,maxval=maxval,factor=factor, - decimal_places=decimal_places, ref_level=ref_level, - sample_rate=sample_rate, #number_size=number_size, - number_rate=number_rate, - average=average, avg_alpha=avg_alpha, label=label, - peak_hold=peak_hold) - - number_size=1 - #s2p = gr.stream_to_vector(gr.sizeof_float, number_size) - one_in_n = gr.keep_one_in_n(gr.sizeof_float, - max(1, int(sample_rate/number_rate))) - - - #c2mag = gr.complex_to_mag(number_size) - self.avg = gr.single_pole_iir_filter_ff(1.0, number_size) - - # FIXME We need to add 3dB to all bins but the DC bin - #log = gr.nlog10_ff(20, number_size, - # -20*math.log10(number_size)-10*math.log10(power/number_size)) - sink = gr.message_sink(gr.sizeof_float , self.msgq, True) - - #fg.connect (s2p, one_in_n, fft, c2mag, self.avg, log, sink) - fg.connect(self.avg,one_in_n,sink) - gr.hier_block.__init__(self, fg, self.avg, sink) - self.win = number_window(self, parent, size=size,label=label) - self.set_average(self.average) - - -class number_sink_c(gr.hier_block, number_sink_base): - def __init__(self, fg, parent, unit='',base_value=0,minval=-100.0,maxval=100.0,factor=1.0, - decimal_places=10, ref_level=50, sample_rate=1, #number_size=512, - number_rate=default_number_rate, average=False, avg_alpha=None, - label='', size=default_numbersink_size, peak_hold=False): - - number_sink_base.__init__(self, unit=unit, input_is_real=False, base_value=base_value,factor=factor, - minval=minval,maxval=maxval,decimal_places=decimal_places, ref_level=ref_level, - sample_rate=sample_rate, #number_size=number_size, - number_rate=number_rate, - average=average, avg_alpha=avg_alpha, label=label, - peak_hold=peak_hold) - - number_size=1 - one_in_n = gr.keep_one_in_n(gr.sizeof_gr_complex, - max(1, int(sample_rate/number_rate))) - - - #c2mag = gr.complex_to_mag(number_size) - self.avg = gr.single_pole_iir_filter_cc(1.0, number_size) - - # FIXME We need to add 3dB to all bins but the DC bin - #log = gr.nlog10_ff(20, number_size, - # -20*math.log10(number_size)-10*math.log10(power/number_size)) - sink = gr.message_sink(gr.sizeof_gr_complex , self.msgq, True) - - #fg.connect (s2p, one_in_n, fft, c2mag, self.avg, log, sink) - fg.connect(self.avg,one_in_n,sink) - gr.hier_block.__init__(self, fg, self.avg, sink) - self.win = number_window(self, parent, size=size,label=label) - self.set_average(self.average) - - -# ------------------------------------------------------------------------ - -myDATA_EVENT = wx.NewEventType() -EVT_DATA_EVENT = wx.PyEventBinder (myDATA_EVENT, 0) - - -class DataEvent(wx.PyEvent): - def __init__(self, data): - wx.PyEvent.__init__(self) - self.SetEventType (myDATA_EVENT) - self.data = data - - def Clone (self): - self.__class__ (self.GetId()) - - -class input_watcher (threading.Thread): - def __init__ (self, msgq, number_size, event_receiver, **kwds): - threading.Thread.__init__ (self, **kwds) - self.setDaemon (1) - self.msgq = msgq - self.number_size = number_size - self.event_receiver = event_receiver - self.keep_running = True - self.start () - - def run (self): - while (self.keep_running): - msg = self.msgq.delete_head() # blocking read of message queue - itemsize = int(msg.arg1()) - nitems = int(msg.arg2()) - - s = msg.to_string() # get the body of the msg as a string - - # There may be more than one number in the message. - # If so, we take only the last one - if nitems > 1: - start = itemsize * (nitems - 1) - s = s[start:start+itemsize] - - complex_data = numpy.fromstring (s, numpy.float32) - de = DataEvent (complex_data) - wx.PostEvent (self.event_receiver, de) - del de - -#======================================================================================== -class static_text_window (wx.StaticText): #plot.PlotCanvas): - def __init__ (self, parent, numbersink,id = -1,label="number", - pos = wx.DefaultPosition, size = wx.DefaultSize, - style = wx.DEFAULT_FRAME_STYLE, name = ""): - #plot.PlotCanvas.__init__ (self, parent, id, pos, size, style, name) - wx.StaticText.__init__(self, parent, id, label, pos, size, style, name) - #self.static_text=wx.StaticText( parent, id, label, pos, (size[0]/2,size[1]/2), style, name) - #gauge_style = wx.GA_HORIZONTAL - #self.gauge=wx.Gauge( parent, id, range=1000, pos=(pos[0],pos[1]+size[1]/2),size=(size[0]/2,size[1]/2), style=gauge_style, name = "gauge") - #wx.BoxSizer.__init__ (self,wx.VERTICAL) - #self.Add (self.static_text, 0, wx.EXPAND) - #self.Add (self.gauge, 1, wx.EXPAND) - self.parent=parent - self.label=label - #self.y_range = None - self.numbersink = numbersink - self.peak_hold = False - self.peak_vals = None - - #self.SetEnableGrid (True) - # self.SetEnableZoom (True) - # self.SetBackgroundColour ('black') - - self.build_popup_menu() - - #EVT_DATA_EVENT (self, self.set_data) - #wx.EVT_CLOSE (self, self.on_close_window) - #self.Bind(wx.EVT_RIGHT_UP, self.on_right_click) - self.Bind(wx.EVT_RIGHT_UP, self.on_right_click) - - #self.input_watcher = input_watcher(numbersink.msgq, numbersink.number_size, self) - - - def on_close_window (self, event): - print "number_window:on_close_window" - self.keep_running = False - - - def set_peak_hold(self, enable): - self.peak_hold = enable - self.peak_vals = None - - def update_y_range (self): - ymax = self.numbersink.ref_level - ymin = self.numbersink.ref_level - self.numbersink.decimal_places * self.numbersink.y_divs - self.y_range = self._axisInterval ('min', ymin, ymax) - - def on_average(self, evt): - # print "on_average" - self.numbersink.set_average(evt.IsChecked()) - - def on_peak_hold(self, evt): - # print "on_peak_hold" - self.numbersink.set_peak_hold(evt.IsChecked()) - - def on_show_gauge(self, evt): - # print "on_show_gauge" - #if evt.IsChecked(): - self.numbersink.set_show_gauge(evt.IsChecked()) - print evt.IsChecked() - # print "show gauge" - #else: - # self.parent.gauge.Hide() - # print "hide gauge" - - def on_incr_ref_level(self, evt): - # print "on_incr_ref_level" - self.numbersink.set_ref_level(self.numbersink.ref_level - + self.numbersink.decimal_places) - - def on_decr_ref_level(self, evt): - # print "on_decr_ref_level" - self.numbersink.set_ref_level(self.numbersink.ref_level - - self.numbersink.decimal_places) - - def on_incr_decimal_places(self, evt): - # print "on_incr_decimal_places" - self.numbersink.set_decimal_places(self.numbersink.decimal_places+1) #next_up(self.numbersink.decimal_places, (1,2,5,10,20))) - - def on_decr_decimal_places(self, evt): - # print "on_decr_decimal_places" - self.numbersink.set_decimal_places(max(self.numbersink.decimal_places-1,0)) #next_down(self.numbersink.decimal_places, (1,2,5,10,20))) - - def on_decimal_places(self, evt): - # print "on_decimal_places" - Id = evt.GetId() - if Id == self.id_decimal_places_0: - self.numbersink.set_decimal_places(0) - elif Id == self.id_decimal_places_1: - self.numbersink.set_decimal_places(1) - elif Id == self.id_decimal_places_2: - self.numbersink.set_decimal_places(2) - elif Id == self.id_decimal_places_3: - self.numbersink.set_decimal_places(3) - elif Id == self.id_decimal_places_6: - self.numbersink.set_decimal_places(6) - elif Id == self.id_decimal_places_9: - self.numbersink.set_decimal_places(9) - - - def on_right_click(self, event): - menu = self.popup_menu - for id, pred in self.checkmarks.items(): - item = menu.FindItemById(id) - item.Check(pred()) - self.PopupMenu(menu, event.GetPosition()) - - - def build_popup_menu(self): - #self.id_hide_gauge = wx.NewId() - self.id_show_gauge = wx.NewId() - self.id_incr_ref_level = wx.NewId() - self.id_decr_ref_level = wx.NewId() - self.id_incr_decimal_places = wx.NewId() - self.id_decr_decimal_places = wx.NewId() - self.id_decimal_places_0 = wx.NewId() - self.id_decimal_places_1 = wx.NewId() - self.id_decimal_places_2 = wx.NewId() - self.id_decimal_places_3 = wx.NewId() - self.id_decimal_places_6 = wx.NewId() - self.id_decimal_places_9 = wx.NewId() - self.id_average = wx.NewId() - self.id_peak_hold = wx.NewId() - - self.Bind(wx.EVT_MENU, self.on_average, id=self.id_average) - self.Bind(wx.EVT_MENU, self.on_peak_hold, id=self.id_peak_hold) - #self.Bind(wx.EVT_MENU, self.on_hide_gauge, id=self.id_hide_gauge) - self.Bind(wx.EVT_MENU, self.on_show_gauge, id=self.id_show_gauge) - self.Bind(wx.EVT_MENU, self.on_incr_ref_level, id=self.id_incr_ref_level) - self.Bind(wx.EVT_MENU, self.on_decr_ref_level, id=self.id_decr_ref_level) - self.Bind(wx.EVT_MENU, self.on_incr_decimal_places, id=self.id_incr_decimal_places) - self.Bind(wx.EVT_MENU, self.on_decr_decimal_places, id=self.id_decr_decimal_places) - self.Bind(wx.EVT_MENU, self.on_decimal_places, id=self.id_decimal_places_0) - self.Bind(wx.EVT_MENU, self.on_decimal_places, id=self.id_decimal_places_1) - self.Bind(wx.EVT_MENU, self.on_decimal_places, id=self.id_decimal_places_2) - self.Bind(wx.EVT_MENU, self.on_decimal_places, id=self.id_decimal_places_3) - self.Bind(wx.EVT_MENU, self.on_decimal_places, id=self.id_decimal_places_6) - self.Bind(wx.EVT_MENU, self.on_decimal_places, id=self.id_decimal_places_9) - - - # make a menu - menu = wx.Menu() - self.popup_menu = menu - menu.AppendCheckItem(self.id_average, "Average") - menu.AppendCheckItem(self.id_peak_hold, "Peak Hold") - #menu.Append(self.id_hide_gauge, "Hide gauge") - menu.AppendCheckItem(self.id_show_gauge, "Show gauge") - menu.Append(self.id_incr_ref_level, "Incr Ref Level") - menu.Append(self.id_decr_ref_level, "Decr Ref Level") - menu.Append(self.id_incr_decimal_places, "Incr decimal places") - menu.Append(self.id_decr_decimal_places, "Decr decimal places") - menu.AppendSeparator() - # we'd use RadioItems for these, but they're not supported on Mac - menu.AppendCheckItem(self.id_decimal_places_0, "0 decimal places") - menu.AppendCheckItem(self.id_decimal_places_1, "1 decimal places") - menu.AppendCheckItem(self.id_decimal_places_2, "2 decimal places") - menu.AppendCheckItem(self.id_decimal_places_3, "3 decimal places") - menu.AppendCheckItem(self.id_decimal_places_6, "6 decimal places") - menu.AppendCheckItem(self.id_decimal_places_9, "9 decimal places") - - self.checkmarks = { - self.id_average : lambda : self.numbersink.average, - self.id_peak_hold : lambda : self.numbersink.peak_hold,# self.id_hide_gauge : lambda : self.numbersink.hide_gauge, - self.id_show_gauge : lambda : self.numbersink.show_gauge, - self.id_decimal_places_0 : lambda : self.numbersink.decimal_places == 0, - self.id_decimal_places_1 : lambda : self.numbersink.decimal_places == 1, - self.id_decimal_places_2 : lambda : self.numbersink.decimal_places == 2, - self.id_decimal_places_3 : lambda : self.numbersink.decimal_places == 3, - self.id_decimal_places_6 : lambda : self.numbersink.decimal_places == 6, - self.id_decimal_places_9 : lambda : self.numbersink.decimal_places == 9, - } - - -def next_up(v, seq): - """ - Return the first item in seq that is > v. - """ - for s in seq: - if s > v: - return s - return v - -def next_down(v, seq): - """ - Return the last item in seq that is < v. - """ - rseq = list(seq[:]) - rseq.reverse() - - for s in rseq: - if s < v: - return s - return v - - -#======================================================================================== -class number_window (plot.PlotCanvas): - def __init__ (self, numbersink, parent, id = -1,label="number", - pos = wx.DefaultPosition, size = wx.DefaultSize, - style = wx.DEFAULT_FRAME_STYLE, name = ""): - plot.PlotCanvas.__init__ (self, parent, id, pos, size, style, name) - #wx.StaticText.__init__(self, parent, id, label, pos, (size[0]/2,size[1]/2), style, name) - #print 'parent',parent - self.static_text=static_text_window( self, numbersink,id, label, pos, (size[0]/2,size[1]/2), style, name) - gauge_style = wx.GA_HORIZONTAL - vbox=wx.BoxSizer(wx.VERTICAL) - vbox.Add (self.static_text, 0, wx.EXPAND) - self.current_value=None - if numbersink.input_is_real: - self.gauge=wx.Gauge( self, id, range=1000, pos=(pos[0],pos[1]+size[1]/2),size=(size[0]/2,size[1]/2), style=gauge_style, name = "gauge") - vbox.Add (self.gauge, 1, wx.EXPAND) - else: - self.gauge=wx.Gauge( self, id, range=1000, pos=(pos[0],pos[1]+size[1]/3),size=(size[0]/2,size[1]/3), style=gauge_style, name = "gauge") - #hbox=wx.BoxSizer(wx.HORIZONTAL) - self.gauge_imag=wx.Gauge( self, id, range=1000, pos=(pos[0],pos[1]+size[1]*2/3),size=(size[0]/2,size[1]/3), style=gauge_style, name = "gauge_imag") - vbox.Add (self.gauge, 1, wx.EXPAND) - vbox.Add (self.gauge_imag, 1, wx.EXPAND) - #vbox.Add (hbox, 1, wx.EXPAND) - self.sizer = vbox - self.SetSizer (self.sizer) - self.SetAutoLayout (True) - self.sizer.Fit (self) - - self.label=label - #self.y_range = None - self.numbersink = numbersink - self.peak_hold = False - self.peak_vals = None - - #self.SetEnableGrid (True) - # self.SetEnableZoom (True) - # self.SetBackgroundColour ('black') - - #self.build_popup_menu() - - EVT_DATA_EVENT (self, self.set_data) - wx.EVT_CLOSE (self, self.on_close_window) - #self.Bind(wx.EVT_RIGHT_UP, self.on_right_click) - #self.Bind(wx.EVT_RIGHT_UP, self.on_right_click) - - self.input_watcher = input_watcher(numbersink.msgq, numbersink.number_size, self) - - - def on_close_window (self, event): - print "number_window:on_close_window" - self.keep_running = False - - def set_show_gauge(self, enable): - self.show_gauge = enable - if enable: - self.gauge.Show() - if not self.numbersink.input_is_real: - self.gauge_imag.Show() - #print 'show' - else: - self.gauge.Hide() - if not self.numbersink.input_is_real: - self.gauge_imag.Hide() - #print 'hide' - - def set_data (self, evt): - numbers = evt.data - L = len (numbers) - - if self.peak_hold: - if self.peak_vals is None: - self.peak_vals = numbers - else: - self.peak_vals = numpy.maximum(numbers, self.peak_vals) - numbers = self.peak_vals - - if self.numbersink.input_is_real: - real_value=numbers[0]*self.numbersink.factor + self.numbersink.base_value - imag_value=0.0 - self.current_value=real_value - else: - real_value=numbers[0]*self.numbersink.factor + self.numbersink.base_value - imag_value=numbers[1]*self.numbersink.factor + self.numbersink.base_value - self.current_value=complex(real_value,imag_value) - #x = max(abs(self.numbersink.sample_rate), abs(self.numbersink.base_value)) - x = max(real_value, imag_value) - if x >= 1e9: - sf = 1e-9 - unit_prefix = "G" - elif x >= 1e6: - sf = 1e-6 - unit_prefix = "M" - elif x>= 1e3: - sf = 1e-3 - unit_prefix = "k" - else : - sf = 1 - unit_prefix = "" - #self.update_y_range () - if self.numbersink.input_is_real: - showtext = "%s: %.*f %s%s" % (self.label, self.numbersink.decimal_places,real_value*sf,unit_prefix,self.numbersink.unit) - else: - showtext = "%s: %.*f,%.*f %s%s" % (self.label, self.numbersink.decimal_places,real_value*sf, - self.numbersink.decimal_places,imag_value*sf,unit_prefix,self.numbersink.unit) - self.static_text.SetLabel(showtext) - #print (int(float((real_value-self.numbersink.base_value)*1000.0/(self.numbersink.maxval-self.numbersink.minval)))+500) - self.gauge.SetValue(int(float((real_value-self.numbersink.base_value)*1000.0/(self.numbersink.maxval-self.numbersink.minval)))+500) - if not self.numbersink.input_is_real: - self.gauge.SetValue(int(float((imag_value-self.numbersink.base_value)*1000.0/(self.numbersink.maxval-self.numbersink.minval)))+500) - - def set_peak_hold(self, enable): - self.peak_hold = enable - self.peak_vals = None - - def update_y_range (self): - ymax = self.numbersink.ref_level - ymin = self.numbersink.ref_level - self.numbersink.decimal_places * self.numbersink.y_divs - self.y_range = self._axisInterval ('min', ymin, ymax) - - def on_average(self, evt): - # print "on_average" - self.numbersink.set_average(evt.IsChecked()) - - def on_peak_hold(self, evt): - # print "on_peak_hold" - self.numbersink.set_peak_hold(evt.IsChecked()) - - - - - - - - - - -# ---------------------------------------------------------------- -# Deprecated interfaces -# ---------------------------------------------------------------- - -# returns (block, win). -# block requires a single input stream of float -# win is a subclass of wxWindow - -def make_number_sink_f(fg, parent, label, number_size, input_rate, ymin = 0, ymax=50): - - block = number_sink_f(fg, parent, label=label, number_size=number_size, sample_rate=input_rate, - decimal_places=(ymax - ymin)/8, ref_level=ymax) - return (block, block.win) - -# returns (block, win). -# block requires a single input stream of gr_complex -# win is a subclass of wxWindow - -def make_number_sink_c(fg, parent, label, number_size, input_rate, ymin=0, ymax=50): - block = number_sink_c(fg, parent, label=label, number_size=number_size, sample_rate=input_rate, - decimal_places=(ymax - ymin)/8, ref_level=ymax) - return (block, block.win) - - -# ---------------------------------------------------------------- -# Standalone test app -# ---------------------------------------------------------------- - -class test_app_flow_graph (stdgui.gui_flow_graph): - def __init__(self, frame, panel, vbox, argv): - stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv) - - #number_size = 256 - - # build our flow graph - input_rate = 20.48e3 - - # Generate a complex sinusoid - src1 = gr.sig_source_c (input_rate, gr.GR_SIN_WAVE, 2e3, 1) - #src1 = gr.sig_source_c (input_rate, gr.GR_CONST_WAVE, 5.75e3, 1) - - # We add these throttle blocks so that this demo doesn't - # suck down all the CPU available. Normally you wouldn't use these. - thr1 = gr.throttle(gr.sizeof_gr_complex, input_rate) - - #sink1 = number_sink_c (self, panel, label="Complex Data", number_size=number_size, - # sample_rate=input_rate, base_value=100e3, - # ref_level=0, decimal_places=3) - #vbox.Add (sink1.win, 1, wx.EXPAND) - #self.connect (src1, thr1, sink1) - - src2 = gr.sig_source_f (input_rate, gr.GR_SIN_WAVE, 2e3, 1) - #src2 = gr.sig_source_f (input_rate, gr.GR_CONST_WAVE, 5.75e3, 1) - thr2 = gr.throttle(gr.sizeof_float, input_rate) - sink2 = number_sink_f (self, panel, unit='Hz',label="Real Data", avg_alpha=0.001,#number_size=number_size*2, - sample_rate=input_rate, base_value=100e3, - ref_level=0, decimal_places=3) - vbox.Add (sink2.win, 1, wx.EXPAND) - sink3 = number_sink_c (self, panel, unit='V',label="Complex Data", avg_alpha=0.001,#number_size=number_size*2, - sample_rate=input_rate, base_value=0, - ref_level=0, decimal_places=3) - vbox.Add (sink3.win, 1, wx.EXPAND) - self.connect (src2, thr2, sink2) - self.connect (src1, thr1, sink3) -def main (): - app = stdgui.stdapp (test_app_flow_graph, - "Number Sink Test App") - app.MainLoop () - -if __name__ == '__main__': - main () diff --git a/gr-wxgui/src/python/scopesink.py b/gr-wxgui/src/python/scopesink.py deleted file mode 100755 index ffd4529b..00000000 --- a/gr-wxgui/src/python/scopesink.py +++ /dev/null @@ -1,650 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2003,2004,2006,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 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 import gr, gru, eng_notation -from gnuradio.wxgui import stdgui -import wx -import gnuradio.wxgui.plot as plot -import numpy -import threading -import struct - -default_scopesink_size = (640, 240) -default_v_scale = 1000 -default_frame_decim = gr.prefs().get_long('wxgui', 'frame_decim', 1) - -class scope_sink_f(gr.hier_block): - def __init__(self, fg, parent, title='', sample_rate=1, - size=default_scopesink_size, frame_decim=default_frame_decim, - v_scale=default_v_scale, t_scale=None): - msgq = gr.msg_queue(2) # message queue that holds at most 2 messages - self.guts = gr.oscope_sink_f(sample_rate, msgq) - gr.hier_block.__init__(self, fg, self.guts, self.guts) - self.win = scope_window(win_info (msgq, sample_rate, frame_decim, - v_scale, t_scale, self.guts, title), parent) - - def set_sample_rate(self, sample_rate): - self.guts.set_sample_rate(sample_rate) - self.win.info.set_sample_rate(sample_rate) - -class scope_sink_c(gr.hier_block): - def __init__(self, fg, parent, title='', sample_rate=1, - size=default_scopesink_size, frame_decim=default_frame_decim, - v_scale=default_v_scale, t_scale=None): - msgq = gr.msg_queue(2) # message queue that holds at most 2 messages - c2f = gr.complex_to_float() - self.guts = gr.oscope_sink_f(sample_rate, msgq) - fg.connect((c2f, 0), (self.guts, 0)) - fg.connect((c2f, 1), (self.guts, 1)) - gr.hier_block.__init__(self, fg, c2f, self.guts) - self.win = scope_window(win_info(msgq, sample_rate, frame_decim, - v_scale, t_scale, self.guts, title), parent) - - def set_sample_rate(self, sample_rate): - self.guts.set_sample_rate(sample_rate) - self.win.info.set_sample_rate(sample_rate) - -# ======================================================================== -# This is the deprecated interface, retained for compatibility... -# -# returns (block, win). -# block requires a N input stream of float -# win is a subclass of wxWindow - -def make_scope_sink_f (fg, parent, label, input_rate): - block = scope_sink_f(fg, parent, title=label, sample_rate=input_rate) - return (block, block.win) - -# ======================================================================== - - -time_base_list = [ # time / division - 1.0e-7, # 100ns / div - 2.5e-7, - 5.0e-7, - 1.0e-6, # 1us / div - 2.5e-6, - 5.0e-6, - 1.0e-5, # 10us / div - 2.5e-5, - 5.0e-5, - 1.0e-4, # 100us / div - 2.5e-4, - 5.0e-4, - 1.0e-3, # 1ms / div - 2.5e-3, - 5.0e-3, - 1.0e-2, # 10ms / div - 2.5e-2, - 5.0e-2 - ] - -v_scale_list = [ # counts / div, LARGER gains are SMALLER /div, appear EARLIER - 2.0e-3, # 2m / div, don't call it V/div it's actually counts/div - 5.0e-3, - 1.0e-2, - 2.0e-2, - 5.0e-2, - 1.0e-1, - 2.0e-1, - 5.0e-1, - 1.0e+0, - 2.0e+0, - 5.0e+0, - 1.0e+1, - 2.0e+1, - 5.0e+1, - 1.0e+2, - 2.0e+2, - 5.0e+2, - 1.0e+3, - 2.0e+3, - 5.0e+3, - 1.0e+4 # 10000 /div, USRP full scale is -/+ 32767 - ] - - -wxDATA_EVENT = wx.NewEventType() - -def EVT_DATA_EVENT(win, func): - win.Connect(-1, -1, wxDATA_EVENT, func) - -class DataEvent(wx.PyEvent): - def __init__(self, data): - wx.PyEvent.__init__(self) - self.SetEventType (wxDATA_EVENT) - self.data = data - - def Clone (self): - self.__class__ (self.GetId()) - - -class win_info (object): - __slots__ = ['msgq', 'sample_rate', 'frame_decim', 'v_scale', - 'scopesink', 'title', - 'time_scale_cursor', 'v_scale_cursor', 'marker', 'xy', - 'autorange', 'running'] - - def __init__ (self, msgq, sample_rate, frame_decim, v_scale, t_scale, - scopesink, title = "Oscilloscope"): - self.msgq = msgq - self.sample_rate = sample_rate - self.frame_decim = frame_decim - self.scopesink = scopesink - self.title = title; - - self.time_scale_cursor = gru.seq_with_cursor(time_base_list, initial_value = t_scale) - self.v_scale_cursor = gru.seq_with_cursor(v_scale_list, initial_value = v_scale) - - self.marker = 'line' - self.xy = False - if v_scale == None: # 0 and None are both False, but 0 != None - self.autorange = True - else: - self.autorange = False # 0 is a valid v_scale - self.running = True - - def get_time_per_div (self): - return self.time_scale_cursor.current () - - def get_volts_per_div (self): - return self.v_scale_cursor.current () - - def set_sample_rate(self, sample_rate): - self.sample_rate = sample_rate - - def get_sample_rate (self): - return self.sample_rate - - def get_decimation_rate (self): - return 1.0 - - def set_marker (self, s): - self.marker = s - - def get_marker (self): - return self.marker - - -class input_watcher (threading.Thread): - def __init__ (self, msgq, event_receiver, frame_decim, **kwds): - threading.Thread.__init__ (self, **kwds) - self.setDaemon (1) - self.msgq = msgq - self.event_receiver = event_receiver - self.frame_decim = frame_decim - self.iscan = 0 - self.keep_running = True - self.start () - - def run (self): - # print "input_watcher: pid = ", os.getpid () - while (self.keep_running): - msg = self.msgq.delete_head() # blocking read of message queue - if self.iscan == 0: # only display at frame_decim - self.iscan = self.frame_decim - - nchan = int(msg.arg1()) # number of channels of data in msg - nsamples = int(msg.arg2()) # number of samples in each channel - - s = msg.to_string() # get the body of the msg as a string - - bytes_per_chan = nsamples * gr.sizeof_float - - records = [] - for ch in range (nchan): - - start = ch * bytes_per_chan - chan_data = s[start:start+bytes_per_chan] - rec = numpy.fromstring (chan_data, numpy.float32) - records.append (rec) - - # print "nrecords = %d, reclen = %d" % (len (records),nsamples) - - de = DataEvent (records) - wx.PostEvent (self.event_receiver, de) - records = [] - del de - - # end if iscan == 0 - self.iscan -= 1 - - -class scope_window (wx.Panel): - - def __init__ (self, info, parent, id = -1, - pos = wx.DefaultPosition, size = wx.DefaultSize, name = ""): - wx.Panel.__init__ (self, parent, -1) - self.info = info - - vbox = wx.BoxSizer (wx.VERTICAL) - - self.graph = graph_window (info, self, -1) - - vbox.Add (self.graph, 1, wx.EXPAND) - vbox.Add (self.make_control_box(), 0, wx.EXPAND) - vbox.Add (self.make_control2_box(), 0, wx.EXPAND) - - self.sizer = vbox - self.SetSizer (self.sizer) - self.SetAutoLayout (True) - self.sizer.Fit (self) - self.set_autorange(self.info.autorange) - - - # second row of control buttons etc. appears BELOW control_box - def make_control2_box (self): - ctrlbox = wx.BoxSizer (wx.HORIZONTAL) - - self.inc_v_button = wx.Button (self, 1101, " < ", style=wx.BU_EXACTFIT) - self.inc_v_button.SetToolTipString ("Increase vertical range") - wx.EVT_BUTTON (self, 1101, self.incr_v_scale) # ID matches button ID above - - self.dec_v_button = wx.Button (self, 1100, " > ", style=wx.BU_EXACTFIT) - self.dec_v_button.SetToolTipString ("Decrease vertical range") - wx.EVT_BUTTON (self, 1100, self.decr_v_scale) - - self.v_scale_label = wx.StaticText (self, 1002, "None") # vertical /div - self.update_v_scale_label () - - self.autorange_checkbox = wx.CheckBox (self, 1102, "Autorange") - self.autorange_checkbox.SetToolTipString ("Select autorange on/off") - wx.EVT_CHECKBOX(self, 1102, self.autorange_checkbox_event) - - ctrlbox.Add ((5,0) ,0) # left margin space - ctrlbox.Add (self.inc_v_button, 0, wx.EXPAND) - ctrlbox.Add (self.dec_v_button, 0, wx.EXPAND) - ctrlbox.Add (self.v_scale_label, 0, wx.ALIGN_CENTER) - ctrlbox.Add ((20,0) ,0) # spacer - ctrlbox.Add (self.autorange_checkbox, 0, wx.ALIGN_CENTER) - - return ctrlbox - - def make_control_box (self): - ctrlbox = wx.BoxSizer (wx.HORIZONTAL) - - tb_left = wx.Button (self, 1001, " < ", style=wx.BU_EXACTFIT) - tb_left.SetToolTipString ("Increase time base") - wx.EVT_BUTTON (self, 1001, self.incr_timebase) - - - tb_right = wx.Button (self, 1000, " > ", style=wx.BU_EXACTFIT) - tb_right.SetToolTipString ("Decrease time base") - wx.EVT_BUTTON (self, 1000, self.decr_timebase) - - self.time_base_label = wx.StaticText (self, 1002, "") - self.update_timebase_label () - - ctrlbox.Add ((5,0) ,0) - # ctrlbox.Add (wx.StaticText (self, -1, "Horiz Scale: "), 0, wx.ALIGN_CENTER) - ctrlbox.Add (tb_left, 0, wx.EXPAND) - ctrlbox.Add (tb_right, 0, wx.EXPAND) - ctrlbox.Add (self.time_base_label, 0, wx.ALIGN_CENTER) - - ctrlbox.Add ((10,0) ,1) # stretchy space - - ctrlbox.Add (wx.StaticText (self, -1, "Trig: "), 0, wx.ALIGN_CENTER) - self.trig_chan_choice = wx.Choice (self, 1004, - choices = ['Ch1', 'Ch2', 'Ch3', 'Ch4']) - self.trig_chan_choice.SetToolTipString ("Select channel for trigger") - wx.EVT_CHOICE (self, 1004, self.trig_chan_choice_event) - ctrlbox.Add (self.trig_chan_choice, 0, wx.ALIGN_CENTER) - - self.trig_mode_choice = wx.Choice (self, 1005, - choices = ['Auto', 'Pos', 'Neg']) - self.trig_mode_choice.SetToolTipString ("Select trigger slope or Auto (untriggered roll)") - wx.EVT_CHOICE (self, 1005, self.trig_mode_choice_event) - ctrlbox.Add (self.trig_mode_choice, 0, wx.ALIGN_CENTER) - - trig_level50 = wx.Button (self, 1006, "50%") - trig_level50.SetToolTipString ("Set trigger level to 50%") - wx.EVT_BUTTON (self, 1006, self.set_trig_level50) - ctrlbox.Add (trig_level50, 0, wx.EXPAND) - - run_stop = wx.Button (self, 1007, "Run/Stop") - run_stop.SetToolTipString ("Toggle Run/Stop mode") - wx.EVT_BUTTON (self, 1007, self.run_stop) - ctrlbox.Add (run_stop, 0, wx.EXPAND) - - ctrlbox.Add ((10, 0) ,1) # stretchy space - - ctrlbox.Add (wx.StaticText (self, -1, "Fmt: "), 0, wx.ALIGN_CENTER) - self.marker_choice = wx.Choice (self, 1002, choices = self._marker_choices) - self.marker_choice.SetToolTipString ("Select plotting with lines, pluses or dots") - wx.EVT_CHOICE (self, 1002, self.marker_choice_event) - ctrlbox.Add (self.marker_choice, 0, wx.ALIGN_CENTER) - - self.xy_choice = wx.Choice (self, 1003, choices = ['X:t', 'X:Y']) - self.xy_choice.SetToolTipString ("Select X vs time or X vs Y display") - wx.EVT_CHOICE (self, 1003, self.xy_choice_event) - ctrlbox.Add (self.xy_choice, 0, wx.ALIGN_CENTER) - - return ctrlbox - - _marker_choices = ['line', 'plus', 'dot'] - - def update_timebase_label (self): - time_per_div = self.info.get_time_per_div () - s = ' ' + eng_notation.num_to_str (time_per_div) + 's/div' - self.time_base_label.SetLabel (s) - - def decr_timebase (self, evt): - self.info.time_scale_cursor.prev () - self.update_timebase_label () - - def incr_timebase (self, evt): - self.info.time_scale_cursor.next () - self.update_timebase_label () - - def update_v_scale_label (self): - volts_per_div = self.info.get_volts_per_div () - s = ' ' + eng_notation.num_to_str (volts_per_div) + '/div' # Not V/div - self.v_scale_label.SetLabel (s) - - def decr_v_scale (self, evt): - self.info.v_scale_cursor.prev () - self.update_v_scale_label () - - def incr_v_scale (self, evt): - self.info.v_scale_cursor.next () - self.update_v_scale_label () - - def marker_choice_event (self, evt): - s = evt.GetString () - self.set_marker (s) - - def set_autorange(self, on): - if on: - self.v_scale_label.SetLabel(" (auto)") - self.info.autorange = True - self.autorange_checkbox.SetValue(True) - self.inc_v_button.Enable(False) - self.dec_v_button.Enable(False) - else: - if self.graph.y_range: - (l,u) = self.graph.y_range # found by autorange - self.info.v_scale_cursor.set_index_by_value((u-l)/8.0) - self.update_v_scale_label() - self.info.autorange = False - self.autorange_checkbox.SetValue(False) - self.inc_v_button.Enable(True) - self.dec_v_button.Enable(True) - - def autorange_checkbox_event(self, evt): - if evt.Checked(): - self.set_autorange(True) - else: - self.set_autorange(False) - - def set_marker (self, s): - self.info.set_marker (s) # set info for drawing routines - i = self.marker_choice.FindString (s) - assert i >= 0, "Hmmm, set_marker problem" - self.marker_choice.SetSelection (i) - - def set_format_line (self): - self.set_marker ('line') - - def set_format_dot (self): - self.set_marker ('dot') - - def set_format_plus (self): - self.set_marker ('plus') - - def xy_choice_event (self, evt): - s = evt.GetString () - self.info.xy = s == 'X:Y' - - def trig_chan_choice_event (self, evt): - s = evt.GetString () - ch = int (s[-1]) - 1 - self.info.scopesink.set_trigger_channel (ch) - - def trig_mode_choice_event (self, evt): - sink = self.info.scopesink - s = evt.GetString () - if s == 'Pos': - sink.set_trigger_mode (gr.gr_TRIG_POS_SLOPE) - elif s == 'Neg': - sink.set_trigger_mode (gr.gr_TRIG_NEG_SLOPE) - elif s == 'Auto': - sink.set_trigger_mode (gr.gr_TRIG_AUTO) - else: - assert 0, "Bad trig_mode_choice string" - - def set_trig_level50 (self, evt): - self.info.scopesink.set_trigger_level_auto () - - def run_stop (self, evt): - self.info.running = not self.info.running - - -class graph_window (plot.PlotCanvas): - - channel_colors = ['BLUE', 'RED', - 'CYAN', 'MAGENTA', 'GREEN', 'YELLOW'] - - def __init__ (self, info, parent, id = -1, - pos = wx.DefaultPosition, size = (640, 240), - style = wx.DEFAULT_FRAME_STYLE, name = ""): - plot.PlotCanvas.__init__ (self, parent, id, pos, size, style, name) - - self.SetXUseScopeTicks (True) - self.SetEnableGrid (True) - self.SetEnableZoom (True) - self.SetEnableLegend(True) - # self.SetBackgroundColour ('black') - - self.info = info; - self.y_range = None - self.x_range = None - self.avg_y_min = None - self.avg_y_max = None - self.avg_x_min = None - self.avg_x_max = None - - EVT_DATA_EVENT (self, self.format_data) - - self.input_watcher = input_watcher (info.msgq, self, info.frame_decim) - - def channel_color (self, ch): - return self.channel_colors[ch % len(self.channel_colors)] - - def format_data (self, evt): - if not self.info.running: - return - - if self.info.xy: - self.format_xy_data (evt) - return - - info = self.info - records = evt.data - nchannels = len (records) - npoints = len (records[0]) - - objects = [] - - Ts = 1.0 / (info.get_sample_rate () / info.get_decimation_rate ()) - x_vals = Ts * numpy.arange (-npoints/2, npoints/2) - - # preliminary clipping based on time axis here, instead of in graphics code - time_per_window = self.info.get_time_per_div () * 10 - n = int (time_per_window / Ts + 0.5) - n = n & ~0x1 # make even - n = max (2, min (n, npoints)) - - self.SetXUseScopeTicks (True) # use 10 divisions, no labels - - for ch in range(nchannels): - r = records[ch] - - # plot middle n points of record - - lb = npoints/2 - n/2 - ub = npoints/2 + n/2 - # points = zip (x_vals[lb:ub], r[lb:ub]) - points = numpy.zeros ((ub-lb, 2), numpy.float64) - points[:,0] = x_vals[lb:ub] - points[:,1] = r[lb:ub] - - m = info.get_marker () - if m == 'line': - objects.append (plot.PolyLine (points, - colour=self.channel_color (ch), - legend=('Ch%d' % (ch+1,)))) - else: - objects.append (plot.PolyMarker (points, - marker=m, - colour=self.channel_color (ch), - legend=('Ch%d' % (ch+1,)))) - - graphics = plot.PlotGraphics (objects, - title=self.info.title, - xLabel = '', yLabel = '') - - time_per_div = info.get_time_per_div () - x_range = (-5.0 * time_per_div, 5.0 * time_per_div) # ranges are tuples! - volts_per_div = info.get_volts_per_div () - if not self.info.autorange: - self.y_range = (-4.0 * volts_per_div, 4.0 * volts_per_div) - self.Draw (graphics, xAxis=x_range, yAxis=self.y_range) - self.update_y_range () # autorange to self.y_range - - - def format_xy_data (self, evt): - info = self.info - records = evt.data - nchannels = len (records) - npoints = len (records[0]) - - if nchannels < 2: - return - - objects = [] - # points = zip (records[0], records[1]) - points = numpy.zeros ((len(records[0]), 2), numpy.float32) - points[:,0] = records[0] - points[:,1] = records[1] - - self.SetXUseScopeTicks (False) - - m = info.get_marker () - if m == 'line': - objects.append (plot.PolyLine (points, - colour=self.channel_color (0))) - else: - objects.append (plot.PolyMarker (points, - marker=m, - colour=self.channel_color (0))) - - graphics = plot.PlotGraphics (objects, - title=self.info.title, - xLabel = 'I', yLabel = 'Q') - - self.Draw (graphics, xAxis=self.x_range, yAxis=self.y_range) - self.update_y_range () - self.update_x_range () - - - def update_y_range (self): - alpha = 1.0/25 - graphics = self.last_draw[0] - p1, p2 = graphics.boundingBox () # min, max points of graphics - - if self.avg_y_min: # prevent vertical scale from jumping abruptly --? - self.avg_y_min = p1[1] * alpha + self.avg_y_min * (1 - alpha) - self.avg_y_max = p2[1] * alpha + self.avg_y_max * (1 - alpha) - else: # initial guess - self.avg_y_min = p1[1] # -500.0 workaround, sometimes p1 is ~ 10^35 - self.avg_y_max = p2[1] # 500.0 - - self.y_range = self._axisInterval ('auto', self.avg_y_min, self.avg_y_max) - # print "p1 %s p2 %s y_min %s y_max %s y_range %s" \ - # % (p1, p2, self.avg_y_min, self.avg_y_max, self.y_range) - - - def update_x_range (self): - alpha = 1.0/25 - graphics = self.last_draw[0] - p1, p2 = graphics.boundingBox () # min, max points of graphics - - if self.avg_x_min: - self.avg_x_min = p1[0] * alpha + self.avg_x_min * (1 - alpha) - self.avg_x_max = p2[0] * alpha + self.avg_x_max * (1 - alpha) - else: - self.avg_x_min = p1[0] - self.avg_x_max = p2[0] - - self.x_range = self._axisInterval ('auto', self.avg_x_min, self.avg_x_max) - - -# ---------------------------------------------------------------- -# Stand-alone test application -# ---------------------------------------------------------------- - -class test_app_flow_graph (stdgui.gui_flow_graph): - def __init__(self, frame, panel, vbox, argv): - stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv) - - if len(argv) > 1: - frame_decim = int(argv[1]) - else: - frame_decim = 1 - - if len(argv) > 2: - v_scale = float(argv[2]) # start up at this v_scale value - else: - v_scale = None # start up in autorange mode, default - - if len(argv) > 3: - t_scale = float(argv[3]) # start up at this t_scale value - else: - t_scale = None # old behavior - - print "frame decim %s v_scale %s t_scale %s" % (frame_decim,v_scale,t_scale) - - input_rate = 1e6 - - # Generate a complex sinusoid - src0 = gr.sig_source_c (input_rate, gr.GR_SIN_WAVE, 25.1e3, 1e3) - - # We add this throttle block so that this demo doesn't suck down - # all the CPU available. You normally wouldn't use it... - throttle = gr.throttle(gr.sizeof_gr_complex, input_rate) - - scope = scope_sink_c (self, panel,"Secret Data",sample_rate=input_rate, - frame_decim=frame_decim, - v_scale=v_scale, t_scale=t_scale) - vbox.Add (scope.win, 1, wx.EXPAND) - - # wire the blocks together - self.connect (src0, throttle, scope) - -def main (): - app = stdgui.stdapp (test_app_flow_graph, "O'Scope Test App") - app.MainLoop () - -if __name__ == '__main__': - main () - -# ---------------------------------------------------------------- diff --git a/gr-wxgui/src/python/stdgui.py b/gr-wxgui/src/python/stdgui.py deleted file mode 100644 index 17873954..00000000 --- a/gr-wxgui/src/python/stdgui.py +++ /dev/null @@ -1,90 +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. -# - -'''A simple wx gui for GNU Radio applications''' - -import wx -import sys -from gnuradio import gr - - -class stdapp (wx.App): - def __init__ (self, flow_graph_maker, title="GNU Radio", nstatus=2): - self.flow_graph_maker = flow_graph_maker - self.title = title - self._nstatus = nstatus - # All our initialization must come before calling wx.App.__init__. - # OnInit is called from somewhere in the guts of __init__. - wx.App.__init__ (self, redirect=False) - - def OnInit (self): - frame = stdframe (self.flow_graph_maker, self.title, self._nstatus) - frame.Show (True) - self.SetTopWindow (frame) - return True - - -class stdframe (wx.Frame): - def __init__ (self, flow_graph_maker, title="GNU Radio", nstatus=2): - # print "stdframe.__init__" - wx.Frame.__init__(self, None, -1, title) - - self.CreateStatusBar (nstatus) - mainmenu = wx.MenuBar () - - menu = wx.Menu () - item = menu.Append (200, 'E&xit', 'Exit') - self.Bind (wx.EVT_MENU, self.OnCloseWindow, item) - mainmenu.Append (menu, "&File") - self.SetMenuBar (mainmenu) - - self.Bind (wx.EVT_CLOSE, self.OnCloseWindow) - self.panel = stdpanel (self, self, flow_graph_maker) - vbox = wx.BoxSizer(wx.VERTICAL) - vbox.Add(self.panel, 1, wx.EXPAND) - self.SetSizer(vbox) - self.SetAutoLayout(True) - vbox.Fit(self) - - def OnCloseWindow (self, event): - self.flow_graph().stop() - self.Destroy () - - def flow_graph (self): - return self.panel.fg - -class stdpanel (wx.Panel): - def __init__ (self, parent, frame, flow_graph_maker): - # print "stdpanel.__init__" - wx.Panel.__init__ (self, parent, -1) - self.frame = frame - - vbox = wx.BoxSizer (wx.VERTICAL) - self.fg = flow_graph_maker (frame, self, vbox, sys.argv) - self.SetSizer (vbox) - self.SetAutoLayout (True) - vbox.Fit (self) - - self.fg.start () - -class gui_flow_graph (gr.flow_graph): - def __init__ (self, *ignore): - gr.flow_graph.__init__ (self) diff --git a/gr-wxgui/src/python/waterfallsink.py b/gr-wxgui/src/python/waterfallsink.py deleted file mode 100755 index 4803cbeb..00000000 --- a/gr-wxgui/src/python/waterfallsink.py +++ /dev/null @@ -1,475 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2003,2004,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 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 import gr, gru, window -from gnuradio.wxgui import stdgui -import wx -import gnuradio.wxgui.plot as plot -import numpy -import os -import threading -import math - -default_fftsink_size = (640,240) -default_fft_rate = gr.prefs().get_long('wxgui', 'fft_rate', 15) - -class waterfall_sink_base(object): - def __init__(self, input_is_real=False, baseband_freq=0, - sample_rate=1, fft_size=512, - fft_rate=default_fft_rate, - average=False, avg_alpha=None, title=''): - - # initialize common attributes - self.baseband_freq = baseband_freq - self.sample_rate = sample_rate - self.fft_size = fft_size - self.fft_rate = fft_rate - self.average = average - if avg_alpha is None: - self.avg_alpha = 2.0 / fft_rate - else: - self.avg_alpha = avg_alpha - self.title = title - self.input_is_real = input_is_real - self.msgq = gr.msg_queue(2) # queue up to 2 messages - - def set_average(self, average): - self.average = average - if average: - self.avg.set_taps(self.avg_alpha) - else: - self.avg.set_taps(1.0) - - def set_avg_alpha(self, avg_alpha): - self.avg_alpha = avg_alpha - - def set_baseband_freq(self, baseband_freq): - self.baseband_freq = baseband_freq - - def set_sample_rate(self, sample_rate): - self.sample_rate = sample_rate - self._set_n() - - def _set_n(self): - self.one_in_n.set_n(max(1, int(self.sample_rate/self.fft_size/self.fft_rate))) - -class waterfall_sink_f(gr.hier_block, waterfall_sink_base): - def __init__(self, fg, parent, baseband_freq=0, - y_per_div=10, ref_level=50, sample_rate=1, fft_size=512, - fft_rate=default_fft_rate, average=False, avg_alpha=None, - title='', size=default_fftsink_size): - - waterfall_sink_base.__init__(self, input_is_real=True, baseband_freq=baseband_freq, - sample_rate=sample_rate, fft_size=fft_size, - fft_rate=fft_rate, - average=average, avg_alpha=avg_alpha, title=title) - - s2p = gr.serial_to_parallel(gr.sizeof_float, self.fft_size) - self.one_in_n = gr.keep_one_in_n(gr.sizeof_float * self.fft_size, - max(1, int(self.sample_rate/self.fft_size/self.fft_rate))) - mywindow = window.blackmanharris(self.fft_size) - fft = gr.fft_vfc(self.fft_size, True, mywindow) - c2mag = gr.complex_to_mag(self.fft_size) - self.avg = gr.single_pole_iir_filter_ff(1.0, self.fft_size) - log = gr.nlog10_ff(20, self.fft_size, -20*math.log10(self.fft_size)) - sink = gr.message_sink(gr.sizeof_float * self.fft_size, self.msgq, True) - - fg.connect (s2p, self.one_in_n, fft, c2mag, self.avg, log, sink) - gr.hier_block.__init__(self, fg, s2p, sink) - - self.win = waterfall_window(self, parent, size=size) - self.set_average(self.average) - - -class waterfall_sink_c(gr.hier_block, waterfall_sink_base): - def __init__(self, fg, parent, baseband_freq=0, - y_per_div=10, ref_level=50, sample_rate=1, fft_size=512, - fft_rate=default_fft_rate, average=False, avg_alpha=None, - title='', size=default_fftsink_size): - - waterfall_sink_base.__init__(self, input_is_real=False, baseband_freq=baseband_freq, - sample_rate=sample_rate, fft_size=fft_size, - fft_rate=fft_rate, - average=average, avg_alpha=avg_alpha, title=title) - - s2p = gr.serial_to_parallel(gr.sizeof_gr_complex, self.fft_size) - self.one_in_n = gr.keep_one_in_n(gr.sizeof_gr_complex * self.fft_size, - max(1, int(self.sample_rate/self.fft_size/self.fft_rate))) - - mywindow = window.blackmanharris(self.fft_size) - fft = gr.fft_vcc(self.fft_size, True, mywindow) - c2mag = gr.complex_to_mag(self.fft_size) - self.avg = gr.single_pole_iir_filter_ff(1.0, self.fft_size) - log = gr.nlog10_ff(20, self.fft_size, -20*math.log10(self.fft_size)) - sink = gr.message_sink(gr.sizeof_float * self.fft_size, self.msgq, True) - - fg.connect(s2p, self.one_in_n, fft, c2mag, self.avg, log, sink) - gr.hier_block.__init__(self, fg, s2p, sink) - - self.win = waterfall_window(self, parent, size=size) - self.set_average(self.average) - - -# ------------------------------------------------------------------------ - -myDATA_EVENT = wx.NewEventType() -EVT_DATA_EVENT = wx.PyEventBinder (myDATA_EVENT, 0) - - -class DataEvent(wx.PyEvent): - def __init__(self, data): - wx.PyEvent.__init__(self) - self.SetEventType (myDATA_EVENT) - self.data = data - - def Clone (self): - self.__class__ (self.GetId()) - - -class input_watcher (threading.Thread): - def __init__ (self, msgq, fft_size, event_receiver, **kwds): - threading.Thread.__init__ (self, **kwds) - self.setDaemon (1) - self.msgq = msgq - self.fft_size = fft_size - self.event_receiver = event_receiver - self.keep_running = True - self.start () - - def run (self): - while (self.keep_running): - msg = self.msgq.delete_head() # blocking read of message queue - itemsize = int(msg.arg1()) - nitems = int(msg.arg2()) - - s = msg.to_string() # get the body of the msg as a string - - # There may be more than one FFT frame in the message. - # If so, we take only the last one - if nitems > 1: - start = itemsize * (nitems - 1) - s = s[start:start+itemsize] - - complex_data = numpy.fromstring (s, numpy.float32) - de = DataEvent (complex_data) - wx.PostEvent (self.event_receiver, de) - del de - - -class waterfall_window (wx.Panel): - def __init__ (self, fftsink, parent, id = -1, - pos = wx.DefaultPosition, size = wx.DefaultSize, - style = wx.DEFAULT_FRAME_STYLE, name = ""): - wx.Panel.__init__(self, parent, id, pos, size, style, name) - - self.fftsink = fftsink - self.bm = wx.EmptyBitmap(self.fftsink.fft_size, 300, -1) - - self.scale_factor = 5.0 # FIXME should autoscale, or set this - - dc1 = wx.MemoryDC() - dc1.SelectObject(self.bm) - dc1.Clear() - - self.pens = self.make_pens() - - wx.EVT_PAINT( self, self.OnPaint ) - wx.EVT_CLOSE (self, self.on_close_window) - EVT_DATA_EVENT (self, self.set_data) - - self.build_popup_menu() - - wx.EVT_CLOSE (self, self.on_close_window) - self.Bind(wx.EVT_RIGHT_UP, self.on_right_click) - - self.input_watcher = input_watcher(fftsink.msgq, fftsink.fft_size, self) - - - def on_close_window (self, event): - print "waterfall_window: on_close_window" - self.keep_running = False - - def const_list(self,const,len): - return [const] * len - - def make_colormap(self): - r = [] - r.extend(self.const_list(0,96)) - r.extend(range(0,255,4)) - r.extend(self.const_list(255,64)) - r.extend(range(255,128,-4)) - - g = [] - g.extend(self.const_list(0,32)) - g.extend(range(0,255,4)) - g.extend(self.const_list(255,64)) - g.extend(range(255,0,-4)) - g.extend(self.const_list(0,32)) - - b = range(128,255,4) - b.extend(self.const_list(255,64)) - b.extend(range(255,0,-4)) - b.extend(self.const_list(0,96)) - return (r,g,b) - - def make_pens(self): - (r,g,b) = self.make_colormap() - pens = [] - for i in range(0,256): - colour = wx.Colour(r[i], g[i], b[i]) - pens.append( wx.Pen(colour, 2, wx.SOLID)) - return pens - - def OnPaint(self, event): - dc = wx.PaintDC(self) - self.DoDrawing(dc) - - def DoDrawing(self, dc=None): - if dc is None: - dc = wx.ClientDC(self) - dc.DrawBitmap(self.bm, 0, 0, False ) - - - def const_list(self,const,len): - a = [const] - for i in range(1,len): - a.append(const) - return a - - def make_colormap(self): - r = [] - r.extend(self.const_list(0,96)) - r.extend(range(0,255,4)) - r.extend(self.const_list(255,64)) - r.extend(range(255,128,-4)) - - g = [] - g.extend(self.const_list(0,32)) - g.extend(range(0,255,4)) - g.extend(self.const_list(255,64)) - g.extend(range(255,0,-4)) - g.extend(self.const_list(0,32)) - - b = range(128,255,4) - b.extend(self.const_list(255,64)) - b.extend(range(255,0,-4)) - b.extend(self.const_list(0,96)) - return (r,g,b) - - def set_data (self, evt): - dB = evt.data - L = len (dB) - - dc1 = wx.MemoryDC() - dc1.SelectObject(self.bm) - dc1.Blit(0,1,self.fftsink.fft_size,300,dc1,0,0,wx.COPY,False,-1,-1) - - x = max(abs(self.fftsink.sample_rate), abs(self.fftsink.baseband_freq)) - if x >= 1e9: - sf = 1e-9 - units = "GHz" - elif x >= 1e6: - sf = 1e-6 - units = "MHz" - else: - sf = 1e-3 - units = "kHz" - - - if self.fftsink.input_is_real: # only plot 1/2 the points - d_max = L/2 - p_width = 2 - else: - d_max = L/2 - p_width = 1 - - scale_factor = self.scale_factor - if self.fftsink.input_is_real: # real fft - for x_pos in range(0, d_max): - value = int(dB[x_pos] * scale_factor) - value = min(255, max(0, value)) - dc1.SetPen(self.pens[value]) - dc1.DrawRectangle(x_pos*p_width, 0, p_width, 1) - else: # complex fft - for x_pos in range(0, d_max): # positive freqs - value = int(dB[x_pos] * scale_factor) - value = min(255, max(0, value)) - dc1.SetPen(self.pens[value]) - dc1.DrawRectangle(x_pos*p_width + d_max, 0, p_width, 1) - for x_pos in range(0 , d_max): # negative freqs - value = int(dB[x_pos+d_max] * scale_factor) - value = min(255, max(0, value)) - dc1.SetPen(self.pens[value]) - dc1.DrawRectangle(x_pos*p_width, 0, p_width, 1) - - self.DoDrawing (None) - - def on_average(self, evt): - # print "on_average" - self.fftsink.set_average(evt.IsChecked()) - - def on_right_click(self, event): - menu = self.popup_menu - for id, pred in self.checkmarks.items(): - item = menu.FindItemById(id) - item.Check(pred()) - self.PopupMenu(menu, event.GetPosition()) - - - def build_popup_menu(self): - self.id_incr_ref_level = wx.NewId() - self.id_decr_ref_level = wx.NewId() - self.id_incr_y_per_div = wx.NewId() - self.id_decr_y_per_div = wx.NewId() - self.id_y_per_div_1 = wx.NewId() - self.id_y_per_div_2 = wx.NewId() - self.id_y_per_div_5 = wx.NewId() - self.id_y_per_div_10 = wx.NewId() - self.id_y_per_div_20 = wx.NewId() - self.id_average = wx.NewId() - - self.Bind(wx.EVT_MENU, self.on_average, id=self.id_average) - #self.Bind(wx.EVT_MENU, self.on_incr_ref_level, id=self.id_incr_ref_level) - #self.Bind(wx.EVT_MENU, self.on_decr_ref_level, id=self.id_decr_ref_level) - #self.Bind(wx.EVT_MENU, self.on_incr_y_per_div, id=self.id_incr_y_per_div) - #self.Bind(wx.EVT_MENU, self.on_decr_y_per_div, id=self.id_decr_y_per_div) - #self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_1) - #self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_2) - #self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_5) - #self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_10) - #self.Bind(wx.EVT_MENU, self.on_y_per_div, id=self.id_y_per_div_20) - - - # make a menu - menu = wx.Menu() - self.popup_menu = menu - menu.AppendCheckItem(self.id_average, "Average") - # menu.Append(self.id_incr_ref_level, "Incr Ref Level") - # menu.Append(self.id_decr_ref_level, "Decr Ref Level") - # menu.Append(self.id_incr_y_per_div, "Incr dB/div") - # menu.Append(self.id_decr_y_per_div, "Decr dB/div") - # menu.AppendSeparator() - # we'd use RadioItems for these, but they're not supported on Mac - #menu.AppendCheckItem(self.id_y_per_div_1, "1 dB/div") - #menu.AppendCheckItem(self.id_y_per_div_2, "2 dB/div") - #menu.AppendCheckItem(self.id_y_per_div_5, "5 dB/div") - #menu.AppendCheckItem(self.id_y_per_div_10, "10 dB/div") - #menu.AppendCheckItem(self.id_y_per_div_20, "20 dB/div") - - self.checkmarks = { - self.id_average : lambda : self.fftsink.average - #self.id_y_per_div_1 : lambda : self.fftsink.y_per_div == 1, - #self.id_y_per_div_2 : lambda : self.fftsink.y_per_div == 2, - #self.id_y_per_div_5 : lambda : self.fftsink.y_per_div == 5, - #self.id_y_per_div_10 : lambda : self.fftsink.y_per_div == 10, - #self.id_y_per_div_20 : lambda : self.fftsink.y_per_div == 20, - } - - -def next_up(v, seq): - """ - Return the first item in seq that is > v. - """ - for s in seq: - if s > v: - return s - return v - -def next_down(v, seq): - """ - Return the last item in seq that is < v. - """ - rseq = list(seq[:]) - rseq.reverse() - - for s in rseq: - if s < v: - return s - return v - - -# ---------------------------------------------------------------- -# Deprecated interfaces -# ---------------------------------------------------------------- - -# returns (block, win). -# block requires a single input stream of float -# win is a subclass of wxWindow - -def make_waterfall_sink_f(fg, parent, title, fft_size, input_rate): - - block = waterfall_sink_f(fg, parent, title=title, fft_size=fft_size, - sample_rate=input_rate) - return (block, block.win) - -# returns (block, win). -# block requires a single input stream of gr_complex -# win is a subclass of wxWindow - -def make_waterfall_sink_c(fg, parent, title, fft_size, input_rate): - block = waterfall_sink_c(fg, parent, title=title, fft_size=fft_size, - sample_rate=input_rate) - return (block, block.win) - - -# ---------------------------------------------------------------- -# Standalone test app -# ---------------------------------------------------------------- - -class test_app_flow_graph (stdgui.gui_flow_graph): - def __init__(self, frame, panel, vbox, argv): - stdgui.gui_flow_graph.__init__ (self, frame, panel, vbox, argv) - - fft_size = 512 - - # build our flow graph - input_rate = 20.000e3 - - # Generate a complex sinusoid - src1 = gr.sig_source_c (input_rate, gr.GR_SIN_WAVE, 5.75e3, 1000) - #src1 = gr.sig_source_c (input_rate, gr.GR_CONST_WAVE, 5.75e3, 1000) - - # We add these throttle blocks so that this demo doesn't - # suck down all the CPU available. Normally you wouldn't use these. - thr1 = gr.throttle(gr.sizeof_gr_complex, input_rate) - - sink1 = waterfall_sink_c (self, panel, title="Complex Data", fft_size=fft_size, - sample_rate=input_rate, baseband_freq=100e3) - vbox.Add (sink1.win, 1, wx.EXPAND) - self.connect (src1, thr1, sink1) - - # generate a real sinusoid - src2 = gr.sig_source_f (input_rate, gr.GR_SIN_WAVE, 5.75e3, 1000) - #src2 = gr.sig_source_f (input_rate, gr.GR_CONST_WAVE, 5.75e3, 1000) - thr2 = gr.throttle(gr.sizeof_float, input_rate) - sink2 = waterfall_sink_f (self, panel, title="Real Data", fft_size=fft_size, - sample_rate=input_rate, baseband_freq=100e3) - vbox.Add (sink2.win, 1, wx.EXPAND) - self.connect (src2, thr2, sink2) - -def main (): - app = stdgui.stdapp (test_app_flow_graph, - "Waterfall Sink Test App") - app.MainLoop () - -if __name__ == '__main__': - main () -- 2.30.2