Temporary working dbpsk2 example until we match everything.
authorTom Rondeau <trondeau@vt.edu>
Mon, 12 Oct 2009 17:28:27 +0000 (13:28 -0400)
committerTom Rondeau <trondeau@vt.edu>
Mon, 12 Oct 2009 17:28:27 +0000 (13:28 -0400)
gnuradio-examples/python/digital/benchmark_qt_loopback2.py [new file with mode: 0755]
gnuradio-examples/python/digital/qt_digital_window2.py [new file with mode: 0644]
gnuradio-examples/python/digital/qt_digital_window2.ui [new file with mode: 0644]

diff --git a/gnuradio-examples/python/digital/benchmark_qt_loopback2.py b/gnuradio-examples/python/digital/benchmark_qt_loopback2.py
new file mode 100755 (executable)
index 0000000..17c8a17
--- /dev/null
@@ -0,0 +1,488 @@
+#!/usr/bin/env python
+
+from gnuradio import gr, gru, modulation_utils
+from gnuradio import eng_notation
+from gnuradio.eng_option import eng_option
+from optparse import OptionParser
+import random, time, struct, sys, os, math
+
+from threading import Thread
+
+# from current dir
+from transmit_path import transmit_path
+from receive_path import receive_path
+
+try:
+    from gnuradio.qtgui import qtgui
+    from PyQt4 import QtGui, QtCore
+    import sip
+except ImportError:
+    print "Please install gr-qtgui."
+    sys.exit(1)
+    
+try:
+    from qt_digital_window import Ui_DigitalWindow
+except ImportError:
+    print "Error: could not find qt_digital_window.py:"
+    print "\t\"pyuic4 qt_digital_window.ui -o qt_digital_window.py\""
+    sys.exit(1)
+
+
+#print os.getpid()
+#raw_input()
+
+
+# ////////////////////////////////////////////////////////////////////
+#        Define the QT Interface and Control Dialog
+# ////////////////////////////////////////////////////////////////////
+
+
+class dialog_box(QtGui.QMainWindow):
+    def __init__(self, snkTx, snkRx, fg, parent=None):
+
+        QtGui.QWidget.__init__(self, parent)
+        self.gui = Ui_DigitalWindow()
+        self.gui.setupUi(self)
+
+        self.fg = fg
+
+        self.set_sample_rate(self.fg.sample_rate())
+
+        self.set_snr(self.fg.snr())
+        self.set_frequency(self.fg.frequency_offset())
+        self.set_time_offset(self.fg.timing_offset())
+
+        self.set_alpha_time(self.fg.rx_timing_gain_alpha())
+        self.set_beta_time(self.fg.rx_timing_gain_beta())
+        self.set_alpha_freq(self.fg.rx_freq_gain_alpha())
+
+        # Add the qtsnk widgets to the hlayout box
+        self.gui.sinkLayout.addWidget(snkTx)
+        self.gui.sinkLayout.addWidget(snkRx)
+
+
+        # Connect up some signals
+        self.connect(self.gui.pauseButton, QtCore.SIGNAL("clicked()"),
+                     self.pauseFg)
+
+        self.connect(self.gui.sampleRateEdit, QtCore.SIGNAL("editingFinished()"),
+                     self.sampleRateEditText)
+
+        self.connect(self.gui.snrEdit, QtCore.SIGNAL("editingFinished()"),
+                     self.snrEditText)
+        self.connect(self.gui.freqEdit, QtCore.SIGNAL("editingFinished()"),
+                     self.freqEditText)
+        self.connect(self.gui.timeEdit, QtCore.SIGNAL("editingFinished()"),
+                     self.timeEditText)
+
+        self.connect(self.gui.alphaTimeEdit, QtCore.SIGNAL("editingFinished()"),
+                     self.alphaTimeEditText)
+        self.connect(self.gui.betaTimeEdit, QtCore.SIGNAL("editingFinished()"),
+                     self.betaTimeEditText)
+        self.connect(self.gui.alphaFreqEdit, QtCore.SIGNAL("editingFinished()"),
+                     self.alphaFreqEditText)
+
+        # Build a timer to update the packet number and PER fields
+        self.update_delay = 250  # time between updating packet rate fields
+        self.pkt_timer = QtCore.QTimer(self)
+        self.connect(self.pkt_timer, QtCore.SIGNAL("timeout()"),
+                     self.updatePacketInfo)
+        self.pkt_timer.start(self.update_delay)
+
+    def pauseFg(self):
+        if(self.gui.pauseButton.text() == "Pause"):
+            self.fg.stop()
+            self.fg.wait()
+            self.gui.pauseButton.setText("Unpause")
+        else:
+            self.fg.start()
+            self.gui.pauseButton.setText("Pause")
+
+    # Accessor functions for Gui to manipulate system parameters
+    def set_sample_rate(self, sr):
+        ssr = eng_notation.num_to_str(sr)
+        self.gui.sampleRateEdit.setText(QtCore.QString("%1").arg(ssr))
+
+    def sampleRateEditText(self):
+        try:
+            rate = self.gui.sampleRateEdit.text().toAscii()
+            srate = eng_notation.str_to_num(rate)
+            #self.fg.set_sample_rate(srate)
+        except RuntimeError:
+            pass
+
+
+    # Accessor functions for Gui to manipulate channel model
+    def set_snr(self, snr):
+        self.gui.snrEdit.setText(QtCore.QString("%1").arg(snr))
+
+    def set_frequency(self, fo):
+        self.gui.freqEdit.setText(QtCore.QString("%1").arg(fo))
+
+    def set_time_offset(self, to):
+        self.gui.timeEdit.setText(QtCore.QString("%1").arg(to))
+
+    def snrEditText(self):
+        try:
+            snr = self.gui.snrEdit.text().toDouble()[0]
+            self.fg.set_snr(snr)
+        except RuntimeError:
+            pass
+
+    def freqEditText(self):
+        try:
+            freq = self.gui.freqEdit.text().toDouble()[0]
+            self.fg.set_frequency_offset(freq)
+        except RuntimeError:
+            pass
+
+    def timeEditText(self):
+        try:
+            to = self.gui.timeEdit.text().toDouble()[0]
+            self.fg.set_timing_offset(to)
+        except RuntimeError:
+            pass
+
+
+    # Accessor functions for Gui to manipulate receiver parameters
+    def set_alpha_time(self, alpha):
+        self.gui.alphaTimeEdit.setText(QtCore.QString("%1").arg(alpha))
+
+    def set_beta_time(self, beta):
+        self.gui.betaTimeEdit.setText(QtCore.QString("%1").arg(beta))
+
+    def set_alpha_freq(self, alpha):
+        self.gui.alphaFreqEdit.setText(QtCore.QString("%1").arg(alpha))
+
+    def alphaFreqEditText(self):
+        try:
+            alpha = self.gui.alphaFreqEdit.text().toDouble()[0]
+            self.fg.set_rx_freq_gain_alpha(alpha)
+        except RuntimeError:
+            pass
+
+    def alphaTimeEditText(self):
+        try:
+            alpha = self.gui.alphaTimeEdit.text().toDouble()[0]
+            self.fg.set_rx_timing_gain_alpha(alpha)
+        except RuntimeError:
+            pass
+
+    def betaTimeEditText(self):
+        try:
+            beta = self.gui.betaTimeEdit.text().toDouble()[0]
+            self.fg.set_rx_timing_gain_beta(beta)
+        except RuntimeError:
+            pass
+
+    # Accessor functions for packet error reporting
+    def updatePacketInfo(self):
+        # Pull these globals in from the main thread
+        global n_rcvd, n_right, pktno
+
+        if(pktno > 0):
+            per = float(n_rcvd - n_right)/float(pktno)
+        else:
+            per = 0
+        self.gui.pktsRcvdEdit.setText(QtCore.QString("%1").arg(n_rcvd))
+        self.gui.pktsCorrectEdit.setText(QtCore.QString("%1").arg(n_right))
+        self.gui.perEdit.setText(QtCore.QString("%1").arg(per))
+
+
+
+# ////////////////////////////////////////////////////////////////////
+#        Define the GNU Radio Top Block
+# ////////////////////////////////////////////////////////////////////
+
+
+
+class my_top_block(gr.top_block):
+    def __init__(self, mod_class, demod_class, rx_callback, options):
+        gr.top_block.__init__(self)
+
+        self._sample_rate = options.sample_rate
+
+        channelon = True;
+
+        self.gui_on = options.gui
+
+        self._frequency_offset = options.frequency_offset
+        self._timing_offset = options.timing_offset
+        self._tx_amplitude = options.tx_amplitude
+        self._snr_dB = options.snr
+
+        self._noise_voltage = self.get_noise_voltage(self._snr_dB)
+
+        self.txpath = transmit_path(mod_class, options)
+        self.throttle = gr.throttle(gr.sizeof_gr_complex, self.sample_rate())
+        self.rxpath = receive_path(demod_class, rx_callback, options)
+
+        # FIXME: do better exposure to lower issues for control
+        self._timing_gain_alpha = self.rxpath.packet_receiver._demodulator._timing_alpha
+        self._timing_gain_beta = self.rxpath.packet_receiver._demodulator._timing_beta
+        self._freq_gain_alpha = self.rxpath.packet_receiver._demodulator._costas_alpha
+
+        if channelon:
+            self.channel = gr.channel_model(self._noise_voltage,
+                                            self.frequency_offset(),
+                                            self.timing_offset())
+            
+            if options.discontinuous:
+                z = 20000*[0,]
+                self.zeros = gr.vector_source_c(z, True)
+                packet_size = 5*((4+8+4+1500+4) * 8)
+                self.mux = gr.stream_mux(gr.sizeof_gr_complex, [packet_size-0, int(9e5)])
+
+                # Connect components
+                self.connect(self.txpath, self.throttle, (self.mux,0))
+                self.connect(self.zeros, (self.mux,1))
+                self.connect(self.mux, self.channel, self.rxpath)
+
+            else:
+                self.connect(self.txpath, self.throttle, self.channel, self.rxpath)
+
+            if self.gui_on:
+                self.qapp = QtGui.QApplication(sys.argv)
+                fftsize = 2048
+
+                self.snk_tx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS,
+                                           0, 1,
+                                           "Tx", True, True, False, True, True)
+                self.snk_rx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS,
+                                           0, 1,
+                                           "Rx", True, True, False, True, True)
+
+                self.snk_tx.set_frequency_axis(-80, 0)
+                self.snk_rx.set_frequency_axis(-60, 20)
+            
+                # Connect to the QT sinks
+                # FIXME: make better exposure to receiver from rxpath
+                self.freq_recov = self.rxpath.packet_receiver._demodulator.clock_recov
+                self.time_recov = self.rxpath.packet_receiver._demodulator.time_recov
+                self.freq_recov.set_alpha(self._freq_gain_alpha)
+                self.freq_recov.set_beta(0.25*self._freq_gain_alpha*self._freq_gain_alpha)
+                self.time_recov.set_alpha(self._timing_gain_alpha)
+                self.time_recov.set_beta(self._timing_gain_beta)
+                self.connect(self.channel, self.snk_tx)
+                self.connect(self.time_recov, self.snk_rx)
+
+                pyTxQt  = self.snk_tx.pyqwidget()
+                pyTx = sip.wrapinstance(pyTxQt, QtGui.QWidget)
+                 
+                pyRxQt  = self.snk_rx.pyqwidget()
+                pyRx = sip.wrapinstance(pyRxQt, QtGui.QWidget)
+
+                self.main_box = dialog_box(pyTx, pyRx, self)
+                self.main_box.show()
+                
+        else:
+            # Connect components
+            self.connect(self.txpath, self.throttle, self.rxpath)
+
+
+
+    # System Parameters
+    def sample_rate(self):
+        return self._sample_rate
+    
+    def set_sample_rate(self, sr):
+        self._sample_rate = sr
+        #self.throttle.set_samples_per_second(self._sample_rate)
+
+    # Channel Model Parameters
+    def snr(self):
+        return self._snr_dB
+    
+    def set_snr(self, snr):
+        self._snr_dB = snr
+        self._noise_voltage = self.get_noise_voltage(self._snr_dB)
+        self.channel.set_noise_voltage(self._noise_voltage)
+
+    def get_noise_voltage(self, SNR):
+        snr = 10.0**(SNR/10.0)        
+        power_in_signal = abs(self._tx_amplitude)**2
+        noise_power = power_in_signal/snr
+        noise_voltage = math.sqrt(noise_power)
+        return noise_voltage
+
+    def frequency_offset(self):
+        return self._frequency_offset * self.sample_rate()
+
+    def set_frequency_offset(self, fo):
+        self._frequency_offset = fo / self.sample_rate()
+        self.channel.set_frequency_offset(self._frequency_offset)
+
+    def timing_offset(self):
+        return self._timing_offset
+    
+    def set_timing_offset(self, to):
+        self._timing_offset = to
+        self.channel.set_timing_offset(self._timing_offset)
+
+
+    # Receiver Parameters
+    def rx_timing_gain_alpha(self):
+        return self._timing_gain_alpha
+
+    def rx_timing_gain_beta(self):
+        return self._timing_gain_beta
+    
+    def set_rx_timing_gain_alpha(self, gain):
+        self._timing_gain_alpha = gain
+        self.time_recov.set_alpha(self._timing_gain_alpha)
+
+    def set_rx_timing_gain_beta(self, gain):
+        self._timing_gain_beta = gain
+        self.time_recov.set_beta(self._timing_gain_beta)
+
+    def rx_freq_gain_alpha(self):
+        return self._freq_gain_alpha
+
+    def rx_freq_gain_beta(self):
+        return self._freq_gain_beta
+    
+    def set_rx_freq_gain_alpha(self, alpha):
+        self._freq_gain_alpha = alpha
+        self._freq_gain_beta = .25 * self._freq_gain_alpha * self._freq_gain_alpha
+        self.freq_recov.set_alpha(self._freq_gain_alpha)
+        self.freq_recov.set_beta(self._freq_gain_beta)
+
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#       Thread to handle the packet sending procedure
+#          Operates in parallel with qApp.exec_()       
+# /////////////////////////////////////////////////////////////////////////////
+
+
+
+class th_send(Thread):
+    def __init__(self, send_fnc, megs, sz):
+        Thread.__init__(self)
+        self.send = send_fnc
+        self.nbytes = int(1e6 * megs)
+        self.pkt_size = int(sz)
+
+    def run(self):
+        # generate and send packets
+        n = 0
+        pktno = 0
+        
+        while n < self.nbytes:
+            self.send(struct.pack('!H', pktno & 0xffff) +
+                      (self.pkt_size - 2) * chr(pktno & 0xff))
+            n += self.pkt_size
+            pktno += 1
+            
+        self.send(eof=True)
+
+    def stop(self):
+        self.nbytes = 0
+
+
+
+# /////////////////////////////////////////////////////////////////////////////
+#                                   main
+# /////////////////////////////////////////////////////////////////////////////
+
+
+
+def main():
+
+    global n_rcvd, n_right, pktno
+
+    n_rcvd = 0
+    n_right = 0
+    pktno = 0
+    
+    def rx_callback(ok, payload):
+        global n_rcvd, n_right, pktno
+        (pktno,) = struct.unpack('!H', payload[0:2])
+        n_rcvd += 1
+        if ok:
+            n_right += 1
+
+        if not options.gui:
+            print "ok = %5s  pktno = %4d  n_rcvd = %4d  n_right = %4d" % (
+                ok, pktno, n_rcvd, n_right)
+        
+
+    def send_pkt(payload='', eof=False):
+        return tb.txpath.send_pkt(payload, eof)
+
+    mods = modulation_utils.type_1_mods()
+    demods = modulation_utils.type_1_demods()
+
+    parser = OptionParser(option_class=eng_option, conflict_handler="resolve")
+    expert_grp = parser.add_option_group("Expert")
+    channel_grp = parser.add_option_group("Channel")
+
+    parser.add_option("-m", "--modulation", type="choice", choices=mods.keys(),
+                      default='dbpsk',
+                      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("-G", "--gui", action="store_true", default=False,
+                      help="Turn on the GUI [default=%default]")
+
+    channel_grp.add_option("", "--sample-rate", type="eng_float", default=1e5,
+                           help="set speed of channel/simulation rate to RATE [default=%default]") 
+    channel_grp.add_option("", "--snr", type="eng_float", default=30,
+                           help="set the SNR of the channel in dB [default=%default]")
+    channel_grp.add_option("", "--frequency-offset", type="eng_float", default=0,
+                           help="set frequency offset introduced by channel [default=%default]")
+    channel_grp.add_option("", "--timing-offset", type="eng_float", default=1.0,
+                           help="set timing offset introduced by channel [default=%default]")
+    channel_grp.add_option("", "--seed", action="store_true", default=False,
+                           help="use a random seed for AWGN noise [default=%default]")
+
+    transmit_path.add_options(parser, expert_grp)
+    receive_path.add_options(parser, expert_grp)
+
+    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.exit(1)
+        
+    r = gr.enable_realtime_scheduling()
+    if r != gr.RT_OK:
+        print "Warning: failed to enable realtime scheduling"
+        
+    # Create an instance of a hierarchical block
+    tb = my_top_block(mods[options.modulation],
+                      demods[options.modulation],
+                      rx_callback, options)
+    tb.start()
+
+    packet_sender = th_send(send_pkt, options.megabytes, options.size)
+    packet_sender.start()
+
+    if(options.gui):
+        tb.qapp.exec_()
+        packet_sender.stop()
+    else:
+        # Process until done; hack in to the join to stop on an interrupt
+        while(packet_sender.isAlive()):
+            try:
+                packet_sender.join(1)
+            except KeyboardInterrupt:
+                packet_sender.stop()
+        
+    
+if __name__ == '__main__':
+    try:
+        main()
+    except KeyboardInterrupt:
+        pass
diff --git a/gnuradio-examples/python/digital/qt_digital_window2.py b/gnuradio-examples/python/digital/qt_digital_window2.py
new file mode 100644 (file)
index 0000000..f111e37
--- /dev/null
@@ -0,0 +1,261 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'qt_digital_window.ui'
+#
+# Created: Mon Oct 12 12:10:54 2009
+#      by: PyQt4 UI code generator 4.4.3
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt4 import QtCore, QtGui
+
+class Ui_DigitalWindow(object):
+    def setupUi(self, DigitalWindow):
+        DigitalWindow.setObjectName("DigitalWindow")
+        DigitalWindow.resize(1019, 754)
+        self.centralwidget = QtGui.QWidget(DigitalWindow)
+        self.centralwidget.setObjectName("centralwidget")
+        self.gridLayout = QtGui.QGridLayout(self.centralwidget)
+        self.gridLayout.setObjectName("gridLayout")
+        self.verticalLayout_2 = QtGui.QVBoxLayout()
+        self.verticalLayout_2.setObjectName("verticalLayout_2")
+        self.sysBox = QtGui.QGroupBox(self.centralwidget)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.sysBox.sizePolicy().hasHeightForWidth())
+        self.sysBox.setSizePolicy(sizePolicy)
+        self.sysBox.setMinimumSize(QtCore.QSize(240, 60))
+        self.sysBox.setMaximumSize(QtCore.QSize(240, 16777215))
+        self.sysBox.setObjectName("sysBox")
+        self.formLayoutWidget = QtGui.QWidget(self.sysBox)
+        self.formLayoutWidget.setGeometry(QtCore.QRect(10, 20, 211, 31))
+        self.formLayoutWidget.setObjectName("formLayoutWidget")
+        self.formLayout = QtGui.QFormLayout(self.formLayoutWidget)
+        self.formLayout.setSizeConstraint(QtGui.QLayout.SetFixedSize)
+        self.formLayout.setVerticalSpacing(20)
+        self.formLayout.setObjectName("formLayout")
+        self.sampleRateEdit = QtGui.QLineEdit(self.formLayoutWidget)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.sampleRateEdit.sizePolicy().hasHeightForWidth())
+        self.sampleRateEdit.setSizePolicy(sizePolicy)
+        self.sampleRateEdit.setMinimumSize(QtCore.QSize(60, 26))
+        self.sampleRateEdit.setMaximumSize(QtCore.QSize(80, 26))
+        self.sampleRateEdit.setObjectName("sampleRateEdit")
+        self.formLayout.setWidget(0, QtGui.QFormLayout.FieldRole, self.sampleRateEdit)
+        self.sampleRateLabel = QtGui.QLabel(self.formLayoutWidget)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.sampleRateLabel.sizePolicy().hasHeightForWidth())
+        self.sampleRateLabel.setSizePolicy(sizePolicy)
+        self.sampleRateLabel.setMinimumSize(QtCore.QSize(0, 20))
+        self.sampleRateLabel.setMaximumSize(QtCore.QSize(16777215, 20))
+        self.sampleRateLabel.setObjectName("sampleRateLabel")
+        self.formLayout.setWidget(0, QtGui.QFormLayout.LabelRole, self.sampleRateLabel)
+        self.verticalLayout_2.addWidget(self.sysBox)
+        spacerItem = QtGui.QSpacerItem(20, 60, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
+        self.verticalLayout_2.addItem(spacerItem)
+        self.gridLayout.addLayout(self.verticalLayout_2, 2, 0, 1, 1)
+        self.verticalLayout_5 = QtGui.QVBoxLayout()
+        self.verticalLayout_5.setObjectName("verticalLayout_5")
+        self.sinkFrame = QtGui.QFrame(self.centralwidget)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.sinkFrame.sizePolicy().hasHeightForWidth())
+        self.sinkFrame.setSizePolicy(sizePolicy)
+        self.sinkFrame.setMinimumSize(QtCore.QSize(500, 550))
+        self.sinkFrame.setFrameShape(QtGui.QFrame.StyledPanel)
+        self.sinkFrame.setFrameShadow(QtGui.QFrame.Raised)
+        self.sinkFrame.setObjectName("sinkFrame")
+        self.gridLayout_2 = QtGui.QGridLayout(self.sinkFrame)
+        self.gridLayout_2.setObjectName("gridLayout_2")
+        self.sinkLayout = QtGui.QHBoxLayout()
+        self.sinkLayout.setObjectName("sinkLayout")
+        self.gridLayout_2.addLayout(self.sinkLayout, 1, 0, 1, 1)
+        self.verticalLayout_5.addWidget(self.sinkFrame)
+        self.gridLayout.addLayout(self.verticalLayout_5, 0, 0, 1, 6)
+        self.channelModeBox = QtGui.QGroupBox(self.centralwidget)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.channelModeBox.sizePolicy().hasHeightForWidth())
+        self.channelModeBox.setSizePolicy(sizePolicy)
+        self.channelModeBox.setMinimumSize(QtCore.QSize(245, 130))
+        self.channelModeBox.setMaximumSize(QtCore.QSize(245, 16777215))
+        self.channelModeBox.setObjectName("channelModeBox")
+        self.formLayoutWidget_2 = QtGui.QWidget(self.channelModeBox)
+        self.formLayoutWidget_2.setGeometry(QtCore.QRect(10, 20, 221, 98))
+        self.formLayoutWidget_2.setObjectName("formLayoutWidget_2")
+        self.formLayout_2 = QtGui.QFormLayout(self.formLayoutWidget_2)
+        self.formLayout_2.setSizeConstraint(QtGui.QLayout.SetFixedSize)
+        self.formLayout_2.setFieldGrowthPolicy(QtGui.QFormLayout.AllNonFixedFieldsGrow)
+        self.formLayout_2.setObjectName("formLayout_2")
+        self.snrLabel = QtGui.QLabel(self.formLayoutWidget_2)
+        self.snrLabel.setObjectName("snrLabel")
+        self.formLayout_2.setWidget(0, QtGui.QFormLayout.LabelRole, self.snrLabel)
+        self.snrEdit = QtGui.QLineEdit(self.formLayoutWidget_2)
+        self.snrEdit.setMinimumSize(QtCore.QSize(60, 0))
+        self.snrEdit.setMaximumSize(QtCore.QSize(80, 16777215))
+        self.snrEdit.setObjectName("snrEdit")
+        self.formLayout_2.setWidget(0, QtGui.QFormLayout.FieldRole, self.snrEdit)
+        self.freqLabel = QtGui.QLabel(self.formLayoutWidget_2)
+        self.freqLabel.setObjectName("freqLabel")
+        self.formLayout_2.setWidget(1, QtGui.QFormLayout.LabelRole, self.freqLabel)
+        self.freqEdit = QtGui.QLineEdit(self.formLayoutWidget_2)
+        self.freqEdit.setMinimumSize(QtCore.QSize(60, 0))
+        self.freqEdit.setMaximumSize(QtCore.QSize(80, 16777215))
+        self.freqEdit.setObjectName("freqEdit")
+        self.formLayout_2.setWidget(1, QtGui.QFormLayout.FieldRole, self.freqEdit)
+        self.timeLabel = QtGui.QLabel(self.formLayoutWidget_2)
+        self.timeLabel.setObjectName("timeLabel")
+        self.formLayout_2.setWidget(2, QtGui.QFormLayout.LabelRole, self.timeLabel)
+        self.timeEdit = QtGui.QLineEdit(self.formLayoutWidget_2)
+        self.timeEdit.setMinimumSize(QtCore.QSize(60, 0))
+        self.timeEdit.setMaximumSize(QtCore.QSize(80, 16777215))
+        self.timeEdit.setObjectName("timeEdit")
+        self.formLayout_2.setWidget(2, QtGui.QFormLayout.FieldRole, self.timeEdit)
+        self.gridLayout.addWidget(self.channelModeBox, 2, 1, 1, 1)
+        self.rxBox_2 = QtGui.QGroupBox(self.centralwidget)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.rxBox_2.sizePolicy().hasHeightForWidth())
+        self.rxBox_2.setSizePolicy(sizePolicy)
+        self.rxBox_2.setMinimumSize(QtCore.QSize(220, 125))
+        self.rxBox_2.setMaximumSize(QtCore.QSize(265, 125))
+        self.rxBox_2.setObjectName("rxBox_2")
+        self.formLayoutWidget_4 = QtGui.QWidget(self.rxBox_2)
+        self.formLayoutWidget_4.setGeometry(QtCore.QRect(10, 20, 248, 188))
+        self.formLayoutWidget_4.setObjectName("formLayoutWidget_4")
+        self.formLayout_4 = QtGui.QFormLayout(self.formLayoutWidget_4)
+        self.formLayout_4.setSizeConstraint(QtGui.QLayout.SetFixedSize)
+        self.formLayout_4.setFieldGrowthPolicy(QtGui.QFormLayout.AllNonFixedFieldsGrow)
+        self.formLayout_4.setObjectName("formLayout_4")
+        self.pktsRcvdLabel = QtGui.QLabel(self.formLayoutWidget_4)
+        self.pktsRcvdLabel.setObjectName("pktsRcvdLabel")
+        self.formLayout_4.setWidget(0, QtGui.QFormLayout.LabelRole, self.pktsRcvdLabel)
+        self.pktsRcvdEdit = QtGui.QLineEdit(self.formLayoutWidget_4)
+        self.pktsRcvdEdit.setMinimumSize(QtCore.QSize(60, 0))
+        self.pktsRcvdEdit.setMaximumSize(QtCore.QSize(80, 16777215))
+        self.pktsRcvdEdit.setObjectName("pktsRcvdEdit")
+        self.formLayout_4.setWidget(0, QtGui.QFormLayout.FieldRole, self.pktsRcvdEdit)
+        self.pktsCorrectLabel = QtGui.QLabel(self.formLayoutWidget_4)
+        self.pktsCorrectLabel.setObjectName("pktsCorrectLabel")
+        self.formLayout_4.setWidget(1, QtGui.QFormLayout.LabelRole, self.pktsCorrectLabel)
+        self.pktsCorrectEdit = QtGui.QLineEdit(self.formLayoutWidget_4)
+        self.pktsCorrectEdit.setMinimumSize(QtCore.QSize(60, 0))
+        self.pktsCorrectEdit.setMaximumSize(QtCore.QSize(80, 16777215))
+        self.pktsCorrectEdit.setObjectName("pktsCorrectEdit")
+        self.formLayout_4.setWidget(1, QtGui.QFormLayout.FieldRole, self.pktsCorrectEdit)
+        self.perLabel = QtGui.QLabel(self.formLayoutWidget_4)
+        self.perLabel.setObjectName("perLabel")
+        self.formLayout_4.setWidget(2, QtGui.QFormLayout.LabelRole, self.perLabel)
+        self.perEdit = QtGui.QLineEdit(self.formLayoutWidget_4)
+        self.perEdit.setMinimumSize(QtCore.QSize(60, 0))
+        self.perEdit.setMaximumSize(QtCore.QSize(80, 16777215))
+        self.perEdit.setObjectName("perEdit")
+        self.formLayout_4.setWidget(2, QtGui.QFormLayout.FieldRole, self.perEdit)
+        self.gridLayout.addWidget(self.rxBox_2, 2, 3, 1, 1)
+        spacerItem1 = QtGui.QSpacerItem(20, 20, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Minimum)
+        self.gridLayout.addItem(spacerItem1, 2, 4, 1, 1)
+        self.verticalLayout = QtGui.QVBoxLayout()
+        self.verticalLayout.setObjectName("verticalLayout")
+        self.pauseButton = QtGui.QPushButton(self.centralwidget)
+        self.pauseButton.setMinimumSize(QtCore.QSize(80, 0))
+        self.pauseButton.setMaximumSize(QtCore.QSize(80, 16777215))
+        self.pauseButton.setObjectName("pauseButton")
+        self.verticalLayout.addWidget(self.pauseButton)
+        spacerItem2 = QtGui.QSpacerItem(20, 60, QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
+        self.verticalLayout.addItem(spacerItem2)
+        self.closeButton = QtGui.QPushButton(self.centralwidget)
+        self.closeButton.setMinimumSize(QtCore.QSize(80, 0))
+        self.closeButton.setMaximumSize(QtCore.QSize(80, 16777215))
+        self.closeButton.setObjectName("closeButton")
+        self.verticalLayout.addWidget(self.closeButton)
+        self.gridLayout.addLayout(self.verticalLayout, 2, 5, 1, 1)
+        self.rxBox = QtGui.QGroupBox(self.centralwidget)
+        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
+        sizePolicy.setHorizontalStretch(0)
+        sizePolicy.setVerticalStretch(0)
+        sizePolicy.setHeightForWidth(self.rxBox.sizePolicy().hasHeightForWidth())
+        self.rxBox.setSizePolicy(sizePolicy)
+        self.rxBox.setMinimumSize(QtCore.QSize(180, 120))
+        self.rxBox.setMaximumSize(QtCore.QSize(180, 16777215))
+        self.rxBox.setObjectName("rxBox")
+        self.formLayoutWidget_3 = QtGui.QWidget(self.rxBox)
+        self.formLayoutWidget_3.setGeometry(QtCore.QRect(10, 10, 161, 101))
+        self.formLayoutWidget_3.setObjectName("formLayoutWidget_3")
+        self.formLayout_3 = QtGui.QFormLayout(self.formLayoutWidget_3)
+        self.formLayout_3.setSizeConstraint(QtGui.QLayout.SetFixedSize)
+        self.formLayout_3.setObjectName("formLayout_3")
+        self.alphaTimeLabel = QtGui.QLabel(self.formLayoutWidget_3)
+        self.alphaTimeLabel.setObjectName("alphaTimeLabel")
+        self.formLayout_3.setWidget(0, QtGui.QFormLayout.LabelRole, self.alphaTimeLabel)
+        self.alphaFreqLabel = QtGui.QLabel(self.formLayoutWidget_3)
+        self.alphaFreqLabel.setObjectName("alphaFreqLabel")
+        self.formLayout_3.setWidget(2, QtGui.QFormLayout.LabelRole, self.alphaFreqLabel)
+        self.alphaTimeEdit = QtGui.QLineEdit(self.formLayoutWidget_3)
+        self.alphaTimeEdit.setMinimumSize(QtCore.QSize(60, 0))
+        self.alphaTimeEdit.setMaximumSize(QtCore.QSize(80, 16777215))
+        self.alphaTimeEdit.setObjectName("alphaTimeEdit")
+        self.formLayout_3.setWidget(0, QtGui.QFormLayout.FieldRole, self.alphaTimeEdit)
+        self.alphaFreqEdit = QtGui.QLineEdit(self.formLayoutWidget_3)
+        self.alphaFreqEdit.setMinimumSize(QtCore.QSize(60, 0))
+        self.alphaFreqEdit.setMaximumSize(QtCore.QSize(80, 16777215))
+        self.alphaFreqEdit.setObjectName("alphaFreqEdit")
+        self.formLayout_3.setWidget(2, QtGui.QFormLayout.FieldRole, self.alphaFreqEdit)
+        self.betaTimeEdit = QtGui.QLineEdit(self.formLayoutWidget_3)
+        self.betaTimeEdit.setMaximumSize(QtCore.QSize(80, 16777215))
+        self.betaTimeEdit.setObjectName("betaTimeEdit")
+        self.formLayout_3.setWidget(1, QtGui.QFormLayout.FieldRole, self.betaTimeEdit)
+        self.betaTimeLabel = QtGui.QLabel(self.formLayoutWidget_3)
+        self.betaTimeLabel.setObjectName("betaTimeLabel")
+        self.formLayout_3.setWidget(1, QtGui.QFormLayout.LabelRole, self.betaTimeLabel)
+        self.gridLayout.addWidget(self.rxBox, 2, 2, 1, 1)
+        DigitalWindow.setCentralWidget(self.centralwidget)
+        self.menubar = QtGui.QMenuBar(DigitalWindow)
+        self.menubar.setGeometry(QtCore.QRect(0, 0, 1019, 24))
+        self.menubar.setObjectName("menubar")
+        self.menuFile = QtGui.QMenu(self.menubar)
+        self.menuFile.setObjectName("menuFile")
+        DigitalWindow.setMenuBar(self.menubar)
+        self.statusbar = QtGui.QStatusBar(DigitalWindow)
+        self.statusbar.setObjectName("statusbar")
+        DigitalWindow.setStatusBar(self.statusbar)
+        self.actionExit = QtGui.QAction(DigitalWindow)
+        self.actionExit.setObjectName("actionExit")
+        self.menuFile.addAction(self.actionExit)
+        self.menubar.addAction(self.menuFile.menuAction())
+
+        self.retranslateUi(DigitalWindow)
+        QtCore.QObject.connect(self.closeButton, QtCore.SIGNAL("clicked()"), DigitalWindow.close)
+        QtCore.QObject.connect(self.actionExit, QtCore.SIGNAL("triggered()"), DigitalWindow.close)
+        QtCore.QMetaObject.connectSlotsByName(DigitalWindow)
+        DigitalWindow.setTabOrder(self.snrEdit, self.freqEdit)
+        DigitalWindow.setTabOrder(self.freqEdit, self.timeEdit)
+
+    def retranslateUi(self, DigitalWindow):
+        DigitalWindow.setWindowTitle(QtGui.QApplication.translate("DigitalWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
+        self.sysBox.setTitle(QtGui.QApplication.translate("DigitalWindow", "System Parameters", None, QtGui.QApplication.UnicodeUTF8))
+        self.sampleRateLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Sample Rate (sps)", None, QtGui.QApplication.UnicodeUTF8))
+        self.channelModeBox.setTitle(QtGui.QApplication.translate("DigitalWindow", "Channel Model Parameters", None, QtGui.QApplication.UnicodeUTF8))
+        self.snrLabel.setText(QtGui.QApplication.translate("DigitalWindow", "SNR (dB)", None, QtGui.QApplication.UnicodeUTF8))
+        self.freqLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Frequency Offset (Hz)", None, QtGui.QApplication.UnicodeUTF8))
+        self.timeLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Timing Offset", None, QtGui.QApplication.UnicodeUTF8))
+        self.rxBox_2.setTitle(QtGui.QApplication.translate("DigitalWindow", "Received Packet Info", None, QtGui.QApplication.UnicodeUTF8))
+        self.pktsRcvdLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Packets Rcvd.", None, QtGui.QApplication.UnicodeUTF8))
+        self.pktsCorrectLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Packets Correct", None, QtGui.QApplication.UnicodeUTF8))
+        self.perLabel.setText(QtGui.QApplication.translate("DigitalWindow", "PER", None, QtGui.QApplication.UnicodeUTF8))
+        self.pauseButton.setText(QtGui.QApplication.translate("DigitalWindow", "Pause", None, QtGui.QApplication.UnicodeUTF8))
+        self.closeButton.setText(QtGui.QApplication.translate("DigitalWindow", "Close", None, QtGui.QApplication.UnicodeUTF8))
+        self.rxBox.setTitle(QtGui.QApplication.translate("DigitalWindow", "Receiver Parameters", None, QtGui.QApplication.UnicodeUTF8))
+        self.alphaTimeLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Alpha: time", None, QtGui.QApplication.UnicodeUTF8))
+        self.alphaFreqLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Alpha: freq", None, QtGui.QApplication.UnicodeUTF8))
+        self.betaTimeLabel.setText(QtGui.QApplication.translate("DigitalWindow", "Beta: time", None, QtGui.QApplication.UnicodeUTF8))
+        self.menuFile.setTitle(QtGui.QApplication.translate("DigitalWindow", "&File", None, QtGui.QApplication.UnicodeUTF8))
+        self.actionExit.setText(QtGui.QApplication.translate("DigitalWindow", "E&xit", None, QtGui.QApplication.UnicodeUTF8))
+
diff --git a/gnuradio-examples/python/digital/qt_digital_window2.ui b/gnuradio-examples/python/digital/qt_digital_window2.ui
new file mode 100644 (file)
index 0000000..dc20ed7
--- /dev/null
@@ -0,0 +1,637 @@
+<ui version="4.0" >
+ <class>DigitalWindow</class>
+ <widget class="QMainWindow" name="DigitalWindow" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>1019</width>
+    <height>754</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>MainWindow</string>
+  </property>
+  <widget class="QWidget" name="centralwidget" >
+   <layout class="QGridLayout" name="gridLayout" >
+    <item row="2" column="0" >
+     <layout class="QVBoxLayout" name="verticalLayout_2" >
+      <item>
+       <widget class="QGroupBox" name="sysBox" >
+        <property name="sizePolicy" >
+         <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize" >
+         <size>
+          <width>240</width>
+          <height>60</height>
+         </size>
+        </property>
+        <property name="maximumSize" >
+         <size>
+          <width>240</width>
+          <height>16777215</height>
+         </size>
+        </property>
+        <property name="title" >
+         <string>System Parameters</string>
+        </property>
+        <widget class="QWidget" name="formLayoutWidget" >
+         <property name="geometry" >
+          <rect>
+           <x>10</x>
+           <y>20</y>
+           <width>211</width>
+           <height>31</height>
+          </rect>
+         </property>
+         <layout class="QFormLayout" name="formLayout" >
+          <property name="sizeConstraint" >
+           <enum>QLayout::SetFixedSize</enum>
+          </property>
+          <property name="verticalSpacing" >
+           <number>20</number>
+          </property>
+          <item row="0" column="1" >
+           <widget class="QLineEdit" name="sampleRateEdit" >
+            <property name="sizePolicy" >
+             <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="minimumSize" >
+             <size>
+              <width>60</width>
+              <height>26</height>
+             </size>
+            </property>
+            <property name="maximumSize" >
+             <size>
+              <width>80</width>
+              <height>26</height>
+             </size>
+            </property>
+           </widget>
+          </item>
+          <item row="0" column="0" >
+           <widget class="QLabel" name="sampleRateLabel" >
+            <property name="sizePolicy" >
+             <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+              <horstretch>0</horstretch>
+              <verstretch>0</verstretch>
+             </sizepolicy>
+            </property>
+            <property name="minimumSize" >
+             <size>
+              <width>0</width>
+              <height>20</height>
+             </size>
+            </property>
+            <property name="maximumSize" >
+             <size>
+              <width>16777215</width>
+              <height>20</height>
+             </size>
+            </property>
+            <property name="text" >
+             <string>Sample Rate (sps)</string>
+            </property>
+           </widget>
+          </item>
+         </layout>
+        </widget>
+       </widget>
+      </item>
+      <item>
+       <spacer name="verticalSpacer_2" >
+        <property name="orientation" >
+         <enum>Qt::Vertical</enum>
+        </property>
+        <property name="sizeType" >
+         <enum>QSizePolicy::Fixed</enum>
+        </property>
+        <property name="sizeHint" stdset="0" >
+         <size>
+          <width>20</width>
+          <height>60</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+     </layout>
+    </item>
+    <item row="0" column="0" colspan="6" >
+     <layout class="QVBoxLayout" name="verticalLayout_5" >
+      <item>
+       <widget class="QFrame" name="sinkFrame" >
+        <property name="sizePolicy" >
+         <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+        <property name="minimumSize" >
+         <size>
+          <width>500</width>
+          <height>550</height>
+         </size>
+        </property>
+        <property name="frameShape" >
+         <enum>QFrame::StyledPanel</enum>
+        </property>
+        <property name="frameShadow" >
+         <enum>QFrame::Raised</enum>
+        </property>
+        <layout class="QGridLayout" name="gridLayout_2" >
+         <item row="1" column="0" >
+          <layout class="QHBoxLayout" name="sinkLayout" />
+         </item>
+        </layout>
+       </widget>
+      </item>
+     </layout>
+    </item>
+    <item row="2" column="1" >
+     <widget class="QGroupBox" name="channelModeBox" >
+      <property name="sizePolicy" >
+       <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+        <horstretch>0</horstretch>
+        <verstretch>0</verstretch>
+       </sizepolicy>
+      </property>
+      <property name="minimumSize" >
+       <size>
+        <width>245</width>
+        <height>130</height>
+       </size>
+      </property>
+      <property name="maximumSize" >
+       <size>
+        <width>245</width>
+        <height>16777215</height>
+       </size>
+      </property>
+      <property name="title" >
+       <string>Channel Model Parameters</string>
+      </property>
+      <widget class="QWidget" name="formLayoutWidget_2" >
+       <property name="geometry" >
+        <rect>
+         <x>10</x>
+         <y>20</y>
+         <width>221</width>
+         <height>98</height>
+        </rect>
+       </property>
+       <layout class="QFormLayout" name="formLayout_2" >
+        <property name="sizeConstraint" >
+         <enum>QLayout::SetFixedSize</enum>
+        </property>
+        <property name="fieldGrowthPolicy" >
+         <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+        </property>
+        <item row="0" column="0" >
+         <widget class="QLabel" name="snrLabel" >
+          <property name="text" >
+           <string>SNR (dB)</string>
+          </property>
+         </widget>
+        </item>
+        <item row="0" column="1" >
+         <widget class="QLineEdit" name="snrEdit" >
+          <property name="minimumSize" >
+           <size>
+            <width>60</width>
+            <height>0</height>
+           </size>
+          </property>
+          <property name="maximumSize" >
+           <size>
+            <width>80</width>
+            <height>16777215</height>
+           </size>
+          </property>
+         </widget>
+        </item>
+        <item row="1" column="0" >
+         <widget class="QLabel" name="freqLabel" >
+          <property name="text" >
+           <string>Frequency Offset (Hz)</string>
+          </property>
+         </widget>
+        </item>
+        <item row="1" column="1" >
+         <widget class="QLineEdit" name="freqEdit" >
+          <property name="minimumSize" >
+           <size>
+            <width>60</width>
+            <height>0</height>
+           </size>
+          </property>
+          <property name="maximumSize" >
+           <size>
+            <width>80</width>
+            <height>16777215</height>
+           </size>
+          </property>
+         </widget>
+        </item>
+        <item row="2" column="0" >
+         <widget class="QLabel" name="timeLabel" >
+          <property name="text" >
+           <string>Timing Offset</string>
+          </property>
+         </widget>
+        </item>
+        <item row="2" column="1" >
+         <widget class="QLineEdit" name="timeEdit" >
+          <property name="minimumSize" >
+           <size>
+            <width>60</width>
+            <height>0</height>
+           </size>
+          </property>
+          <property name="maximumSize" >
+           <size>
+            <width>80</width>
+            <height>16777215</height>
+           </size>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </widget>
+      <zorder>formLayoutWidget_2</zorder>
+      <zorder>rxBox</zorder>
+     </widget>
+    </item>
+    <item row="2" column="3" >
+     <widget class="QGroupBox" name="rxBox_2" >
+      <property name="sizePolicy" >
+       <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+        <horstretch>0</horstretch>
+        <verstretch>0</verstretch>
+       </sizepolicy>
+      </property>
+      <property name="minimumSize" >
+       <size>
+        <width>220</width>
+        <height>125</height>
+       </size>
+      </property>
+      <property name="maximumSize" >
+       <size>
+        <width>265</width>
+        <height>125</height>
+       </size>
+      </property>
+      <property name="title" >
+       <string>Received Packet Info</string>
+      </property>
+      <widget class="QWidget" name="formLayoutWidget_4" >
+       <property name="geometry" >
+        <rect>
+         <x>10</x>
+         <y>20</y>
+         <width>248</width>
+         <height>188</height>
+        </rect>
+       </property>
+       <layout class="QFormLayout" name="formLayout_4" >
+        <property name="sizeConstraint" >
+         <enum>QLayout::SetFixedSize</enum>
+        </property>
+        <property name="fieldGrowthPolicy" >
+         <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
+        </property>
+        <item row="0" column="0" >
+         <widget class="QLabel" name="pktsRcvdLabel" >
+          <property name="text" >
+           <string>Packets Rcvd.</string>
+          </property>
+         </widget>
+        </item>
+        <item row="0" column="1" >
+         <widget class="QLineEdit" name="pktsRcvdEdit" >
+          <property name="minimumSize" >
+           <size>
+            <width>60</width>
+            <height>0</height>
+           </size>
+          </property>
+          <property name="maximumSize" >
+           <size>
+            <width>80</width>
+            <height>16777215</height>
+           </size>
+          </property>
+         </widget>
+        </item>
+        <item row="1" column="0" >
+         <widget class="QLabel" name="pktsCorrectLabel" >
+          <property name="text" >
+           <string>Packets Correct</string>
+          </property>
+         </widget>
+        </item>
+        <item row="1" column="1" >
+         <widget class="QLineEdit" name="pktsCorrectEdit" >
+          <property name="minimumSize" >
+           <size>
+            <width>60</width>
+            <height>0</height>
+           </size>
+          </property>
+          <property name="maximumSize" >
+           <size>
+            <width>80</width>
+            <height>16777215</height>
+           </size>
+          </property>
+         </widget>
+        </item>
+        <item row="2" column="0" >
+         <widget class="QLabel" name="perLabel" >
+          <property name="text" >
+           <string>PER</string>
+          </property>
+         </widget>
+        </item>
+        <item row="2" column="1" >
+         <widget class="QLineEdit" name="perEdit" >
+          <property name="minimumSize" >
+           <size>
+            <width>60</width>
+            <height>0</height>
+           </size>
+          </property>
+          <property name="maximumSize" >
+           <size>
+            <width>80</width>
+            <height>16777215</height>
+           </size>
+          </property>
+         </widget>
+        </item>
+       </layout>
+       <zorder>pktsRcvdLabel</zorder>
+       <zorder>pktsCorrectLabel</zorder>
+       <zorder>perLabel</zorder>
+       <zorder>pktsRcvdEdit</zorder>
+       <zorder>pktsCorrectEdit</zorder>
+       <zorder>perEdit</zorder>
+       <zorder>rxBox</zorder>
+      </widget>
+     </widget>
+    </item>
+    <item row="2" column="4" >
+     <spacer name="horizontalSpacer" >
+      <property name="orientation" >
+       <enum>Qt::Horizontal</enum>
+      </property>
+      <property name="sizeHint" stdset="0" >
+       <size>
+        <width>20</width>
+        <height>20</height>
+       </size>
+      </property>
+     </spacer>
+    </item>
+    <item row="2" column="5" >
+     <layout class="QVBoxLayout" name="verticalLayout" >
+      <item>
+       <widget class="QPushButton" name="pauseButton" >
+        <property name="minimumSize" >
+         <size>
+          <width>80</width>
+          <height>0</height>
+         </size>
+        </property>
+        <property name="maximumSize" >
+         <size>
+          <width>80</width>
+          <height>16777215</height>
+         </size>
+        </property>
+        <property name="text" >
+         <string>Pause</string>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <spacer name="verticalSpacer" >
+        <property name="orientation" >
+         <enum>Qt::Vertical</enum>
+        </property>
+        <property name="sizeType" >
+         <enum>QSizePolicy::Fixed</enum>
+        </property>
+        <property name="sizeHint" stdset="0" >
+         <size>
+          <width>20</width>
+          <height>60</height>
+         </size>
+        </property>
+       </spacer>
+      </item>
+      <item>
+       <widget class="QPushButton" name="closeButton" >
+        <property name="minimumSize" >
+         <size>
+          <width>80</width>
+          <height>0</height>
+         </size>
+        </property>
+        <property name="maximumSize" >
+         <size>
+          <width>80</width>
+          <height>16777215</height>
+         </size>
+        </property>
+        <property name="text" >
+         <string>Close</string>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </item>
+    <item row="2" column="2" >
+     <widget class="QGroupBox" name="rxBox" >
+      <property name="sizePolicy" >
+       <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
+        <horstretch>0</horstretch>
+        <verstretch>0</verstretch>
+       </sizepolicy>
+      </property>
+      <property name="minimumSize" >
+       <size>
+        <width>180</width>
+        <height>120</height>
+       </size>
+      </property>
+      <property name="maximumSize" >
+       <size>
+        <width>180</width>
+        <height>16777215</height>
+       </size>
+      </property>
+      <property name="title" >
+       <string>Receiver Parameters</string>
+      </property>
+      <widget class="QWidget" name="formLayoutWidget_3" >
+       <property name="geometry" >
+        <rect>
+         <x>10</x>
+         <y>10</y>
+         <width>161</width>
+         <height>101</height>
+        </rect>
+       </property>
+       <layout class="QFormLayout" name="formLayout_3" >
+        <property name="sizeConstraint" >
+         <enum>QLayout::SetFixedSize</enum>
+        </property>
+        <item row="0" column="0" >
+         <widget class="QLabel" name="alphaTimeLabel" >
+          <property name="text" >
+           <string>Alpha: time</string>
+          </property>
+         </widget>
+        </item>
+        <item row="2" column="0" >
+         <widget class="QLabel" name="alphaFreqLabel" >
+          <property name="text" >
+           <string>Alpha: freq</string>
+          </property>
+         </widget>
+        </item>
+        <item row="0" column="1" >
+         <widget class="QLineEdit" name="alphaTimeEdit" >
+          <property name="minimumSize" >
+           <size>
+            <width>60</width>
+            <height>0</height>
+           </size>
+          </property>
+          <property name="maximumSize" >
+           <size>
+            <width>80</width>
+            <height>16777215</height>
+           </size>
+          </property>
+         </widget>
+        </item>
+        <item row="2" column="1" >
+         <widget class="QLineEdit" name="alphaFreqEdit" >
+          <property name="minimumSize" >
+           <size>
+            <width>60</width>
+            <height>0</height>
+           </size>
+          </property>
+          <property name="maximumSize" >
+           <size>
+            <width>80</width>
+            <height>16777215</height>
+           </size>
+          </property>
+         </widget>
+        </item>
+        <item row="1" column="1" >
+         <widget class="QLineEdit" name="betaTimeEdit" >
+          <property name="maximumSize" >
+           <size>
+            <width>80</width>
+            <height>16777215</height>
+           </size>
+          </property>
+         </widget>
+        </item>
+        <item row="1" column="0" >
+         <widget class="QLabel" name="betaTimeLabel" >
+          <property name="text" >
+           <string>Beta: time</string>
+          </property>
+         </widget>
+        </item>
+       </layout>
+      </widget>
+     </widget>
+    </item>
+   </layout>
+   <zorder>channelModeBox</zorder>
+   <zorder></zorder>
+   <zorder>rxBox_2</zorder>
+   <zorder>horizontalSpacer</zorder>
+   <zorder></zorder>
+   <zorder>rxBox</zorder>
+  </widget>
+  <widget class="QMenuBar" name="menubar" >
+   <property name="geometry" >
+    <rect>
+     <x>0</x>
+     <y>0</y>
+     <width>1019</width>
+     <height>24</height>
+    </rect>
+   </property>
+   <widget class="QMenu" name="menuFile" >
+    <property name="title" >
+     <string>&amp;File</string>
+    </property>
+    <addaction name="actionExit" />
+   </widget>
+   <addaction name="menuFile" />
+  </widget>
+  <widget class="QStatusBar" name="statusbar" />
+  <action name="actionExit" >
+   <property name="text" >
+    <string>E&amp;xit</string>
+   </property>
+  </action>
+ </widget>
+ <tabstops>
+  <tabstop>snrEdit</tabstop>
+  <tabstop>freqEdit</tabstop>
+  <tabstop>timeEdit</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>closeButton</sender>
+   <signal>clicked()</signal>
+   <receiver>DigitalWindow</receiver>
+   <slot>close()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>322</x>
+     <y>623</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>66</x>
+     <y>561</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>actionExit</sender>
+   <signal>triggered()</signal>
+   <receiver>DigitalWindow</receiver>
+   <slot>close()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>-1</x>
+     <y>-1</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>617</x>
+     <y>327</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>