# 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 AudioGrab(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): # 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) 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 # make a fakesink to capture audio fakesink = gst.element_factory_make("fakesink", "fakesink") fakesink.connect("handoff",on_buffer) fakesink.set_property("signal-handoffs",True) self.pipeline.add(fakesink) # attach it to the pipeline conv = self.pipeline.get_by_name("conv") gst.element_link_many(conv, fakesink) def gstmessage_cb(bus, message): if message.type in (gst.MESSAGE_EOS, gst.MESSAGE_ERROR): logger.debug(message.type) self.stop_sound_device() 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