fixed issue where usrp siggen continued to transmit after program exit
[debian/gnuradio] / gr-utils / src / python / usrp_siggen_gui.py
1 #!/usr/bin/env python
2 #
3 # Copyright 2009 Free Software Foundation, Inc.
4
5 # This file is part of GNU Radio
6
7 # GNU Radio is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3, or (at your option)
10 # any later version.
11
12 # GNU Radio is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
16
17 # You should have received a copy of the GNU General Public License
18 # along with GNU Radio; see the file COPYING.  If not, write to
19 # the Free Software Foundation, Inc., 51 Franklin Street,
20 # Boston, MA 02110-1301, USA.
21
22
23 import wx
24 from gnuradio import gr
25 from gnuradio.gr.pubsub import pubsub
26 from gnuradio.wxgui import gui, forms
27 import usrp_siggen
28 import sys, math
29
30 class app_gui(pubsub):
31     def __init__(self, frame, panel, vbox, top_block, options, args):
32         pubsub.__init__(self)
33         self.frame = frame      # Use for top-level application window frame
34         self.panel = panel      # Use as parent class for created windows
35         self.vbox = vbox        # Use as sizer for created windows
36         self.tb = top_block     # GUI-unaware flowgraph class
37         self.options = options  # Supplied command-line options
38         self.args = args        # Supplied command-line arguments
39         self.build_gui()
40
41     # Event response handlers
42     def evt_set_status_msg(self, msg):
43         self.frame.SetStatusText(msg, 0)
44
45     # GUI construction
46     def build_gui(self):
47         self.vbox.AddSpacer(5)
48         self.vbox.AddStretchSpacer()
49         ##################################################
50         # Baseband controls
51         ##################################################
52         bb_vbox = forms.static_box_sizer(parent=self.panel, label="Baseband Modulation", orient=wx.VERTICAL, bold=True)
53         self.vbox.Add(bb_vbox, 0, wx.EXPAND)
54         sine_bb_hbox = wx.BoxSizer(wx.HORIZONTAL)
55         sweep_bb_hbox = wx.BoxSizer(wx.HORIZONTAL)
56         tone_bb_hbox = wx.BoxSizer(wx.HORIZONTAL)
57         self.vbox.AddSpacer(10)
58         self.vbox.AddStretchSpacer()
59         #callback to show/hide forms
60         def set_type(type):
61             sine_bb_hbox.ShowItems(type == gr.GR_SIN_WAVE)
62             sweep_bb_hbox.ShowItems(type == 'sweep')
63             tone_bb_hbox.ShowItems(type == '2tone')
64             self.vbox.Layout()
65         self.tb.subscribe(usrp_siggen.TYPE_KEY, set_type)
66         #create sine forms
67         sine_bb_hbox.AddSpacer(10)
68         forms.text_box(
69             parent=self.panel, sizer=sine_bb_hbox,
70             label='Frequency (Hz)',
71             ps=self.tb,
72             key=usrp_siggen.WAVEFORM_FREQ_KEY,
73             converter=forms.float_converter(),
74         )
75         sine_bb_hbox.AddStretchSpacer()
76         #create sweep forms
77         sweep_bb_hbox.AddSpacer(10)
78         forms.text_box(
79             parent=self.panel, sizer=sweep_bb_hbox,
80             label='Sweep Width (Hz)',
81             ps=self.tb,
82             key=usrp_siggen.WAVEFORM_FREQ_KEY,
83             converter=forms.float_converter(),
84         )
85         sweep_bb_hbox.AddStretchSpacer()
86         forms.text_box(
87             parent=self.panel, sizer=sweep_bb_hbox,
88             label='Sweep Rate (Hz)',
89             ps=self.tb,
90             key=usrp_siggen.WAVEFORM2_FREQ_KEY,
91             converter=forms.float_converter(),
92         )
93         sweep_bb_hbox.AddStretchSpacer()
94         #create 2tone forms
95         tone_bb_hbox.AddSpacer(10)
96         forms.text_box(
97             parent=self.panel, sizer=tone_bb_hbox,
98             label='Tone 1 (Hz)',
99             ps=self.tb,
100             key=usrp_siggen.WAVEFORM_FREQ_KEY,
101             converter=forms.float_converter(),
102         )
103         tone_bb_hbox.AddStretchSpacer()
104         forms.text_box(
105             parent=self.panel, sizer=tone_bb_hbox,
106             label='Tone 2 (Hz)',
107             ps=self.tb,
108             key=usrp_siggen.WAVEFORM2_FREQ_KEY,
109             converter=forms.float_converter(),
110         )
111         tone_bb_hbox.AddStretchSpacer()
112         forms.radio_buttons(
113             parent=self.panel, sizer=bb_vbox,
114             choices=usrp_siggen.waveforms.keys(),
115             labels=usrp_siggen.waveforms.values(),
116             ps=self.tb,
117             key=usrp_siggen.TYPE_KEY,
118             style=wx.NO_BORDER | wx.RA_HORIZONTAL,
119         )
120         bb_vbox.AddSpacer(10)
121         bb_vbox.Add(sine_bb_hbox, 0, wx.EXPAND)
122         bb_vbox.Add(sweep_bb_hbox, 0, wx.EXPAND)
123         bb_vbox.Add(tone_bb_hbox, 0, wx.EXPAND)
124         set_type(self.tb[usrp_siggen.TYPE_KEY])
125         ##################################################
126         # Frequency controls
127         ##################################################
128         fc_vbox = forms.static_box_sizer(parent=self.panel, label="Center Frequency", orient=wx.VERTICAL, bold=True)
129         fc_vbox.AddSpacer(5)
130         # First row of frequency controls (center frequency)
131         freq_hbox = wx.BoxSizer(wx.HORIZONTAL)
132         fc_vbox.Add(freq_hbox, 0, wx.EXPAND)
133         fc_vbox.AddSpacer(10)
134         # Second row of frequency controls (results)
135         tr_hbox = wx.BoxSizer(wx.HORIZONTAL)
136         fc_vbox.Add(tr_hbox, 0, wx.EXPAND)
137         fc_vbox.AddSpacer(5)
138         # Add frequency controls to top window sizer
139         self.vbox.Add(fc_vbox, 0, wx.EXPAND)
140         self.vbox.AddSpacer(10)
141         self.vbox.AddStretchSpacer()
142         freq_hbox.AddSpacer(5)
143         forms.text_box(
144             parent=self.panel, sizer=freq_hbox,
145             proportion=1,
146             converter=forms.float_converter(),
147             ps=self.tb,
148             key=usrp_siggen.TX_FREQ_KEY,
149         )
150         freq_hbox.AddSpacer(10)
151         forms.slider(
152             parent=self.panel, sizer=freq_hbox,
153             proportion=2,
154             ps=self.tb,
155             key=usrp_siggen.TX_FREQ_KEY,
156             minimum=self.tb[usrp_siggen.FREQ_RANGE_KEY][0],
157             maximum=self.tb[usrp_siggen.FREQ_RANGE_KEY][1],
158             num_steps=100,
159         )
160         freq_hbox.AddSpacer(5)
161         tr_hbox.AddSpacer(5)
162         forms.static_text(
163             parent=self.panel, sizer=tr_hbox,
164             label='Daughterboard (Hz)',
165             ps=self.tb,
166             key=usrp_siggen.BB_FREQ_KEY,
167             converter=forms.float_converter(),
168             proportion=1,
169         )
170         tr_hbox.AddSpacer(10)
171         forms.static_text(
172             parent=self.panel, sizer=tr_hbox,
173             label='USRP DDC (Hz)',
174             ps=self.tb,
175             key=usrp_siggen.DDC_FREQ_KEY,
176             converter=forms.float_converter(),
177             proportion=1,
178         )
179         tr_hbox.AddSpacer(5)
180         ##################################################
181         # Amplitude controls
182         ##################################################
183         amp_hbox = forms.static_box_sizer(parent=self.panel, label="Amplitude", orient=wx.VERTICAL, bold=True)
184         amp_hbox.AddSpacer(5)
185         # First row of amp controls (ampl)
186         lvl_hbox = wx.BoxSizer(wx.HORIZONTAL)
187         amp_hbox.Add(lvl_hbox, 0, wx.EXPAND)
188         amp_hbox.AddSpacer(10)
189         # Second row of amp controls (tx gain)
190         gain_hbox = wx.BoxSizer(wx.HORIZONTAL)
191         amp_hbox.Add(gain_hbox, 0, wx.EXPAND)
192         amp_hbox.AddSpacer(5)
193         self.vbox.Add(amp_hbox, 0, wx.EXPAND)
194         self.vbox.AddSpacer(10)
195         self.vbox.AddStretchSpacer()
196         lvl_hbox.AddSpacer(5)
197         forms.text_box(
198             parent=self.panel, sizer=lvl_hbox,
199             proportion=1,
200             converter=forms.float_converter(),
201             ps=self.tb,
202             key=usrp_siggen.AMPLITUDE_KEY,
203             label="Level (0.0-1.0)",
204         )
205         lvl_hbox.AddSpacer(10)
206         forms.log_slider(
207             parent=self.panel, sizer=lvl_hbox,
208             proportion=2,
209             ps=self.tb,
210             key=usrp_siggen.AMPLITUDE_KEY,
211             min_exp=-6,
212             max_exp=0,
213             base=10,
214             num_steps=100,
215         )
216         lvl_hbox.AddSpacer(5)
217         if self.tb[usrp_siggen.GAIN_RANGE_KEY][0] < self.tb[usrp_siggen.GAIN_RANGE_KEY][1]:
218             gain_hbox.AddSpacer(5)
219             forms.text_box(
220                 parent=self.panel, sizer=gain_hbox,
221                 proportion=1,
222                 converter=forms.float_converter(),
223                 ps=self.tb,
224                 key=usrp_siggen.GAIN_KEY,
225                 label="TX Gain (dB)",
226             )
227             gain_hbox.AddSpacer(10)
228             forms.slider(
229                 parent=self.panel, sizer=gain_hbox,
230                 proportion=2,
231                 ps=self.tb,
232                 key=usrp_siggen.GAIN_KEY,
233                 minimum=self.tb[usrp_siggen.GAIN_RANGE_KEY][0],
234                 maximum=self.tb[usrp_siggen.GAIN_RANGE_KEY][1],
235                 step_size=self.tb[usrp_siggen.GAIN_RANGE_KEY][2],
236             )
237             gain_hbox.AddSpacer(5)
238         ##################################################
239         # Sample Rate controls
240         ##################################################
241         sam_hbox = forms.static_box_sizer(parent=self.panel, label="Sample Rate", orient=wx.HORIZONTAL, bold=True)
242         self.vbox.Add(sam_hbox, 0, wx.EXPAND)
243         self.vbox.AddSpacer(10)
244         self.vbox.AddStretchSpacer()
245         sam_hbox.AddSpacer(5)
246         forms.text_box(
247             parent=self.panel, sizer=sam_hbox,
248             converter=forms.int_converter(),
249             ps=self.tb,
250             key=usrp_siggen.INTERP_KEY,
251             label="Interpolation",
252         )
253         sam_hbox.AddStretchSpacer(20)
254         forms.static_text(
255             parent=self.panel, sizer=sam_hbox,
256             label='Sample Rate (sps)',
257             ps=self.tb,
258             key=usrp_siggen.SAMP_RATE_KEY,
259             converter=forms.float_converter(),
260         )
261         sam_hbox.AddStretchSpacer(20)
262         forms.static_text(
263             parent=self.panel, sizer=sam_hbox,
264             label='Link Rate (bits/sec)',
265             ps=self.tb,
266             key=usrp_siggen.LINK_RATE_KEY,
267             converter=forms.float_converter(),
268         )
269         sam_hbox.AddSpacer(5)
270         ##################################################
271         # USRP status
272         ##################################################
273         u2_hbox = forms.static_box_sizer(parent=self.panel, label="USRP Status", orient=wx.HORIZONTAL, bold=True)
274         self.vbox.Add(u2_hbox, 0, wx.EXPAND)
275         self.vbox.AddSpacer(10)
276         self.vbox.AddStretchSpacer()
277         u2_hbox.AddSpacer(10)
278         forms.static_text(
279             parent=self.panel, sizer=u2_hbox,
280             ps=self.tb,
281             key=usrp_siggen.DESC_KEY,
282             converter=forms.str_converter(),
283         )
284         self.vbox.AddSpacer(5)
285         self.vbox.AddStretchSpacer()
286
287 def main():
288     try:
289         # Get command line parameters
290         (options, args) = usrp_siggen.get_options()
291
292         # Create the top block using these
293         tb = usrp_siggen.top_block(options, args)
294
295         # Create the GUI application
296         app = gui.app(top_block=tb,                    # Constructed top block
297                       gui=app_gui,                     # User interface class
298                       options=options,                 # Command line options
299                       args=args,                       # Command line args
300                       title="USRP Signal Generator",  # Top window title
301                       nstatus=1,                       # Number of status lines
302                       start=True,                      # Whether to start flowgraph
303                       realtime=True)                   # Whether to set realtime priority
304
305         # And run it
306         app.MainLoop()
307
308     except RuntimeError, e:
309         print e
310         sys.exit(1)
311
312 # Make sure to create the top block (tb) within a function:
313 # That code in main will allow tb to go out of scope on return,
314 # which will call the decontructor on usrp and stop transmit.
315 # Whats odd is that grc works fine with tb in the __main__,
316 # perhaps its because the try/except clauses around tb.
317 if __name__ == "__main__": main()