Saturday, July 11, 2009

Forks: Simple GUI

Hello again I bring you this time a simple frequency setting program with a GUI written in Python making heavy use of GNURadio. It's not pretty, but it works. The comments are terrible.

#! /usr/bin/env python

from gnuradio import gr, gru, audio, eng_notation
from gnuradio.eng_option import eng_option
from gnuradio.wxgui import stdgui2, form
from optparse import OptionParser
import wx

#This class exists to provide a clear reference to forms
class myform(form.form):
def __init__(self):
form.form.__init__(self)

class app_top_block(stdgui2.std_top_block):
def __init__(self, frame, panel, vbox, argv):
stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv)

self.frame = frame
self.panel = panel

parser = OptionParser(option_class=eng_option)

parser.add_option("-s", "--sample-rate", type="eng_float", default=44100, help="Set sample rate to RATE [default:%default]")
parser.add_option("-v", "--volume", type="float", default=0.1, help="Set initial volume level [default:%default]")
parser.add_option("-l", "--left-frequency", type="int", dest="left", default=350, help="Set initial frequency for left side [default:%default]")
parser.add_option("-r", "--right-frequency", type="int", dest="right", default=440, help="Set intial frequency for right side [default:%default]")

(options, args) = parser.parse_args()
sample_rate = int(options.sample_rate)
self.ampl = options.volume
self.left = options.left
self.right = options.right

if len(args) != 0:
parser.print_help()
sys.exit(1)

#simply uses generated waves at this point but could be swapped out for
#something more exciting
self.src0 = gr.sig_source_f (sample_rate, gr.GR_SIN_WAVE, self.left, 1)
self.src1 = gr.sig_source_f (sample_rate, gr.GR_SIN_WAVE, self.right, 1)

#the multiply blocks serve as volume controls
self.amp0 = gr.multiply_const_ff(self.ampl)
self.amp1 = gr.multiply_const_ff(self.ampl)

dst = audio.sink (sample_rate, "")

self.connect (self.src0, self.amp0, (dst,0))
self.connect (self.src1, self.amp1, (dst,1))

self._build_gui(vbox)

def _build_gui(self, vbox_arg):

panel = self.panel
vbox = vbox_arg

freq_box = wx.BoxSizer(wx.HORIZONTAL)
left_box = wx.BoxSizer(wx.VERTICAL)
right_box = wx.BoxSizer(wx.VERTICAL)
volume_box = wx.BoxSizer(wx.VERTICAL)

self.left_form = myform()
self.right_form = myform()
self.volume_form = myform()

left_box.Add((5,0), 0)
self.left_form['title'] = form.static_text_field(parent=panel, sizer=left_box, value="Left Channel")
left_box.Add((2,0), 1)
self.left_form['curFreq'] = form.static_int_field(parent=panel, sizer=left_box, label="Curent Frequency", value=self.left)
left_box.Add((1,0), 1)
self.left_form['newFreq'] = form.int_field(parent=panel, sizer=left_box, label="Enter new Frequency", value=self.left)
left_box.Add((1,0), 1)
left_button = wx.Button(panel, -1, "Set Frequency")
left_box.Add(left_button, 0, wx.CENTER)
left_box.Add((5,0), 0)

right_box.Add((5,0), 0)
self.right_form['title'] = form.static_text_field(parent=panel, sizer=right_box, value="Right Channel")
right_box.Add((2,0), 1)
self.right_form['curFreq'] = form.static_int_field(parent=panel, sizer=right_box, label="Current Frequency", value=self.right)
right_box.Add((2,0), 1)
self.right_form['newFreq'] = form.int_field(parent=panel, sizer=right_box, label="Enter new Frequency", value=self.right)
right_box.Add((2,0), 1)
right_button = wx.Button(panel, -1, "Set Frequency")
right_box.Add(right_button, 0, wx.CENTER)
right_box.Add((5,0), 0)

freq_box.Add((5,0), 0)
freq_box.Add(left_box, 1)
freq_box.Add((5,0), 1)
freq_box.Add(right_box, 1)

volume_box.Add((1,0), 1)
self.volume_form['curVol'] = form.static_float_field(parent=panel, sizer=volume_box, label="Current Volume", value=self.ampl)
volume_box.Add((1,0), 1)
self.volume_form['newVol'] = form.float_field(parent=panel, sizer=volume_box, label="Enter New Volume", value=self.ampl)
volume_box.Add((1,0), 1)
volume_button = wx.Button(panel, -1, "Set Volume")
volume_box.Add(volume_button, 0, wx.CENTER)
volume_box.Add((5,0), 0)

vbox.Add(freq_box, 1, wx.EXPAND)
vbox.Add(volume_box, 1, wx.EXPAND)

left_button.Bind(wx.EVT_BUTTON, self.set_left_frequency, id=left_button.GetId())
right_button.Bind(wx.EVT_BUTTON, self.set_right_frequency, id=right_button.GetId())
volume_button.Bind(wx.EVT_BUTTON, self.set_volume, id=volume_button.GetId())

#the k parameter in each of the following functions exists to catch extra
#information being passed by Bind
def set_volume(self, k):
volume = self.volume_form['newVol'].get_value()
self.amp0.set_k(volume)
self.amp1.set_k(volume)
self.volume_form['curVol'].set_value(volume)

def set_right_frequency(self, k):
freq = self.right_form['newFreq'].get_value()
self.src1.set_frequency(freq)
self.right_form['curFreq'].set_value(freq)

def set_left_frequency(self, k):
freq = self.left_form['newFreq'].get_value()
self.src0.set_frequency(freq)
self.left_form['curFreq'].set_value(freq)


def main():
app = stdgui2.stdapp(app_top_block, "GUI Frequency Setter", nstatus=1)
app.MainLoop()

if __name__ == '__main__':
main()

No comments:

Post a Comment