#!/usr/bin/env python #This program is written from instructions #9-25-08 #import the overall GUI module from gnuradio.wxgui import stdgui2 #import fft module for spectrum analyzers etc. from gnuradio.wxgui import fftsink2 #import scope module for oscilloscope displays from gnuradio.wxgui import scopesink2 #import waterfall module for waterfall displays from gnuradio.wxgui import waterfallsink2 #import number value sink module to display number values of incoming data from gnuradio.wxgui import numbersink2 #import slider module from gnuradio.wxgui import slider #import module to handle forms from gnuradio.wxgui import form #import wx python import wx #import the gnuradio modules required for the application from gnuradio import gr, eng_notation, blks2 from gnuradio import audio from gnuradio.eng_option import eng_option import sys import math #define class based on stdgui2.std_top_block which is derived from gr.top_block #this script is for generating a tone, controlling the frequency and displaying #fft spectrum of the tone. class tone_flow_graph (stdgui2.std_top_block): def __init__(self, frame, panel, vbox, argv): stdgui2.std_top_block.__init__ (self,frame,panel,vbox,argv) #set initial values tone_rate = int(48000) freq = 800 ampl = .5 #must do this. Define local instances for frame and panel self.frame = frame self.panel = panel #define tone source self.src1 = gr.sig_source_f (tone_rate, gr.GR_SIN_WAVE, freq, ampl) #create a sink representing the audio card audio_sink = audio.sink (tone_rate) #connect source to sink ****NOTE**** WITHOUT THIS THE PROGRAM FREEZES!!!!! self.connect (self.src1, audio_sink) #these lines test the status windows. self._set_status_msg("Left Message",0) self._set_status_msg("Right Message",1) # this calls module to build gui self._build_gui(vbox, panel, tone_rate) # sets starting frequency to default self.set_freq(freq) # sets starting waveform to SINE self.set_wfm('SINE') def _set_status_msg(self, msg, which=0): self.frame.GetStatusBar().SetStatusText(msg, which) def _build_gui(self, vbox, panel, tone_rate): #for passing results from form entries to their proper modules. def _form_set_freq(kv): return self.set_freq(kv['freq']) def _form_set_wfm(kv): return self.set_wfm(kv['wfm']) #this defines the fft display, rate, size of sample and reference level at top #of display self.spectrum_display = fftsink2.fft_sink_f (panel, title="TONE OUTPUT", ref_level = 30, fft_size=1024, sample_rate=tone_rate) #connect the tone generator output to fft display self.connect (self.src1, self.spectrum_display) #add the display as a box in our panel #parameters??? vbox.Add (self.spectrum_display.win, 1, wx.EXPAND) # control area form for frequency display 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)) #slider for freq control also at bottom hbox.Add((5,0), 0) myform['freq_slider'] = \ form.quantized_slider_field(parent=self.panel, sizer=hbox, weight=3, range=(200, 10000, 1), callback=self.set_freq) #form for entering square or sine hbox.Add((5,0), 0) myform['wfm'] = form.text_field( parent=self.panel, sizer=hbox, label="WFM", weight=1, callback=myform.check_input_and_call(_form_set_wfm)) #this actually adds the boxes to frame without it, they work but are invisible hbox.Add((5,0), 0) vbox.Add(hbox, 0, wx.EXPAND) #define module to trap event of slider moving and what to do about it def on_rotate (self, event): self.rot += event.delta if (self.state == "FREQ"): if self.rot >= 3: self.set_freq(self.freq + 1) self.rot -= 3 elif self.rot <=-3: self.set_freq(self.freq - 1) self.rot += 3 #define module to actually set frequency def set_freq(self, target_freq): #this is handy subfunction of gr.sig_source self.src1.set_frequency(target_freq) self.freq = target_freq self.myform['freq'].set_value(target_freq) # update displayed value in form self.myform['freq_slider'].set_value(target_freq) # update displayed value - actually moves slider to position proportional to freq self.update_status_bar() self._set_status_msg("FREQUENCY", 0) return True # self._set_status_msg("Failed", 0) # return False #define module to set waveform def set_wfm(self, waveform): if (waveform == "SQUARE"): self.src1.set_waveform(gr.GR_SQR_WAVE) self.myform['wfm'].set_value(waveform) #update form display self.update_status_bar() self._set_status_msg("SQUARE", 0) elif (waveform == "SINE"): self.src1.set_waveform(gr.GR_SIN_WAVE) self.myform['wfm'].set_value(waveform) #update form display self.update_status_bar() self._set_status_msg("SINE", 0) #this allows printing at bottom right status bar- that is set by '1' option def update_status_bar (self): msg = "Tuning..." self._set_status_msg(msg, 1) #this runs everything and gives window a title if __name__ == '__main__': app = stdgui2.stdapp (tone_flow_graph, "Tone Generator") app.MainLoop()