diff options
author | eb <eb@221aa14e-8319-0410-a670-987f0aec2ac5> | 2008-02-08 04:36:24 +0000 |
---|---|---|
committer | eb <eb@221aa14e-8319-0410-a670-987f0aec2ac5> | 2008-02-08 04:36:24 +0000 |
commit | 05005e3d3fad3c9baee9906714510b5d12e0fa6f (patch) | |
tree | 6f3785d80ac03b213dce984c9eb14be9b4c86571 /gnuradio-core/src/python/gnuradio | |
parent | 42ad2adb86981f4488edbe33169683f787b807c3 (diff) |
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
Diffstat (limited to 'gnuradio-core/src/python/gnuradio')
38 files changed, 6 insertions, 5559 deletions
diff --git a/gnuradio-core/src/python/gnuradio/Makefile.am b/gnuradio-core/src/python/gnuradio/Makefile.am index 388681e550..d01882151a 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 48cfff0e76..0000000000 --- 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 08836bbc0c..0000000000 --- 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 74fa098d46..0000000000 --- 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 a4917cf64c..0000000000 --- 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 d449d74fb5..0000000000 --- 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 21980a22e5..0000000000 --- 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 dc9526e9ab..0000000000 --- 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 b7451d4737..0000000000 --- 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 635ad1dbc3..0000000000 --- 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 6ec66825c1..0000000000 --- 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 fcf7d8ebce..0000000000 --- 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 a7ba245949..0000000000 --- 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 344d84d9be..0000000000 --- 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 473a70af35..0000000000 --- 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 5cc8652786..0000000000 --- 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 6ec0635605..0000000000 --- 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 49b052bc59..0000000000 --- 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 d5e677eeb2..0000000000 --- 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 acedf3b69a..0000000000 --- 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 22b1e1dabb..0000000000 --- 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 7a72406880..0000000000 --- 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 7ccb5afced..0000000000 --- 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 76b24cd905..0000000000 --- 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 604e5c88b3..0000000000 --- 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 b3e8ad7acc..0000000000 --- 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 b2b9451cf8..0000000000 --- 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 ffcdc1446f..0000000000 --- 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 5ee49cea56..0000000000 --- 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 89528a8285..0000000000 --- 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 77cc53e3f6..7406d062d9 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 774996be07..15ff17d7ef 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 13152dd296..0000000000 --- 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 '<endpoint (%s, %s)>' % (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 '<edge (%s, %s)>' % (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 39e479b289..0000000000 --- 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 8bcf6421c6..0000000000 --- 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 0799c72e48..0000000000 --- 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 5c84d5fe0f..0000000000 --- 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 c2f1698c88..91ddf7cd70 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 |