diff options
author | Walter Bender <walter@walter-laptop.(none)> | 2009-09-04 14:32:40 (GMT) |
---|---|---|
committer | Walter Bender <walter@walter-laptop.(none)> | 2009-09-04 14:32:40 (GMT) |
commit | 18cbcb178b31eb39039c3aa6bdc1189e5764e8bc (patch) | |
tree | 46ef830199ac24bcb51be0fcb21b3490a5fc5d21 | |
parent | 18095e0c61b77bfcabf44cffc0d1869150db34ac (diff) |
added invert function
-rwxr-xr-x | drawwaveform.py | 126 | ||||
-rw-r--r-- | sound_toolbar.py | 111 |
2 files changed, 133 insertions, 104 deletions
diff --git a/drawwaveform.py b/drawwaveform.py index dcdd55a..1828ee4 100755 --- a/drawwaveform.py +++ b/drawwaveform.py @@ -1,4 +1,23 @@ #! /usr/bin/python +# +# Author: Arjun Sarwal arjun@laptop.org +# Copyright (C) 2007, Arjun Sarwal +# Copyright (C) 2009, Walter Bender +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + import pygst pygst.require("0.10") import pygtk @@ -39,12 +58,13 @@ class DrawWaveform(gtk.DrawingArea): self.avg='' self.pp='' self.count=0 + self.invert=False self.param1= config.WINDOW_H/65536.0 self.param2= config.WINDOW_H/2.0 self.y_mag = 3.0 self.g = 1 #Gain (not in dB) introduced by Capture Gain and Mic Boost - self._freq_range = 4 #See comment in sound_toolbar.py to see what different ranges are all about + self._freq_range = 4 #See comment in sound_toolbar.py re freq_range self.draw_interval = 10 self.num_of_points = 115 self.details_iter = 50 @@ -57,7 +77,8 @@ class DrawWaveform(gtk.DrawingArea): self.rms = 0 self.avg = 0 self.Rv = 0 - self.y_mag_bias_multiplier = 1 #constant to multiply with self.param2 while scaling values + # constant to multiply with self.param2 while scaling values + self.y_mag_bias_multiplier = 1 self.log_param1 = "" self.log_param2 = "" self.log_param3 = "" @@ -171,9 +192,15 @@ class DrawWaveform(gtk.DrawingArea): self.context = False self.handler_block(self.expose_event_id) + def set_invert_state(self, invert_state): + self.invert = invert_state + + def get_invert_state(self): + return self.invert def get_drawing_interval(self): - """Returns the pixel interval horizontally between plots of two consecutive points""" + """Returns the pixel interval horizontally between plots of two + consecutive points""" return self.draw_interval @@ -184,11 +211,12 @@ class DrawWaveform(gtk.DrawingArea): colmap = self.get_colormap() clr = colmap.alloc_color(0, 65535, 0, False, False) self._line_gc = self.window.new_gc(foreground = clr) - self._line_gc.set_line_attributes(self._FOREGROUND_LINE_THICKNESS, gdk.LINE_SOLID,\ - gdk.CAP_ROUND, gdk.JOIN_BEVEL) + self._line_gc.set_line_attributes(self._FOREGROUND_LINE_THICKNESS,\ + gdk.LINE_SOLID,\ + gdk.CAP_ROUND, gdk.JOIN_BEVEL) self._back_surf = gdk.Pixmap(self.window, int(config.WINDOW_W), \ - int(config.WINDOW_H)) + int(config.WINDOW_H)) cr = self._back_surf.cairo_create() #background @@ -221,16 +249,18 @@ class DrawWaveform(gtk.DrawingArea): def _expose(self, widget, event): - """This function is the "expose" event handler and does all the drawing""" + """This function is the "expose" event handler and does all the + drawing""" - #######################Real time drawing################################### + ##################### Real time drawing ################### if(self.context == True): #Draw the background #We could probably make this faster with another pixmap. self._init_background() - self.window.draw_drawable(self.get_style().bg_gc[0], self._back_surf, 0, 0, 0, \ - 0, config.WINDOW_W, config.WINDOW_H) + self.window.draw_drawable(self.get_style().bg_gc[0], \ + self._back_surf, 0, 0, 0, 0, \ + config.WINDOW_W, config.WINDOW_H) #Iterate for each graph for graph_id in self.graph_id: @@ -251,36 +281,38 @@ class DrawWaveform(gtk.DrawingArea): self.draw_interval = 3 self.max_samples = span/self.draw_interval - if(len(self.main_buffers)>=self.max_samples): - del self.main_buffers[0:(len(self.main_buffers)-(self.max_samples+1))] + del self.main_buffers[0:(len(self.main_buffers)-\ + (self.max_samples+1))] if(self.fft_show==False): self.y_mag_bias_multiplier = 1 - #Depending upon the X span of the graph, deciding the total number of points to take + """ Depending upon the X span of the graph, deciding + the total number of points to take """ else: - ###############FFT################ + ############## FFT ############### Fs = 48000 nfft = 65536 if self.integer_buffer: self.integer_buffer = self.integer_buffer[0:256] self.fftx = fft(self.integer_buffer, 256,-1) self.fftx = self.fftx[0:self.max_samples] - self.main_buffers = [(abs(x) * 0.02) for x in self.fftx] + self.main_buffers = [(abs(x) * 0.02) \ + for x in self.fftx] self.y_mag_bias_multiplier=0.1 ################################## - #################Getting data###################### + ################ Getting data ################# if self.source[graph_id]==0: self.buffers=self.main_buffers else: pass #write code here that gets data from file ############################################### - ################Scaling the values################### + ########### Scaling the values ################ if config.CONTEXT == 2: self.y_mag = 1 self.y_mag_bias_multiplier = 1 @@ -289,7 +321,13 @@ class DrawWaveform(gtk.DrawingArea): val=[] for i in self.buffers: - temp_val_float = (self.param1*i*self.y_mag) + (self.param2*self.y_mag_bias_multiplier) + # only apply invert to time display + if self.invert is True and self.fft_show is False: + temp_val_float = -(self.param1*i*self.y_mag) +\ + (self.param2*self.y_mag_bias_multiplier) + else: + temp_val_float = (self.param1*i*self.y_mag) +\ + (self.param2*self.y_mag_bias_multiplier) if(temp_val_float>=self.Yend[graph_id]): temp_val_float= self.Yend[graph_id] if(temp_val_float<=self.Ystart[graph_id]): @@ -297,12 +335,11 @@ class DrawWaveform(gtk.DrawingArea): val.append( config.WINDOW_H - temp_val_float ) self.peaks=val - ################################################ + ############################################### - - - ##########The actual drawing of the graph################## - #TODO: Improvement : The color setting shouldn't happen in every drawing loop, should happen only once + ###### The actual drawing of the graph ######## + """TODO: Improvement : The color setting shouldn't happen + in every drawing loop, should happen only once""" colmap = self.get_colormap() r,g,b = self.get_stroke_color_from_sugar() clr = colmap.alloc_color( r, g, b, False, False) @@ -318,7 +355,7 @@ class DrawWaveform(gtk.DrawingArea): self.window.draw_lines(self._line_gc, lines) else: self.window.draw_points(self._line_gc, lines) - ############################################################ + ############################################### """ @@ -327,7 +364,8 @@ class DrawWaveform(gtk.DrawingArea): self.pr_time=time.time() layout = pango.Layout(self.pango_context) layout.set_text(str(fr) +self.debug_str) - self.window.draw_layout(self.get_style().white_gc, self.t_x, self.t_y, layout) + self.window.draw_layout(self.get_style().white_gc, self.t_x, self.t_y,\ + layout) """ return True @@ -335,7 +373,6 @@ class DrawWaveform(gtk.DrawingArea): def set_side_toolbar_reference(self, side_toolbar): self.side_toolbar_copy = side_toolbar - def set_electrical_ui_reference(self, electrical_ui): self.electrical_ui_copy = electrical_ui @@ -345,7 +382,8 @@ class DrawWaveform(gtk.DrawingArea): 1 - uses from file""" self.source[graph_id] = source - def set_graph_params(self, graph_id, Xstart, Ystart, Xend, Yend, type, color): + def set_graph_params(self, graph_id, Xstart, Ystart, Xend, Yend, type,\ + color): """Sets Xstart, Ystart --> the bottom left co-ordinates Xend, Yend --> the top right co-ordinates type --> 0 for a connected graph, 1 for a dotted graph @@ -357,7 +395,6 @@ class DrawWaveform(gtk.DrawingArea): self.type[graph_id] = type self.color[graph_id] = color - def get_fft_mode(self): """Returns if FFT is ON (True) or OFF (False)""" return self.fft_show @@ -370,42 +407,37 @@ class DrawWaveform(gtk.DrawingArea): """See sound_toolbar to see what all frequency ranges are""" self._freq_range = freq_range - def get_stroke_color_from_sugar(self): - """Returns in (r,g,b) format the stroke color set in the profile on the XO""" + """Returns in (r,g,b) format the stroke color from the Sugar profile""" color = profile.get_color() stroke = color.get_stroke_color() colorstring = stroke.strip() if colorstring[0] == '#': - colorstring = colorstring[1:] - r,g,b = colorstring[:2], colorstring[2:4], colorstring[4:] - r+="00" - g+="00" - b+="00" - r,g,b = [int(n, 16) for n in (r,g,b)] + colorstring = colorstring[1:] + r,g,b = colorstring[:2], colorstring[2:4], colorstring[4:] + r+="00" + g+="00" + b+="00" + r,g,b = [int(n, 16) for n in (r,g,b)] return (r,g,b) - def get_fill_color_from_sugar(self): - """Returns in (r,g,b) format the fill color set in the profile on the XO""" + """Returns in (r,g,b) format the fill color from the Sugar profile""" color = profile.get_color() fill = color.get_fill_color() colorstring = fill.strip() if colorstring[0] == '#': - colorstring = colorstring[1:] - r,g,b = colorstring[:2], colorstring[2:4], colorstring[4:] - r+="00" - g+="00" - b+="00" - r,g,b = [int(n, 16) for n in (r,g,b)] + colorstring = colorstring[1:] + r,g,b = colorstring[:2], colorstring[2:4], colorstring[4:] + r+="00" + g+="00" + b+="00" + r,g,b = [int(n, 16) for n in (r,g,b)] return (r,g,b) - def get_mag_params(self): return self.g, self.y_mag def set_mag_params(self, g=1.0, y_mag=3.0): self.g = g self.y_mag = y_mag - - diff --git a/sound_toolbar.py b/sound_toolbar.py index 589698e..49e9cc7 100644 --- a/sound_toolbar.py +++ b/sound_toolbar.py @@ -1,9 +1,9 @@ #! /usr/bin/python # # Author: Arjun Sarwal arjun@laptop.org -# Copyright (C) 2007, OLPC +# Copyright (C) 2007, Arjun Sarwal +# Copyright (C) 2009, Walter Bender # -# # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or @@ -57,7 +57,6 @@ class SoundToolbar(gtk.Toolbar): self._STR_XAXIS2 = _("ms ") self._STR_XAXIS3 = _("Hz ") - self.string_for_textbox = "" self.g = 1.0 @@ -67,15 +66,15 @@ class SoundToolbar(gtk.Toolbar): self.logging_status = False - #######################time######################### + ###################### time ######################## self._time = ToolButton('domain-time2') self.insert(self._time, -1) self._time.show() self._time.set_tooltip(_('Time base')) self._time.connect('clicked', self._timefreq_control_cb, True) - ################################################### + #################################################### - #######################frequency###################### + ###################### frequency ################### self._freq = ToolButton('domain-freq') self.insert(self._freq, -1) self._freq.show() @@ -83,10 +82,21 @@ class SoundToolbar(gtk.Toolbar): self._freq.connect('clicked', self._timefreq_control_cb, False) #################################################### + ####################### invert ##################### + self._invert = ToolButton('invert') + self.insert(self._invert, -1) + self._invert.show() + self._invert.set_tooltip(_('Invert')) + self._invert.connect('clicked', self._invert_control_cb) + #################################################### + #self.time_freq_state = self.wave_copy.get_fft_mode() #self._time.set_active(not(self.time_freq_state)) #self._freq.set_active(self.time_freq_state) + self.wave_copy.set_invert_state(False) + print "##### invert state: " + str(self.wave_copy.get_invert_state()) + self.freq_low_img = gtk.Image() self.freq_high_img = gtk.Image() @@ -99,17 +109,17 @@ class SoundToolbar(gtk.Toolbar): self.freq_low_img_tool.add(self.freq_low_img) self.freq_high_img_tool.add(self.freq_high_img) - - #######################frequency control##################### + ################ frequency control ################# self.adjustmentf = gtk.Adjustment(70, 10, 70 ,20, 20, 0.0) - self.adjustmentf.connect("value_changed", self.cb_page_sizef, self.adjustmentf) + self.adjustmentf.connect("value_changed", self.cb_page_sizef, \ + self.adjustmentf) self._freq_range = gtk.HScale(self.adjustmentf) self._freq_range.set_draw_value(False) self._freq_range.set_update_policy(gtk.UPDATE_CONTINUOUS) self._freq_range.set_size_request(120,15) self._freq_range_tool = gtk.ToolItem() self._freq_range_tool.add(self._freq_range) - ############################################################ + #################################################### self.insert(self.freq_low_img_tool,-1) self.insert(self._freq_range_tool, -1) @@ -121,7 +131,7 @@ class SoundToolbar(gtk.Toolbar): self.freq_low_img_tool.show() self.freq_high_img_tool.show() - #######################pause button###################### + ################## pause button #################### self._pause = ToolButton('media-playback-pause') self.insert(self._pause, -1) self._pause.show() @@ -136,19 +146,21 @@ class SoundToolbar(gtk.Toolbar): self.loginterval_img = gtk.Image() - self.loginterval_img.set_from_file(config.ICONS_DIR + '/sample_rate.svg') + self.loginterval_img.set_from_file(config.ICONS_DIR + \ + '/sample_rate.svg') self.loginterval_img_tool = gtk.ToolItem() self.loginterval_img_tool.add(self.loginterval_img) self.insert(self.loginterval_img_tool,-1) self.loginterval_img.show() self.loginterval_img_tool.show() - - #######################Logging Interval##################### + ################# Logging Interval ################# self._loginterval_combo = ComboBox() - self.interval = [_('Now'), _('30 seconds') , _('2 minutes'), _('10 minutes') , _('30 minutes') ] + self.interval = [_('Now'), _('30 seconds') , _('2 minutes'), \ + _('10 minutes') , _('30 minutes') ] - self._interval_changed_id = self._loginterval_combo.connect("changed", self.loginterval_control) + self._interval_changed_id = self._loginterval_combo.connect("changed",\ + self.loginterval_control) for i, s in enumerate(self.interval): self._loginterval_combo.append_item(i, s, None) @@ -159,17 +171,15 @@ class SoundToolbar(gtk.Toolbar): self.insert(self._loginterval_tool,-1) self._loginterval_tool.show() self.logginginterval_status = 'picture' - ############################################################ + #################################################### - #######################Start Logging/Stop Logging##################### + ############## Start Logging/Stop Logging ########## self._record = ToolButton('media-record') self.insert(self._record, -1) self._record.show() self._record.set_tooltip(_('Start Recording')) self._record.connect('clicked', self.record_control) - ###################################################################### - - + #################################################### def record_control(self, data=None): """Depending upon the selected interval, does either @@ -182,7 +192,6 @@ class SoundToolbar(gtk.Toolbar): self._record.set_icon('media-playback-stop') self._record.show() self._record.set_tooltip(_('Stop Recording')) - if interval==0: self._record.set_icon('media-record') self._record.show() @@ -199,10 +208,9 @@ class SoundToolbar(gtk.Toolbar): self._record.show() self._record.set_tooltip(_('Start Recording')) - def interval_convert(self): - """Converts picture/time interval to an integer - which denotes the number of times the audiograb buffer must be called before a value is written. + """Converts picture/time interval to an integer which denotes the number + of times the audiograb buffer must be called before a value is written. When set to 0, the whole of current buffer will be written 1second= about 66 ticks at 48khz sampling""" if self.logginginterval_status == 'picture': @@ -215,11 +223,8 @@ class SoundToolbar(gtk.Toolbar): return 53340 elif self.logginginterval_status == '30minute': return 160000 - - def loginterval_control(self, combobox): - if (self._loginterval_combo.get_active() != -1): if (self._loginterval_combo.get_active() == 0): self.logginginterval_status = 'picture' @@ -232,31 +237,20 @@ class SoundToolbar(gtk.Toolbar): if (self._loginterval_combo.get_active() == 3): self.logginginterval_status = '30minute' - - - def _pauseplay_control_cb(self, data=None): - if self.audiograb_copy.get_freeze_the_display()==True: self.audiograb_copy.set_freeze_the_display(False) self._pause.set_icon('media-playback-pause-insensitive') self._pause.set_tooltip(_('Unfreeze the display')) self._pause.show() - return False - - if self.audiograb_copy.get_freeze_the_display()==False: + else: self.audiograb_copy.set_freeze_the_display(True) self._pause.set_icon('media-playback-pause') self._pause.set_tooltip(_('Freeze the display')) self._pause.show() - return False - return False - - def _timefreq_control_cb(self, data=None, time_state=True): - if time_state==True and self.wave_copy.get_fft_mode()==True: self.wave_copy.set_fft_mode(False) self._time.set_icon('domain-time2') @@ -265,7 +259,6 @@ class SoundToolbar(gtk.Toolbar): self._freq.show() self._update_string_for_textbox() return False - if time_state==False and self.wave_copy.get_fft_mode()==False: self.wave_copy.set_fft_mode(True) self._time.set_icon('domain-time') @@ -273,63 +266,68 @@ class SoundToolbar(gtk.Toolbar): self._time.show() self._freq.show() self._update_string_for_textbox() - return False - return False + def _invert_control_cb(self, data=None): + print "invert_control_cb; current state: " + \ + str(self.wave_copy.get_invert_state()) + if self.wave_copy.get_invert_state()==True: + self.wave_copy.set_invert_state(False) + print "invert_control_cb; changing to False" + self._invert.set_icon('invert') + self._invert.show() + else: + self.wave_copy.set_invert_state(True) + print "invert_control_cb; changing to True" + self._invert.set_icon('invert2') + self._invert.show() + return False def cb_page_sizef(self, get, data=None): - if(get.value>=10 and get.value<20): self._freq_range.set_value(10) self.audiograb_copy.set_sampling_rate(4000) self.wave_copy.set_freq_range(1) - if(get.value>=20 and get.value<46): self._freq_range.set_value(30) self.audiograb_copy.set_sampling_rate(4000) self.wave_copy.set_freq_range(2) - if(get.value>=46 and get.value<62): self._freq_range.set_value(50) self.audiograb_copy.set_sampling_rate(16000) self.wave_copy.set_freq_range(3) - if(get.value>=62 and get.value<=70): self._freq_range.set_value(70) self.audiograb_copy.set_sampling_rate(48000) self.wave_copy.set_freq_range(4) - self._update_string_for_textbox() - return True - def calculate_x_axis_scale(self): sampling_rate = self.audiograb_copy.get_sampling_rate() draw_interval = self.wave_copy.get_drawing_interval() - if self.wave_copy.get_fft_mode() == False: scale = (50000.0/sampling_rate)/draw_interval #TODO: fix this [:4] bad bad hack! - self._STR_SCALEX = self._STR_XAXIS1 + str(scale)[:4] + self._STR_XAXIS2 + self._STR_SCALEX = self._STR_XAXIS1 + str(scale)[:4] + \ + self._STR_XAXIS2 return else: #TODO: fix this [:4] bad bad hack! scale = 1.04167/draw_interval - self._STR_SCALEX = self._STR_XAXIS1 + str(scale)[:4] + self._STR_XAXIS3 + self._STR_SCALEX = self._STR_XAXIS1 + str(scale)[:4] + \ + self._STR_XAXIS3 return - def context_off(self): - """When some other context is switched to and the sound context is switched off""" + """When some other context is switched to and the sound context + is switched off""" self.g, self.y_mag = self.wave_copy.get_mag_params() self.capture_gain = self.audiograb_copy.get_capture_gain() self.mic_boost = self.audiograb_copy.get_mic_boost() self.audiograb_copy.stop_sound_device() self.wave_copy.set_fft_mode(False) - def context_on(self): """When the sound context is switched on""" self.audiograb_copy.start_sound_device() @@ -341,7 +339,6 @@ class SoundToolbar(gtk.Toolbar): self.wave_copy.set_mag_params(self.g, self.y_mag) self._update_string_for_textbox() - def _update_string_for_textbox(self): self.calculate_x_axis_scale() self.string_for_textbox = "" |