def _build_gui(self, vbox, no_gui): def _form_set_freq(kv): return self.set_freq(kv['freq']) self.src_fft = None if 0 and not(no_gui): self.src_fft = fftsink2.fft_sink_c(self.panel, title="Data from USRP", fft_size=512, sample_rate=self.rxpath.if_rate, ref_scale=32768.0, ref_level=0, y_per_div=10, y_divs=12) self.connect (self.rxpath.u, self.src_fft) vbox.Add (self.src_fft.win, 4, wx.EXPAND) if 1 and not(no_gui): rx_fft = fftsink2.fft_sink_c(self.panel, title="Post s/w Resampling", fft_size=512, sample_rate=self.rxpath.quad_rate, ref_level=80, y_per_div=20) self.connect (self.rxpath.resamp, rx_fft) vbox.Add (rx_fft.win, 4, wx.EXPAND) if 1 and not(no_gui): post_deemph_fft = fftsink2.fft_sink_f(self.panel, title="Post Deemph", fft_size=512, sample_rate=self.rxpath.audio_rate, y_per_div=10, ref_level=-40) self.connect (self.rxpath.fmrx.deemph, post_deemph_fft) vbox.Add (post_deemph_fft.win, 4, wx.EXPAND) if 0: post_filt_fft = fftsink2.fft_sink_f(self.panel, title="Post Filter", fft_size=512, sample_rate=audio_rate, y_per_div=10, ref_level=-40) self.connect (self.guts.audio_filter, post_filt) vbox.Add (fft_win4, 4, wx.EXPAND) # control area form at bottom self.myform = myform = form.form() hbox = wx.BoxSizer(wx.HORIZONTAL) hbox.Add((5,0), 0) myform['freq'] = form.float_field( parent=self.panel, sizer=hbox, label="Freq", weight=1, callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg)) #hbox.Add((5,0), 0) #myform['freq_slider'] = \ # form.quantized_slider_field(parent=self.panel, sizer=hbox, weight=3, # range=(87.9e6, 108.1e6, 0.1e6), # callback=self.set_freq) hbox.Add((5,0), 0) vbox.Add(hbox, 0, wx.EXPAND) hbox = wx.BoxSizer(wx.HORIZONTAL) hbox.Add((5,0), 0) myform['volume'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Volume", weight=3, range=self.volume_range(), callback=self.set_volume) hbox.Add((5,0), 0) myform['squelch'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Squelch", weight=3, range=self.rxpath.squelch_range(), callback=self.set_squelch) g = self.rxpath.u.get_gain_range() hbox.Add((5,0), 0) myform['gain'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Gain", weight=3, range=(g.start(), g.stop(), g.step()), callback=self.set_gain) hbox.Add((5,0), 0) vbox.Add(hbox, 0, wx.EXPAND) try: self.knob = powermate.powermate(self.frame) self.rot = 0 powermate.EVT_POWERMATE_ROTATE (self.frame, self.on_rotate) powermate.EVT_POWERMATE_BUTTON (self.frame, self.on_button) except: print "FYI: No Powermate or Contour Knob found"
def _build_gui(self, vbox, usrp_rate, demod_rate, audio_rate): def _form_set_freq(kv): return self.set_freq(kv['freq']) if 1: self.src_fft = fftsink2.fft_sink_c(self.panel, title="Data from USRP2", fft_size=512, sample_rate=usrp_rate, ref_scale=1.0, ref_level=0, y_divs=12) self.connect (self.u, self.src_fft) vbox.Add (self.src_fft.win, 4, wx.EXPAND) if 1: post_filt_fft = fftsink2.fft_sink_f(self.panel, title="Post Demod", fft_size=1024, sample_rate=usrp_rate, y_per_div=10, ref_level=0) self.connect (self.guts.fm_demod, post_filt_fft) vbox.Add (post_filt_fft.win, 4, wx.EXPAND) if 0: post_deemph_fft = fftsink2.fft_sink_f(self.panel, title="Post Deemph", fft_size=512, sample_rate=audio_rate, y_per_div=10, ref_level=-20) self.connect (self.guts.deemph, post_deemph_fft) vbox.Add (post_deemph_fft.win, 4, wx.EXPAND) # control area form at bottom self.myform = myform = form.form() hbox = wx.BoxSizer(wx.HORIZONTAL) hbox.Add((5,0), 0) myform['freq'] = form.float_field( parent=self.panel, sizer=hbox, label="Freq", weight=1, callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg)) hbox.Add((5,0), 0) myform['freq_slider'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, weight=3, range=(87.9e6, 108.1e6, 0.1e6), callback=self.set_freq) hbox.Add((5,0), 0) vbox.Add(hbox, 0, wx.EXPAND) hbox = wx.BoxSizer(wx.HORIZONTAL) hbox.Add((5,0), 0) myform['volume'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Volume", weight=3, range=self.volume_range(), callback=self.set_vol) hbox.Add((5,0), 1) myform['gain'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Gain", weight=3, range=self.u.gain_range(), callback=self.set_gain) hbox.Add((5,0), 0) vbox.Add(hbox, 0, wx.EXPAND) try: self.knob = powermate.powermate(self.frame) self.rot = 0 powermate.EVT_POWERMATE_ROTATE (self.frame, self.on_rotate) powermate.EVT_POWERMATE_BUTTON (self.frame, self.on_button) except: pass
def _build_gui(self, vbox, usrp_rate, demod_rate, audio_rate): def _form_set_freq(kv): return self.set_freq(kv["freq"]) if 1: self.src_fft = fftsink2.fft_sink_c( self.panel, title="Data from USRP", fft_size=512, sample_rate=usrp_rate, ref_scale=32768.0, ref_level=0, y_divs=12, ) self.connect(self.u, self.src_fft) vbox.Add(self.src_fft.win, 4, wx.EXPAND) if 1: post_fm_demod_fft = fftsink2.fft_sink_f( self.panel, title="Post FM Demod", fft_size=512, sample_rate=demod_rate, y_per_div=10, ref_level=0 ) self.connect(self.guts.fm_demod, post_fm_demod_fft) vbox.Add(post_fm_demod_fft.win, 4, wx.EXPAND) if 0: post_stereo_carrier_generator_fft = fftsink2.fft_sink_c( self.panel, title="Post Stereo_carrier_generator", fft_size=512, sample_rate=audio_rate, y_per_div=10, ref_level=0, ) self.connect(self.guts.stereo_carrier_generator, post_stereo_carrier_generator_fft) vbox.Add(post_stereo_carrier_generator_fft.win, 4, wx.EXPAND) if 0: post_deemphasis_left = fftsink2.fft_sink_f( self.panel, title="Post_Deemphasis_Left", fft_size=512, sample_rate=audio_rate, y_per_div=10, ref_level=0, ) self.connect(self.guts.deemph_Left, post_deemphasis_left) vbox.Add(post_deemphasis_left.win, 4, wx.EXPAND) if 0: post_deemphasis_right = fftsink2.fft_sink_f( self.panel, title="Post_Deemphasis_Right", fft_size=512, sample_rate=audio_rate, y_per_div=10, ref_level=-20, ) self.connect(self.guts.deemph_Left, post_deemphasis_right) vbox.Add(post_deemphasis_right.win, 4, wx.EXPAND) if 0: LmR_fft = fftsink2.fft_sink_f( self.panel, title="LmR", fft_size=512, sample_rate=audio_rate, y_per_div=10, ref_level=-20 ) self.connect(self.guts.LmR_real, LmR_fft) vbox.Add(LmR_fft.win, 4, wx.EXPAND) if 0: self.scope = scopesink2.scope_sink_f(self.panel, sample_rate=demod_rate) self.connect(self.guts.fm_demod_a, self.scope) vbox.Add(self.scope.win, 4, wx.EXPAND) # control area form at bottom self.myform = myform = form.form() hbox = wx.BoxSizer(wx.HORIZONTAL) hbox.Add((5, 0), 0) myform["freq"] = form.float_field( parent=self.panel, sizer=hbox, label="Freq", weight=1, callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg), ) hbox.Add((5, 0), 0) myform["freq_slider"] = form.quantized_slider_field( parent=self.panel, sizer=hbox, weight=3, range=(87.9e6, 108.1e6, 0.1e6), callback=self.set_freq ) hbox.Add((5, 0), 0) vbox.Add(hbox, 0, wx.EXPAND) hbox = wx.BoxSizer(wx.HORIZONTAL) hbox.Add((5, 0), 0) myform["volume"] = form.quantized_slider_field( parent=self.panel, sizer=hbox, label="Volume", weight=3, range=self.volume_range(), callback=self.set_vol ) hbox.Add((5, 0), 1) myform["gain"] = form.quantized_slider_field( parent=self.panel, sizer=hbox, label="Gain", weight=3, range=self.subdev.gain_range(), callback=self.set_gain, ) hbox.Add((5, 0), 0) myform["sqlch_thrsh"] = form.quantized_slider_field( parent=self.panel, sizer=hbox, label="Stereo Squelch Threshold", weight=3, range=(0.0, 1.0, 0.01), callback=self.set_squelch, ) hbox.Add((5, 0), 0) vbox.Add(hbox, 0, wx.EXPAND) try: self.knob = powermate.powermate(self.frame) self.rot = 0 powermate.EVT_POWERMATE_ROTATE(self.frame, self.on_rotate) powermate.EVT_POWERMATE_BUTTON(self.frame, self.on_button) except: print "FYI: No Powermate or Contour Knob found"
def _build_gui(self, vbox, usrp_rate, demod_rate, audio_rate): def _form_set_freq(kv): return self.set_freq(kv['freq']) if 0: self.src_fft = fftsink2.fft_sink_c(self.panel, title="Data from USRP", fft_size=512, sample_rate=usrp_rate, ref_scale=32768.0, ref_level=0.0, y_divs=12) self.connect(self.u, self.src_fft) vbox.Add(self.src_fft.win, 4, wx.EXPAND) if 0: self.post_filt_fft = fftsink2.fft_sink_c( self.panel, title="Post Channel filter", fft_size=512, sample_rate=demod_rate) self.connect(self.chan_filt, self.post_filt_fft) vbox.Add(self.post_filt_fft.win, 4, wx.EXPAND) if 0: post_demod_fft = fftsink2.fft_sink_f(self.panel, title="Post Demod", fft_size=1024, sample_rate=demod_rate, y_per_div=10, ref_level=0) self.connect(self.am_demod, post_demod_fft) vbox.Add(post_demod_fft.win, 4, wx.EXPAND) if 1: audio_fft = fftsink2.fft_sink_f(self.panel, title="Audio", fft_size=512, sample_rate=audio_rate, y_per_div=10, ref_level=20) self.connect(self.audio_filt, audio_fft) vbox.Add(audio_fft.win, 4, wx.EXPAND) # control area form at bottom self.myform = myform = form.form() hbox = wx.BoxSizer(wx.HORIZONTAL) hbox.Add((5, 0), 0) myform['freq'] = form.float_field(parent=self.panel, sizer=hbox, label="Freq", weight=1, callback=myform.check_input_and_call( _form_set_freq, self._set_status_msg)) hbox.Add((5, 0), 0) myform['freq_slider'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, weight=3, range=(520.0e3, 1611.0e3, 1.0e3), callback=self.set_freq) hbox.Add((5, 0), 0) vbox.Add(hbox, 0, wx.EXPAND) hbox = wx.BoxSizer(wx.HORIZONTAL) hbox.Add((5, 0), 0) myform['volume'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Volume", weight=3, range=self.volume_range(), callback=self.set_vol) hbox.Add((5, 0), 1) g = self.u.get_gain_range() myform['gain'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Gain", weight=3, range=(g.start(), g.stop(), g.step()), callback=self.set_gain) hbox.Add((5, 0), 0) vbox.Add(hbox, 0, wx.EXPAND) try: self.knob = powermate.powermate(self.frame) self.rot = 0 powermate.EVT_POWERMATE_ROTATE(self.frame, self.on_rotate) powermate.EVT_POWERMATE_BUTTON(self.frame, self.on_button) except: print "FYI: No Powermate or Contour Knob found"
def __init__(self, *args, **kwds): # begin wxGlade: MyFrame.__init__ kwds["style"] = wx.DEFAULT_FRAME_STYLE wx.Frame.__init__(self, *args, **kwds) # Menu Bar self.frame_1_menubar = wx.MenuBar() self.SetMenuBar(self.frame_1_menubar) wxglade_tmp_menu = wx.Menu() self.Exit = wx.MenuItem(wxglade_tmp_menu, ID_EXIT, "Exit", "Exit", wx.ITEM_NORMAL) wxglade_tmp_menu.AppendItem(self.Exit) self.frame_1_menubar.Append(wxglade_tmp_menu, "File") # Menu Bar end self.panel_1 = wx.Panel(self, -1) self.button_1 = wx.Button(self, ID_BUTTON_1, "LSB") self.button_2 = wx.Button(self, ID_BUTTON_2, "USB") self.button_3 = wx.Button(self, ID_BUTTON_3, "AM") self.button_4 = wx.Button(self, ID_BUTTON_4, "CW") self.button_5 = wx.ToggleButton(self, ID_BUTTON_5, "Upper") self.slider_fcutoff_hi = wx.Slider(self, ID_SLIDER_1, 0, -15798, 15799, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.button_6 = wx.ToggleButton(self, ID_BUTTON_6, "Lower") self.slider_fcutoff_lo = wx.Slider(self, ID_SLIDER_2, 0, -15799, 15798, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.panel_5 = wx.Panel(self, -1) self.label_1 = wx.StaticText(self, -1, " Band\nCenter") self.text_ctrl_1 = wx.TextCtrl(self, ID_TEXT_1, "") self.panel_6 = wx.Panel(self, -1) self.panel_7 = wx.Panel(self, -1) self.panel_2 = wx.Panel(self, -1) self.button_7 = wx.ToggleButton(self, ID_BUTTON_7, "Freq") self.slider_3 = wx.Slider(self, ID_SLIDER_3, 3000, 0, 6000) self.spin_ctrl_1 = wx.SpinCtrl(self, ID_SPIN_1, "", min=0, max=100) self.button_8 = wx.ToggleButton(self, ID_BUTTON_8, "Vol") self.slider_4 = wx.Slider(self, ID_SLIDER_4, 0, 0, 500) self.slider_5 = wx.Slider(self, ID_SLIDER_5, 0, 0, 20) self.button_9 = wx.ToggleButton(self, ID_BUTTON_9, "Time") self.button_11 = wx.Button(self, ID_BUTTON_11, "Rew") self.button_10 = wx.Button(self, ID_BUTTON_10, "Fwd") self.panel_3 = wx.Panel(self, -1) self.label_2 = wx.StaticText(self, -1, "PGA ") self.panel_4 = wx.Panel(self, -1) self.panel_8 = wx.Panel(self, -1) self.panel_9 = wx.Panel(self, -1) self.label_3 = wx.StaticText(self, -1, "AM Sync\nCarrier") self.slider_6 = wx.Slider(self, ID_SLIDER_6, 50, 0, 200, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.label_4 = wx.StaticText(self, -1, "Antenna Tune") self.slider_7 = wx.Slider(self, ID_SLIDER_7, 1575, 950, 2200, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.panel_10 = wx.Panel(self, -1) self.button_12 = wx.ToggleButton(self, ID_BUTTON_12, "Auto Tune") self.button_13 = wx.Button(self, ID_BUTTON_13, "Calibrate") self.button_14 = wx.Button(self, ID_BUTTON_14, "Reset") self.panel_11 = wx.Panel(self, -1) self.panel_12 = wx.Panel(self, -1) self.__set_properties() self.__do_layout() # end wxGlade parser = OptionParser(option_class=eng_option) parser.add_option("", "--address", type="string", default="addr=192.168.10.2", help="Address of UHD device, [default=%default]") parser.add_option("-c", "--ddc-freq", type="eng_float", default=3.9e6, help="set Rx DDC frequency to FREQ", metavar="FREQ") parser.add_option( "-s", "--samp-rate", type="eng_float", default=256e3, help="set sample rate (bandwidth) [default=%default]") parser.add_option("-a", "--audio_file", default="", help="audio output file", metavar="FILE") parser.add_option("-r", "--radio_file", default="", help="radio output file", metavar="FILE") parser.add_option("-i", "--input_file", default="", help="radio input file", metavar="FILE") parser.add_option( "-O", "--audio-output", type="string", default="", help="audio output device name. E.g., hw:0,0, /dev/dsp, or pulse") (options, args) = parser.parse_args() self.usrp_center = options.ddc_freq input_rate = options.samp_rate self.slider_range = input_rate * 0.9375 self.f_lo = self.usrp_center - (self.slider_range / 2) self.f_hi = self.usrp_center + (self.slider_range / 2) self.af_sample_rate = 32000 fir_decim = long(input_rate / self.af_sample_rate) # data point arrays for antenna tuner self.xdata = [] self.ydata = [] self.tb = gr.top_block() # radio variables, initial conditions self.frequency = self.usrp_center # these map the frequency slider (0-6000) to the actual range self.f_slider_offset = self.f_lo self.f_slider_scale = 10000 self.spin_ctrl_1.SetRange(self.f_lo, self.f_hi) self.text_ctrl_1.SetValue(str(int(self.usrp_center))) self.slider_5.SetValue(0) self.AM_mode = False self.slider_3.SetValue( (self.frequency - self.f_slider_offset) / self.f_slider_scale) self.spin_ctrl_1.SetValue(int(self.frequency)) POWERMATE = True try: self.pm = powermate.powermate(self) except: sys.stderr.write("Unable to find PowerMate or Contour Shuttle\n") POWERMATE = False if POWERMATE: powermate.EVT_POWERMATE_ROTATE(self, self.on_rotate) powermate.EVT_POWERMATE_BUTTON(self, self.on_pmButton) self.active_button = 7 # command line options if options.audio_file == "": SAVE_AUDIO_TO_FILE = False else: SAVE_AUDIO_TO_FILE = True if options.radio_file == "": SAVE_RADIO_TO_FILE = False else: SAVE_RADIO_TO_FILE = True if options.input_file == "": self.PLAY_FROM_USRP = True else: self.PLAY_FROM_USRP = False if self.PLAY_FROM_USRP: self.src = uhd.usrp_source(device_addr=options.address, io_type=uhd.io_type.COMPLEX_FLOAT32, num_channels=1) self.src.set_samp_rate(input_rate) input_rate = self.src.get_samp_rate() self.src.set_center_freq(self.usrp_center, 0) self.tune_offset = 0 else: self.src = gr.file_source(gr.sizeof_short, options.input_file) self.tune_offset = 2200 # 2200 works for 3.5-4Mhz band # convert rf data in interleaved short int form to complex s2ss = gr.stream_to_streams(gr.sizeof_short, 2) s2f1 = gr.short_to_float() s2f2 = gr.short_to_float() src_f2c = gr.float_to_complex() self.tb.connect(self.src, s2ss) self.tb.connect((s2ss, 0), s2f1) self.tb.connect((s2ss, 1), s2f2) self.tb.connect(s2f1, (src_f2c, 0)) self.tb.connect(s2f2, (src_f2c, 1)) # save radio data to a file if SAVE_RADIO_TO_FILE: radio_file = gr.file_sink(gr.sizeof_short, options.radio_file) self.tb.connect(self.src, radio_file) # 2nd DDC xlate_taps = gr.firdes.low_pass ( \ 1.0, input_rate, 16e3, 4e3, gr.firdes.WIN_HAMMING ) self.xlate = gr.freq_xlating_fir_filter_ccf ( \ fir_decim, xlate_taps, self.tune_offset, input_rate ) # Complex Audio filter audio_coeffs = gr.firdes.complex_band_pass( 1.0, # gain self.af_sample_rate, # sample rate -3000, # low cutoff 0, # high cutoff 100, # transition gr.firdes.WIN_HAMMING) # window self.slider_fcutoff_hi.SetValue(0) self.slider_fcutoff_lo.SetValue(-3000) self.audio_filter = gr.fir_filter_ccc(1, audio_coeffs) # Main +/- 16Khz spectrum display self.fft = fftsink2.fft_sink_c(self.panel_2, fft_size=512, sample_rate=self.af_sample_rate, average=True, size=(640, 240)) # AM Sync carrier if AM_SYNC_DISPLAY: self.fft2 = fftsink.fft_sink_c(self.tb, self.panel_9, y_per_div=20, fft_size=512, sample_rate=self.af_sample_rate, average=True, size=(640, 240)) c2f = gr.complex_to_float() # AM branch self.sel_am = gr.multiply_const_cc(0) # the following frequencies turn out to be in radians/sample # gr.pll_refout_cc(alpha,beta,min_freq,max_freq) # suggested alpha = X, beta = .25 * X * X pll = gr.pll_refout_cc(.5, .0625, (2. * math.pi * 7.5e3 / self.af_sample_rate), (2. * math.pi * 6.5e3 / self.af_sample_rate)) self.pll_carrier_scale = gr.multiply_const_cc(complex(10, 0)) am_det = gr.multiply_cc() # these are for converting +7.5kHz to -7.5kHz # for some reason gr.conjugate_cc() adds noise ?? c2f2 = gr.complex_to_float() c2f3 = gr.complex_to_float() f2c = gr.float_to_complex() phaser1 = gr.multiply_const_ff(1) phaser2 = gr.multiply_const_ff(-1) # filter for pll generated carrier pll_carrier_coeffs = gr.firdes.complex_band_pass( 2.0, # gain self.af_sample_rate, # sample rate 7400, # low cutoff 7600, # high cutoff 100, # transition gr.firdes.WIN_HAMMING) # window self.pll_carrier_filter = gr.fir_filter_ccc(1, pll_carrier_coeffs) self.sel_sb = gr.multiply_const_ff(1) combine = gr.add_ff() #AGC sqr1 = gr.multiply_ff() intr = gr.iir_filter_ffd([.004, 0], [0, .999]) offset = gr.add_const_ff(1) agc = gr.divide_ff() self.scale = gr.multiply_const_ff(0.00001) dst = audio.sink(long(self.af_sample_rate), options.audio_output) if self.PLAY_FROM_USRP: self.tb.connect(self.src, self.xlate, self.fft) else: self.tb.connect(src_f2c, self.xlate, self.fft) self.tb.connect(self.xlate, self.audio_filter, self.sel_am, (am_det, 0)) self.tb.connect(self.sel_am, pll, self.pll_carrier_scale, self.pll_carrier_filter, c2f3) self.tb.connect((c2f3, 0), phaser1, (f2c, 0)) self.tb.connect((c2f3, 1), phaser2, (f2c, 1)) self.tb.connect(f2c, (am_det, 1)) self.tb.connect(am_det, c2f2, (combine, 0)) self.tb.connect(self.audio_filter, c2f, self.sel_sb, (combine, 1)) if AM_SYNC_DISPLAY: self.tb.connect(self.pll_carrier_filter, self.fft2) self.tb.connect(combine, self.scale) self.tb.connect(self.scale, (sqr1, 0)) self.tb.connect(self.scale, (sqr1, 1)) self.tb.connect(sqr1, intr, offset, (agc, 1)) self.tb.connect(self.scale, (agc, 0)) self.tb.connect(agc, dst) if SAVE_AUDIO_TO_FILE: f_out = gr.file_sink(gr.sizeof_short, options.audio_file) sc1 = gr.multiply_const_ff(64000) f2s1 = gr.float_to_short() self.tb.connect(agc, sc1, f2s1, f_out) self.tb.start() # for mouse position reporting on fft display self.fft.win.Bind(wx.EVT_LEFT_UP, self.Mouse) # and left click to re-tune self.fft.win.Bind(wx.EVT_LEFT_DOWN, self.Click) # start a timer to check for web commands if WEB_CONTROL: self.timer = UpdateTimer(self, 1000) # every 1000 mSec, 1 Sec wx.EVT_BUTTON(self, ID_BUTTON_1, self.set_lsb) wx.EVT_BUTTON(self, ID_BUTTON_2, self.set_usb) wx.EVT_BUTTON(self, ID_BUTTON_3, self.set_am) wx.EVT_BUTTON(self, ID_BUTTON_4, self.set_cw) wx.EVT_BUTTON(self, ID_BUTTON_10, self.fwd) wx.EVT_BUTTON(self, ID_BUTTON_11, self.rew) wx.EVT_BUTTON(self, ID_BUTTON_13, self.AT_calibrate) wx.EVT_BUTTON(self, ID_BUTTON_14, self.AT_reset) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_5, self.on_button) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_6, self.on_button) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_7, self.on_button) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_8, self.on_button) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_9, self.on_button) wx.EVT_SLIDER(self, ID_SLIDER_1, self.set_filter) wx.EVT_SLIDER(self, ID_SLIDER_2, self.set_filter) wx.EVT_SLIDER(self, ID_SLIDER_3, self.slide_tune) wx.EVT_SLIDER(self, ID_SLIDER_4, self.set_volume) wx.EVT_SLIDER(self, ID_SLIDER_5, self.set_pga) wx.EVT_SLIDER(self, ID_SLIDER_6, self.am_carrier) wx.EVT_SLIDER(self, ID_SLIDER_7, self.antenna_tune) wx.EVT_SPINCTRL(self, ID_SPIN_1, self.spin_tune) wx.EVT_MENU(self, ID_EXIT, self.TimeToQuit)
def _build_gui(self, vbox, usrp_rate, demod_rate, audio_rate): def _form_set_freq(kv): return self.set_freq(kv['freq']) if 0: self.src_fft = fftsink.fft_sink_c (self, self.panel, title="Data from USRP", fft_size=512, sample_rate=usrp_rate) self.connect (self.src, self.src_fft) vbox.Add (self.src_fft.win, 4, wx.EXPAND) if 0: post_demod_fft = fftsink.fft_sink_f (self, self.panel, title="Post Demod", fft_size=512, sample_rate=demod_rate, y_per_div=10, ref_level=-40) self.connect (self.am_demod, post_demod_fft) vbox.Add (post_demod_fft.win, 4, wx.EXPAND) if 0: post_filt_fft = fftsink.fft_sink_f (self, self.panel, title="Post Filter", fft_size=512, sample_rate=audio_rate, y_per_div=10, ref_level=-40) self.connect (self.set_blacklevel, post_filt) vbox.Add (fft_win4, 4, wx.EXPAND) # control area form at bottom self.myform = myform = form.form() if not (self.u is None): hbox = wx.BoxSizer(wx.HORIZONTAL) hbox.Add((5,0), 0) myform['freq'] = form.float_field( parent=self.panel, sizer=hbox, label="Freq", weight=1, callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg)) hbox.Add((5,0), 0) myform['freq_slider'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, weight=3, range=(self.tv_freq_min, self.tv_freq_max, 0.25e6), callback=self.set_freq) hbox.Add((5,0), 0) vbox.Add(hbox, 0, wx.EXPAND) hbox = wx.BoxSizer(wx.HORIZONTAL) hbox.Add((5,0), 0) myform['contrast'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Contrast", weight=3, range=(-2.0, 2.0, 0.1), callback=self.set_contrast) hbox.Add((5,0), 1) myform['brightness'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Brightness", weight=3, range=(-255.0, 255.0, 1.0), callback=self.set_brightness) hbox.Add((5,0), 0) if not (self.u is None): g = self.u.get_gain_range() myform['gain'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Gain", weight=3, range=(g.start(), g.stop(), g.step()), callback=self.set_gain) hbox.Add((5,0), 0) vbox.Add(hbox, 0, wx.EXPAND) try: self.knob = powermate.powermate(self.frame) self.rot = 0 powermate.EVT_POWERMATE_ROTATE (self.frame, self.on_rotate) powermate.EVT_POWERMATE_BUTTON (self.frame, self.on_button) except: print "FYI: No Powermate or Contour Knob found"
def __init__(self, *args, **kwds): # begin wxGlade: MyFrame.__init__ kwds["style"] = wx.DEFAULT_FRAME_STYLE wx.Frame.__init__(self, *args, **kwds) # Menu Bar self.frame_1_menubar = wx.MenuBar() self.SetMenuBar(self.frame_1_menubar) wxglade_tmp_menu = wx.Menu() self.Exit = wx.MenuItem(wxglade_tmp_menu, ID_EXIT, "Exit", "Exit", wx.ITEM_NORMAL) wxglade_tmp_menu.AppendItem(self.Exit) self.frame_1_menubar.Append(wxglade_tmp_menu, "File") # Menu Bar end self.panel_1 = wx.Panel(self, -1) self.button_1 = wx.Button(self, ID_BUTTON_1, "LSB") self.button_2 = wx.Button(self, ID_BUTTON_2, "USB") self.button_3 = wx.Button(self, ID_BUTTON_3, "AM") self.button_4 = wx.Button(self, ID_BUTTON_4, "CW") self.button_5 = wx.ToggleButton(self, ID_BUTTON_5, "Upper") self.slider_1 = wx.Slider(self, ID_SLIDER_1, 0, -15799, 15799, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.button_6 = wx.ToggleButton(self, ID_BUTTON_6, "Lower") self.slider_2 = wx.Slider(self, ID_SLIDER_2, 0, -15799, 15799, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.panel_5 = wx.Panel(self, -1) self.label_1 = wx.StaticText(self, -1, " Band\nCenter") self.text_ctrl_1 = wx.TextCtrl(self, ID_TEXT_1, "") self.panel_6 = wx.Panel(self, -1) self.panel_7 = wx.Panel(self, -1) self.panel_2 = wx.Panel(self, -1) self.button_7 = wx.ToggleButton(self, ID_BUTTON_7, "Freq") self.slider_3 = wx.Slider(self, ID_SLIDER_3, 3000, 0, 6000) self.spin_ctrl_1 = wx.SpinCtrl(self, ID_SPIN_1, "", min=0, max=100) self.button_8 = wx.ToggleButton(self, ID_BUTTON_8, "Vol") self.slider_4 = wx.Slider(self, ID_SLIDER_4, 0, 0, 500) self.slider_5 = wx.Slider(self, ID_SLIDER_5, 0, 0, 20) self.button_9 = wx.ToggleButton(self, ID_BUTTON_9, "Time") self.button_11 = wx.Button(self, ID_BUTTON_11, "Rew") self.button_10 = wx.Button(self, ID_BUTTON_10, "Fwd") self.panel_3 = wx.Panel(self, -1) self.label_2 = wx.StaticText(self, -1, "PGA ") self.panel_4 = wx.Panel(self, -1) self.panel_8 = wx.Panel(self, -1) self.panel_9 = wx.Panel(self, -1) self.label_3 = wx.StaticText(self, -1, "AM Sync\nCarrier") self.slider_6 = wx.Slider(self, ID_SLIDER_6, 50, 0, 200, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.label_4 = wx.StaticText(self, -1, "Antenna Tune") self.slider_7 = wx.Slider(self, ID_SLIDER_7, 1575, 950, 2200, style=wx.SL_HORIZONTAL | wx.SL_LABELS) self.panel_10 = wx.Panel(self, -1) self.button_12 = wx.ToggleButton(self, ID_BUTTON_12, "Auto Tune") self.button_13 = wx.Button(self, ID_BUTTON_13, "Calibrate") self.button_14 = wx.Button(self, ID_BUTTON_14, "Reset") self.panel_11 = wx.Panel(self, -1) self.panel_12 = wx.Panel(self, -1) self.__set_properties() self.__do_layout() # end wxGlade parser = OptionParser(option_class=eng_option) parser.add_option( "-c", "--ddc-freq", type="eng_float", default=3.9e6, help="set Rx DDC frequency to FREQ", metavar="FREQ" ) parser.add_option("-a", "--audio_file", default="", help="audio output file", metavar="FILE") parser.add_option("-r", "--radio_file", default="", help="radio output file", metavar="FILE") parser.add_option("-i", "--input_file", default="", help="radio input file", metavar="FILE") parser.add_option("-d", "--decim", type="int", default=250, help="USRP decimation") parser.add_option( "-R", "--rx-subdev-spec", type="subdev", default=None, help="select USRP Rx side A or B (default=first one with a daughterboard)", ) (options, args) = parser.parse_args() self.usrp_center = options.ddc_freq usb_rate = 64e6 / options.decim self.slider_range = usb_rate * 0.9375 self.f_lo = self.usrp_center - (self.slider_range / 2) self.f_hi = self.usrp_center + (self.slider_range / 2) self.af_sample_rate = 32000 fir_decim = long(usb_rate / self.af_sample_rate) # data point arrays for antenna tuner self.xdata = [] self.ydata = [] self.tb = gr.top_block() # radio variables, initial conditions self.frequency = self.usrp_center # these map the frequency slider (0-6000) to the actual range self.f_slider_offset = self.f_lo self.f_slider_scale = 10000 / options.decim self.spin_ctrl_1.SetRange(self.f_lo, self.f_hi) self.text_ctrl_1.SetValue(str(int(self.usrp_center))) self.slider_5.SetValue(0) self.AM_mode = False self.slider_3.SetValue((self.frequency - self.f_slider_offset) / self.f_slider_scale) self.spin_ctrl_1.SetValue(int(self.frequency)) POWERMATE = True try: self.pm = powermate.powermate(self) except: sys.stderr.write("Unable to find PowerMate or Contour Shuttle\n") POWERMATE = False if POWERMATE: powermate.EVT_POWERMATE_ROTATE(self, self.on_rotate) powermate.EVT_POWERMATE_BUTTON(self, self.on_pmButton) self.active_button = 7 # command line options if options.audio_file == "": SAVE_AUDIO_TO_FILE = False else: SAVE_AUDIO_TO_FILE = True if options.radio_file == "": SAVE_RADIO_TO_FILE = False else: SAVE_RADIO_TO_FILE = True if options.input_file == "": self.PLAY_FROM_USRP = True else: self.PLAY_FROM_USRP = False if self.PLAY_FROM_USRP: self.src = usrp.source_s(decim_rate=options.decim) if options.rx_subdev_spec is None: options.rx_subdev_spec = pick_subdevice(self.src) self.src.set_mux(usrp.determine_rx_mux_value(self.src, options.rx_subdev_spec)) self.subdev = usrp.selected_subdev(self.src, options.rx_subdev_spec) self.src.tune(0, self.subdev, self.usrp_center) self.tune_offset = 0 # -self.usrp_center - self.src.rx_freq(0) else: self.src = gr.file_source(gr.sizeof_short, options.input_file) self.tune_offset = 2200 # 2200 works for 3.5-4Mhz band # save radio data to a file if SAVE_RADIO_TO_FILE: file = gr.file_sink(gr.sizeof_short, options.radio_file) self.tb.connect(self.src, file) # 2nd DDC xlate_taps = gr.firdes.low_pass(1.0, usb_rate, 16e3, 4e3, gr.firdes.WIN_HAMMING) self.xlate = gr.freq_xlating_fir_filter_ccf(fir_decim, xlate_taps, self.tune_offset, usb_rate) # convert rf data in interleaved short int form to complex s2ss = gr.stream_to_streams(gr.sizeof_short, 2) s2f1 = gr.short_to_float() s2f2 = gr.short_to_float() src_f2c = gr.float_to_complex() self.tb.connect(self.src, s2ss) self.tb.connect((s2ss, 0), s2f1) self.tb.connect((s2ss, 1), s2f2) self.tb.connect(s2f1, (src_f2c, 0)) self.tb.connect(s2f2, (src_f2c, 1)) # Complex Audio filter audio_coeffs = gr.firdes.complex_band_pass( 1.0, # gain self.af_sample_rate, # sample rate -3000, # low cutoff 0, # high cutoff 100, # transition gr.firdes.WIN_HAMMING, ) # window self.slider_1.SetValue(0) self.slider_2.SetValue(-3000) self.audio_filter = gr.fir_filter_ccc(1, audio_coeffs) # Main +/- 16Khz spectrum display self.fft = fftsink2.fft_sink_c( self.panel_2, fft_size=512, sample_rate=self.af_sample_rate, average=True, size=(640, 240) ) # AM Sync carrier if AM_SYNC_DISPLAY: self.fft2 = fftsink.fft_sink_c( self.tb, self.panel_9, y_per_div=20, fft_size=512, sample_rate=self.af_sample_rate, average=True, size=(640, 240), ) c2f = gr.complex_to_float() # AM branch self.sel_am = gr.multiply_const_cc(0) # the following frequencies turn out to be in radians/sample # gr.pll_refout_cc(alpha,beta,min_freq,max_freq) # suggested alpha = X, beta = .25 * X * X pll = gr.pll_refout_cc( 0.5, 0.0625, (2.0 * math.pi * 7.5e3 / self.af_sample_rate), (2.0 * math.pi * 6.5e3 / self.af_sample_rate) ) self.pll_carrier_scale = gr.multiply_const_cc(complex(10, 0)) am_det = gr.multiply_cc() # these are for converting +7.5kHz to -7.5kHz # for some reason gr.conjugate_cc() adds noise ?? c2f2 = gr.complex_to_float() c2f3 = gr.complex_to_float() f2c = gr.float_to_complex() phaser1 = gr.multiply_const_ff(1) phaser2 = gr.multiply_const_ff(-1) # filter for pll generated carrier pll_carrier_coeffs = gr.firdes.complex_band_pass( 2.0, # gain self.af_sample_rate, # sample rate 7400, # low cutoff 7600, # high cutoff 100, # transition gr.firdes.WIN_HAMMING, ) # window self.pll_carrier_filter = gr.fir_filter_ccc(1, pll_carrier_coeffs) self.sel_sb = gr.multiply_const_ff(1) combine = gr.add_ff() # AGC sqr1 = gr.multiply_ff() intr = gr.iir_filter_ffd([0.004, 0], [0, 0.999]) offset = gr.add_const_ff(1) agc = gr.divide_ff() self.scale = gr.multiply_const_ff(0.00001) dst = audio.sink(long(self.af_sample_rate)) self.tb.connect(src_f2c, self.xlate, self.fft) self.tb.connect(self.xlate, self.audio_filter, self.sel_am, (am_det, 0)) self.tb.connect(self.sel_am, pll, self.pll_carrier_scale, self.pll_carrier_filter, c2f3) self.tb.connect((c2f3, 0), phaser1, (f2c, 0)) self.tb.connect((c2f3, 1), phaser2, (f2c, 1)) self.tb.connect(f2c, (am_det, 1)) self.tb.connect(am_det, c2f2, (combine, 0)) self.tb.connect(self.audio_filter, c2f, self.sel_sb, (combine, 1)) if AM_SYNC_DISPLAY: self.tb.connect(self.pll_carrier_filter, self.fft2) self.tb.connect(combine, self.scale) self.tb.connect(self.scale, (sqr1, 0)) self.tb.connect(self.scale, (sqr1, 1)) self.tb.connect(sqr1, intr, offset, (agc, 1)) self.tb.connect(self.scale, (agc, 0)) self.tb.connect(agc, dst) if SAVE_AUDIO_TO_FILE: f_out = gr.file_sink(gr.sizeof_short, options.audio_file) sc1 = gr.multiply_const_ff(64000) f2s1 = gr.float_to_short() self.tb.connect(agc, sc1, f2s1, f_out) self.tb.start() # for mouse position reporting on fft display em.eventManager.Register(self.Mouse, wx.EVT_MOTION, self.fft.win) # and left click to re-tune em.eventManager.Register(self.Click, wx.EVT_LEFT_DOWN, self.fft.win) # start a timer to check for web commands if WEB_CONTROL: self.timer = UpdateTimer(self, 1000) # every 1000 mSec, 1 Sec wx.EVT_BUTTON(self, ID_BUTTON_1, self.set_lsb) wx.EVT_BUTTON(self, ID_BUTTON_2, self.set_usb) wx.EVT_BUTTON(self, ID_BUTTON_3, self.set_am) wx.EVT_BUTTON(self, ID_BUTTON_4, self.set_cw) wx.EVT_BUTTON(self, ID_BUTTON_10, self.fwd) wx.EVT_BUTTON(self, ID_BUTTON_11, self.rew) wx.EVT_BUTTON(self, ID_BUTTON_13, self.AT_calibrate) wx.EVT_BUTTON(self, ID_BUTTON_14, self.AT_reset) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_5, self.on_button) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_6, self.on_button) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_7, self.on_button) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_8, self.on_button) wx.EVT_TOGGLEBUTTON(self, ID_BUTTON_9, self.on_button) wx.EVT_SLIDER(self, ID_SLIDER_1, self.set_filter) wx.EVT_SLIDER(self, ID_SLIDER_2, self.set_filter) wx.EVT_SLIDER(self, ID_SLIDER_3, self.slide_tune) wx.EVT_SLIDER(self, ID_SLIDER_4, self.set_volume) wx.EVT_SLIDER(self, ID_SLIDER_5, self.set_pga) wx.EVT_SLIDER(self, ID_SLIDER_6, self.am_carrier) wx.EVT_SLIDER(self, ID_SLIDER_7, self.antenna_tune) wx.EVT_SPINCTRL(self, ID_SPIN_1, self.spin_tune) wx.EVT_MENU(self, ID_EXIT, self.TimeToQuit)
def _build_gui(self, vbox, usrp_rate, demod_rate, audio_rate): def _form_set_freq(kv): return self.set_freq(kv['freq']) if 1: self.src_fft = fftsink2.fft_sink_c(self.panel, title="Data from USRP2", fft_size=512, sample_rate=usrp_rate, ref_scale=1.0, ref_level=0, y_divs=12) self.connect(self.u, self.src_fft) vbox.Add(self.src_fft.win, 4, wx.EXPAND) if 1: post_filt_fft = fftsink2.fft_sink_f(self.panel, title="Post Demod", fft_size=1024, sample_rate=usrp_rate, y_per_div=10, ref_level=0) self.connect(self.guts.fm_demod, post_filt_fft) vbox.Add(post_filt_fft.win, 4, wx.EXPAND) if 0: post_deemph_fft = fftsink2.fft_sink_f(self.panel, title="Post Deemph", fft_size=512, sample_rate=audio_rate, y_per_div=10, ref_level=-20) self.connect(self.guts.deemph, post_deemph_fft) vbox.Add(post_deemph_fft.win, 4, wx.EXPAND) # control area form at bottom self.myform = myform = form.form() hbox = wx.BoxSizer(wx.HORIZONTAL) hbox.Add((5, 0), 0) myform['freq'] = form.float_field(parent=self.panel, sizer=hbox, label="Freq", weight=1, callback=myform.check_input_and_call( _form_set_freq, self._set_status_msg)) hbox.Add((5, 0), 0) myform['freq_slider'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, weight=3, range=(87.9e6, 108.1e6, 0.1e6), callback=self.set_freq) hbox.Add((5, 0), 0) vbox.Add(hbox, 0, wx.EXPAND) hbox = wx.BoxSizer(wx.HORIZONTAL) hbox.Add((5, 0), 0) myform['volume'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Volume", weight=3, range=self.volume_range(), callback=self.set_vol) hbox.Add((5, 0), 1) myform['gain'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Gain", weight=3, range=self.u.gain_range(), callback=self.set_gain) hbox.Add((5, 0), 0) vbox.Add(hbox, 0, wx.EXPAND) try: self.knob = powermate.powermate(self.frame) self.rot = 0 powermate.EVT_POWERMATE_ROTATE(self.frame, self.on_rotate) powermate.EVT_POWERMATE_BUTTON(self.frame, self.on_button) except: pass
def _build_gui(self, vbox, usrp_rate, demod_rate, audio_rate): def _form_set_freq(kv): return self.set_freq(kv['freq']) if 1: self.src_fft = fftsink2.fft_sink_c(self.panel, title="Data from USRP", fft_size=512, sample_rate=usrp_rate, ref_scale=32768.0, ref_level=0, y_divs=12) self.connect(self.u, self.src_fft) vbox.Add(self.src_fft.win, 4, wx.EXPAND) if 1: post_fm_demod_fft = fftsink2.fft_sink_f(self.panel, title="Post FM Demod", fft_size=512, sample_rate=demod_rate, y_per_div=10, ref_level=0) self.connect(self.guts.fm_demod, post_fm_demod_fft) vbox.Add(post_fm_demod_fft.win, 4, wx.EXPAND) if 0: post_stereo_carrier_generator_fft = fftsink2.fft_sink_c( self.panel, title="Post Stereo_carrier_generator", fft_size=512, sample_rate=audio_rate, y_per_div=10, ref_level=0) self.connect(self.guts.stereo_carrier_generator, post_stereo_carrier_generator_fft) vbox.Add(post_stereo_carrier_generator_fft.win, 4, wx.EXPAND) if 0: post_deemphasis_left = fftsink2.fft_sink_f( self.panel, title="Post_Deemphasis_Left", fft_size=512, sample_rate=audio_rate, y_per_div=10, ref_level=0) self.connect(self.guts.deemph_Left, post_deemphasis_left) vbox.Add(post_deemphasis_left.win, 4, wx.EXPAND) if 0: post_deemphasis_right = fftsink2.fft_sink_f( self.panel, title="Post_Deemphasis_Right", fft_size=512, sample_rate=audio_rate, y_per_div=10, ref_level=-20) self.connect(self.guts.deemph_Left, post_deemphasis_right) vbox.Add(post_deemphasis_right.win, 4, wx.EXPAND) if 0: LmR_fft = fftsink2.fft_sink_f(self.panel, title="LmR", fft_size=512, sample_rate=audio_rate, y_per_div=10, ref_level=-20) self.connect(self.guts.LmR_real, LmR_fft) vbox.Add(LmR_fft.win, 4, wx.EXPAND) if 0: self.scope = scopesink2.scope_sink_f(self.panel, sample_rate=demod_rate) self.connect(self.guts.fm_demod, self.scope) vbox.Add(self.scope.win, 4, wx.EXPAND) # control area form at bottom self.myform = myform = form.form() hbox = wx.BoxSizer(wx.HORIZONTAL) hbox.Add((5, 0), 0) myform['freq'] = form.float_field(parent=self.panel, sizer=hbox, label="Freq", weight=1, callback=myform.check_input_and_call( _form_set_freq, self._set_status_msg)) hbox.Add((5, 0), 0) myform['freq_slider'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, weight=3, range=(self.fm_freq_min, self.fm_freq_max, 0.1e6), callback=self.set_freq) hbox.Add((5, 0), 0) vbox.Add(hbox, 0, wx.EXPAND) hbox = wx.BoxSizer(wx.HORIZONTAL) hbox.Add((5, 0), 0) myform['volume'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Volume", weight=3, range=self.volume_range(), callback=self.set_vol) hbox.Add((5, 0), 1) g = self.u.get_gain_range() myform['gain'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Gain", weight=3, range=(g.start(), g.stop(), g.step()), callback=self.set_gain) hbox.Add((5, 0), 0) myform['sqlch_thrsh'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Stereo Squelch Threshold", weight=3, range=(0.0,1.0,0.01), callback=self.set_squelch) hbox.Add((5, 0), 0) vbox.Add(hbox, 0, wx.EXPAND) try: self.knob = powermate.powermate(self.frame) self.rot = 0 powermate.EVT_POWERMATE_ROTATE(self.frame, self.on_rotate) powermate.EVT_POWERMATE_BUTTON(self.frame, self.on_button) except: print "FYI: No Powermate or Contour Knob found"
def _build_gui(self, vbox, usrp_rate, demod_rate, audio_rate): def _form_set_freq(kv): return self.set_freq(kv['freq']) if 0: self.src_fft = fftsink2.fft_sink_c(self.panel, title="Data from USRP", fft_size=512, sample_rate=usrp_rate, ref_scale=32768.0, ref_level=0.0, y_divs=12) self.connect (self.u, self.src_fft) vbox.Add (self.src_fft.win, 4, wx.EXPAND) if 0: self.post_filt_fft = fftsink2.fft_sink_c(self.panel, title="Post Channel filter", fft_size=512, sample_rate=demod_rate) self.connect (self.chan_filt, self.post_filt_fft) vbox.Add (self.post_filt_fft.win, 4, wx.EXPAND) if 0: post_demod_fft = fftsink2.fft_sink_f(self.panel, title="Post Demod", fft_size=1024, sample_rate=demod_rate, y_per_div=10, ref_level=0) self.connect (self.am_demod, post_demod_fft) vbox.Add (post_demod_fft.win, 4, wx.EXPAND) if 1: audio_fft = fftsink2.fft_sink_f(self.panel, title="Audio", fft_size=512, sample_rate=audio_rate, y_per_div=10, ref_level=20) self.connect (self.audio_filt, audio_fft) vbox.Add (audio_fft.win, 4, wx.EXPAND) # control area form at bottom self.myform = myform = form.form() hbox = wx.BoxSizer(wx.HORIZONTAL) hbox.Add((5,0), 0) myform['freq'] = form.float_field( parent=self.panel, sizer=hbox, label="Freq", weight=1, callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg)) hbox.Add((5,0), 0) myform['freq_slider'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, weight=3, range=(520.0e3, 1611.0e3, 1.0e3), callback=self.set_freq) hbox.Add((5,0), 0) vbox.Add(hbox, 0, wx.EXPAND) hbox = wx.BoxSizer(wx.HORIZONTAL) hbox.Add((5,0), 0) myform['volume'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Volume", weight=3, range=self.volume_range(), callback=self.set_vol) hbox.Add((5,0), 1) g = self.u.get_gain_range() myform['gain'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Gain", weight=3, range=(g.start(), g.stop(), g.step()), callback=self.set_gain) hbox.Add((5,0), 0) vbox.Add(hbox, 0, wx.EXPAND) try: self.knob = powermate.powermate(self.frame) self.rot = 0 powermate.EVT_POWERMATE_ROTATE (self.frame, self.on_rotate) powermate.EVT_POWERMATE_BUTTON (self.frame, self.on_button) except: print "FYI: No Powermate or Contour Knob found"
def _build_gui(self, vbox, no_gui): def _form_set_freq(kv): return self.set_freq(kv['freq']) self.src_fft = None if 1 and not (no_gui): self.src_fft = fftsink2.fft_sink_c(self.panel, title="Data from USRP", fft_size=512, sample_rate=self.rxpath.if_rate, ref_scale=32768.0, ref_level=0, y_per_div=10, y_divs=12) self.connect(self.rxpath.u, self.src_fft) vbox.Add(self.src_fft.win, 4, wx.EXPAND) if 1 and not (no_gui): rx_fft = fftsink2.fft_sink_c(self.panel, title="Post s/w DDC", fft_size=512, sample_rate=self.rxpath.quad_rate, ref_level=80, y_per_div=20) self.connect(self.rxpath.ddc, rx_fft) vbox.Add(rx_fft.win, 4, wx.EXPAND) if 1 and not (no_gui): post_deemph_fft = fftsink2.fft_sink_f( self.panel, title="Post Deemph", fft_size=512, sample_rate=self.rxpath.audio_rate, y_per_div=10, ref_level=-40) self.connect(self.rxpath.fmrx.deemph, post_deemph_fft) vbox.Add(post_deemph_fft.win, 4, wx.EXPAND) if 0: post_filt_fft = fftsink2.fft_sink_f(self.panel, title="Post Filter", fft_size=512, sample_rate=audio_rate, y_per_div=10, ref_level=-40) self.connect(self.guts.audio_filter, post_filt) vbox.Add(fft_win4, 4, wx.EXPAND) # control area form at bottom self.myform = myform = form.form() hbox = wx.BoxSizer(wx.HORIZONTAL) hbox.Add((5, 0), 0) myform['freq'] = form.float_field(parent=self.panel, sizer=hbox, label="Freq", weight=1, callback=myform.check_input_and_call( _form_set_freq, self._set_status_msg)) #hbox.Add((5,0), 0) #myform['freq_slider'] = \ # form.quantized_slider_field(parent=self.panel, sizer=hbox, weight=3, # range=(87.9e6, 108.1e6, 0.1e6), # callback=self.set_freq) hbox.Add((5, 0), 0) vbox.Add(hbox, 0, wx.EXPAND) hbox = wx.BoxSizer(wx.HORIZONTAL) hbox.Add((5, 0), 0) myform['volume'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Volume", weight=3, range=self.volume_range(), callback=self.set_volume) hbox.Add((5, 0), 0) myform['squelch'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Squelch", weight=3, range=self.rxpath.squelch_range(), callback=self.set_squelch) hbox.Add((5, 0), 0) myform['gain'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, label="Gain", weight=3, range=self.rxpath.subdev.gain_range(), callback=self.set_gain) hbox.Add((5, 0), 0) vbox.Add(hbox, 0, wx.EXPAND) try: self.knob = powermate.powermate(self.frame) self.rot = 0 powermate.EVT_POWERMATE_ROTATE(self.frame, self.on_rotate) powermate.EVT_POWERMATE_BUTTON(self.frame, self.on_button) except: print "FYI: No Powermate or Contour Knob found"
def __init__(self, *args, **kwds): # begin wxGlade: MyFrame.__init__ kwds["style"] = wx.DEFAULT_FRAME_STYLE wx.Frame.__init__(self, *args, **kwds) # Menu Bar self.frame_1_menubar = wx.MenuBar() self.SetMenuBar(self.frame_1_menubar) wxglade_tmp_menu = wx.Menu() self.Exit = wx.MenuItem(wxglade_tmp_menu, ID_EXIT, "Exit", "Exit", wx.ITEM_NORMAL) wxglade_tmp_menu.AppendItem(self.Exit) self.frame_1_menubar.Append(wxglade_tmp_menu, "File") # Menu Bar end self.panel_1 = wx.Panel(self, -1) self.button_1 = wx.Button(self, ID_BUTTON_1, "LSB") self.button_2 = wx.Button(self, ID_BUTTON_2, "USB") self.button_3 = wx.Button(self, ID_BUTTON_3, "AM") self.button_4 = wx.Button(self, ID_BUTTON_4, "CW") self.button_5 = wx.ToggleButton(self, ID_BUTTON_5, "Upper") self.slider_fcutoff_hi = wx.Slider(self, ID_SLIDER_1, 0, -15798, 15799, style=wx.SL_HORIZONTAL|wx.SL_LABELS) self.button_6 = wx.ToggleButton(self, ID_BUTTON_6, "Lower") self.slider_fcutoff_lo = wx.Slider(self, ID_SLIDER_2, 0, -15799, 15798, style=wx.SL_HORIZONTAL|wx.SL_LABELS) self.panel_5 = wx.Panel(self, -1) self.label_1 = wx.StaticText(self, -1, " Band\nCenter") self.text_ctrl_1 = wx.TextCtrl(self, ID_TEXT_1, "") self.panel_6 = wx.Panel(self, -1) self.panel_7 = wx.Panel(self, -1) self.panel_2 = wx.Panel(self, -1) self.button_7 = wx.ToggleButton(self, ID_BUTTON_7, "Freq") self.slider_3 = wx.Slider(self, ID_SLIDER_3, 3000, 0, 6000) self.spin_ctrl_1 = wx.SpinCtrl(self, ID_SPIN_1, "", min=0, max=100) self.button_8 = wx.ToggleButton(self, ID_BUTTON_8, "Vol") self.slider_4 = wx.Slider(self, ID_SLIDER_4, 0, 0, 500) self.slider_5 = wx.Slider(self, ID_SLIDER_5, 0, 0, 20) self.button_9 = wx.ToggleButton(self, ID_BUTTON_9, "Time") self.button_11 = wx.Button(self, ID_BUTTON_11, "Rew") self.button_10 = wx.Button(self, ID_BUTTON_10, "Fwd") self.panel_3 = wx.Panel(self, -1) self.label_2 = wx.StaticText(self, -1, "PGA ") self.panel_4 = wx.Panel(self, -1) self.panel_8 = wx.Panel(self, -1) self.panel_9 = wx.Panel(self, -1) self.panel_10 = wx.Panel(self, -1) self.panel_11 = wx.Panel(self, -1) self.panel_12 = wx.Panel(self, -1) self.__set_properties() self.__do_layout() # end wxGlade parser = OptionParser (option_class=eng_option) parser.add_option("", "--args", type="string", default="addr=''", help="Arguments for UHD device, [default=%default]") parser.add_option("", "--spec", type="string", default="A:0", help="UHD device subdev spec, [default=%default]") parser.add_option ("-c", "--ddc-freq", type="eng_float", default=3.9e6, help="set Rx DDC frequency to FREQ", metavar="FREQ") parser.add_option ("-s", "--samp-rate", type="eng_float", default=256000, help="set sample rate (bandwidth) [default=%default]") parser.add_option ("-a", "--audio_file", default="", help="audio output file", metavar="FILE") parser.add_option ("-r", "--radio_file", default="", help="radio output file", metavar="FILE") parser.add_option ("-i", "--input_file", default="", help="radio input file", metavar="FILE") parser.add_option ("-O", "--audio-output", type="string", default="", help="audio output device name. E.g., hw:0,0, /dev/dsp, or pulse") parser.add_option ("", "--audio-rate", type="int", default=32000, help="audio output sample rate [default=%default]") (options, args) = parser.parse_args () self.usrp_center = options.ddc_freq self.input_rate = input_rate = options.samp_rate self.slider_range = input_rate * 0.9375 self.f_lo = self.usrp_center - (self.slider_range/2) self.f_hi = self.usrp_center + (self.slider_range/2) self.af_sample_rate = options.audio_rate self.tb = gr.top_block() # radio variables, initial conditions self.frequency = self.usrp_center # these map the frequency slider (0-6000) to the actual range self.f_slider_offset = self.f_lo self.f_slider_scale = 10000/250 self.spin_ctrl_1.SetRange(self.f_lo,self.f_hi) self.text_ctrl_1.SetValue(str(int(self.usrp_center))) self.slider_5.SetValue(0) self.AM_mode = False self.slider_3.SetValue((self.frequency-self.f_slider_offset)/self.f_slider_scale) self.spin_ctrl_1.SetValue(int(self.frequency)) POWERMATE = True try: self.pm = powermate.powermate(self) except: sys.stderr.write("Unable to find PowerMate or Contour Shuttle\n") POWERMATE = False if POWERMATE: powermate.EVT_POWERMATE_ROTATE(self, self.on_rotate) powermate.EVT_POWERMATE_BUTTON(self, self.on_pmButton) self.active_button = 7 # command line options if options.audio_file == "": SAVE_AUDIO_TO_FILE = False else: SAVE_AUDIO_TO_FILE = True if options.radio_file == "": SAVE_RADIO_TO_FILE = False else: SAVE_RADIO_TO_FILE = True if options.input_file == "": self.PLAY_FROM_USRP = True else: self.PLAY_FROM_USRP = False if self.PLAY_FROM_USRP: self.src = uhd.usrp_source(options.args, stream_args=uhd.stream_args('fc32')) self.src.set_samp_rate(input_rate) self.src.set_subdev_spec(options.spec) self.input_rate = input_rate = self.src.get_samp_rate() self.src.set_center_freq(self.usrp_center, 0) self.tune_offset = 0 fir_decim = long(self.input_rate / self.af_sample_rate) rrate = self.af_sample_rate / (self.input_rate / float(fir_decim)) print "Actual Input Rate: ", self.input_rate print "FIR DECIM: ", fir_decim print "Remaining resampling: ", rrate print "Sampling Rate at Audio Sink: ", (self.input_rate / fir_decim) * rrate print "Request Rate at Audio Sink: ", self.af_sample_rate else: self.src = blocks.file_source (gr.sizeof_short,options.input_file) self.tune_offset = 2200 # 2200 works for 3.5-4Mhz band # convert rf data in interleaved short int form to complex s2ss = blocks.stream_to_streams(gr.sizeof_short,2) s2f1 = blocks.short_to_float() s2f2 = blocks.short_to_float() src_f2c = blocks.float_to_complex() self.tb.connect(self.src,s2ss) self.tb.connect((s2ss,0),s2f1) self.tb.connect((s2ss,1),s2f2) self.tb.connect(s2f1,(src_f2c,0)) self.tb.connect(s2f2,(src_f2c,1)) fir_decim = long(self.input_rate / self.af_sample_rate) rrate = self.af_sample_rate / (self.input_rate / float(fir_decim)) print "FIR DECIM: ", fir_decim print "Remaining resampling: ", rrate print "Sampling Rate at Audio Sink: ", (self.input_rate / fir_decim) * rrate print "Request Rate at Audio Sink: ", self.af_sample_rate # save radio data to a file if SAVE_RADIO_TO_FILE: radio_file = blocks.file_sink(gr.sizeof_short, options.radio_file) self.tb.connect (self.src, radio_file) # 2nd DDC xlate_taps = filter.firdes.low_pass ( \ 1.0, input_rate, 16e3, 4e3, filter.firdes.WIN_HAMMING ) self.xlate = filter.freq_xlating_fir_filter_ccf ( \ fir_decim, xlate_taps, self.tune_offset, input_rate ) nflts = 32 audio_coeffs = filter.firdes.complex_band_pass ( nflts, # gain self.input_rate*nflts, # sample rate -3000.0, # low cutoff 0.0, # high cutoff 100.0, # transition filter.firdes.WIN_KAISER, 7.0) # window self.slider_fcutoff_hi.SetValue(0) self.slider_fcutoff_lo.SetValue(-3000) # Filter and resample based on actual radio's sample rate self.audio_filter = filter.pfb.arb_resampler_ccc(rrate, audio_coeffs) # Main +/- 16Khz spectrum display self.fft = fftsink2.fft_sink_c(self.panel_2, fft_size=512, sample_rate=self.af_sample_rate, average=True, size=(640,240), baseband_freq=self.usrp_center) c2f = blocks.complex_to_float() # AM branch self.sel_am = blocks.multiply_const_cc(0) # the following frequencies turn out to be in radians/sample # analog.pll_refout_cc(alpha,beta,min_freq,max_freq) # suggested alpha = X, beta = .25 * X * X pll = analog.pll_refout_cc(.05,(2.*math.pi*7.5e3/self.af_sample_rate), (2.*math.pi*6.5e3/self.af_sample_rate)) self.pll_carrier_scale = blocks.multiply_const_cc(complex(10,0)) am_det = blocks.multiply_cc() # these are for converting +7.5kHz to -7.5kHz # for some reason blocks.conjugate_cc() adds noise ?? c2f2 = blocks.complex_to_float() c2f3 = blocks.complex_to_float() f2c = blocks.float_to_complex() phaser1 = blocks.multiply_const_ff(1) phaser2 = blocks.multiply_const_ff(-1) # filter for pll generated carrier pll_carrier_coeffs = filter.firdes.complex_band_pass ( 2.0, # gain self.af_sample_rate, # sample rate 7400, # low cutoff 7600, # high cutoff 100, # transition filter.firdes.WIN_HAMMING) # window self.pll_carrier_filter = filter.fir_filter_ccc (1, pll_carrier_coeffs) self.sel_sb = blocks.multiply_const_ff(1) combine = blocks.add_ff() #AGC sqr1 = blocks.multiply_ff() intr = filter.iir_filter_ffd( [.004, 0], [0, .999] ) offset = blocks.add_const_ff(1) agc = blocks.divide_ff() self.scale = blocks.multiply_const_ff(0.00001) dst = audio.sink(long(self.af_sample_rate), options.audio_output) if self.PLAY_FROM_USRP: self.tb.connect(self.src, self.xlate, self.fft) else: self.tb.connect(src_f2c, self.xlate, self.fft) self.tb.connect(self.xlate,self.audio_filter,self.sel_am,(am_det,0)) self.tb.connect(self.sel_am,pll,self.pll_carrier_scale, self.pll_carrier_filter,c2f3) self.tb.connect((c2f3,0),phaser1,(f2c,0)) self.tb.connect((c2f3,1),phaser2,(f2c,1)) self.tb.connect(f2c,(am_det,1)) self.tb.connect(am_det,c2f2,(combine,0)) self.tb.connect(self.audio_filter,c2f, self.sel_sb,(combine,1)) self.tb.connect(combine,self.scale) self.tb.connect(self.scale,(sqr1,0)) self.tb.connect(self.scale,(sqr1,1)) self.tb.connect(sqr1, intr, offset, (agc, 1)) self.tb.connect(self.scale,(agc, 0)) self.tb.connect(agc, blocks.null_sink(gr.sizeof_float)) self.tb.connect(c2f3, dst) if SAVE_AUDIO_TO_FILE: f_out = blocks.file_sink(gr.sizeof_short,options.audio_file) sc1 = blocks.multiply_const_ff(64000) f2s1 = blocks.float_to_short() self.tb.connect(agc,sc1,f2s1,f_out) self.tb.start() # left click to re-tune self.fft.win.plotter.Bind(wx.EVT_LEFT_DOWN, self.Click) # start a timer to check for web commands if WEB_CONTROL: self.timer = UpdateTimer(self, 1000) # every 1000 mSec, 1 Sec wx.EVT_BUTTON(self,ID_BUTTON_1,self.set_lsb) wx.EVT_BUTTON(self,ID_BUTTON_2,self.set_usb) wx.EVT_BUTTON(self,ID_BUTTON_3,self.set_am) wx.EVT_BUTTON(self,ID_BUTTON_4,self.set_cw) wx.EVT_BUTTON(self,ID_BUTTON_10,self.fwd) wx.EVT_BUTTON(self,ID_BUTTON_11,self.rew) wx.EVT_TOGGLEBUTTON(self,ID_BUTTON_5,self.on_button) wx.EVT_TOGGLEBUTTON(self,ID_BUTTON_6,self.on_button) wx.EVT_TOGGLEBUTTON(self,ID_BUTTON_7,self.on_button) wx.EVT_TOGGLEBUTTON(self,ID_BUTTON_8,self.on_button) wx.EVT_TOGGLEBUTTON(self,ID_BUTTON_9,self.on_button) wx.EVT_SLIDER(self,ID_SLIDER_1,self.set_filter) wx.EVT_SLIDER(self,ID_SLIDER_2,self.set_filter) wx.EVT_SLIDER(self,ID_SLIDER_3,self.slide_tune) wx.EVT_SLIDER(self,ID_SLIDER_4,self.set_volume) wx.EVT_SLIDER(self,ID_SLIDER_5,self.set_pga) wx.EVT_SPINCTRL(self,ID_SPIN_1,self.spin_tune) wx.EVT_MENU(self, ID_EXIT, self.TimeToQuit)