Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWalter Bender <walter@sugarlabs.org>2010-06-30 17:29:42 (GMT)
committer Walter Bender <walter@sugarlabs.org>2010-06-30 17:29:42 (GMT)
commit80d1f37f02c0713dc7dc401b02b15364c2276019 (patch)
treeb0d59de9374f02c22e589fde31536188c8b8082c
parentee578a5eb9a728be6cce94b56f1a7ce0e25b87fd (diff)
support for 0.86+ toolbars; general cleanup
-rw-r--r--audiograb.py277
-rw-r--r--config.py20
-rw-r--r--drawwaveform.py125
-rw-r--r--measure.py173
-rw-r--r--sensor_toolbar.py90
-rw-r--r--sound_toolbar.py110
-rw-r--r--toolbar_side.py54
7 files changed, 519 insertions, 330 deletions
diff --git a/audiograb.py b/audiograb.py
index d6966f1..73ade5d 100644
--- a/audiograb.py
+++ b/audiograb.py
@@ -2,10 +2,11 @@
#
# Author: Arjun Sarwal arjun@laptop.org
# Copyright (C) 2007, Arjun Sarwal
-# Copyright (C) 2009, Walter Bender
+# Copyright (C) 2009,10 Walter Bender
# Copyright (C) 2009, Benjamin Berg, Sebastian Berg
# Copyright (C) 2009, Sayamindu Dasgupta
-#
+# Copyright (C) 2010, Sascha Silbe
+#
# 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
@@ -24,12 +25,14 @@ import pygst
pygst.require("0.10")
import gst
import gst.interfaces
-import numpy as np
+from numpy import fromstring
import os
import subprocess
from string import find
import time
-import config
+from config import RATE, BIAS, DC_MODE_ENABLE, CAPTURE_GAIN, MIC_BOOST,\
+ SOUND_MAX_WAVE_LOGS, QUIT_MIC_BOOST, QUIT_DC_MODE_ENABLE,\
+ QUIT_CAPTURE_GAIN, QUIT_BIAS
from threading import Timer
# Initialize logging.
@@ -46,11 +49,12 @@ SENSOR_DC_BIAS = 'resistance'
class AudioGrab:
""" The interface between measure and the audio device """
- def __init__(self, callable1, journal):
+ def __init__(self, callable1, activity):
""" Initialize the class: callable1 is a data buffer;
journal is used for logging """
+
self.callable1 = callable1
- self.ji = journal
+ self.activity = activity
self.sensor = None
self.temp_buffer = [0]
@@ -61,7 +65,7 @@ class AudioGrab:
# self.logging_status = False
self.screenshot = True
- self.rate = 48000
+ self.rate = 48000
self.final_count = 0
self.count_temp = 0
self.entry_count = 0
@@ -72,6 +76,10 @@ class AudioGrab:
self.counter_buffer = 0
+ self._dc_control = None
+ self._mic_bias_control = None
+ self._capture_control = None
+ self._mic_boost_control = None
self._hardwired = False # Query controls or use hardwired names
# Set up gst pipeline
@@ -81,11 +89,11 @@ class AudioGrab:
self.caps1 = gst.element_factory_make("capsfilter", "caps1")
self.pipeline.add(self.caps1)
caps_str = "audio/x-raw-int,rate=%d,channels=1,depth=16" % \
- (config.RATE)
+ (RATE)
self.caps1.set_property("caps", gst.caps_from_string(caps_str) )
self.fakesink = gst.element_factory_make("fakesink", "fsink")
- self.pipeline.add(self.fakesink)
- self.fakesink.connect("handoff", self.on_buffer)
+ self.pipeline.add(self.fakesink)
+ self.fakesink.connect("handoff", self.on_buffer)
self.fakesink.set_property("signal-handoffs", True)
gst.element_link_many(self.alsasrc, self.caps1, self.fakesink)
@@ -104,21 +112,44 @@ class AudioGrab:
self._mic_bias_control = self._find_control(['mic bias',
'dc input bias',
'v_refout'])
+ if self._mic_bias_control is not None:
+ log.debug("Mic Bias is %s" % (
+ self._mic_bias_control.props.untranslated_label))
+ log.debug("Min %s" % (str(self._mic_bias_control.min_volume)))
+ log.debug("Max %s" % (str(self._mic_bias_control.max_volume)))
+ log.debug("Channels %s" % (
+ str(self._mic_bias_control.num_channels)))
self._mic_boost_control = self._find_control(['mic boost',
+ 'mic boost (+20db)',
'internal mic boost',
'analog mic boost'])
+ if self._mic_boost_control is not None:
+ log.debug("Mic Boost is %s" % (
+ self._mic_boost_control.props.untranslated_label))
+ log.debug("Min %s" % (str(self._mic_boost_control.min_volume)))
+ log.debug("Max %s" % (str(self._mic_boost_control.max_volume)))
+ log.debug("Channels %s" % (
+ str(self._mic_boost_control.num_channels)))
+
self._mic_gain_control = self._find_control(['mic'])
self._capture_control = self._find_control(['capture'])
+ if self._capture_control is not None:
+ log.debug("Capture is %s" % (
+ self._capture_control.props.untranslated_label))
+ log.debug("Min %s" % (str(self._capture_control.min_volume)))
+ log.debug("Max %s" % (str(self._capture_control.max_volume)))
+ log.debug("Channels %s" % (
+ str(self._capture_control.num_channels)))
self._master_control = self._find_control(['master'])
- except: # F9- (To do: what is the specific exception raised?)
+ except AttributeError: # F9- (no untranslated_label attribute)
self._hardwired = True
# Variables for saving and resuming state of sound device
- self.master = self.get_master()
- self.bias = config.BIAS
- self.dcmode = config.DC_MODE_ENABLE
- self.capture_gain = config.CAPTURE_GAIN
- self.mic_boost = config.MIC_BOOST
+ self.master = self.get_master()
+ self.bias = BIAS
+ self.dcmode = DC_MODE_ENABLE
+ self.capture_gain = CAPTURE_GAIN
+ self.mic_boost = MIC_BOOST
self.mic = self.get_mic_gain()
# Timer for interval sampling and switch to indicate when to capture
@@ -140,19 +171,19 @@ class AudioGrab:
pass
return
- def on_buffer(self, element, buffer, pad):
+ def on_buffer(self, element, buffer, pad):
"""The function that is called whenever new data is available
This is the signal handler for the handoff signal"""
- temp_buffer = np.fromstring(buffer, 'int16')
+ temp_buffer = fromstring(buffer, 'int16')
if not self.dont_queue_the_buffer:
self._new_buffer(temp_buffer)
else:
pass
if self.logging_state:
- if self.waveform_id == config.SOUND_MAX_WAVE_LOGS:
+ if self.waveform_id == SOUND_MAX_WAVE_LOGS:
self.waveform_id = 1
self.logging_state = False
- self.ji.stop_session()
+ self.activity.ji.stop_session()
else:
if self.capture_interval_sample or\
self.buffer_interval_logging == 0:
@@ -162,15 +193,13 @@ class AudioGrab:
# for the logging session
if self.buffer_interval_logging == 0:
self.logging_state = False
- self.ji.stop_session()
+ self.activity.ji.stop_session()
self.waveform_id = 1
- if config.CONTEXT == 'sensor':
- try:
+ if self.activity.CONTEXT == 'sensor':
+ if not self._hardwired: # don't display label on F9
self.sensor.set_sample_value(str(temp_buffer[0]))
- except:
- pass
return False
-
+
def set_freeze_the_display(self, freeze=False):
"""Useful when just the display is needed to be frozen, but logging
should continue"""
@@ -189,14 +218,14 @@ class AudioGrab:
def _emit_for_logging(self, buf):
"""Sends the data for logging"""
if self.buffer_interval_logging == 0:
- self.ji.take_screenshot()
+ self.activity.ji.take_screenshot()
else:
if self.screenshot == True:
- self.ji.take_screenshot(self.waveform_id)
+ self.activity.ji.take_screenshot(self.waveform_id)
self.waveform_id+=1
else:
# save value to Journal
- self.ji.write_value(buf[0])
+ self.activity.ji.write_value(buf[0])
# display value on Sensor toolbar
try:
self.sensor.set_sample_value(str(buf[0]))
@@ -243,7 +272,8 @@ class AudioGrab:
""" Create the next timer that will go off at the proper interval.
This is used when the user has selected a sampling interval > 0
and the logging_state is True. """
- self.capture_timer = Timer(self.buffer_interval_logging, self.sample_now)
+ self.capture_timer = Timer(self.buffer_interval_logging,
+ self.sample_now)
self.capture_timer.start()
def take_picture(self):
@@ -338,6 +368,8 @@ class AudioGrab:
controls.sort(key=lambda e: e[1])
if controls:
+ log.debug("found control: %s" %\
+ (str(controls[0][0].props.untranslated_label)))
return controls[0][0]
return None
@@ -368,7 +400,7 @@ class AudioGrab:
value = bool(control.flags & gst.interfaces.MIXER_TRACK_MUTE)
log.debug('Getting %s (%s) mute status: %r', name,
- control.props.untranslated_label, value)
+ control.props.untranslated_label, value)
return value
def _set_mute(self, control, name, value):
@@ -379,7 +411,7 @@ class AudioGrab:
self._mixer.set_mute(control, value)
log.debug('Set mute for %s (%s) to %r', name,
- control.props.untranslated_label, value)
+ control.props.untranslated_label, value)
return
def _get_volume(self, control, name):
@@ -388,10 +420,12 @@ class AudioGrab:
log.warning('No %s control, returning constant volume', name)
return 100
- try: # sometimes control is not None and yet it is not a tuple?
+ try: # sometimes get_volume does not return a tuple
hw_volume = self._mixer.get_volume(control)[0]
except IndexError:
- log.debug('ERROR getting control %s', control)
+ log.warning('_get_volume: %s (%d-%d) %d channels' % (
+ control.props.untranslated_label, control.min_volume,
+ control.max_volume, control.num_channels))
return 100
min_vol = control.min_volume
@@ -410,10 +444,15 @@ class AudioGrab:
# convert value to scale of control
min_vol = control.min_volume
max_vol = control.max_volume
- hw_volume = value*(max_vol - min_vol)//100 + min_vol
- self._mixer.set_volume(control, (hw_volume,)*control.num_channels)
- log.debug('Set volume of %s (%s) to %d (%d)', name,
- control.props.untranslated_label, value, hw_volume)
+ if min_vol != max_vol:
+ hw_volume = value*(max_vol - min_vol)//100 + min_vol
+ self._mixer.set_volume(control, (hw_volume,)*control.num_channels)
+ log.debug('Set volume of %s (%s) to %d (%d)', name,
+ control.props.untranslated_label, value, hw_volume)
+ else:
+ log.warning('_set_volume: %s (%d-%d) %d channels' % (
+ control.props.untranslated_label, control.min_volume,
+ control.max_volume, control.num_channels))
return
def mute_master(self):
@@ -456,41 +495,66 @@ class AudioGrab:
return int(p)
def set_bias(self, bias_state=False):
- """Enables / disables bias voltage. On XO-1.5 it uses the 80% setting.
- """
+ """Enables / disables bias voltage."""
if not self._hardwired:
- if not isinstance(self._mic_bias_control,
- gst.interfaces.MixerOptions):
+ # if not isinstance(self._mic_bias_control,
+ # gst.interfaces.MixerOptions):
+ if self._mic_bias_control not in self._mixer.list_tracks():
+ log.warning("set_bias: not in mixer")
return self._set_mute(self._mic_bias_control, 'Mic Bias',
not bias_state)
- values = self._mic_bias_control.get_values()
+ #values = self._mic_bias_control.get_values()
# We assume that values are sorted from lowest (=off) to highest.
# Since they are mixed strings ("Off", "50%", etc.), we cannot
# easily ensure this by sorting with the default sort order.
- if bias_state:
- self._mixer.set_option(self._mic_bias_control, values[-1])
- else:
- self._mixer.set_option(self._mic_bias_control, values[0])
+ log.debug("set bias max is %s" % (str(
+ self._mic_bias_control.max_volume)))
+ try:
+ if bias_state:
+ # self._mixer.set_option(self._mic_bias_control, values[-1])
+ self._mixer.set_volume(self._mic_bias_control,
+ self._mic_bias_control.max_volume)
+ else:
+ self._mixer.set_volume(self._mic_bias_control,
+ self._mic_bias_control.min_volume)
+ # self._mixer.set_option(self._mic_bias_control, values[0])
+ except TypeError:
+ log.warning('set_bias: %s (%d-%d) %d channels' % (
+ self._mic_bias_control.props.untranslated_label,
+ self._mic_bias_control.min_volume,
+ self._mic_bias_control.max_volume,
+ self._mic_bias_control.num_channels))
+ self._set_mute(self._mic_bias_control, 'Mic Bias',
+ not bias_state)
else:
- if bias_state==False:
- bias_str="mute"
+ if bias_state:
+ bias_str="unmute"
else:
- bias_str="unmute"
+ bias_str="mute"
os.system("amixer set 'V_REFOUT Enable' " + bias_str)
return
def get_bias(self):
"""Check whether bias voltage is enabled."""
if not self._hardwired:
- if not isinstance(self._mic_bias_control,
- gst.interfaces.MixerOptions):
+ if self._mic_bias_control not in self._mixer.list_tracks():
+ # gst.interfaces.MixerOptions):
+ log.warning("get_bias: not in mixer")
return not self._get_mute(self._mic_bias_control, 'Mic Bias',
False)
- values = self._mic_bias_control.get_values()
- current = self._mixer.get_option(self._mic_bias_control)
+ #values = self._mic_bias_control.get_option()
+ #values = self._mic_bias_control.get_values()
+ log.warning('get_bias: %s (%d-%d) %d channels' % (
+ self._mic_bias_control.props.untranslated_label,
+ self._mic_bias_control.min_volume,
+ self._mic_bias_control.max_volume,
+ self._mic_bias_control.num_channels))
+ current = self._mixer.get_volume(self._mic_bias_control)
# same ordering assertion as in set_bias() applies
- if current == values[0]:
+ # if current == values[0]:
+ log.debug('current: %s' % (str(current)))
+ if current == self._mic_bias_control.min_volume:
return False
return True
else:
@@ -500,19 +564,19 @@ class AudioGrab:
p = p[find(p,"[")+1:]
p = p[:find(p,"]")]
if p=="on":
- return True
+ return True
return False
- def set_dc_mode(self, dc_mode = False):
+ def set_dc_mode(self, dc_mode=False):
"""Sets the DC Mode Enable control
pass False to mute and True to unmute"""
if not self._hardwired:
self._set_mute(self._dc_control, 'DC mode', not dc_mode)
else:
- if dc_mode==False:
- dcm_str="mute"
+ if dc_mode:
+ dcm_str="unmute"
else:
- dcm_str="unmute"
+ dcm_str="mute"
os.system("amixer set 'DC Mode Enable' " + dcm_str)
return
@@ -528,33 +592,51 @@ class AudioGrab:
p = p[find(p,"[")+1:]
p = p[:find(p,"]")]
if p=="on":
- return True
+ return True
else:
- return False
+ return False
def set_mic_boost(self, mic_boost=False):
"""Set Mic Boost.
True = +20dB, False = 0dB"""
if not self._hardwired:
- if not isinstance(self._mic_boost_control,
- gst.interfaces.MixerOptions):
+ if self._mic_boost_control not in self._mixer.list_tracks():
+ # gst.interfaces.MixerOptions):
+ log.warning("set_mic_boost not in mixer %s" %\
+ (str(self._mic_boost_control)))
return self._set_mute(self._mic_boost_control, 'Mic Boost',
mic_boost)
- values = self._mic_boost_control.get_values()
+ #values = self._mic_boost_control.get_values()
+ value = self._mixer.get_volume(self._mic_boost_control)
+ """
if '20dB' not in values or '0dB' not in values:
logging.error("Mic Boost (%s) is an option list, but doesn't "
"contain 0dB and 20dB settings",
self._mic_boost_control.props.label)
return
- if mic_boost:
- self._mixer.set_option(self._mic_boost_control, '20dB')
- else:
- self._mixer.set_option(self._mic_boost_control, '0dB')
+ """
+ try:
+ if mic_boost:
+ # self._mixer.set_option(self._mic_boost_control, '20dB')
+ self._mixer.set_volume(self._mic_boost_control,
+ self._mic_boost_control.max_volume)
+ else:
+ # self._mixer.set_option(self._mic_boost_control, '0dB')
+ self._mixer.set_volume(self._mic_boost_control,
+ self._mic_boost_control.min_volume)
+ except TypeError:
+ log.warning('set_mic_boost: %s (%d-%d) %d channels' % (
+ self._mic_boost_control.props.untranslated_label,
+ self._mic_boost_control.min_volume,
+ self._mic_boost_control.max_volume,
+ self._mic_boost_control.num_channels))
+ return self._set_mute(self._mic_boost_control, 'Mic Boost',
+ not mic_boost)
else:
- if mic_boost==False:
- mb_str="mute"
+ if mic_boost:
+ mb_str="unmute"
else:
- mb_str="unmute"
+ mb_str="mute"
os.system("amixer set 'Mic Boost (+20dB)' " + mb_str)
return
@@ -562,18 +644,29 @@ class AudioGrab:
"""Return Mic Boost setting.
True = +20dB, False = 0dB"""
if not self._hardwired:
- if not isinstance(self._mic_boost_control,
- gst.interfaces.MixerOptions):
+ if self._mic_boost_control not in self._mixer.list_tracks():
+ logging.error("get_mic_boost not found in mixer %s" %\
+ (str(self._mic_boost_control)))
return self._get_mute(self._mic_boost_control, 'Mic Boost',
False)
- values = self._mic_boost_control.get_values()
+ #values = self._mic_boost_control.get_values()
+ # values = self._mixer.get_option(self._mic_boost_control)
+ """
if '20dB' not in values or '0dB' not in values:
logging.error("Mic Boost (%s) is an option list, but doesn't "
"contain 0dB and 20dB settings",
self._mic_boost_control.props.label)
return False
- current = self._mixer.get_option(self._mic_boost_control)
- if current == '20dB':
+ """
+ log.warning('get_mic_boost: %s (%d-%d) %d channels' % (
+ self._mic_boost_control.props.untranslated_label,
+ self._mic_boost_control.min_volume,
+ self._mic_boost_control.max_volume,
+ self._mic_boost_control.num_channels))
+ current = self._mixer.get_volume(self._mic_boost_control)
+ log.debug('current: %s' % (str(current)))
+ # if current == '20dB':
+ if current != self._mic_boost_control.min_volume:
return True
return False
else:
@@ -583,9 +676,9 @@ class AudioGrab:
p = p[find(p,"[")+1:]
p = p[:find(p,"]")]
if p=="on":
- return True
+ return True
else:
- return False
+ return False
def set_capture_gain(self, capture_val):
"""Sets the Capture gain slider settings
@@ -652,7 +745,7 @@ class AudioGrab:
SENSOR_AC_NO_BIAS: (False, False, 50, True),
SENSOR_AC_BIAS: (False, True, 40, True),
SENSOR_DC_NO_BIAS: (True, False, 0, False),
- SENSOR_DC_BIAS: (True, True, 0, False),
+ SENSOR_DC_BIAS: (True, True, 0, False)
}
mode, bias, gain, boost = PARAMETERS[sensor_type]
log.debug("====================================")
@@ -665,20 +758,32 @@ class AudioGrab:
"""Helper to modify (some) of the sensor settings."""
if mode is not None:
self.set_dc_mode(mode)
+ if self._dc_control is not None:
+ os.system("amixer get '%s'" %\
+ (self._dc_control.props.untranslated_label))
if bias is not None:
self.set_bias(bias)
+ if self._mic_bias_control is not None:
+ os.system("amixer get '%s'" %\
+ (self._mic_bias_control.props.untranslated_label))
if gain is not None:
self.set_capture_gain(gain)
+ if self._capture_control is not None:
+ os.system("amixer get '%s'" %\
+ (self._capture_control.props.untranslated_label))
if boost is not None:
self.set_mic_boost(boost)
+ if self._mic_boost_control is not None:
+ os.system("amixer get '%s'" %\
+ (self._mic_boost_control.props.untranslated_label))
return
def on_activity_quit(self):
"""When Activity quits"""
- self.set_mic_boost(config.QUIT_MIC_BOOST)
- self.set_dc_mode(config.QUIT_DC_MODE_ENABLE)
- self.set_capture_gain(config.QUIT_CAPTURE_GAIN)
- self.set_bias(config.QUIT_BIAS)
+ self.set_mic_boost(QUIT_MIC_BOOST)
+ self.set_dc_mode(QUIT_DC_MODE_ENABLE)
+ self.set_capture_gain(QUIT_CAPTURE_GAIN)
+ self.set_bias(QUIT_BIAS)
self.stop_sound_device()
return
@@ -694,7 +799,7 @@ class AudioGrab_XO_1_5(AudioGrab):
SENSOR_AC_NO_BIAS: (False, False, 80, True),
SENSOR_AC_BIAS: (False, True, 80, True),
SENSOR_DC_NO_BIAS: (True, False, 80, False),
- SENSOR_DC_BIAS: (True, True, 80, False),
+ SENSOR_DC_BIAS: (True, True, 90, False)
}
log.debug("====================================")
log.debug("Set Sensor Type to %s" % (str(sensor_type)))
@@ -710,6 +815,8 @@ class AudioGrab_Unknown(AudioGrab):
PARAMETERS = {
SENSOR_AC_NO_BIAS: (None, False, 50, True),
SENSOR_AC_BIAS: (None, True, 40, True),
+ SENSOR_DC_NO_BIAS: (True, False, 80, False),
+ SENSOR_DC_BIAS: (True, True, 90, False)
}
log.debug("====================================")
log.debug("Set Sensor Type to %s" % (str(sensor_type)))
diff --git a/config.py b/config.py
index bbf406a..e7f8785 100644
--- a/config.py
+++ b/config.py
@@ -21,18 +21,16 @@
Global configuration for Measure.
"""
-import os
+from os import environ, path
try:
from sugar.activity import activity
+ MEASURE_ROOT = activity.get_bundle_path()
SUGAR = True
except ImportError:
+ MEASURE_ROOT = environ['HOME']
SUGAR = False
-if SUGAR:
- MEASURE_ROOT = activity.get_bundle_path()
-else:
- MEASURE_ROOT = os.environ['HOME']
-ICONS_DIR = os.path.join(MEASURE_ROOT, 'icons')
+ICONS_DIR = path.join(MEASURE_ROOT, 'icons')
#Multiplied with width and height to set placement of text
TEXT_X_M = 0.65
@@ -58,14 +56,8 @@ QUIT_CAPTURE_GAIN = 100
QUIT_BIAS = True
QUIT_PCM = 70
-#Toolbars
+#Toolbars for 0.84- Sugar
TOOLBARS = ['project','sound','sensor']
-#Which context is active on start
-CONTEXT = 'sound'
-
-#How many maximum screenshots Measure will save while recording in Sound context
+#Maximum no. of screenshots Measure will save while recording in Sound context
SOUND_MAX_WAVE_LOGS = 10
-
-#To track if one context is logging, other wouldn't also do it simultaneously
-LOGGING_IN_SESSION = False
diff --git a/drawwaveform.py b/drawwaveform.py
index 9d85f50..a8f0197 100644
--- a/drawwaveform.py
+++ b/drawwaveform.py
@@ -26,19 +26,26 @@ import gobject
import time
import os
import audioop
-import math
-import numpy as np
+from math import floor, ceil
+from numpy import array, where, float64, multiply, fft, arange, blackman
from ringbuffer import RingBuffer1d
from gtk import gdk
try:
import gconf
+ _using_gconf = True
except ImportError: # older Sugar didn't use gconf
from sugar import profile
+ _using_gconf = False
from gettext import gettext as _
-import config
+from config import MAX_GRAPHS, SUGAR
+# Initialize logging.
+import logging
+log = logging.getLogger('Measure')
+log.setLevel(logging.DEBUG)
+logging.basicConfig()
class DrawWaveform(gtk.DrawingArea):
""" Handles all the drawing of waveforms """
@@ -49,15 +56,16 @@ class DrawWaveform(gtk.DrawingArea):
TRIGGER_POS = 1
TRIGGER_NEG = 2
- def __init__(self, input_frequency=48000):
+ def __init__(self, activity, input_frequency=48000):
""" Initialize drawing area and scope parameter """
gtk.DrawingArea.__init__(self)
self.add_events(gtk.gdk.BUTTON_PRESS_MASK | \
gtk.gdk.PROPERTY_CHANGE_MASK)
+ self.using_gconf = _using_gconf
+ self.activity = activity
self._input_freq = input_frequency
- self.stroke_color = None
self.triggering = self.TRIGGER_NONE
self.trigger_xpos = 0.0
self.trigger_ypos = 0.5
@@ -65,8 +73,8 @@ class DrawWaveform(gtk.DrawingArea):
self.active = False
self._redraw_atom = gtk.gdk.atom_intern('MeasureRedraw')
- self.buffers = np.array([])
- self.main_buffers = np.array([])
+ self.buffers = array([])
+ self.main_buffers = array([])
self.str_buffer=''
self.peaks = []
self.fftx = []
@@ -79,7 +87,7 @@ class DrawWaveform(gtk.DrawingArea):
self.count = 0
self.invert = False
- self.y_mag = 3.0
+ self.y_mag = 3.0 # additional scale factor for display
self.gain = 1.0 # (not in dB) introduced by Capture Gain and Mic Boost
self.bias = 0 # vertical position fine-tuning from slider
self._freq_range = 4 # See comment in sound_toolbar.py
@@ -104,7 +112,6 @@ class DrawWaveform(gtk.DrawingArea):
self._TRIGGER_LINE_THICKNESS = 3
self._FOREGROUND_LINE_THICKNESS = 6
- # self.logging_status = False
self.f = None
self.stop = False
self.fft_show = False
@@ -117,7 +124,7 @@ class DrawWaveform(gtk.DrawingArea):
self.expose_event_id = self.connect("expose_event", self._expose)
self.pr_time = 0
- self.MAX_GRAPHS = config.MAX_GRAPHS # Maximum simultaneous graphs
+ self.MAX_GRAPHS = MAX_GRAPHS # Maximum simultaneous graphs
self.graph_show_state = []
self.Xstart = []
@@ -136,7 +143,7 @@ class DrawWaveform(gtk.DrawingArea):
self.Xend.append(1000)
self.Yend.append(500)
self.type .append(0)
- self.color.append([65535,0,0])
+ self.color.append("#FF0000")
self.source.append(0)
self.graph_id.append(x)
@@ -146,11 +153,7 @@ class DrawWaveform(gtk.DrawingArea):
self.Xend[0] = 1150
self.Yend[0] = 750
self.type[0] = 0
-
- if config.SUGAR:
- self.color[0] = self.get_stroke_color_from_sugar()
- else:
- self.color[0] = '#ffffff'
+ self.color[0] = self.get_stroke_color_from_sugar()
self.source[0] = 0
"""
@@ -194,7 +197,6 @@ class DrawWaveform(gtk.DrawingArea):
self.debug_str="start"
self.context = True
-
def set_max_samples(self, num):
""" Maximum no. of samples in ringbuffer """
@@ -263,31 +265,29 @@ class DrawWaveform(gtk.DrawingArea):
return
def do_realize(self):
- """ Some initializations upon first 'realizing' the drawing area """
+ """ Called when we are creating all of our window resources """
gtk.DrawingArea.do_realize(self)
- # force a native X window to exist
+
+ # Force a native X window to exist
xid = self.window.xid
colormap = self.get_colormap()
self._line_gc = []
for graph_id in self.graph_id:
- r, g, b = self.color[graph_id]
- clr = colormap.alloc_color(r, g, b, False, False)
+ if len(self.color) > graph_id:
+ clr = colormap.alloc_color(self.color[graph_id])
- self._line_gc.append(self.window.new_gc(foreground=clr))
- self._line_gc[graph_id].set_line_attributes(
- self._FOREGROUND_LINE_THICKNESS, gdk.LINE_SOLID,
- gdk.CAP_ROUND, gdk.JOIN_BEVEL)
+ self._line_gc.append(self.window.new_gc(foreground=clr))
+ self._line_gc[graph_id].set_line_attributes(
+ self._FOREGROUND_LINE_THICKNESS, gdk.LINE_SOLID,
+ gdk.CAP_ROUND, gdk.JOIN_BEVEL)
- self._line_gc[graph_id].set_foreground(clr)
+ self._line_gc[graph_id].set_foreground(clr)
- if config.SUGAR:
- r, g, b = self.get_stroke_color_from_sugar()
- else:
- r = g = b = 255
- clr = colormap.alloc_color(r, g, b, False, False)
+ # Sugar stroke color
+ clr = colormap.alloc_color(self.color[0])
self._trigger_line_gc = self.window.new_gc(foreground=clr)
self._trigger_line_gc.set_line_attributes(
@@ -349,7 +349,7 @@ class DrawWaveform(gtk.DrawingArea):
for graph_id in self.graph_id:
if self.graph_show_state[graph_id] == True:
buf = self.ringbuffer.read(None, self.input_step)
- samples = math.ceil(
+ samples = ceil(
self.allocation.width/self.draw_interval)
if len(buf) == 0:
# We don't have enough data to plot.
@@ -377,7 +377,7 @@ class DrawWaveform(gtk.DrawingArea):
ints &= buf[samples-samples_to_end+1:\
-samples_to_end-2] > ypos
- ints = np.where(ints)[0]
+ ints = where(ints)[0]
if len(ints) > 0:
position = max(position, ints[-1])
@@ -387,7 +387,7 @@ class DrawWaveform(gtk.DrawingArea):
ints &= buf[samples-samples_to_end+1:\
-samples_to_end-2] < ypos
- ints = np.where(ints)[0]
+ ints = where(ints)[0]
if len(ints) > 0:
position = max(position, ints[-1])
@@ -404,9 +404,9 @@ class DrawWaveform(gtk.DrawingArea):
data = buf[position-samples+samples_to_end:\
position+samples_to_end+2].astype(
- np.float64)
+ float64)
else:
- data = buf[-samples:].astype(np.float64)
+ data = buf[-samples:].astype(float64)
else:
###############FFT################
@@ -415,12 +415,12 @@ class DrawWaveform(gtk.DrawingArea):
try:
# Multiply input with the window
- np.multiply(buf, self.fft_window, buf)
+ multiply(buf, self.fft_window, buf)
# Should be fast enough even without pow(2) stuff.
- self.fftx = np.fft.rfft(buf)
+ self.fftx = fft.rfft(buf)
self.fftx = abs(self.fftx)
- data = np.multiply(self.fftx, 0.02, self.fftx)
+ data = multiply(self.fftx, 0.02, self.fftx)
##################################
except ValueError:
# TODO: Figure out how this can happen.
@@ -429,7 +429,7 @@ class DrawWaveform(gtk.DrawingArea):
return True
################Scaling the values###################
- if config.CONTEXT == 'sensor':
+ if self.activity.CONTEXT == 'sensor':
self.y_mag = 1.0
if self.invert:
@@ -447,7 +447,7 @@ class DrawWaveform(gtk.DrawingArea):
##########The actual drawing of the graph##################
- lines = (np.arange(len(data), dtype='float32') *\
+ lines = (arange(len(data), dtype='float32') *\
self.draw_interval) + x_offset
# Use ints or draw_lines will throw warnings
@@ -524,15 +524,15 @@ class DrawWaveform(gtk.DrawingArea):
if self.fft_show:
max_freq = (self.freq_div*self.get_ticks())
wanted_step = 1.0/max_freq/2*self._input_freq
- self.input_step = max(math.floor(wanted_step), 1)
+ self.input_step = max(floor(wanted_step), 1)
self.draw_interval = 5.0
- self.set_max_samples(math.ceil(self.allocation.width/float(
+ self.set_max_samples(ceil(self.allocation.width/float(
self.draw_interval)*2)*self.input_step)
# Create the (blackman) window
- self.fft_window = np.blackman(math.ceil(self.allocation.width/float(
+ self.fft_window = blackman(ceil(self.allocation.width/float(
self.draw_interval)*2))
self.draw_interval *= wanted_step/self.input_step
@@ -544,8 +544,7 @@ class DrawWaveform(gtk.DrawingArea):
samples = time * self._input_freq
self.set_max_samples(samples * self.max_samples_fact)
- self.input_step = max(math.ceil(samples/(
- self.allocation.width/3.0)),1)
+ self.input_step = max(ceil(samples/(self.allocation.width/3.0)),1)
self.draw_interval = self.allocation.width/(
float(samples)/self.input_step)
@@ -560,29 +559,17 @@ class DrawWaveform(gtk.DrawingArea):
def get_stroke_color_from_sugar(self):
"""Returns in (r,g,b) format the stroke color from the Sugar profile"""
- # Hitting gconf is a large overhead.
- if self.stroke_color is None:
- try:
- client = gconf.client_get_default()
- color = client.get_string("/desktop/sugar/user/color")
- except:
- color = profile.get_color().to_string()
-
- if color == None:
- return(255, 255, 255)
-
- stroke,fill = color.split(",")
- colorstring = stroke.strip()
- if colorstring[0] == '#':
- colorstring = colorstring[1:]
- r, g, b = colorstring[:2], colorstring[2:4], colorstring[4:]
- r += r
- g += g
- b += b
- r, g, b = [int(n, 16) for n in (r, g, b)]
- self.stroke_color = (r, g, b)
-
- return self.stroke_color
+ if self.using_gconf:
+ client = gconf.client_get_default()
+ color = client.get_string("/desktop/sugar/user/color")
+ else:
+ color = profile.get_color().to_string()
+
+ if color == None:
+ return("#ffffff")
+
+ stroke, fill = color.split(",")
+ return stroke.strip()
def get_mag_params(self):
return self.gain, self.y_mag
diff --git a/measure.py b/measure.py
index ff11609..abb4ac4 100644
--- a/measure.py
+++ b/measure.py
@@ -25,23 +25,37 @@ pygst.require("0.10")
import pygtk
import gtk
import gobject
-import time
import dbus
-import config #This has all the globals
-import os
-import tempfile
-from os import environ
-from os.path import join
+from time import sleep
+from config import TOOLBARS, ICONS_DIR
+from tempfile import mkstemp
+from os import environ, path, chmod
+from textbox import TextBox
+from gettext import gettext as _
+
+from sugar.activity import activity
+try: # 0.86+ toolbar widgets
+ from sugar.bundle.activitybundle import ActivityBundle
+ from sugar.activity.widgets import ActivityToolbarButton
+ from sugar.activity.widgets import StopButton
+ from sugar.graphics.toolbarbox import ToolbarBox
+ from sugar.graphics.toolbarbox import ToolbarButton
+ _new_sugar_system = True
+except ImportError:
+ from sugar.activity.activity import ActivityToolbox
+ _new_sugar_system = False
+from sugar.datastore import datastore
from journal import JournalInteraction
-import audiograb
+from audiograb import AudioGrab_XO_1_5, AudioGrab_XO_1, AudioGrab_Unknown
from drawwaveform import DrawWaveform
from toolbar_side import SideToolbar
-from toolbar_top import Toolbar
-from textbox import TextBox
+from sound_toolbar import SoundToolbar
+from sensor_toolbar import SensorToolbar
-from sugar.activity import activity
-from sugar.datastore import datastore
+def _is_xo(hw):
+ """ Return True if this is xo hardware """
+ return hw in ['xo1','xo1.5']
# Initialize logging.
import logging
@@ -65,14 +79,15 @@ def _get_hardware():
return 'xo1'
else:
return 'unknown'
- elif os.path.exists('/etc/olpc-release') or \
- os.path.exists('/sys/power/olpc-pm'):
+ elif path.exists('/etc/olpc-release') or \
+ path.exists('/sys/power/olpc-pm'):
return 'xo1'
# elif 'olpc' in dev.GetProperty('system.kernel.version'):
# return 'xo1'
else:
return 'unknown'
+
class MeasureActivity(activity.Activity):
""" Oscilloscope Sugar activity """
@@ -86,15 +101,17 @@ class MeasureActivity(activity.Activity):
activity.Activity.__init__(self, handle)
try:
- tmp_dir = os.path.join(activity.get_activity_root(), "data")
+ tmp_dir = path.join(activity.get_activity_root(), "data")
except:
# Early versions of Sugar (e.g., 656) didn't support
# get_activity_root()
- tmp_dir = os.path.join(os.environ['HOME'],
+ tmp_dir = path.join(environ['HOME'],
".sugar/default/org.laptop.MeasureActivity/data")
self.active_status = True
self.ACTIVE = True
+ self.LOGGING_IN_SESSION = False
+ self.CONTEXT = ''
self.connect("notify::active", self._active_cb)
self.connect("destroy", self.on_quit)
@@ -103,25 +120,23 @@ class MeasureActivity(activity.Activity):
self.existing = True
else:
#logging.debug('1.1 Launched from frame or from Mesh View')
- self._jobject.file_path = str(tempfile.mkstemp(dir=tmp_dir)[1])
- os.chmod(self._jobject.file_path, 0777)
+ self._jobject.file_path = str(mkstemp(dir=tmp_dir)[1])
+ chmod(self._jobject.file_path, 0777)
self.existing = False
self.ji = JournalInteraction(self._jobject.file_path, self.existing)
- self.wave = DrawWaveform()
+ self.wave = DrawWaveform(self)
self.hw = _get_hardware()
print "running on %s hardware" % (self.hw)
if self.hw == 'xo1.5':
- self.audiograb = \
- audiograb.AudioGrab_XO_1_5(self.wave.new_buffer, self.ji)
+ self.audiograb = AudioGrab_XO_1_5(self.wave.new_buffer, self)
elif self.hw == 'xo1':
- self.audiograb = \
- audiograb.AudioGrab_XO_1(self.wave.new_buffer, self.ji)
- else: # Use 1.5 settings as default, 0)
- self.audiograb = \
- audiograb.AudioGrab_Unknown(self.wave.new_buffer, self.ji)
- # log.error('Sorry, we do not support your hardware yet.')
+ self.audiograb = AudioGrab_XO_1(self.wave.new_buffer, self)
+ else:
+ self.audiograb = AudioGrab_Unknown(self.wave.new_buffer, self)
+
+ self.new_sugar_system = _new_sugar_system
self.side_toolbar = SideToolbar(self)
self.text_box = TextBox()
@@ -136,15 +151,76 @@ class MeasureActivity(activity.Activity):
self.set_canvas(self.box1)
- toolbox = Toolbar(self)
- self.set_toolbox(toolbox)
+ if self.new_sugar_system:
+ # Use 0.86 toolbar design
+ toolbox = ToolbarBox()
+
+ activity_button = ActivityToolbarButton(self)
+ toolbox.toolbar.insert(activity_button, 0)
+ activity_button.show()
+ else:
+ toolbox = ActivityToolbox(self)
+ self.set_toolbox(toolbox)
+ toolbox.connect("current-toolbar-changed", self._toolbar_changed_cb)
+
+ self.sound_toolbar = SoundToolbar(self)
+ if self.new_sugar_system:
+ self._sound_button = ToolbarButton(
+ page=self.sound_toolbar,
+ icon_name='sound-tools')
+ toolbox.toolbar.insert(self._sound_button, -1)
+ self._sound_button.show()
+ else:
+ toolbox.add_toolbar(_('Sound'), self.sound_toolbar)
+ self.sound_toolbar.show()
+
+ if _is_xo(self.hw):
+ self.sensor_toolbar = SensorToolbar(self)
+ if self.new_sugar_system:
+ self._sensor_button = ToolbarButton(
+ page=self.sensor_toolbar,
+ icon_name='sensor-tools')
+ toolbox.toolbar.insert(self._sensor_button, -1)
+ self._sensor_button.show()
+ else:
+ toolbox.add_toolbar(_('Sensors'), self.sensor_toolbar)
+ self.sensor_toolbar.show()
+
+ if self.new_sugar_system:
+ _separator = gtk.SeparatorToolItem()
+ _separator.props.draw = True
+ _separator.set_expand(False)
+ toolbox.toolbar.insert(_separator, -1)
+ _separator.show()
+ self.mode_image = gtk.Image()
+ self.mode_image.set_from_file(ICONS_DIR + '/domain-time2.svg')
+ mode_image_tool = gtk.ToolItem()
+ mode_image_tool.add(self.mode_image)
+ toolbox.toolbar.insert(mode_image_tool,-1)
+ _separator = gtk.SeparatorToolItem()
+ _separator.props.draw = False
+ _separator.set_expand(True)
+ toolbox.toolbar.insert(_separator, -1)
+ _separator.show()
+ _stop_button = StopButton(self)
+ _stop_button.props.accelerator = _('<Ctrl>Q')
+ toolbox.toolbar.insert(_stop_button, -1)
+ _stop_button.show()
+
+ self.set_toolbox(toolbox)
+
+ if not self.new_sugar_system:
+ toolbox.set_current_toolbar(TOOLBARS.index('sound'))
+ else:
+ self._sound_button.set_expanded(True)
+
toolbox.show()
self.show_all()
self.first = True
- self.set_show_hide_windows()
+ self.set_show_hide_windows('sound')
self.wave.set_active(True)
self.wave.set_context_on()
@@ -153,10 +229,18 @@ class MeasureActivity(activity.Activity):
if mode == 'sound':
self.wave.set_context_on()
self.side_toolbar.set_show_hide(True, mode)
+ if not self.new_sugar_system:
+ toolbox.set_current_toolbar(TOOLBARS.index('sound'))
+ else:
+ self._sound_button.set_expanded(True)
return
elif mode == 'sensor':
self.wave.set_context_on()
self.side_toolbar.set_show_hide(True, mode)
+ if not self.new_sugar_system:
+ toolbox.set_current_toolbar(TOOLBARS.index('sensor'))
+ else:
+ self._sensor_button.set_expanded(True)
return
def on_quit(self,data=None):
@@ -167,13 +251,13 @@ class MeasureActivity(activity.Activity):
def _active_cb( self, widget, pspec ):
""" Callback to handle starting/pausing capture when active/idle """
- if(self.first == True):
+ if self.first:
self.audiograb.start_grabbing()
self.first = False
- if (not self.props.active and self.ACTIVE):
+ if not self.props.active and self.ACTIVE:
self.audiograb.pause_grabbing()
self.active_status = False
- elif (self.props.active and not self.ACTIVE):
+ elif self.props.active and not self.ACTIVE:
self.audiograb.resume_grabbing()
self.active_status = True
@@ -189,4 +273,29 @@ class MeasureActivity(activity.Activity):
""" Read data from journal on start """
return
+ def _toolbar_changed_cb(self, toolbox, num):
+ """ Callback for changing the primary toolbar (0.84-) """
+ if TOOLBARS[num] == 'sound':
+ self.set_sound_context()
+ elif TOOLBARS[num] == 'sensor':
+ self.set_sensor_context()
+ return True
+
+ def set_sound_context(self):
+ """ Called when sound toolbar is selected or button pushed """
+ self.set_show_hide_windows('sound')
+ if _is_xo(self.hw):
+ self.sensor_toolbar.context_off()
+ sleep(0.5)
+ self.sound_toolbar.context_on()
+ self.CONTEXT = 'sound'
+
+ def set_sensor_context(self):
+ """ Called when sensor toolbar is selected or button pushed """
+ self.set_show_hide_windows('sensor')
+ self.sound_toolbar.context_off()
+ sleep(0.5)
+ self.sensor_toolbar.context_on()
+ self.CONTEXT = 'sensor'
+
gtk.gdk.threads_init()
diff --git a/sensor_toolbar.py b/sensor_toolbar.py
index 63499be..0fc873c 100644
--- a/sensor_toolbar.py
+++ b/sensor_toolbar.py
@@ -3,7 +3,7 @@
#
# Author: Arjun Sarwal arjun@laptop.org
# Copyright (C) 2007, Arjun Sarwal
-# Copyright (C) 2009, Walter Bender
+# Copyright (C) 2009,10 Walter Bender
# Copyright (C) 2009, Benjamin Berg, Sebastian Berg
#
# This program is free software; you can redistribute it and/or modify
@@ -22,10 +22,10 @@
import pygtk
import gtk
-import time
+from time import sleep
from gettext import gettext as _
-import config
+from config import ICONS_DIR
from sugar.graphics.toolbutton import ToolButton
from sugar.graphics.combobox import ComboBox
@@ -35,7 +35,7 @@ log = logging.getLogger('Measure')
log.setLevel(logging.DEBUG)
try:
import gconf
-except:
+except ImportError:
from sugar import profile
@@ -59,20 +59,16 @@ class SensorToolbar(gtk.Toolbar):
self.gain_state = None
self.boost_state = None
- # self.b = 0
-
self.string_for_textbox = ""
- self.wave = activity.wave
- self.ag = activity.audiograb
- self.ag.set_sensor(self)
- self.textbox_copy = activity.text_box
- self.ji = activity.ji
+ self.activity = activity
+ self.activity.audiograb.set_sensor(self)
- # self.logging_status = False
-
# Set up Resistance Button
- self._resistance = ToolButton('bias-on2')
+ if self.activity.new_sugar_system:
+ self._resistance = ToolButton('bias-on')
+ else:
+ self._resistance = ToolButton('bias-on2')
self.insert(self._resistance, -1)
self._resistance.show()
self._resistance.set_tooltip(_('Resistance Sensor'))
@@ -91,7 +87,7 @@ class SensorToolbar(gtk.Toolbar):
self.insert(self._invert, -1)
self._invert.set_tooltip(_('Invert'))
self._invert.connect('clicked', self._invert_control_cb)
- self.wave.set_invert_state(False)
+ self.activity.wave.set_invert_state(False)
separator = gtk.SeparatorToolItem()
separator.props.draw = True
@@ -99,7 +95,7 @@ class SensorToolbar(gtk.Toolbar):
# Set up Logging Interval combo box
self.loginterval_img = gtk.Image()
- self.loginterval_img.set_from_file(config.ICONS_DIR+'/sample_rate.svg')
+ self.loginterval_img.set_from_file(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)
@@ -141,18 +137,15 @@ class SensorToolbar(gtk.Toolbar):
def set_sample_value(self, label=""):
""" Write a sample value to the toolbar label """
- self.sample_value.set_text(label)
+ self.sample_value.set_text(str(label))
self.sample_value.show()
def record_control(self, data=None):
"""Depending upon the selected interval, does either
a logging session, or just logs the current buffer"""
- # config.LOGGING_IN_SESSION appears to be a duplicate of
- # self.logging_status.
- #
- if config.LOGGING_IN_SESSION == False:
- Xscale = (1.00/self.ag.get_sampling_rate())
+ if self.activity.LOGGING_IN_SESSION == False:
+ Xscale = (1.00/self.activity.audiograb.get_sampling_rate())
Yscale = 0.0
interval = self.interval_convert()
try:
@@ -160,21 +153,18 @@ class SensorToolbar(gtk.Toolbar):
username = client.get_string("/desktop/suagr/user/nick")
except:
username = profile.get_nick_name()
- self.ji.start_new_session(username, Xscale, Yscale,
+ self.activity.ji.start_new_session(username, Xscale, Yscale,
self.logginginterval_status)
- self.ag.set_logging_params(True, interval, False)
- config.LOGGING_IN_SESSION = True
- # self.logging_status = True
+ self.activity.audiograb.set_logging_params(True, interval, False)
+ self.activity.LOGGING_IN_SESSION = True
self._record.set_icon('record-stop')
self._record.show()
self._record.set_tooltip(_('Stop Recording'))
else:
- # if self.logging_status == True:
- self.ag.set_logging_params(False)
- time.sleep(0.2)
- self.ji.stop_session()
- config.LOGGING_IN_SESSION = False
- # self.logging_status = False
+ self.activity.audiograb.set_logging_params(False)
+ sleep(0.2)
+ self.activity.ji.stop_session()
+ self.activity.LOGGING_IN_SESSION = False
self._record.set_icon('media-record')
self._record.show()
self._record.set_tooltip(_('Start Recording'))
@@ -203,6 +193,11 @@ class SensorToolbar(gtk.Toolbar):
def set_resistance_voltage_mode(self, data=None, mode_to_set='resistance'):
""" Callback for Resistance/Voltage Buttons """
+
+ # Make sure the current context is for sensor capture.
+ if self.activity.CONTEXT != 'sensor':
+ self.activity.set_sensor_context()
+
self.set_mode(mode_to_set)
if mode_to_set == 'resistance':
self._resistance.set_icon('bias-on2')
@@ -210,26 +205,31 @@ class SensorToolbar(gtk.Toolbar):
self._resistance.show()
self._voltage.show()
self._update_string_for_textbox()
- return False
+ self.activity.mode_image.set_from_file(ICONS_DIR +\
+ '/bias-on2.svg')
elif mode_to_set == 'voltage':
self._resistance.set_icon('bias-on')
self._voltage.set_icon('bias-off2')
self._resistance.show()
self._voltage.show()
self._update_string_for_textbox()
- return False
+ self.activity.mode_image.set_from_file(ICONS_DIR +\
+ '/bias-off2.svg')
else:
logging.error("unknown mode %s" % (mode_to_set))
- return False
+ if self.activity.new_sugar_system:
+ self.activity.sound_toolbar._time.set_icon('domain-time')
+ self.activity.sound_toolbar._freq.set_icon('domain-freq')
+ return False
def _invert_control_cb(self, data=None):
""" Callback for Invert Button """
- if self.wave.get_invert_state()==True:
- self.wave.set_invert_state(False)
+ if self.activity.wave.get_invert_state()==True:
+ self.activity.wave.set_invert_state(False)
self._invert.set_icon('invert')
self._invert.show()
else:
- self.wave.set_invert_state(True)
+ self.activity.wave.set_invert_state(True)
self._invert.set_icon('invert2')
self._invert.show()
self._update_string_for_textbox()
@@ -238,19 +238,19 @@ class SensorToolbar(gtk.Toolbar):
def set_mode(self, mode='resistance'):
""" Set the mixer settings to match the current mode. """
self.mode = mode
- self.ag.set_sensor_type(self.mode)
+ self.activity.audiograb.set_sensor_type(self.mode)
return
def context_off(self):
""" Called when sensor toolbar is no longer selected. """
- self.ag.pause_grabbing()
+ self.activity.audiograb.pause_grabbing()
def context_on(self):
""" Called when sensor toolbar is selected. """
- self.ag.resume_grabbing()
- self.ag.set_sensor_type(self.mode)
+ self.activity.audiograb.resume_grabbing()
+ self.activity.audiograb.set_sensor_type(self.mode)
self._update_string_for_textbox()
- self.wave.set_trigger(self.wave.TRIGGER_NONE)
+ self.activity.wave.set_trigger(self.activity.wave.TRIGGER_NONE)
def _update_string_for_textbox(self):
""" Update the status field at the bottom of the canvas. """
@@ -260,6 +260,6 @@ class SensorToolbar(gtk.Toolbar):
self.string_for_textbox += self._STR_R
else:
self.string_for_textbox += self._STR_V
- if self.wave.get_invert_state()==True:
+ if self.activity.wave.get_invert_state()==True:
self.string_for_textbox += self._STR_I
- self.textbox_copy.set_data_params(0, self.string_for_textbox)
+ self.activity.text_box.set_data_params(0, self.string_for_textbox)
diff --git a/sound_toolbar.py b/sound_toolbar.py
index 11c165e..da65f5b 100644
--- a/sound_toolbar.py
+++ b/sound_toolbar.py
@@ -22,10 +22,9 @@
import pygtk
import gtk
import gobject
-from time import *
from gettext import gettext as _
-import config #This has all the globals
+from config import ICONS_DIR, CAPTURE_GAIN, MIC_BOOST
# Initialize logging.
import logging
@@ -38,7 +37,7 @@ from sugar.graphics.combobox import ComboBox
from sugar.graphics.toolcombobox import ToolComboBox
try:
import gconf
-except:
+except ImportError:
from sugar import profile
# Initialize logging.
@@ -64,10 +63,7 @@ class SoundToolbar(gtk.Toolbar):
""" Initialize the toolbar controls. """
gtk.Toolbar.__init__(self)
- self.wave = activity.wave
- self.ag = activity.audiograb
- self.textbox_copy = activity.text_box
- self.ji = activity.ji
+ self.activity = activity
self._STR_BASIC = _("Sound") + " "
self._STR1 = _("Time Base") + " "
@@ -87,8 +83,8 @@ class SoundToolbar(gtk.Toolbar):
self.gain = 1.0
self.y_mag = 3.0
- self.capture_gain = config.CAPTURE_GAIN
- self.mic_boost = config.MIC_BOOST
+ self.capture_gain = CAPTURE_GAIN
+ self.mic_boost = MIC_BOOST
# self.logging_status = False
self._record = None
@@ -115,7 +111,8 @@ class SoundToolbar(gtk.Toolbar):
self._freq_stepper_up.set_tooltip(_('Zoom out'))
self._freq_stepper_up.connect('clicked', self._freq_stepper_up_cb)
- self.adjustmentf = gtk.Adjustment(.5, self.LOWER, self.UPPER, 0.01, 0.1, 0)
+ self.adjustmentf = gtk.Adjustment(0.5, self.LOWER, self.UPPER, 0.01,
+ 0.1, 0)
self.adjustmentf.connect("value_changed", self.cb_page_sizef)
self._freq_range = gtk.HScale(self.adjustmentf)
self._freq_range.set_inverted(True)
@@ -150,7 +147,7 @@ class SoundToolbar(gtk.Toolbar):
separator.show()
self.loginterval_img = gtk.Image()
- self.loginterval_img.set_from_file(config.ICONS_DIR+'sample_rate.svg')
+ self.loginterval_img.set_from_file(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)
@@ -193,8 +190,9 @@ class SoundToolbar(gtk.Toolbar):
# Set up Trigger Combo box
self._trigger_combo = ComboBox()
self.trigger = [_('None'), _('Rising Edge') , _('Falling Edge') ]
- self.trigger_conf = [self.wave.TRIGGER_NONE, self.wave.TRIGGER_POS,
- self.wave.TRIGGER_NEG]
+ self.trigger_conf = [self.activity.wave.TRIGGER_NONE,
+ self.activity.wave.TRIGGER_POS,
+ self.activity.wave.TRIGGER_NEG]
self._trigger_changed_id = self._trigger_combo.connect("changed",
self.update_trigger_control)
@@ -213,8 +211,8 @@ class SoundToolbar(gtk.Toolbar):
def record_control(self, data=None):
"""Depending upon the selected interval, either starts/stops
a logging session, or just logs the current buffer"""
- if config.LOGGING_IN_SESSION == False:
- Xscale = (1.00/self.ag.get_sampling_rate())
+ if self.activity.LOGGING_IN_SESSION == False:
+ Xscale = (1.00/self.activity.audiograb.get_sampling_rate())
Yscale = 0.0
interval = self.interval_convert()
try:
@@ -222,10 +220,10 @@ class SoundToolbar(gtk.Toolbar):
username = client.get_string("/desktop/suagr/user/nick")
except:
username = profile.get_nick_name()
- self.ji.start_new_session(username, Xscale, Yscale,
+ self.activity.ji.start_new_session(username, Xscale, Yscale,
self.logginginterval_status)
- self.ag.set_logging_params(True, interval, True)
- config.LOGGING_IN_SESSION = True
+ self.activity.audiograb.set_logging_params(True, interval, True)
+ self.activity.LOGGING_IN_SESSION = True
# self.logging_status = True
self._record.set_icon('record-stop')
self._record.show()
@@ -233,12 +231,12 @@ class SoundToolbar(gtk.Toolbar):
self._record.set_icon('media-record')
self._record.show()
self.record_state = False
- config.LOGGING_IN_SESSION = False
+ self.activity.LOGGING_IN_SESSION = False
self.logging_status = False
else:
# if self.logging_status == True:
- self.ag.set_logging_params(False)
- config.LOGGING_IN_SESSION = False
+ self.activity.audiograb.set_logging_params(False)
+ self.activity.LOGGING_IN_SESSION = False
# self.logging_status = False
self._record.set_icon('media-record')
self._record.show()
@@ -253,7 +251,7 @@ class SoundToolbar(gtk.Toolbar):
if self.logginginterval_status == 'picture':
return 0
elif self.logginginterval_status == '30second':
- return 30 #2667
+ return 30 #2667
elif self.logginginterval_status == '2minute':
return 120 #10668
elif self.logginginterval_status == '10minute':
@@ -286,7 +284,7 @@ class SoundToolbar(gtk.Toolbar):
the sampling interval > 0. """
if self._record == None:
return
- if config.LOGGING_IN_SESSION == True:
+ if self.activity.LOGGING_IN_SESSION == True:
self._record.set_tooltip(_('Stop sampling'))
else: # No sampling in progress
if (self._loginterval_combo.get_active() == 0):
@@ -301,18 +299,18 @@ class SoundToolbar(gtk.Toolbar):
if active == -1:
return
- self.wave.set_trigger(self.trigger_conf[active])
+ self.activity.wave.set_trigger(self.trigger_conf[active])
return
def _pauseplay_control_cb(self, data=None):
""" Callback for Pause Button """
- if self.ag.get_freeze_the_display()==True:
- self.ag.set_freeze_the_display(False)
+ if self.activity.audiograb.get_freeze_the_display()==True:
+ self.activity.audiograb.set_freeze_the_display(False)
self._pause.set_icon('media-playback-pause-insensitive')
self._pause.set_tooltip(_('Unfreeze the display'))
self._pause.show()
else:
- self.ag.set_freeze_the_display(True)
+ self.activity.audiograb.set_freeze_the_display(True)
self._pause.set_icon('media-playback-pause')
self._pause.set_tooltip(_('Freeze the display'))
self._pause.show()
@@ -320,21 +318,32 @@ class SoundToolbar(gtk.Toolbar):
def _timefreq_control_cb(self, data=None, time_state=True):
""" Callback for Time and Freq. Buttons """
- if time_state==True and self.wave.get_fft_mode()==True:
- self.wave.set_fft_mode(False)
+
+ # Make sure the current context is for sound capture.
+ if self.activity.CONTEXT != 'sound':
+ self.activity.set_sound_context()
+
+ if time_state==True:
+ self.activity.wave.set_fft_mode(False)
self._time.set_icon('domain-time2')
self._freq.set_icon('domain-freq')
self._time.show()
self._freq.show()
self._update_string_for_textbox()
- return False
- if time_state==False and self.wave.get_fft_mode()==False:
- self.wave.set_fft_mode(True)
+ self.activity.mode_image.set_from_file(ICONS_DIR +\
+ '/domain-time2.svg')
+ else:
+ self.activity.wave.set_fft_mode(True)
self._time.set_icon('domain-time')
self._freq.set_icon('domain-freq2')
self._time.show()
self._freq.show()
self._update_string_for_textbox()
+ self.activity.mode_image.set_from_file(ICONS_DIR +\
+ '/domain-freq2.svg')
+ if self.activity.new_sugar_system:
+ self.activity.sensor_toolbar._resistance.set_icon('bias-on')
+ self.activity.sensor_toolbar._voltage.set_icon('bias-off')
return False
def _freq_stepper_up_cb(self, data=None):
@@ -380,7 +389,7 @@ class SoundToolbar(gtk.Toolbar):
time_div = 0.001*max(self.adjustmentf.value, 0.05)
freq_div = 1000*max(self.adjustmentf.value, 0.01)
- self.wave.set_div(time_div, freq_div)
+ self.activity.wave.set_div(time_div, freq_div)
self._update_string_for_textbox()
@@ -389,42 +398,39 @@ class SoundToolbar(gtk.Toolbar):
def context_off(self):
"""When some other context is switched to and the sound context
is switched off"""
- self.gain, self.y_mag = self.wave.get_mag_params()
- self.capture_gain = self.ag.get_capture_gain()
- self.mic_boost = self.ag.get_mic_boost()
- self.ag.stop_sound_device()
- self.wave.set_fft_mode(False)
+ self.gain, self.y_mag = self.activity.wave.get_mag_params()
+ self.capture_gain = self.activity.audiograb.get_capture_gain()
+ self.mic_boost = self.activity.audiograb.get_mic_boost()
+ self.activity.audiograb.stop_sound_device()
+ self.activity.wave.set_fft_mode(False)
def context_on(self):
"""When the sound context is switched on"""
- self.ag.start_sound_device()
- #self.ag.set_dc_mode(False)
- #self.ag.set_bias(True)
- #self.ag.set_capture_gain(self.capture_gain)
- #self.ag.set_mic_boost(self.mic_boost)
- self.ag.set_sensor_type("sound")
- self.wave.set_fft_mode(False)
- self.wave.set_mag_params(self.gain, self.y_mag)
+ self.activity.audiograb.start_sound_device()
+ self.activity.audiograb.set_sensor_type("sound")
+ self.activity.wave.set_fft_mode(False)
+ self.activity.wave.set_mag_params(self.gain, self.y_mag)
self._update_string_for_textbox()
self.update_trigger_control()
def _update_string_for_textbox(self):
""" Update the text at the bottom of the canvas """
- if self.wave.get_fft_mode() == False:
+ if self.activity.wave.get_fft_mode() == False:
self._STR_SCALEX = self._STR_XAXIS_TEXT % \
- {'unit': self._ms, 'division': self.wave.time_div*1000}
+ {'unit': self._ms,
+ 'division': self.activity.wave.time_div*1000}
else:
self._STR_SCALEX = self._STR_XAXIS_TEXT % \
- {'unit': self._Hz, 'division': self.wave.freq_div}
+ {'unit': self._Hz, 'division': self.activity.wave.freq_div}
self.string_for_textbox = ""
self.string_for_textbox += (self._STR_BASIC + "\t")
- if self.wave.get_fft_mode() == False:
+ if self.activity.wave.get_fft_mode() == False:
self.string_for_textbox += self._STR1
else:
self.string_for_textbox += self._STR2
- if self.wave.get_invert_state()==True:
+ if self.activity.wave.get_invert_state()==True:
self.string_for_textbox += self._STR3
self.string_for_textbox += ("\n" + self._STR_SCALEX)
- self.textbox_copy.set_data_params(0, self.string_for_textbox)
+ self.activity.text_box.set_data_params(0, self.string_for_textbox)
diff --git a/toolbar_side.py b/toolbar_side.py
index 3d7cfd2..e0b6d29 100644
--- a/toolbar_side.py
+++ b/toolbar_side.py
@@ -4,7 +4,7 @@
# Copyright (C) 2007, Arjun Sarwal
# Copyright (C) 2009,10 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
@@ -25,8 +25,6 @@ from gettext import gettext as _
from sugar.graphics.toolbutton import ToolButton
-import config
-
#class SideToolbar(gtk.DrawingArea):
class SideToolbar(gtk.Toolbar):
""" A toolbar on the side of the canvas for adjusting gain/bias """
@@ -36,14 +34,12 @@ class SideToolbar(gtk.Toolbar):
def __init__(self, activity):
""" Set up initial toolbars """
- # gtk.DrawingArea.__init__(self)
gtk.Toolbar.__init__(self)
- self.wave = activity.wave
- self.ag = activity.audiograb
+ self.activity = activity
self.show_toolbar = True
- self.mode = config.CONTEXT
+ self.mode = 'sound'
self.mode_values = {'sound':3, 'sensor':2}
self.button_up = ToolButton('amp-high')
@@ -54,12 +50,12 @@ class SideToolbar(gtk.Toolbar):
self.adjustmenty = gtk.Adjustment(self.mode_values[self.mode],
self.LOWER, self.UPPER, 0.1, 0.1, 0.0)
self.adjustmenty.connect("value_changed", self._yscrollbar_cb,
- self.adjustmenty)
+ self.adjustmenty)
self.yscrollbar = gtk.VScale(self.adjustmenty)
self.yscrollbar.set_draw_value(False)
self.yscrollbar.set_inverted(True)
self.yscrollbar.set_update_policy(gtk.UPDATE_CONTINUOUS)
-
+
self.button_down = ToolButton('amp-low')
self.button_down.set_tooltip(_('Decrease amplitude'))
self.button_down.connect('clicked', self._button_down_cb)
@@ -75,40 +71,32 @@ class SideToolbar(gtk.Toolbar):
def _yscrollbar_cb(self, adjy, data=None):
""" Callback for scrollbar """
if self.mode == 'sound':
- if adjy.value <= 1.5:
- self.wave.set_mag_params(1.0, adjy.value) #0dB
- self.ag.set_capture_gain(0)
- elif adjy.value <= 2.5:
- self.wave.set_mag_params(1.9952, adjy.value*1.5) #6dB
- self.ag.set_capture_gain(25)
- elif adjy.value <= 3.5:
- self.wave.set_mag_params(3.981, adjy.value*3.0) #12dB
- self.ag.set_capture_gain(50)
- else:
- self.wave.set_mag_params(13.335, adjy.value*4.0) #22.5dB
- self.ag.set_capture_gain(100)
- self.wave.set_bias_param(0)
+ self.activity.wave.set_mag_params(1.0, adjy.value)
+ aelf.activity.audiograb.set_capture_gain(adjy.value*\
+ 100/(self.UPPER-self.LOWER))
+ self.activity.wave.set_bias_param(0)
elif self.mode == 'sensor':
- self.wave.set_bias_param(int((adjy.value-2)*300))
+ self.activity.wave.set_bias_param(int(300*\
+ (adjy.value - (self.UPPER-self.LOWER)/2)))
self.mode_values[self.mode] = adjy.value
return True
def _button_up_cb(self, data=None):
"""Moves slider up"""
- new_value = self.yscrollbar.get_value() + (self.UPPER-self.LOWER)/100.0
- if new_value <= self.UPPER:
- self.yscrollbar.set_value(new_value)
- else:
- self.yscrollbar.set_value(self.UPPER)
+ new_value = self.yscrollbar.get_value() + (self.UPPER-self.LOWER)/100.0
+ if new_value <= self.UPPER:
+ self.yscrollbar.set_value(new_value)
+ else:
+ self.yscrollbar.set_value(self.UPPER)
return True
def _button_down_cb(self, data=None):
"""Moves slider down"""
- new_value = self.yscrollbar.get_value() - (self.UPPER-self.LOWER)/100.0
- if new_value >= self.LOWER:
- self.yscrollbar.set_value(new_value)
- else:
- self.yscrollbar.set_value(self.LOWER)
+ new_value = self.yscrollbar.get_value() - (self.UPPER-self.LOWER)/100.0
+ if new_value >= self.LOWER:
+ self.yscrollbar.set_value(new_value)
+ else:
+ self.yscrollbar.set_value(self.LOWER)
return True
def set_show_hide(self, show=True, mode='sound'):