From 6e82c5964e31f3cc937911069709af9830071338 Mon Sep 17 00:00:00 2001 From: Aleksey Lim Date: Fri, 25 Dec 2009 15:34:56 +0000 Subject: Use only one directory level for sources --- (limited to 'espeak.py') diff --git a/espeak.py b/espeak.py new file mode 100644 index 0000000..389045d --- /dev/null +++ b/espeak.py @@ -0,0 +1,118 @@ +# 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +import gst +import gobject +import subprocess + +import logging +logger = logging.getLogger('speak') + +supported = True + +class BaseAudioGrab(gobject.GObject): + __gsignals__ = { + 'new-buffer': (gobject.SIGNAL_RUN_FIRST, None, [gobject.TYPE_PYOBJECT]) + } + + def __init__(self): + gobject.GObject.__init__(self) + self.pipeline = None + self.quiet = True + + def restart_sound_device(self): + self.quiet = False + + self.pipeline.set_state(gst.STATE_NULL) + self.pipeline.set_state(gst.STATE_PLAYING) + + def stop_sound_device(self): + if self.pipeline is None: + return + + self.pipeline.set_state(gst.STATE_NULL) + # Shut theirs mouths down + self._new_buffer('') + + self.quiet = True + + def make_pipeline(self, cmd): + if self.pipeline is not None: + self.stop_sound_device() + del self.pipeline + + # 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 + self.pipeline = gst.parse_launch( + cmd + ' ' \ + '! decodebin ' \ + '! tee name=tee ' \ + 'tee.! audioconvert ' \ + '! alsasink ' \ + 'tee.! queue ' \ + '! audioconvert ! fakesink name=sink') + + def on_buffer(element, buffer, pad): + # we got a new buffer of data, ask for another + gobject.timeout_add(100, self._new_buffer, str(buffer)) + return True + + sink = self.pipeline.get_by_name('sink') + sink.props.signal_handoffs = True + sink.connect('handoff', on_buffer) + + def gstmessage_cb(bus, message): + self._was_message = True + + if message.type == gst.MESSAGE_WARNING: + def check_after_warnings(): + if not self._was_message: + self.stop_sound_device() + return True + + logger.debug(message.type) + self._was_message = False + gobject.timeout_add(500, self._new_buffer, str(buffer)) + + elif message.type in (gst.MESSAGE_EOS, gst.MESSAGE_ERROR): + logger.debug(message.type) + self.stop_sound_device() + + self._was_message = False + bus = self.pipeline.get_bus() + bus.add_signal_watch() + bus.connect('message', gstmessage_cb) + + def _new_buffer(self, buf): + if not self.quiet: + # pass captured audio to anyone who is interested + self.emit("new-buffer", buf) + return False + +# load proper espeak plugin +try: + import gst + gst.element_factory_make('espeak') + from espeak_gst import AudioGrabGst as AudioGrab + from espeak_gst import * + logger.info('use gst-plugins-espeak') +except Exception, e: + logger.info('disable gst-plugins-espeak: %s' % e) + if subprocess.call('which espeak', shell=True) == 0: + from espeak_cmd import AudioGrabCmd as AudioGrab + from espeak_cmd import * + else: + logger.info('disable espeak_cmd') + supported = False -- cgit v0.9.1