summaryrefslogtreecommitdiff
path: root/gr-digital/examples/narrowband
diff options
context:
space:
mode:
Diffstat (limited to 'gr-digital/examples/narrowband')
-rw-r--r--gr-digital/examples/narrowband/README153
-rwxr-xr-xgr-digital/examples/narrowband/benchmark_add_channel.py102
-rwxr-xr-xgr-digital/examples/narrowband/benchmark_rx.py141
-rwxr-xr-xgr-digital/examples/narrowband/benchmark_tx.py154
-rwxr-xr-xgr-digital/examples/narrowband/digital_bert_rx.py211
-rwxr-xr-xgr-digital/examples/narrowband/digital_bert_tx.py138
-rw-r--r--gr-digital/examples/narrowband/receive_path.py155
-rwxr-xr-xgr-digital/examples/narrowband/rx_voice.py164
-rw-r--r--gr-digital/examples/narrowband/transmit_path.py126
-rwxr-xr-xgr-digital/examples/narrowband/tunnel.py297
-rwxr-xr-xgr-digital/examples/narrowband/tx_voice.py171
-rw-r--r--gr-digital/examples/narrowband/uhd_interface.py225
12 files changed, 0 insertions, 2037 deletions
diff --git a/gr-digital/examples/narrowband/README b/gr-digital/examples/narrowband/README
deleted file mode 100644
index 1c50ad69b..000000000
--- a/gr-digital/examples/narrowband/README
+++ /dev/null
@@ -1,153 +0,0 @@
-Quick overview of what's here:
-
-* benchmark_tx.py: generates packets of the size you
-specify and sends them across the air using the USRP. Known to work
-well using the USRP with the RFX transceiver daughterboards.
-You can specify the bitrate to use with the -r <bitrate> command line
-parameter. The default is 500k. Some machines will do 1M or more.
-You can select the modulation to use with the -m <modulation> command
-line argument. The legal values for <modulation> are gmsk, dbpsk and dqpsk.
-
-* benchmark_rx.py: the receiver half of benchmark_tx.py.
-Command line arguments are pretty much the same as rx. Works well
-with a USRP and RFX transceiver daughterboards. Will also work
-with TVRX daugherboard, but you'll need to fiddle with the gain. See
-below. Prints a summary of each packet received and keeps a running
-total of packets received, and how many of them were error free.
-There are two levels of error reporting going on. If the access code
-(PN code) and header of a packet were properly detected, then you'll
-get an output line. If the CRC32 of the payload was correct you get
-"ok = True", else "ok = False". The "pktno" is extracted from the
-received packet. If there are skipped numbers, you're missing some
-packets. Be sure you've got a suitable antenna connected to the TX/RX
-port on each board. For the RFX-400, "70 cm" / 420 MHz antennas for ham
-handi-talkies work great. These are available at ham radio supplies,
-etc. The boards need to be at least 3m apart. You can also try
-experimenting with the rx gain (-g <gain> command line option).
-
-Generally speaking, I start the rx first on one machine, and then fire
-up the tx on the other machine. The tx also supports a discontinous
-transmission mode where it sends bursts of 5 packets and then waits 1
-second. This is useful for ensuring that all the receiver control
-loops lock up fast enough.
-
-* tunnel.py: This program provides a framework for building your own
-MACs. It creates a "TAP" interface in the kernel, typically gr0,
-and sends and receives ethernet frames through it. See
-/usr/src/linux/Documentation/networking/tuntap.txt and/or Google for
-"universal tun tap". The Linux 2.6 kernel includes the tun module, you
-don't have to build it. You may have to "modprobe tun" if it's not
-loaded by default. If /dev/net/tun doesn't exist, try "modprobe tun".
-
-To run this program you'll need to be root or running with the
-appropriate capability to open the tun interface. You'll need to fire
-up two copies on different machines. Once each is running you'll need
-to ifconfig the gr0 interface to set the IP address.
-
-This will allow two machines to talk, but anything beyond the two
-machines depends on your networking setup. Left as an exercise...
-
-On machine A:
-
- $ su
- # ./tunnel.py --freq 423.0M --bitrate 500k
- # # in another window on A, also as root...
- # ifconfig gr0 192.168.200.1
-
-
-On machine B:
-
- $ su
- # ./tunnel.py --freq 423.0M --bitrate 500k
- # # in another window on B, also as root...
- # ifconfig gr0 192.168.200.2
-
-Now, on machine A you shold be able to ping machine B:
-
- $ ping 192.168.200.2
-
-and you should see some output for each packet in the
-tunnel.py window if you used the -v option.
-
-Likewise, on machine B:
-
- $ ping 192.168.200.1
-
-This now uses a carrier sense MAC, so you should be able to ssh
-between the machines, web browse, etc.
-
-* run_length.py: This program takes a single argument '-f FILE' and
-outputs the number of runs of similar bits within the file. It is
-useful as a diagnostic tool when experimenting with line coding or
-whitening algorithms.
-
-
-
-**********************************************************************
-**********************************************************************
-
-
-BERT testing example scripts
-
-benchmark_tx.py
-
-This sets up a BPSK transmitter that is modulated with a pseudorandom
-sequence of bits. The PN code is generated by sending an all 1s
-sequence through a 7-bit scrambler. The transmitter performs the BPSK
-modulation, then passes the complex baseband waveform through a
-root-raised-cosine filter and onto the USRP.
-
-The --sps parameter controls how many baseband samples per symbol
-are created and passed through the RRC filter, prior to going to the
-USRP over the USB for interpolation to the final DAC rate.
-
-The baseband bit rate is controlled by -r or --rate. This value, when
-multiplied by the --sps parameter, must result in valid interpolation
-rate for the USRP. For example, if the baseband rate is 250k bits/sec,
-and the samples per symbol is 4, then the final rate is 1M samples/sec,
-which results in an interpolation rate of 128. The valid interpolation
-rates for the USRP are multiples of 4 between 16 and 512.
-
-Finally, the RRC excess bandwidth may be specified by --excess-bw.
-(See ./benchmark_tx.py -h for additional parameters.)
-
-
-benchmark_rx.py
-
-This sets up a BPSK receiver to demodulate the received waveform. It
-accepts a similar set of parameters as the transmitter, except that one
-specifies the USRP decimation rate desired. The resulting sample stream
-rate must be an integral number of baseband symbols. For example, the
-parameters corresponding to the above transmitter would be to use a
-decimation rate of 8 (32 sps), 16 (16 sps), 32 (8 sps), 64, (4 sps), or
-128 (2 sps). The lower the USRP decimation, the more CPU is required to
-demodulate the signal, so not all valid decimation rates will work.
-
-The baseband signal from the USRP is first passed through an AGC to
-establish an average power of 1.0. It is then passed through a matched
-filter (another RRC), a Costas phase-locked loop, and a Mueller and
-Muller bit timing recovery loop. The resulting constellation has an SNR
-estimation probe attached, and is then sliced into a bit stream.
-
-The recovered bits are then passed through a 7-bit descrambler. If
-there are no channel errors, the all 1s sequence is recovered. In the
-event of a channel error, there will be a 0 in the bit stream for each
-feedback tap in the descrambler. In this case, the CCSDS descrambler is
-using 3 feedback taps.
-
-Finally, the signal is passed into a bit density measurement probe. The
-channel BER is measured by dividing the 0s density by three. This
-measurement is inaccurate at high BER rates (>10%) as the error 0s
-begin to overlap.
-
-The benchmark script will, once per second, output the Costas loop
-frequency offset, the recovered timing error, the estimated SNR, and the
-average BER.
-
-NOTE: The particular SNR estimator used is inaccurate below about 7dB,
-and will report erroneously high values even for random noise.
-
-There are a variety of Costas and M&M loop parameters one can adjust.
-See ./benchmark_rx.py -h for the full set.
-
-
diff --git a/gr-digital/examples/narrowband/benchmark_add_channel.py b/gr-digital/examples/narrowband/benchmark_add_channel.py
deleted file mode 100755
index c69ee60b0..000000000
--- a/gr-digital/examples/narrowband/benchmark_add_channel.py
+++ /dev/null
@@ -1,102 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2010,2011 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# GNU Radio is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from gnuradio import gr
-from gnuradio import eng_notation
-from gnuradio.eng_option import eng_option
-from optparse import OptionParser
-
-import random, math, sys
-
-class my_top_block(gr.top_block):
- def __init__(self, ifile, ofile, options):
- gr.top_block.__init__(self)
-
- SNR = 10.0**(options.snr/10.0)
- frequency_offset = options.frequency_offset
- time_offset = options.time_offset
- phase_offset = options.phase_offset*(math.pi/180.0)
-
- # calculate noise voltage from SNR
- power_in_signal = abs(options.tx_amplitude)**2
- noise_power = power_in_signal/SNR
- noise_voltage = math.sqrt(noise_power)
-
- self.src = gr.file_source(gr.sizeof_gr_complex, ifile)
- #self.throttle = gr.throttle(gr.sizeof_gr_complex, options.sample_rate)
- self.channel = gr.channel_model(noise_voltage, frequency_offset,
- time_offset, noise_seed=-random.randint(0,100000))
- self.phase = gr.multiply_const_cc(complex(math.cos(phase_offset),
- math.sin(phase_offset)))
- self.snk = gr.file_sink(gr.sizeof_gr_complex, ofile)
-
- self.connect(self.src, self.channel, self.phase, self.snk)
-
-
-# /////////////////////////////////////////////////////////////////////////////
-# main
-# /////////////////////////////////////////////////////////////////////////////
-
-def main():
- # Create Options Parser:
- usage = "benchmack_add_channel.py [options] <input file> <output file>"
- parser = OptionParser (usage=usage, option_class=eng_option, conflict_handler="resolve")
- parser.add_option("-n", "--snr", type="eng_float", default=30,
- help="set the SNR of the channel in dB [default=%default]")
- parser.add_option("", "--seed", action="store_true", default=False,
- help="use a random seed for AWGN noise [default=%default]")
- parser.add_option("-f", "--frequency-offset", type="eng_float", default=0,
- help="set frequency offset introduced by channel [default=%default]")
- parser.add_option("-t", "--time-offset", type="eng_float", default=1.0,
- help="set timing offset between Tx and Rx [default=%default]")
- parser.add_option("-p", "--phase-offset", type="eng_float", default=0,
- help="set phase offset (in degrees) between Tx and Rx [default=%default]")
- parser.add_option("-m", "--use-multipath", action="store_true", default=False,
- help="Use a multipath channel [default=%default]")
- parser.add_option("", "--tx-amplitude", type="eng_float",
- default=1.0,
- help="tell the simulator the signal amplitude [default=%default]")
-
- (options, args) = parser.parse_args ()
-
- if len(args) != 2:
- parser.print_help(sys.stderr)
- sys.exit(1)
-
- ifile = args[0]
- ofile = args[1]
-
- # build the graph
- tb = my_top_block(ifile, ofile, options)
-
- r = gr.enable_realtime_scheduling()
- if r != gr.RT_OK:
- print "Warning: Failed to enable realtime scheduling."
-
- tb.start() # start flow graph
- tb.wait() # wait for it to finish
-
-if __name__ == '__main__':
- try:
- main()
- except KeyboardInterrupt:
- pass
diff --git a/gr-digital/examples/narrowband/benchmark_rx.py b/gr-digital/examples/narrowband/benchmark_rx.py
deleted file mode 100755
index 1962fdc4b..000000000
--- a/gr-digital/examples/narrowband/benchmark_rx.py
+++ /dev/null
@@ -1,141 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2010,2011 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# GNU Radio is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from gnuradio import gr, gru
-from gnuradio import eng_notation
-from gnuradio.eng_option import eng_option
-from optparse import OptionParser
-
-# From gr-digital
-from gnuradio import digital
-
-# from current dir
-from receive_path import receive_path
-from uhd_interface import uhd_receiver
-
-import struct
-import sys
-
-#import os
-#print os.getpid()
-#raw_input('Attach and press enter: ')
-
-class my_top_block(gr.top_block):
- def __init__(self, demodulator, rx_callback, options):
- gr.top_block.__init__(self)
-
- if(options.rx_freq is not None):
- # Work-around to get the modulation's bits_per_symbol
- args = demodulator.extract_kwargs_from_options(options)
- symbol_rate = options.bitrate / demodulator(**args).bits_per_symbol()
-
- self.source = uhd_receiver(options.args, symbol_rate,
- options.samples_per_symbol,
- options.rx_freq, options.rx_gain,
- options.spec, options.antenna,
- options.verbose)
- options.samples_per_symbol = self.source._sps
-
- elif(options.from_file is not None):
- sys.stderr.write(("Reading samples from '%s'.\n\n" % (options.from_file)))
- self.source = gr.file_source(gr.sizeof_gr_complex, options.from_file)
- else:
- sys.stderr.write("No source defined, pulling samples from null source.\n\n")
- self.source = gr.null_source(gr.sizeof_gr_complex)
-
- # Set up receive path
- # do this after for any adjustments to the options that may
- # occur in the sinks (specifically the UHD sink)
- self.rxpath = receive_path(demodulator, rx_callback, options)
-
- self.connect(self.source, self.rxpath)
-
-
-# /////////////////////////////////////////////////////////////////////////////
-# main
-# /////////////////////////////////////////////////////////////////////////////
-
-global n_rcvd, n_right
-
-def main():
- global n_rcvd, n_right
-
- n_rcvd = 0
- n_right = 0
-
- def rx_callback(ok, payload):
- global n_rcvd, n_right
- (pktno,) = struct.unpack('!H', payload[0:2])
- n_rcvd += 1
- if ok:
- n_right += 1
-
- print "ok = %5s pktno = %4d n_rcvd = %4d n_right = %4d" % (
- ok, pktno, n_rcvd, n_right)
-
- demods = digital.modulation_utils.type_1_demods()
-
- # Create Options Parser:
- parser = OptionParser (option_class=eng_option, conflict_handler="resolve")
- expert_grp = parser.add_option_group("Expert")
-
- parser.add_option("-m", "--modulation", type="choice", choices=demods.keys(),
- default='psk',
- help="Select modulation from: %s [default=%%default]"
- % (', '.join(demods.keys()),))
- parser.add_option("","--from-file", default=None,
- help="input file of samples to demod")
-
- receive_path.add_options(parser, expert_grp)
- uhd_receiver.add_options(parser)
-
- for mod in demods.values():
- mod.add_options(expert_grp)
-
- (options, args) = parser.parse_args ()
-
- if len(args) != 0:
- parser.print_help(sys.stderr)
- sys.exit(1)
-
- if options.from_file is None:
- if options.rx_freq is None:
- sys.stderr.write("You must specify -f FREQ or --freq FREQ\n")
- parser.print_help(sys.stderr)
- sys.exit(1)
-
-
- # build the graph
- tb = my_top_block(demods[options.modulation], rx_callback, options)
-
- r = gr.enable_realtime_scheduling()
- if r != gr.RT_OK:
- print "Warning: Failed to enable realtime scheduling."
-
- tb.start() # start flow graph
- tb.wait() # wait for it to finish
-
-if __name__ == '__main__':
- try:
- main()
- except KeyboardInterrupt:
- pass
diff --git a/gr-digital/examples/narrowband/benchmark_tx.py b/gr-digital/examples/narrowband/benchmark_tx.py
deleted file mode 100755
index 9afacb495..000000000
--- a/gr-digital/examples/narrowband/benchmark_tx.py
+++ /dev/null
@@ -1,154 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2010,2011 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# GNU Radio is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from gnuradio import gr
-from gnuradio import eng_notation
-from gnuradio.eng_option import eng_option
-from optparse import OptionParser
-
-# From gr-digital
-from gnuradio import digital
-
-# from current dir
-from transmit_path import transmit_path
-from uhd_interface import uhd_transmitter
-
-import time, struct, sys
-
-#import os
-#print os.getpid()
-#raw_input('Attach and press enter')
-
-class my_top_block(gr.top_block):
- def __init__(self, modulator, options):
- gr.top_block.__init__(self)
-
- if(options.tx_freq is not None):
- # Work-around to get the modulation's bits_per_symbol
- args = modulator.extract_kwargs_from_options(options)
- symbol_rate = options.bitrate / modulator(**args).bits_per_symbol()
-
- self.sink = uhd_transmitter(options.args, symbol_rate,
- options.samples_per_symbol,
- options.tx_freq, options.tx_gain,
- options.spec, options.antenna,
- options.verbose)
- options.samples_per_symbol = self.sink._sps
-
- elif(options.to_file is not None):
- sys.stderr.write(("Saving samples to '%s'.\n\n" % (options.to_file)))
- self.sink = gr.file_sink(gr.sizeof_gr_complex, options.to_file)
- else:
- sys.stderr.write("No sink defined, dumping samples to null sink.\n\n")
- self.sink = gr.null_sink(gr.sizeof_gr_complex)
-
- # do this after for any adjustments to the options that may
- # occur in the sinks (specifically the UHD sink)
- self.txpath = transmit_path(modulator, options)
-
- self.connect(self.txpath, self.sink)
-
-# /////////////////////////////////////////////////////////////////////////////
-# main
-# /////////////////////////////////////////////////////////////////////////////
-
-def main():
-
- def send_pkt(payload='', eof=False):
- return tb.txpath.send_pkt(payload, eof)
-
- mods = digital.modulation_utils.type_1_mods()
-
- parser = OptionParser(option_class=eng_option, conflict_handler="resolve")
- expert_grp = parser.add_option_group("Expert")
-
- parser.add_option("-m", "--modulation", type="choice", choices=mods.keys(),
- default='psk',
- help="Select modulation from: %s [default=%%default]"
- % (', '.join(mods.keys()),))
-
- parser.add_option("-s", "--size", type="eng_float", default=1500,
- help="set packet size [default=%default]")
- parser.add_option("-M", "--megabytes", type="eng_float", default=1.0,
- help="set megabytes to transmit [default=%default]")
- parser.add_option("","--discontinuous", action="store_true", default=False,
- help="enable discontinous transmission (bursts of 5 packets)")
- parser.add_option("","--from-file", default=None,
- help="use intput file for packet contents")
- parser.add_option("","--to-file", default=None,
- help="Output file for modulated samples")
-
- transmit_path.add_options(parser, expert_grp)
- uhd_transmitter.add_options(parser)
-
- for mod in mods.values():
- mod.add_options(expert_grp)
-
- (options, args) = parser.parse_args ()
-
- if len(args) != 0:
- parser.print_help()
- sys.exit(1)
-
- if options.from_file is not None:
- source_file = open(options.from_file, 'r')
-
- # build the graph
- tb = my_top_block(mods[options.modulation], options)
-
- r = gr.enable_realtime_scheduling()
- if r != gr.RT_OK:
- print "Warning: failed to enable realtime scheduling"
-
- tb.start() # start flow graph
-
- # generate and send packets
- nbytes = int(1e6 * options.megabytes)
- n = 0
- pktno = 0
- pkt_size = int(options.size)
-
- while n < nbytes:
- if options.from_file is None:
- data = (pkt_size - 2) * chr(pktno & 0xff)
- else:
- data = source_file.read(pkt_size - 2)
- if data == '':
- break;
-
- payload = struct.pack('!H', pktno & 0xffff) + data
- send_pkt(payload)
- n += len(payload)
- sys.stderr.write('.')
- if options.discontinuous and pktno % 5 == 4:
- time.sleep(1)
- pktno += 1
-
- send_pkt(eof=True)
-
- tb.wait() # wait for it to finish
-
-if __name__ == '__main__':
- try:
- main()
- except KeyboardInterrupt:
- pass
diff --git a/gr-digital/examples/narrowband/digital_bert_rx.py b/gr-digital/examples/narrowband/digital_bert_rx.py
deleted file mode 100755
index 4055aa244..000000000
--- a/gr-digital/examples/narrowband/digital_bert_rx.py
+++ /dev/null
@@ -1,211 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2008,2011 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# GNU Radio is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from gnuradio import gr, eng_notation
-from optparse import OptionParser
-from gnuradio.eng_option import eng_option
-import gnuradio.gr.gr_threading as _threading
-import sys, time, math
-
-from gnuradio import digital
-
-# from current dir
-from uhd_interface import uhd_receiver
-
-n2s = eng_notation.num_to_str
-
-class status_thread(_threading.Thread):
- def __init__(self, tb):
- _threading.Thread.__init__(self)
- self.setDaemon(1)
- self.tb = tb
- self.done = False
- self.start()
-
- def run(self):
- while not self.done:
- print "Freq. Offset: {0:5.0f} Hz Timing Offset: {1:10.1f} ppm Estimated SNR: {2:4.1f} dB BER: {3:g}".format(
- tb.frequency_offset(), tb.timing_offset()*1e6, tb.snr(), tb.ber())
- try:
- time.sleep(1.0)
- except KeyboardInterrupt:
- self.done = True
-
-
-
-class bert_receiver(gr.hier_block2):
- def __init__(self, bitrate,
- constellation, samples_per_symbol,
- differential, excess_bw, gray_coded,
- freq_bw, timing_bw, phase_bw,
- verbose, log):
-
- gr.hier_block2.__init__(self, "bert_receive",
- gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
- gr.io_signature(0, 0, 0)) # Output signature
-
- self._bitrate = bitrate
-
- self._demod = digital.generic_demod(constellation, samples_per_symbol,
- differential, excess_bw, gray_coded,
- freq_bw, timing_bw, phase_bw,
- verbose, log)
-
- self._symbol_rate = self._bitrate / self._demod.bits_per_symbol()
- self._sample_rate = self._symbol_rate * samples_per_symbol
-
- # Add an SNR probe on the demodulated constellation
- self._snr_probe = digital.probe_mpsk_snr_est_c(digital.SNR_EST_M2M4, alpha=10.0/self._symbol_rate)
- self.connect(self._demod.time_recov, self._snr_probe)
-
- # Descramble BERT sequence. A channel error will create 3 incorrect bits
- self._descrambler = gr.descrambler_bb(0x8A, 0x7F, 7) # CCSDS 7-bit descrambler
-
- # Measure BER by the density of 0s in the stream
- self._ber = gr.probe_density_b(1.0/self._symbol_rate)
-
- self.connect(self, self._demod, self._descrambler, self._ber)
-
- def frequency_offset(self):
- return self._demod.freq_recov.get_frequency()*self._sample_rate/(2*math.pi)
-
- def timing_offset(self):
- return self._demod.time_recov.get_clock_rate()
-
- def snr(self):
- return self._snr_probe.snr()
-
- def ber(self):
- return (1.0-self._ber.density())/3.0
-
-
-
-class rx_psk_block(gr.top_block):
- def __init__(self, demod, options):
-
- gr.top_block.__init__(self, "rx_mpsk")
-
- self._demodulator_class = demod
-
- # Get demod_kwargs
- demod_kwargs = self._demodulator_class.extract_kwargs_from_options(options)
-
- # demodulator
- self._demodulator = self._demodulator_class(**demod_kwargs)
-
- if(options.rx_freq is not None):
- symbol_rate = options.bitrate / self._demodulator.bits_per_symbol()
- self._source = uhd_receiver(options.args, symbol_rate,
- options.samples_per_symbol,
- options.rx_freq, options.rx_gain,
- options.spec,
- options.antenna, options.verbose)
- options.samples_per_symbol = self._source._sps
-
- elif(options.from_file is not None):
- self._source = gr.file_source(gr.sizeof_gr_complex, options.from_file)
- else:
- self._source = gr.null_source(gr.sizeof_gr_complex)
-
- # Create the BERT receiver
- self._receiver = bert_receiver(options.bitrate,
- self._demodulator._constellation,
- options.samples_per_symbol,
- options.differential,
- options.excess_bw,
- gray_coded=True,
- freq_bw=options.freq_bw,
- timing_bw=options.timing_bw,
- phase_bw=options.phase_bw,
- verbose=options.verbose,
- log=options.log)
-
- self.connect(self._source, self._receiver)
-
- def snr(self):
- return self._receiver.snr()
-
- def mag(self):
- return self._receiver.signal_mean()
-
- def var(self):
- return self._receiver.noise_variance()
-
- def ber(self):
- return self._receiver.ber()
-
- def frequency_offset(self):
- return self._receiver.frequency_offset()
-
- def timing_offset(self):
- return self._receiver.timing_offset()
-
-
-def get_options(demods):
- parser = OptionParser(option_class=eng_option, conflict_handler="resolve")
- parser.add_option("","--from-file", default=None,
- help="input file of samples to demod")
- parser.add_option("-m", "--modulation", type="choice", choices=demods.keys(),
- default='psk',
- help="Select modulation from: %s [default=%%default]"
- % (', '.join(demods.keys()),))
- parser.add_option("-r", "--bitrate", type="eng_float", default=250e3,
- help="Select modulation bit rate (default=%default)")
- parser.add_option("-S", "--samples-per-symbol", type="float", default=2,
- help="set samples/symbol [default=%default]")
- if not parser.has_option("--verbose"):
- parser.add_option("-v", "--verbose", action="store_true", default=False)
- if not parser.has_option("--log"):
- parser.add_option("", "--log", action="store_true", default=False,
- help="Log all parts of flow graph to files (CAUTION: lots of data)")
-
- uhd_receiver.add_options(parser)
-
- demods = digital.modulation_utils.type_1_demods()
- for mod in demods.values():
- mod.add_options(parser)
-
- (options, args) = parser.parse_args()
- if len(args) != 0:
- parser.print_help()
- sys.exit(1)
-
- return (options, args)
-
-
-if __name__ == "__main__":
- demods = digital.modulation_utils.type_1_demods()
-
- (options, args) = get_options(demods)
-
- demod = demods[options.modulation]
- tb = rx_psk_block(demod, options)
-
- print "\n*** SNR estimator is inaccurate below about 7dB"
- print "*** BER estimator is inaccurate above about 10%\n"
- updater = status_thread(tb)
-
- try:
- tb.run()
- except KeyboardInterrupt:
- updater.done = True
- updater = None
diff --git a/gr-digital/examples/narrowband/digital_bert_tx.py b/gr-digital/examples/narrowband/digital_bert_tx.py
deleted file mode 100755
index f29e997af..000000000
--- a/gr-digital/examples/narrowband/digital_bert_tx.py
+++ /dev/null
@@ -1,138 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2008,2011 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# GNU Radio is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from gnuradio import gr, eng_notation
-from gnuradio.eng_option import eng_option
-from optparse import OptionParser
-import sys
-
-from gnuradio import digital
-
-# from current dir
-from uhd_interface import uhd_transmitter
-
-n2s = eng_notation.num_to_str
-
-class bert_transmit(gr.hier_block2):
- def __init__(self, constellation, samples_per_symbol,
- differential, excess_bw, gray_coded,
- verbose, log):
-
- gr.hier_block2.__init__(self, "bert_transmit",
- gr.io_signature(0, 0, 0), # Output signature
- gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Input signature
-
- # Create BERT data bit stream
- self._bits = gr.vector_source_b([1,], True) # Infinite stream of ones
- self._scrambler = gr.scrambler_bb(0x8A, 0x7F, 7) # CCSDS 7-bit scrambler
-
- self._mod = digital.generic_mod(constellation, samples_per_symbol,
- differential, excess_bw, gray_coded,
- verbose, log)
-
- self._pack = gr.unpacked_to_packed_bb(self._mod.bits_per_symbol(), gr.GR_MSB_FIRST)
-
- self.connect(self._bits, self._scrambler, self._pack, self._mod, self)
-
-
-class tx_psk_block(gr.top_block):
- def __init__(self, mod, options):
- gr.top_block.__init__(self, "tx_mpsk")
-
- self._modulator_class = mod
-
- # Get mod_kwargs
- mod_kwargs = self._modulator_class.extract_kwargs_from_options(options)
-
- # transmitter
- self._modulator = self._modulator_class(**mod_kwargs)
-
- if(options.tx_freq is not None):
- symbol_rate = options.bitrate / self._modulator.bits_per_symbol()
- self._sink = uhd_transmitter(options.args, symbol_rate,
- options.samples_per_symbol,
- options.tx_freq, options.tx_gain,
- options.spec,
- options.antenna, options.verbose)
- options.samples_per_symbol = self._sink._sps
-
- elif(options.to_file is not None):
- self._sink = gr.file_sink(gr.sizeof_gr_complex, options.to_file)
- else:
- self._sink = gr.null_sink(gr.sizeof_gr_complex)
-
-
- self._transmitter = bert_transmit(self._modulator._constellation,
- options.samples_per_symbol,
- options.differential,
- options.excess_bw,
- gray_coded=True,
- verbose=options.verbose,
- log=options.log)
-
- self.amp = gr.multiply_const_cc(options.amplitude)
- self.connect(self._transmitter, self.amp, self._sink)
-
-
-def get_options(mods):
- parser = OptionParser(option_class=eng_option, conflict_handler="resolve")
- parser.add_option("-m", "--modulation", type="choice", choices=mods.keys(),
- default='psk',
- help="Select modulation from: %s [default=%%default]"
- % (', '.join(mods.keys()),))
- parser.add_option("", "--amplitude", type="eng_float", default=0.2,
- help="set Tx amplitude (0-1) (default=%default)")
- parser.add_option("-r", "--bitrate", type="eng_float", default=250e3,
- help="Select modulation bit rate (default=%default)")
- parser.add_option("-S", "--samples-per-symbol", type="float", default=2,
- help="set samples/symbol [default=%default]")
- parser.add_option("","--to-file", default=None,
- help="Output file for modulated samples")
- if not parser.has_option("--verbose"):
- parser.add_option("-v", "--verbose", action="store_true", default=False)
- if not parser.has_option("--log"):
- parser.add_option("", "--log", action="store_true", default=False)
-
- uhd_transmitter.add_options(parser)
-
- for mod in mods.values():
- mod.add_options(parser)
-
- (options, args) = parser.parse_args()
- if len(args) != 0:
- parser.print_help()
- sys.exit(1)
-
- return (options, args)
-
-if __name__ == "__main__":
- mods = digital.modulation_utils.type_1_mods()
-
- (options, args) = get_options(mods)
-
- mod = mods[options.modulation]
- tb = tx_psk_block(mod, options)
-
- try:
- tb.run()
- except KeyboardInterrupt:
- pass
diff --git a/gr-digital/examples/narrowband/receive_path.py b/gr-digital/examples/narrowband/receive_path.py
deleted file mode 100644
index 1f9310506..000000000
--- a/gr-digital/examples/narrowband/receive_path.py
+++ /dev/null
@@ -1,155 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2005-2007,2011 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# GNU Radio is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from gnuradio import gr, gru
-from gnuradio import eng_notation
-from gnuradio import digital
-
-import copy
-import sys
-
-# /////////////////////////////////////////////////////////////////////////////
-# receive path
-# /////////////////////////////////////////////////////////////////////////////
-
-class receive_path(gr.hier_block2):
- def __init__(self, demod_class, rx_callback, options):
- gr.hier_block2.__init__(self, "receive_path",
- gr.io_signature(1, 1, gr.sizeof_gr_complex),
- gr.io_signature(0, 0, 0))
-
- options = copy.copy(options) # make a copy so we can destructively modify
-
- self._verbose = options.verbose
- self._bitrate = options.bitrate # desired bit rate
-
- self._rx_callback = rx_callback # this callback is fired when a packet arrives
- self._demod_class = demod_class # the demodulator_class we're using
-
- self._chbw_factor = options.chbw_factor # channel filter bandwidth factor
-
- # Get demod_kwargs
- demod_kwargs = self._demod_class.extract_kwargs_from_options(options)
-
- # Build the demodulator
- self.demodulator = self._demod_class(**demod_kwargs)
-
- # Make sure the channel BW factor is between 1 and sps/2
- # or the filter won't work.
- if(self._chbw_factor < 1.0 or self._chbw_factor > self.samples_per_symbol()/2):
- sys.stderr.write("Channel bandwidth factor ({0}) must be within the range [1.0, {1}].\n".format(self._chbw_factor, self.samples_per_symbol()/2))
- sys.exit(1)
-
- # Design filter to get actual channel we want
- sw_decim = 1
- chan_coeffs = gr.firdes.low_pass (1.0, # gain
- sw_decim * self.samples_per_symbol(), # sampling rate
- self._chbw_factor, # midpoint of trans. band
- 0.5, # width of trans. band
- gr.firdes.WIN_HANN) # filter type
- self.channel_filter = gr.fft_filter_ccc(sw_decim, chan_coeffs)
-
- # receiver
- self.packet_receiver = \
- digital.demod_pkts(self.demodulator,
- access_code=None,
- callback=self._rx_callback,
- threshold=-1)
-
- # Carrier Sensing Blocks
- alpha = 0.001
- thresh = 30 # in dB, will have to adjust
- self.probe = gr.probe_avg_mag_sqrd_c(thresh,alpha)
-
- # Display some information about the setup
- if self._verbose:
- self._print_verbage()
-
- # connect block input to channel filter
- self.connect(self, self.channel_filter)
-
- # connect the channel input filter to the carrier power detector
- self.connect(self.channel_filter, self.probe)
-
- # connect channel filter to the packet receiver
- self.connect(self.channel_filter, self.packet_receiver)
-
- def bitrate(self):
- return self._bitrate
-
- def samples_per_symbol(self):
- return self.demodulator._samples_per_symbol
-
- def differential(self):
- return self.demodulator._differential
-
- def carrier_sensed(self):
- """
- Return True if we think carrier is present.
- """
- #return self.probe.level() > X
- return self.probe.unmuted()
-
- def carrier_threshold(self):
- """
- Return current setting in dB.
- """
- return self.probe.threshold()
-
- def set_carrier_threshold(self, threshold_in_db):
- """
- Set carrier threshold.
-
- @param threshold_in_db: set detection threshold
- @type threshold_in_db: float (dB)
- """
- self.probe.set_threshold(threshold_in_db)
-
-
- def add_options(normal, expert):
- """
- Adds receiver-specific options to the Options Parser
- """
- if not normal.has_option("--bitrate"):
- normal.add_option("-r", "--bitrate", type="eng_float", default=100e3,
- help="specify bitrate [default=%default].")
- normal.add_option("-v", "--verbose", action="store_true", default=False)
- expert.add_option("-S", "--samples-per-symbol", type="float", default=2,
- help="set samples/symbol [default=%default]")
- expert.add_option("", "--log", action="store_true", default=False,
- help="Log all parts of flow graph to files (CAUTION: lots of data)")
- expert.add_option("", "--chbw-factor", type="float", default=1.0,
- help="Channel bandwidth = chbw_factor x signal bandwidth [defaut=%default]")
-
- # Make a static method to call before instantiation
- add_options = staticmethod(add_options)
-
-
- def _print_verbage(self):
- """
- Prints information about the receive path
- """
- print "\nReceive Path:"
- print "modulation: %s" % (self._demod_class.__name__)
- print "bitrate: %sb/s" % (eng_notation.num_to_str(self._bitrate))
- print "samples/symbol: %.4f" % (self.samples_per_symbol())
- print "Differential: %s" % (self.differential())
diff --git a/gr-digital/examples/narrowband/rx_voice.py b/gr-digital/examples/narrowband/rx_voice.py
deleted file mode 100755
index 100caff8e..000000000
--- a/gr-digital/examples/narrowband/rx_voice.py
+++ /dev/null
@@ -1,164 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2005,2006,2009,2011 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# GNU Radio is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from gnuradio import gr, blks2, audio, uhd
-from gnuradio import eng_notation
-from gnuradio.eng_option import eng_option
-from optparse import OptionParser
-
-from gnuradio import digital
-from gnuradio import vocoder
-
-import random
-import struct
-import sys
-
-# from current dir
-from receive_path import receive_path
-from uhd_interface import uhd_receiver
-
-#import os
-#print os.getpid()
-#raw_input('Attach and press enter')
-
-
-class audio_tx(gr.hier_block2):
- def __init__(self, audio_output_dev):
- gr.hier_block2.__init__(self, "audio_tx",
- gr.io_signature(0, 0, 0), # Input signature
- gr.io_signature(0, 0, 0)) # Output signature
-
- self.sample_rate = sample_rate = 8000
- self.packet_src = gr.message_source(33)
- voice_decoder = vocoder.gsm_fr_decode_ps()
- s2f = gr.short_to_float ()
- sink_scale = gr.multiply_const_ff(1.0/32767.)
- audio_sink = audio.sink(sample_rate, audio_output_dev)
- self.connect(self.packet_src, voice_decoder, s2f, sink_scale, audio_sink)
-
- def msgq(self):
- return self.packet_src.msgq()
-
-
-class my_top_block(gr.top_block):
- def __init__(self, demod_class, rx_callback, options):
- gr.top_block.__init__(self)
- self.rxpath = receive_path(demod_class, rx_callback, options)
- self.audio_tx = audio_tx(options.audio_output)
-
- if(options.rx_freq is not None):
- self.source = uhd_receiver(options.args, options.bitrate,
- options.samples_per_symbol,
- options.rx_freq, options.rx_gain,
- options.antenna, options.verbose)
- options.samples_per_symbol = self.source._sps
-
- audio_rate = self.audio_tx.sample_rate
- usrp_rate = self.source.get_sample_rate()
- rrate = audio_rate / usrp_rate
- self.resampler = blks2.pfb_arb_resampler_ccf(rrate)
-
- self.connect(self.source, self.resampler, self.rxpath)
-
- elif(options.from_file is not None):
- self.thr = gr.throttle(gr.sizeof_gr_complex, options.bitrate)
- self.source = gr.file_source(gr.sizeof_gr_complex, options.from_file)
- self.connect(self.source, self.thr, self.rxpath)
-
- else:
- self.thr = gr.throttle(gr.sizeof_gr_complex, 1e6)
- self.source = gr.null_source(gr.sizeof_gr_complex)
- self.connect(self.source, self.thr, self.rxpath)
-
- self.connect(self.audio_tx)
-
-# /////////////////////////////////////////////////////////////////////////////
-# main
-# /////////////////////////////////////////////////////////////////////////////
-
-global n_rcvd, n_right
-
-def main():
- global n_rcvd, n_right
-
- n_rcvd = 0
- n_right = 0
-
- def rx_callback(ok, payload):
- global n_rcvd, n_right
- n_rcvd += 1
- if ok:
- n_right += 1
-
- tb.audio_tx.msgq().insert_tail(gr.message_from_string(payload))
-
- print "ok = %r n_rcvd = %4d n_right = %4d" % (
- ok, n_rcvd, n_right)
-
- demods = digital.modulation_utils.type_1_demods()
-
- # Create Options Parser:
- parser = OptionParser (option_class=eng_option, conflict_handler="resolve")
- expert_grp = parser.add_option_group("Expert")
-
- parser.add_option("-m", "--modulation", type="choice", choices=demods.keys(),
- default='gmsk',
- help="Select modulation from: %s [default=%%default]"
- % (', '.join(demods.keys()),))
- parser.add_option("-O", "--audio-output", type="string", default="",
- help="pcm output device name. E.g., hw:0,0 or /dev/dsp")
- parser.add_option("","--from-file", default=None,
- help="input file of samples to demod")
- receive_path.add_options(parser, expert_grp)
- uhd_receiver.add_options(parser)
-
- for mod in demods.values():
- mod.add_options(expert_grp)
-
- parser.set_defaults(bitrate=50e3) # override default bitrate default
- (options, args) = parser.parse_args ()
-
- if len(args) != 0:
- parser.print_help(sys.stderr)
- sys.exit(1)
-
- if options.from_file is None:
- if options.rx_freq is None:
- sys.stderr.write("You must specify -f FREQ or --freq FREQ\n")
- parser.print_help(sys.stderr)
- sys.exit(1)
-
-
- # build the graph
- tb = my_top_block(demods[options.modulation], rx_callback, options)
-
- r = gr.enable_realtime_scheduling()
- if r != gr.RT_OK:
- print "Warning: Failed to enable realtime scheduling."
-
- tb.run()
-
-if __name__ == '__main__':
- try:
- main()
- except KeyboardInterrupt:
- pass
diff --git a/gr-digital/examples/narrowband/transmit_path.py b/gr-digital/examples/narrowband/transmit_path.py
deleted file mode 100644
index 4d6162ed6..000000000
--- a/gr-digital/examples/narrowband/transmit_path.py
+++ /dev/null
@@ -1,126 +0,0 @@
-#
-# Copyright 2005-2007,2011 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# GNU Radio is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from gnuradio import gr
-from gnuradio import eng_notation
-from gnuradio import digital
-
-import copy
-import sys
-
-# /////////////////////////////////////////////////////////////////////////////
-# transmit path
-# /////////////////////////////////////////////////////////////////////////////
-
-class transmit_path(gr.hier_block2):
- def __init__(self, modulator_class, options):
- '''
- See below for what options should hold
- '''
- gr.hier_block2.__init__(self, "transmit_path",
- gr.io_signature(0,0,0),
- gr.io_signature(1,1,gr.sizeof_gr_complex))
-
- options = copy.copy(options) # make a copy so we can destructively modify
-
- self._verbose = options.verbose
- self._tx_amplitude = options.tx_amplitude # digital amplitude sent to USRP
- self._bitrate = options.bitrate # desired bit rate
- self._modulator_class = modulator_class # the modulator_class we are using
-
- # Get mod_kwargs
- mod_kwargs = self._modulator_class.extract_kwargs_from_options(options)
-
- # transmitter
- self.modulator = self._modulator_class(**mod_kwargs)
-
- self.packet_transmitter = \
- digital.mod_pkts(self.modulator,
- access_code=None,
- msgq_limit=4,
- pad_for_usrp=True)
-
- self.amp = gr.multiply_const_cc(1)
- self.set_tx_amplitude(self._tx_amplitude)
-
- # Display some information about the setup
- if self._verbose:
- self._print_verbage()
-
- # Connect components in the flowgraph
- self.connect(self.packet_transmitter, self.amp, self)
-
- def set_tx_amplitude(self, ampl):
- """
- Sets the transmit amplitude sent to the USRP in volts
- @param: ampl 0 <= ampl < 1.
- """
- self._tx_amplitude = max(0.0, min(ampl, 1))
- self.amp.set_k(self._tx_amplitude)
-
- def send_pkt(self, payload='', eof=False):
- """
- Calls the transmitter method to send a packet
- """
- return self.packet_transmitter.send_pkt(payload, eof)
-
- def bitrate(self):
- return self._bitrate
-
- def samples_per_symbol(self):
- return self.modulator._samples_per_symbol
-
- def differential(self):
- return self.modulator._differential
-
- def add_options(normal, expert):
- """
- Adds transmitter-specific options to the Options Parser
- """
- if not normal.has_option('--bitrate'):
- normal.add_option("-r", "--bitrate", type="eng_float",
- default=100e3,
- help="specify bitrate [default=%default].")
- normal.add_option("", "--tx-amplitude", type="eng_float",
- default=0.250, metavar="AMPL",
- help="set transmitter digital amplitude: 0 <= AMPL < 1 [default=%default]")
- normal.add_option("-v", "--verbose", action="store_true",
- default=False)
-
- expert.add_option("-S", "--samples-per-symbol", type="float",
- default=2,
- help="set samples/symbol [default=%default]")
- expert.add_option("", "--log", action="store_true",
- default=False,
- help="Log all parts of flow graph to file (CAUTION: lots of data)")
-
- # Make a static method to call before instantiation
- add_options = staticmethod(add_options)
-
- def _print_verbage(self):
- """
- Prints information about the transmit path
- """
- print "Tx amplitude %s" % (self._tx_amplitude)
- print "modulation: %s" % (self._modulator_class.__name__)
- print "bitrate: %sb/s" % (eng_notation.num_to_str(self._bitrate))
- print "samples/symbol: %.4f" % (self.samples_per_symbol())
- print "Differential: %s" % (self.differential())
diff --git a/gr-digital/examples/narrowband/tunnel.py b/gr-digital/examples/narrowband/tunnel.py
deleted file mode 100755
index 65205b9f6..000000000
--- a/gr-digital/examples/narrowband/tunnel.py
+++ /dev/null
@@ -1,297 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2005,2006,2009,2011 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# GNU Radio is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-
-# ////////////////////////////////////////////////////////////////////
-#
-# This code sets up up a virtual ethernet interface (typically
-# gr0), and relays packets between the interface and the GNU Radio
-# PHY+MAC
-#
-# What this means in plain language, is that if you've got a couple
-# of USRPs on different machines, and if you run this code on those
-# machines, you can talk between them using normal TCP/IP
-# networking.
-#
-# ////////////////////////////////////////////////////////////////////
-
-
-from gnuradio import gr, digital
-from gnuradio import eng_notation
-from gnuradio.eng_option import eng_option
-from optparse import OptionParser
-
-# from current dir
-from receive_path import receive_path
-from transmit_path import transmit_path
-from uhd_interface import uhd_transmitter
-from uhd_interface import uhd_receiver
-
-import os, sys
-import random, time, struct
-
-#print os.getpid()
-#raw_input('Attach and press enter')
-
-# ////////////////////////////////////////////////////////////////////
-#
-# Use the Universal TUN/TAP device driver to move packets to/from
-# kernel
-#
-# See /usr/src/linux/Documentation/networking/tuntap.txt
-#
-# ////////////////////////////////////////////////////////////////////
-
-# Linux specific...
-# TUNSETIFF ifr flags from <linux/tun_if.h>
-
-IFF_TUN = 0x0001 # tunnel IP packets
-IFF_TAP = 0x0002 # tunnel ethernet frames
-IFF_NO_PI = 0x1000 # don't pass extra packet info
-IFF_ONE_QUEUE = 0x2000 # beats me ;)
-
-def open_tun_interface(tun_device_filename):
- from fcntl import ioctl
-
- mode = IFF_TAP | IFF_NO_PI
- TUNSETIFF = 0x400454ca
-
- tun = os.open(tun_device_filename, os.O_RDWR)
- ifs = ioctl(tun, TUNSETIFF, struct.pack("16sH", "gr%d", mode))
- ifname = ifs[:16].strip("\x00")
- return (tun, ifname)
-
-
-# ////////////////////////////////////////////////////////////////////
-# the flow graph
-# ////////////////////////////////////////////////////////////////////
-
-class my_top_block(gr.top_block):
-
- def __init__(self, mod_class, demod_class,
- rx_callback, options):
-
- gr.top_block.__init__(self)
-
- # Get the modulation's bits_per_symbol
- args = mod_class.extract_kwargs_from_options(options)
- symbol_rate = options.bitrate / mod_class(**args).bits_per_symbol()
-
- self.source = uhd_receiver(options.args, symbol_rate,
- options.samples_per_symbol,
- options.rx_freq, options.rx_gain,
- options.spec, options.antenna,
- options.verbose)
-
- self.sink = uhd_transmitter(options.args, symbol_rate,
- options.samples_per_symbol,
- options.tx_freq, options.tx_gain,
- options.spec, options.antenna,
- options.verbose)
-
- options.samples_per_symbol = self.source._sps
-
- self.txpath = transmit_path(mod_class, options)
- self.rxpath = receive_path(demod_class, rx_callback, options)
- self.connect(self.txpath, self.sink)
- self.connect(self.source, self.rxpath)
-
- def send_pkt(self, payload='', eof=False):
- return self.txpath.send_pkt(payload, eof)
-
- def carrier_sensed(self):
- """
- Return True if the receive path thinks there's carrier
- """
- return self.rxpath.carrier_sensed()
-
- def set_freq(self, target_freq):
- """
- Set the center frequency we're interested in.
- """
-
- self.sink.set_freq(target_freq)
- self.source.set_freq(target_freq)
-
-
-# ////////////////////////////////////////////////////////////////////
-# Carrier Sense MAC
-# ////////////////////////////////////////////////////////////////////
-
-class cs_mac(object):
- """
- Prototype carrier sense MAC
-
- Reads packets from the TUN/TAP interface, and sends them to the
- PHY. Receives packets from the PHY via phy_rx_callback, and sends
- them into the TUN/TAP interface.
-
- Of course, we're not restricted to getting packets via TUN/TAP,
- this is just an example.
- """
-
- def __init__(self, tun_fd, verbose=False):
- self.tun_fd = tun_fd # file descriptor for TUN/TAP interface
- self.verbose = verbose
- self.tb = None # top block (access to PHY)
-
- def set_top_block(self, tb):
- self.tb = tb
-
- def phy_rx_callback(self, ok, payload):
- """
- Invoked by thread associated with PHY to pass received packet up.
-
- @param ok: bool indicating whether payload CRC was OK
- @param payload: contents of the packet (string)
- """
- if self.verbose:
- print "Rx: ok = %r len(payload) = %4d" % (ok, len(payload))
- if ok:
- os.write(self.tun_fd, payload)
-
- def main_loop(self):
- """
- Main loop for MAC.
- Only returns if we get an error reading from TUN.
-
- FIXME: may want to check for EINTR and EAGAIN and reissue read
- """
- min_delay = 0.001 # seconds
-
- while 1:
- payload = os.read(self.tun_fd, 10*1024)
- if not payload:
- self.tb.send_pkt(eof=True)
- break
-
- if self.verbose:
- print "Tx: len(payload) = %4d" % (len(payload),)
-
- delay = min_delay
- while self.tb.carrier_sensed():
- sys.stderr.write('B')
- time.sleep(delay)
- if delay < 0.050:
- delay = delay * 2 # exponential back-off
-
- self.tb.send_pkt(payload)
-
-
-# /////////////////////////////////////////////////////////////////////////////
-# main
-# /////////////////////////////////////////////////////////////////////////////
-
-def main():
-
- mods = digital.modulation_utils.type_1_mods()
- demods = digital.modulation_utils.type_1_demods()
-
- parser = OptionParser (option_class=eng_option, conflict_handler="resolve")
- expert_grp = parser.add_option_group("Expert")
- parser.add_option("-m", "--modulation", type="choice", choices=mods.keys(),
- default='gmsk',
- help="Select modulation from: %s [default=%%default]"
- % (', '.join(mods.keys()),))
-
- parser.add_option("-s", "--size", type="eng_float", default=1500,
- help="set packet size [default=%default]")
- parser.add_option("-v","--verbose", action="store_true", default=False)
- expert_grp.add_option("-c", "--carrier-threshold", type="eng_float", default=30,
- help="set carrier detect threshold (dB) [default=%default]")
- expert_grp.add_option("","--tun-device-filename", default="/dev/net/tun",
- help="path to tun device file [default=%default]")
-
- transmit_path.add_options(parser, expert_grp)
- receive_path.add_options(parser, expert_grp)
- uhd_receiver.add_options(parser)
- uhd_transmitter.add_options(parser)
-
- for mod in mods.values():
- mod.add_options(expert_grp)
-
- for demod in demods.values():
- demod.add_options(expert_grp)
-
- (options, args) = parser.parse_args ()
- if len(args) != 0:
- parser.print_help(sys.stderr)
- sys.exit(1)
-
- # open the TUN/TAP interface
- (tun_fd, tun_ifname) = open_tun_interface(options.tun_device_filename)
-
- # Attempt to enable realtime scheduling
- r = gr.enable_realtime_scheduling()
- if r == gr.RT_OK:
- realtime = True
- else:
- realtime = False
- print "Note: failed to enable realtime scheduling"
-
- # instantiate the MAC
- mac = cs_mac(tun_fd, verbose=True)
-
- # build the graph (PHY)
- tb = my_top_block(mods[options.modulation],
- demods[options.modulation],
- mac.phy_rx_callback,
- options)
-
- mac.set_top_block(tb) # give the MAC a handle for the PHY
-
- if tb.txpath.bitrate() != tb.rxpath.bitrate():
- print "WARNING: Transmit bitrate = %sb/sec, Receive bitrate = %sb/sec" % (
- eng_notation.num_to_str(tb.txpath.bitrate()),
- eng_notation.num_to_str(tb.rxpath.bitrate()))
-
- print "modulation: %s" % (options.modulation,)
- print "freq: %s" % (eng_notation.num_to_str(options.tx_freq))
- print "bitrate: %sb/sec" % (eng_notation.num_to_str(tb.txpath.bitrate()),)
- print "samples/symbol: %3d" % (tb.txpath.samples_per_symbol(),)
-
- tb.rxpath.set_carrier_threshold(options.carrier_threshold)
- print "Carrier sense threshold:", options.carrier_threshold, "dB"
-
- print
- print "Allocated virtual ethernet interface: %s" % (tun_ifname,)
- print "You must now use ifconfig to set its IP address. E.g.,"
- print
- print " $ sudo ifconfig %s 192.168.200.1" % (tun_ifname,)
- print
- print "Be sure to use a different address in the same subnet for each machine."
- print
-
-
- tb.start() # Start executing the flow graph (runs in separate threads)
-
- mac.main_loop() # don't expect this to return...
-
- tb.stop() # but if it does, tell flow graph to stop.
- tb.wait() # wait for it to finish
-
-
-if __name__ == '__main__':
- try:
- main()
- except KeyboardInterrupt:
- pass
diff --git a/gr-digital/examples/narrowband/tx_voice.py b/gr-digital/examples/narrowband/tx_voice.py
deleted file mode 100755
index 3d767a077..000000000
--- a/gr-digital/examples/narrowband/tx_voice.py
+++ /dev/null
@@ -1,171 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2005-2007,2009,2011 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# GNU Radio is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from gnuradio import gr, blks2, audio, uhd
-from gnuradio import eng_notation
-from gnuradio.eng_option import eng_option
-from optparse import OptionParser
-
-from gnuradio import digital
-from gnuradio import vocoder
-
-import random
-import time
-import struct
-import sys
-
-# from current dir
-from transmit_path import transmit_path
-from uhd_interface import uhd_transmitter
-
-#import os
-#print os.getpid()
-#raw_input('Attach and press enter')
-
-
-class audio_rx(gr.hier_block2):
- def __init__(self, audio_input_dev):
- gr.hier_block2.__init__(self, "audio_rx",
- gr.io_signature(0, 0, 0), # Input signature
- gr.io_signature(0, 0, 0)) # Output signature
- self.sample_rate = sample_rate = 8000
- src = audio.source(sample_rate, audio_input_dev)
- src_scale = gr.multiply_const_ff(32767)
- f2s = gr.float_to_short()
- voice_coder = vocoder.gsm_fr_encode_sp()
- self.packets_from_encoder = gr.msg_queue()
- packet_sink = gr.message_sink(33, self.packets_from_encoder, False)
- self.connect(src, src_scale, f2s, voice_coder, packet_sink)
-
- def get_encoded_voice_packet(self):
- return self.packets_from_encoder.delete_head()
-
-
-class my_top_block(gr.top_block):
-
- def __init__(self, modulator_class, options):
- gr.top_block.__init__(self)
- self.txpath = transmit_path(modulator_class, options)
- self.audio_rx = audio_rx(options.audio_input)
-
- if(options.tx_freq is not None):
- self.sink = uhd_transmitter(options.address, options.bitrate,
- options.samples_per_symbol,
- options.tx_freq, options.tx_gain,
- options.antenna, options.verbose)
- options.samples_per_symbol = self.sink._sps
- audio_rate = self.audio_rx.sample_rate
- usrp_rate = self.sink.get_sample_rate()
- rrate = usrp_rate / audio_rate
-
- elif(options.to_file is not None):
- self.sink = gr.file_sink(gr.sizeof_gr_complex, options.to_file)
- rrate = 1
- else:
- self.sink = gr.null_sink(gr.sizeof_gr_complex)
- rrate = 1
-
- self.resampler = blks2.pfb_arb_resampler_ccf(rrate)
-
- self.connect(self.audio_rx)
- self.connect(self.txpath, self.resampler, self.sink)
-
-
-# /////////////////////////////////////////////////////////////////////////////
-# main
-# /////////////////////////////////////////////////////////////////////////////
-
-def main():
-
- def send_pkt(payload='', eof=False):
- return tb.txpath.send_pkt(payload, eof)
-
- def rx_callback(ok, payload):
- print "ok = %r, payload = '%s'" % (ok, payload)
-
- mods = digital.modulation_utils.type_1_mods()
-
- parser = OptionParser(option_class=eng_option, conflict_handler="resolve")
- expert_grp = parser.add_option_group("Expert")
-
- parser.add_option("-m", "--modulation", type="choice", choices=mods.keys(),
- default='gmsk',
- help="Select modulation from: %s [default=%%default]"
- % (', '.join(mods.keys()),))
- parser.add_option("-M", "--megabytes", type="eng_float", default=0,
- help="set megabytes to transmit [default=inf]")
- parser.add_option("-I", "--audio-input", type="string", default="",
- help="pcm input device name. E.g., hw:0,0 or /dev/dsp")
- parser.add_option("","--to-file", default=None,
- help="Output file for modulated samples")
-
- transmit_path.add_options(parser, expert_grp)
- uhd_transmitter.add_options(parser)
-
- for mod in mods.values():
- mod.add_options(expert_grp)
-
- parser.set_defaults(bitrate=50e3) # override default bitrate default
- (options, args) = parser.parse_args ()
-
- if len(args) != 0:
- parser.print_help()
- sys.exit(1)
-
- if options.to_file is None:
- if options.tx_freq is None:
- sys.stderr.write("You must specify -f FREQ or --freq FREQ\n")
- parser.print_help(sys.stderr)
- sys.exit(1)
-
- # build the graph
- tb = my_top_block(mods[options.modulation], options)
-
- r = gr.enable_realtime_scheduling()
- if r != gr.RT_OK:
- print "Warning: failed to enable realtime scheduling"
-
-
- tb.start() # start flow graph
-
- # generate and send packets
- nbytes = int(1e6 * options.megabytes)
- n = 0
- pktno = 0
-
- while nbytes == 0 or n < nbytes:
- packet = tb.audio_rx.get_encoded_voice_packet()
- s = packet.to_string()
- send_pkt(s)
- n += len(s)
- sys.stderr.write('.')
- pktno += 1
-
- send_pkt(eof=True)
- tb.wait() # wait for it to finish
-
-
-if __name__ == '__main__':
- try:
- main()
- except KeyboardInterrupt:
- pass
diff --git a/gr-digital/examples/narrowband/uhd_interface.py b/gr-digital/examples/narrowband/uhd_interface.py
deleted file mode 100644
index fe022c731..000000000
--- a/gr-digital/examples/narrowband/uhd_interface.py
+++ /dev/null
@@ -1,225 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2010,2011 Free Software Foundation, Inc.
-#
-# This file is part of GNU Radio
-#
-# GNU Radio is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3, or (at your option)
-# any later version.
-#
-# GNU Radio is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with GNU Radio; see the file COPYING. If not, write to
-# the Free Software Foundation, Inc., 51 Franklin Street,
-# Boston, MA 02110-1301, USA.
-#
-
-from gnuradio import gr, uhd
-from gnuradio import eng_notation
-from gnuradio.eng_option import eng_option
-from optparse import OptionParser
-
-import sys
-
-def add_freq_option(parser):
- """
- Hackery that has the -f / --freq option set both tx_freq and rx_freq
- """
- def freq_callback(option, opt_str, value, parser):
- parser.values.rx_freq = value
- parser.values.tx_freq = value
-
- if not parser.has_option('--freq'):
- parser.add_option('-f', '--freq', type="eng_float",
- action="callback", callback=freq_callback,
- help="set Tx and/or Rx frequency to FREQ [default=%default]",
- metavar="FREQ")
-
-class uhd_interface:
- def __init__(self, istx, args, sym_rate, sps, freq=None,
- gain=None, spec=None, antenna=None):
-
- if(istx):
- self.u = uhd.usrp_sink(device_addr=args, stream_args=uhd.stream_args('fc32'))
- else:
- self.u = uhd.usrp_source(device_addr=args, stream_args=uhd.stream_args('fc32'))
-
- # Set the subdevice spec
- if(spec):
- self.u.set_subdev_spec(spec, 0)
-
- # Set the antenna
- if(antenna):
- self.u.set_antenna(antenna, 0)
-
- self._args = args
- self._ant = antenna
- self._spec = spec
- self._gain = self.set_gain(gain)
- self._freq = self.set_freq(freq)
-
- self._rate, self._sps = self.set_sample_rate(sym_rate, sps)
-
- def set_sample_rate(self, sym_rate, req_sps):
- start_sps = req_sps
- while(True):
- asked_samp_rate = sym_rate * req_sps
- self.u.set_samp_rate(asked_samp_rate)
- actual_samp_rate = self.u.get_samp_rate()
-
- sps = actual_samp_rate/sym_rate
- if(sps < 2):
- req_sps +=1
- else:
- actual_sps = sps
- break
-
- if(sps != req_sps):
- print "\nSymbol Rate: %f" % (sym_rate)
- print "Requested sps: %f" % (start_sps)
- print "Given sample rate: %f" % (actual_samp_rate)
- print "Actual sps for rate: %f" % (actual_sps)
-
- if(actual_samp_rate != asked_samp_rate):
- print "\nRequested sample rate: %f" % (asked_samp_rate)
- print "Actual sample rate: %f" % (actual_samp_rate)
-
- return (actual_samp_rate, actual_sps)
-
- def get_sample_rate(self):
- return self.u.get_samp_rate()
-
- def set_gain(self, gain=None):
- if gain is None:
- # if no gain was specified, use the mid-point in dB
- g = self.u.get_gain_range()
- gain = float(g.start()+g.stop())/2
- print "\nNo gain specified."
- print "Setting gain to %f (from [%f, %f])" % \
- (gain, g.start(), g.stop())
-
- self.u.set_gain(gain, 0)
- return gain
-
- def set_freq(self, freq=None):
- if(freq is None):
- sys.stderr.write("You must specify -f FREQ or --freq FREQ\n")
- sys.exit(1)
-
- r = self.u.set_center_freq(freq, 0)
- if r:
- return freq
- else:
- frange = self.u.get_freq_range()
- sys.stderr.write(("\nRequested frequency (%f) out or range [%f, %f]\n") % \
- (freq, frange.start(), frange.stop()))
- sys.exit(1)
-
-#-------------------------------------------------------------------#
-# TRANSMITTER
-#-------------------------------------------------------------------#
-
-class uhd_transmitter(uhd_interface, gr.hier_block2):
- def __init__(self, args, sym_rate, sps, freq=None, gain=None,
- spec=None, antenna=None, verbose=False):
- gr.hier_block2.__init__(self, "uhd_transmitter",
- gr.io_signature(1,1,gr.sizeof_gr_complex),
- gr.io_signature(0,0,0))
-
- # Set up the UHD interface as a transmitter
- uhd_interface.__init__(self, True, args, sym_rate, sps,
- freq, gain, spec, antenna)
-
- self.connect(self, self.u)
-
- if(verbose):
- self._print_verbage()
-
- def add_options(parser):
- add_freq_option(parser)
- parser.add_option("-a", "--args", type="string", default="",
- help="UHD device address args [default=%default]")
- parser.add_option("", "--spec", type="string", default=None,
- help="Subdevice of UHD device where appropriate")
- parser.add_option("-A", "--antenna", type="string", default=None,
- help="select Rx Antenna where appropriate")
- parser.add_option("", "--tx-freq", type="eng_float", default=None,
- help="set transmit frequency to FREQ [default=%default]",
- metavar="FREQ")
- parser.add_option("", "--tx-gain", type="eng_float", default=None,
- help="set transmit gain in dB (default is midpoint)")
- parser.add_option("-v", "--verbose", action="store_true", default=False)
-
- # Make a static method to call before instantiation
- add_options = staticmethod(add_options)
-
- def _print_verbage(self):
- """
- Prints information about the UHD transmitter
- """
- print "\nUHD Transmitter:"
- print "Args: %s" % (self._args)
- print "Freq: %sHz" % (eng_notation.num_to_str(self._freq))
- print "Gain: %f dB" % (self._gain)
- print "Sample Rate: %ssps" % (eng_notation.num_to_str(self._rate))
- print "Antenna: %s" % (self._ant)
- print "Subdev Sec: %s" % (self._spec)
-
-
-#-------------------------------------------------------------------#
-# RECEIVER
-#-------------------------------------------------------------------#
-
-
-class uhd_receiver(uhd_interface, gr.hier_block2):
- def __init__(self, args, sym_rate, sps, freq=None, gain=None,
- spec=None, antenna=None, verbose=False):
- gr.hier_block2.__init__(self, "uhd_receiver",
- gr.io_signature(0,0,0),
- gr.io_signature(1,1,gr.sizeof_gr_complex))
-
- # Set up the UHD interface as a receiver
- uhd_interface.__init__(self, False, args, sym_rate, sps,
- freq, gain, spec, antenna)
-
- self.connect(self.u, self)
-
- if(verbose):
- self._print_verbage()
-
- def add_options(parser):
- add_freq_option(parser)
- parser.add_option("-a", "--args", type="string", default="",
- help="UHD device address args [default=%default]")
- parser.add_option("", "--spec", type="string", default=None,
- help="Subdevice of UHD device where appropriate")
- parser.add_option("-A", "--antenna", type="string", default=None,
- help="select Rx Antenna where appropriate")
- parser.add_option("", "--rx-freq", type="eng_float", default=None,
- help="set receive frequency to FREQ [default=%default]",
- metavar="FREQ")
- parser.add_option("", "--rx-gain", type="eng_float", default=None,
- help="set receive gain in dB (default is midpoint)")
- if not parser.has_option("--verbose"):
- parser.add_option("-v", "--verbose", action="store_true", default=False)
-
- # Make a static method to call before instantiation
- add_options = staticmethod(add_options)
-
- def _print_verbage(self):
- """
- Prints information about the UHD transmitter
- """
- print "\nUHD Receiver:"
- print "UHD Args: %s" % (self._args)
- print "Freq: %sHz" % (eng_notation.num_to_str(self._freq))
- print "Gain: %f dB" % (self._gain)
- print "Sample Rate: %ssps" % (eng_notation.num_to_str(self._rate))
- print "Antenna: %s" % (self._ant)
- print "Spec: %s" % (self._spec)