From d83c269464cf301fc71067ecf7702eefd6f5816d Mon Sep 17 00:00:00 2001 From: Aleksey Lim Date: Thu, 05 Feb 2009 23:35:29 +0000 Subject: Switch Espeak to gst-plugins-espeak --- (limited to 'Speak.activity/audio.py') 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) -- cgit v0.9.1