Changes to the examples to fit updates to qtgui.
[debian/gnuradio] / gr-qtgui / src / python / qt_digital.py
1 #!/usr/bin/env python
2
3 from gnuradio import gr, blks2
4 from gnuradio.qtgui import qtgui
5 from gnuradio import eng_notation
6 from PyQt4 import QtGui, QtCore
7 import sys, sip
8 import scipy
9
10 try:
11     from qt_digital_window import Ui_DigitalWindow
12 except ImportError:
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\""
15     sys.exit(1)
16
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)
22
23         self.fg = fg
24
25         self.set_sample_rate(self.fg.sample_rate())
26
27         self.set_snr(self.fg.snr())
28         self.set_frequency(self.fg.frequency_offset())
29         self.set_time_offset(self.fg.timing_offset())
30
31         self.set_gain_mu(self.fg.rx_gain_mu())
32         self.set_alpha(self.fg.rx_alpha())
33
34         # Add the qtsnk widgets to the hlayout box
35         self.gui.sinkLayout.addWidget(snkTx)
36         self.gui.sinkLayout.addWidget(snkRx)
37
38
39         # Connect up some signals
40         self.connect(self.gui.pauseButton, QtCore.SIGNAL("clicked()"),
41                      self.pauseFg)
42
43         self.connect(self.gui.sampleRateEdit, QtCore.SIGNAL("editingFinished()"),
44                      self.sampleRateEditText)
45
46         self.connect(self.gui.snrEdit, QtCore.SIGNAL("editingFinished()"),
47                      self.snrEditText)
48         self.connect(self.gui.freqEdit, QtCore.SIGNAL("editingFinished()"),
49                      self.freqEditText)
50         self.connect(self.gui.timeEdit, QtCore.SIGNAL("editingFinished()"),
51                      self.timeEditText)
52
53         self.connect(self.gui.gainMuEdit, QtCore.SIGNAL("editingFinished()"),
54                      self.gainMuEditText)
55         self.connect(self.gui.alphaEdit, QtCore.SIGNAL("editingFinished()"),
56                      self.alphaEditText)
57
58
59     def pauseFg(self):
60         if(self.gui.pauseButton.text() == "Pause"):
61             self.fg.stop()
62             self.fg.wait()
63             self.gui.pauseButton.setText("Unpause")
64         else:
65             self.fg.start()
66             self.gui.pauseButton.setText("Pause")
67
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))
72
73     def sampleRateEditText(self):
74         try:
75             rate = self.gui.sampleRateEdit.text().toAscii()
76             srate = eng_notation.str_to_num(rate)
77             self.fg.set_sample_rate(srate)
78         except RuntimeError:
79             pass
80
81
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))
85
86     def set_frequency(self, fo):
87         self.gui.freqEdit.setText(QtCore.QString("%1").arg(fo))
88
89     def set_time_offset(self, to):
90         self.gui.timeEdit.setText(QtCore.QString("%1").arg(to))
91
92     def snrEditText(self):
93         try:
94             snr = self.gui.snrEdit.text().toDouble()[0]
95             self.fg.set_snr(snr)
96         except RuntimeError:
97             pass
98
99     def freqEditText(self):
100         try:
101             freq = self.gui.freqEdit.text().toDouble()[0]
102             self.fg.set_frequency_offset(freq)
103         except RuntimeError:
104             pass
105
106     def timeEditText(self):
107         try:
108             to = self.gui.timeEdit.text().toDouble()[0]
109             self.fg.set_timing_offset(to)
110         except RuntimeError:
111             pass
112
113
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))
117
118     def set_alpha(self, alpha):
119         self.gui.alphaEdit.setText(QtCore.QString("%1").arg(alpha))
120
121     def alphaEditText(self):
122         try:
123             alpha = self.gui.alphaEdit.text().toDouble()[0]
124             self.fg.set_rx_alpha(alpha)
125         except RuntimeError:
126             pass
127
128     def gainMuEditText(self):
129         try:
130             gain = self.gui.gainMuEdit.text().toDouble()[0]
131             self.fg.set_rx_gain_mu(gain)
132         except RuntimeError:
133             pass
134
135
136 class my_top_block(gr.top_block):
137     def __init__(self):
138         gr.top_block.__init__(self)
139
140         self.qapp = QtGui.QApplication(sys.argv)
141
142         self._sample_rate = 2000e3
143
144         self.sps = 2
145         self.excess_bw = 0.35
146         self.gray_code = True
147         
148         fftsize = 2048
149
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)
153
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)
156
157
158         # Set up the carrier & clock recovery parameters
159         self.arity = 4
160         self.mu = 0.5
161         self.gain_mu = 0.05
162         self.omega = self.sps
163         self.gain_omega = .25 * self.gain_mu * self.gain_mu
164         self.omega_rel_lim = 0.05
165         
166         self.alpha = 0.15
167         self.beta  = 0.25 * self.alpha * self.alpha
168         self.fmin = -1000/self.sample_rate()
169         self.fmax = 1000/self.sample_rate()
170         
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,
176                                             self.omega_rel_lim)
177         
178         
179         self.snr_dB = 15
180         noise = self.get_noise_voltage(self.snr_dB)
181         self.fo = 100/self.sample_rate()
182         self.to = 1.0
183         self.channel = gr.channel_model(noise, self.fo, self.to)
184
185         self.thr = gr.throttle(gr.sizeof_char, self._sample_rate)
186         self.snk_tx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS, 
187                                    0, self._sample_rate*self.sps,
188                                    "Tx", True, True, False, True, True)
189
190         self.snk_rx = qtgui.sink_c(fftsize, gr.firdes.WIN_BLACKMAN_hARRIS,
191                                    0, self._sample_rate,
192                                    "Rx", True, True, False, True, True)
193
194         self.connect(self.src, self.thr, self.mod, self.channel, self.snk_tx)
195         self.connect(self.channel, self.rx_rrc, self.receiver, self.snk_rx)
196         
197         pyTxQt  = self.snk_tx.pyqwidget()
198         pyTx = sip.wrapinstance(pyTxQt, QtGui.QWidget)
199
200         pyRxQt  = self.snk_rx.pyqwidget()
201         pyRx = sip.wrapinstance(pyRxQt, QtGui.QWidget)
202
203         self.main_box = dialog_box(pyTx, pyRx, self);
204         self.main_box.show()
205
206
207     def get_noise_voltage(self, SNR):
208         S = 0                            # dBm, assuming signal power normalized
209         N = S - SNR                      # dBm
210         npwr = pow(10.0, N/10.0)         # ratio
211         nv = scipy.sqrt(npwr * self.sps) # convert the noise voltage
212         return nv
213
214
215     # System Parameters
216     def sample_rate(self):
217         return self._sample_rate
218     
219     def set_sample_rate(self, sr):
220         self._sample_rate = sr
221
222
223     # Channel Model Parameters
224     def snr(self):
225         return self.snr_dB
226     
227     def set_snr(self, snr):
228         self.snr_dB = snr
229         noise = self.get_noise_voltage(self.snr_dB)
230         self.channel.set_noise_voltage(noise)
231
232     def frequency_offset(self):
233         return self.fo * self.sample_rate()
234
235     def set_frequency_offset(self, fo):
236         self.fo = fo / self.sample_rate()
237         self.channel.set_frequency_offset(self.fo)
238
239     def timing_offset(self):
240         return self.to
241     
242     def set_timing_offset(self, to):
243         self.to = to
244         self.channel.set_timing_offset(self.to)
245
246
247     # Receiver Parameters
248     def rx_gain_mu(self):
249         return self.gain_mu
250
251     def rx_gain_omega(self):
252         return self.gain_omega
253     
254     def set_rx_gain_mu(self, gain):
255         self.gain_mu = gain
256         self.gain_omega = .25 * self.gain_mu * self.gain_mu
257         self.receiver.set_gain_mu(self.gain_mu)
258         self.receiver.set_gain_omega(self.gain_omega)
259
260     def rx_alpha(self):
261         return self.alpha
262
263     def rx_beta(self):
264         return self.beta
265     
266     def set_rx_alpha(self, alpha):
267         self.alpha = alpha
268         self.beta = .25 * self.alpha * self.alpha
269         self.receiver.set_alpha(self.alpha)
270         self.receiver.set_beta(self.beta)
271
272     
273 if __name__ == "__main__":
274     tb = my_top_block();
275     tb.start()
276     tb.qapp.exec_()