Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/Speak.activity/audio.py
diff options
context:
space:
mode:
Diffstat (limited to 'Speak.activity/audio.py')
-rw-r--r--Speak.activity/audio.py83
1 files changed, 43 insertions, 40 deletions
diff --git a/Speak.activity/audio.py b/Speak.activity/audio.py
index 1176fb5..646dac9 100644
--- a/Speak.activity/audio.py
+++ b/Speak.activity/audio.py
@@ -23,17 +23,17 @@
# This code is a stripped down version of the audio grabber from Measure
-import pygst
-pygst.require("0.10")
import gst
import pygtk
import gtk, gobject
import signal, os
import time
import dbus
-import audioop
+import logging
from struct import *
+logger = logging.getLogger('speak')
+
class AudioGrab(gobject.GObject):
__gsignals__ = {
'new-buffer': (gobject.SIGNAL_RUN_FIRST, None, [gobject.TYPE_PYOBJECT])
@@ -43,13 +43,29 @@ class AudioGrab(gobject.GObject):
gobject.GObject.__init__(self)
self.pipeline = None
- def playfile(self, filename):
+ def playfile(self, status, text):
+ pitch = int(status.pitch)
+ rate = int(status.rate)
+ # espeak uses 80 to 370
+ rate = 80 + (370-80) * rate / 100
+
+ logger.debug('pitch=%d rate=%d voice=%s text=%s' % (pitch, rate,
+ status.voice.name, text))
+
self.stop_sound_device()
+ self._quiet = False
# build a pipeline that reads the given file
# and sends it to both the real audio output
# and a fake one that we use to draw from
- p = 'filesrc name=file-source ! decodebin ! tee name=tee tee.! audioconvert ! alsasink tee.! queue ! audioconvert name=conv'
+ p = 'espeak text="%s" pitch=%d rate=%d voice=%s ' \
+ '! decodebin ' \
+ '! tee name=tee ' \
+ 'tee.! audioconvert ' \
+ '! alsasink ' \
+ 'tee.! queue ' \
+ '! audioconvert name=conv' \
+ % (text, pitch, rate, status.voice.name)
self.pipeline = gst.parse_launch(p)
# make a fakesink to capture audio
@@ -58,13 +74,14 @@ class AudioGrab(gobject.GObject):
fakesink.set_property("signal-handoffs",True)
self.pipeline.add(fakesink)
+ bus = self.pipeline.get_bus()
+ bus.add_signal_watch()
+ bus.connect('message', self._gstmessage_cb)
+
# attach it to the pipeline
conv = self.pipeline.get_by_name("conv")
gst.element_link_many(conv, fakesink)
- # set the source file
- self.pipeline.get_by_name("file-source").set_property('location', filename)
-
# play
self.restart_sound_device()
@@ -72,42 +89,22 @@ class AudioGrab(gobject.GObject):
# we should stop the sound device and stop emitting buffers
# to save on CPU and battery usage when there is no audio playing
- def playfd(self, fd):
- self.stop_sound_device()
-
- # build a pipeline that reads the given file
- # and sends it to both the real audio output
- # and a fake one that we use to draw from
- if self.pipeline is None:
- p = 'fdsrc name=fd-source ! wavparse ! tee name=tee tee.! audioconvert ! alsasink tee.! queue ! audioconvert name=conv'
- self.pipeline = gst.parse_launch(p)
-
- # make a fakesink to capture audio
- fakesink = gst.element_factory_make("fakesink", "fakesink")
- fakesink.connect("handoff",self.on_buffer)
- fakesink.set_property("signal-handoffs",True)
- self.pipeline.add(fakesink)
+ def _gstmessage_cb(self, bus, message):
+ type = message.type
- # attach it to the pipeline
- conv = self.pipeline.get_by_name("conv")
- gst.element_link_many(conv, fakesink)
+ if type == gst.MESSAGE_EOS:
+ # END OF SOUND FILE
+ self.stop_sound_device()
+ elif type == gst.MESSAGE_ERROR:
+ self.stop_sound_device()
- # set the source file
- self.pipeline.get_by_name("fd-source").set_property('fd', fd)
-
- # play
- self.restart_sound_device()
-
- # how do we detect when the sample has finished playing?
- # we should stop the sound device and stop emitting buffers
- # to save on CPU and battery usage when there is no audio playing
-
def on_quit(self):
self.pipeline.set_state(gst.STATE_NULL)
def _new_buffer(self, buf):
- # pass captured audio to anyone who is interested via the main thread
- self.emit("new-buffer", buf)
+ if not self._quiet:
+ # pass captured audio to anyone who is interested via the main thread
+ self.emit("new-buffer", buf)
return False
def on_buffer(self,element,buffer,pad):
@@ -116,9 +113,15 @@ class AudioGrab(gobject.GObject):
return True
def stop_sound_device(self):
- if self.pipeline is not None:
- self.pipeline.set_state(gst.STATE_NULL)
+ if self.pipeline is None:
+ return
+
+ self.pipeline.set_state(gst.STATE_NULL)
+ # Shut theirs mouths down
+ self._new_buffer('')
+ self._quiet = True
def restart_sound_device(self):
+ self.pipeline.set_state(gst.STATE_NULL)
self.pipeline.set_state(gst.STATE_PLAYING)