3 from gnuradio import gr, blks2
4 from gnuradio.qtgui import qtgui
5 from gnuradio import eng_notation
6 from PyQt4 import QtGui, QtCore
11 from qt_digital_window import Ui_DigitalWindow
13 print "Error: could not find qt_digital_window.py:"
14 print "\t\"Please run: pyuic4 qt_digital_window.ui -o qt_digital_window.py\""
17 class dialog_box(QtGui.QMainWindow):
18 def __init__(self, snkTx, snkRx, fg, parent=None):
19 QtGui.QWidget.__init__(self, parent)
20 self.gui = Ui_DigitalWindow()
21 self.gui.setupUi(self)
25 self.set_sample_rate(self.fg.sample_rate())
27 self.set_snr(self.fg.snr())
28 self.set_frequency(self.fg.frequency_offset())
29 self.set_time_offset(self.fg.timing_offset())
31 self.set_gain_mu(self.fg.rx_gain_mu())
32 self.set_alpha(self.fg.rx_alpha())
34 # Add the qtsnk widgets to the hlayout box
35 self.gui.sinkLayout.addWidget(snkTx)
36 self.gui.sinkLayout.addWidget(snkRx)
39 # Connect up some signals
40 self.connect(self.gui.pauseButton, QtCore.SIGNAL("clicked()"),
43 self.connect(self.gui.sampleRateEdit, QtCore.SIGNAL("editingFinished()"),
44 self.sampleRateEditText)
46 self.connect(self.gui.snrEdit, QtCore.SIGNAL("editingFinished()"),
48 self.connect(self.gui.freqEdit, QtCore.SIGNAL("editingFinished()"),
50 self.connect(self.gui.timeEdit, QtCore.SIGNAL("editingFinished()"),
53 self.connect(self.gui.gainMuEdit, QtCore.SIGNAL("editingFinished()"),
55 self.connect(self.gui.alphaEdit, QtCore.SIGNAL("editingFinished()"),
60 if(self.gui.pauseButton.text() == "Pause"):
63 self.gui.pauseButton.setText("Unpause")
66 self.gui.pauseButton.setText("Pause")
68 # Accessor functions for Gui to manipulate system parameters
69 def set_sample_rate(self, sr):
70 ssr = eng_notation.num_to_str(sr)
71 self.gui.sampleRateEdit.setText(QtCore.QString("%1").arg(ssr))
73 def sampleRateEditText(self):
75 rate = self.gui.sampleRateEdit.text().toAscii()
76 srate = eng_notation.str_to_num(rate)
77 self.fg.set_sample_rate(srate)
82 # Accessor functions for Gui to manipulate channel model
83 def set_snr(self, snr):
84 self.gui.snrEdit.setText(QtCore.QString("%1").arg(snr))
86 def set_frequency(self, fo):
87 self.gui.freqEdit.setText(QtCore.QString("%1").arg(fo))
89 def set_time_offset(self, to):
90 self.gui.timeEdit.setText(QtCore.QString("%1").arg(to))
92 def snrEditText(self):
94 snr = self.gui.snrEdit.text().toDouble()[0]
99 def freqEditText(self):
101 freq = self.gui.freqEdit.text().toDouble()[0]
102 self.fg.set_frequency_offset(freq)
106 def timeEditText(self):
108 to = self.gui.timeEdit.text().toDouble()[0]
109 self.fg.set_timing_offset(to)
114 # Accessor functions for Gui to manipulate receiver parameters
115 def set_gain_mu(self, gain):
116 self.gui.gainMuEdit.setText(QtCore.QString("%1").arg(gain))
118 def set_alpha(self, alpha):
119 self.gui.alphaEdit.setText(QtCore.QString("%1").arg(alpha))
121 def alphaEditText(self):
123 alpha = self.gui.alphaEdit.text().toDouble()[0]
124 self.fg.set_rx_alpha(alpha)
128 def gainMuEditText(self):
130 gain = self.gui.gainMuEdit.text().toDouble()[0]
131 self.fg.set_rx_gain_mu(gain)
136 class my_top_block(gr.top_block):
138 gr.top_block.__init__(self)
140 self.qapp = QtGui.QApplication(sys.argv)
142 self._sample_rate = 200e3
145 self.excess_bw = 0.35
146 self.gray_code = True
150 self.data = scipy.random.randint(0, 255, 1000)
151 self.src = gr.vector_source_b(self.data.tolist(), True)
152 self.mod = blks2.dqpsk_mod(self.sps, self.excess_bw, self.gray_code, False, False)
154 self.rrctaps = gr.firdes.root_raised_cosine(1, self.sps, 1, self.excess_bw, 21)
155 self.rx_rrc = gr.fir_filter_ccf(1, self.rrctaps)
158 # Set up the carrier & clock recovery parameters
162 self.omega = self.sps
163 self.gain_omega = .25 * self.gain_mu * self.gain_mu
164 self.omega_rel_lim = 0.05
167 self.beta = 0.25 * self.alpha * self.alpha
168 self.fmin = -1000/self.sample_rate()
169 self.fmax = 1000/self.sample_rate()
171 self.receiver = gr.mpsk_receiver_cc(self.arity, 0,
172 self.alpha, self.beta,
173 self.fmin, self.fmax,
174 self.mu, self.gain_mu,
175 self.omega, self.gain_omega,
180 noise = self.get_noise_voltage(self.snr_dB)
181 self.fo = 100/self.sample_rate()
183 self.channel = gr.channel_model(noise, self.fo, self.to)
185 self.thr = gr.throttle(gr.sizeof_char, 10*fftsize)
186 self.snk_tx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, -1/2, 1/2,
187 "Tx", True, True, False, True, True)
189 self.snk_rx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, -1/2, 1/2,
190 "Rx", True, True, False, True, True)
192 self.connect(self.src, self.thr, self.mod, self.channel, self.snk_tx)
193 self.connect(self.channel, self.rx_rrc, self.receiver, self.snk_rx)
195 pyTxQt = self.snk_tx.pyqwidget()
196 pyTx = sip.wrapinstance(pyTxQt, QtGui.QWidget)
198 pyRxQt = self.snk_rx.pyqwidget()
199 pyRx = sip.wrapinstance(pyRxQt, QtGui.QWidget)
201 self.main_box = dialog_box(pyTx, pyRx, self);
205 def get_noise_voltage(self, SNR):
206 S = 0 # dBm, assuming signal power normalized
208 npwr = pow(10.0, N/10.0) # ratio
209 nv = scipy.sqrt(npwr * self.sps) # convert the noise voltage
214 def sample_rate(self):
215 return self._sample_rate
217 def set_sample_rate(self, sr):
218 self._sample_rate = sr
221 # Channel Model Parameters
225 def set_snr(self, snr):
227 noise = self.get_noise_voltage(self.snr_dB)
228 self.channel.set_noise_voltage(noise)
230 def frequency_offset(self):
231 return self.fo * self.sample_rate()
233 def set_frequency_offset(self, fo):
234 self.fo = fo / self.sample_rate()
235 self.channel.set_frequency_offset(self.fo)
237 def timing_offset(self):
240 def set_timing_offset(self, to):
242 self.channel.set_timing_offset(self.to)
245 # Receiver Parameters
246 def rx_gain_mu(self):
249 def rx_gain_omega(self):
250 return self.gain_omega
252 def set_rx_gain_mu(self, gain):
254 self.gain_omega = .25 * self.gain_mu * self.gain_mu
255 self.receiver.set_gain_mu(self.gain_mu)
256 self.receiver.set_gain_omega(self.gain_omega)
264 def set_rx_alpha(self, alpha):
266 self.beta = .25 * self.alpha * self.alpha
267 self.receiver.set_alpha(self.alpha)
268 self.receiver.set_beta(self.beta)
271 if __name__ == "__main__":