<div><font color="#000099">Hello, on this subject, I think it is not necessary to create a special plugin for sugar, you can do the same in this way:</font></div><div><font color="#000099">Check it out at: <a href="http://git.sugarlabs.org/speak/mainline">http://git.sugarlabs.org/speak/mainline</a></font></div>
<div><br></div><div><font color="#990000">class BaseAudioGrab(GObject.GObject):</font></div><div><font color="#990000"> __gsignals__ = {</font></div><div><font color="#990000"> 'new-buffer': (GObject.SIGNAL_RUN_FIRST,</font></div>
<div><font color="#990000"> None, [GObject.TYPE_PYOBJECT])}</font></div><div><font color="#990000"><br></font></div><div><font color="#990000"> def __init__(self):</font></div><div><font color="#990000"> GObject.GObject.__init__(self)</font></div>
<div><font color="#990000"> self.pipeline = None</font></div><div><font color="#990000"> self._was_message = False</font></div><div><font color="#990000"> </font></div><div><font color="#990000"> def speak(self, status, text):</font></div>
<div><font color="#990000"> # 175 is default value, min is 80</font></div><div><font color="#990000"> rate = 60 + int(((175 - 80) * 2) * status.rate / RATE_MAX)</font></div><div><font color="#990000"> wavpath = "/tmp/speak.wav"</font></div>
<div><font color="#990000"><br></font></div><div><font color="#990000"> subprocess.call(["espeak", "-w", wavpath, "-p", str(status.pitch),</font></div><div><font color="#990000"> "-s", str(rate), "-v", <a href="http://status.voice.name">status.voice.name</a>, text],</font></div>
<div><font color="#990000"> stdout=subprocess.PIPE)</font></div><div><font color="#990000"> </font></div><div><font color="#990000"> self.stop_sound_device()</font></div><div><font color="#990000"> </font></div>
<div><font color="#990000"> self.make_pipeline(wavpath)</font></div><div><font color="#990000"> </font></div><div><font color="#990000"> def restart_sound_device(self):</font></div><div><font color="#990000"> try:</font></div>
<div><font color="#990000"> self.pipeline.set_state(Gst.State.NULL)</font></div><div><font color="#990000"> self.pipeline.set_state(Gst.State.READY)</font></div><div><font color="#990000"> self.pipeline.set_state(Gst.State.PLAYING)</font></div>
<div><font color="#990000"> except:</font></div><div><font color="#990000"> pass</font></div><div><font color="#990000"><br></font></div><div><font color="#990000"> def stop_sound_device(self):</font></div>
<div><font color="#990000"> if self.pipeline is None:</font></div><div><font color="#990000"> return</font></div><div><font color="#990000"> try:</font></div><div><font color="#990000"> self.pipeline.set_state(Gst.State.NULL)</font></div>
<div><font color="#990000"> self.pipeline.set_state(Gst.State.READY)</font></div><div><font color="#990000"> self._new_buffer('')</font></div><div><font color="#990000"> except:</font></div>
<div><font color="#990000"> pass</font></div><div><font color="#990000"><br></font></div><div><font color="#990000"> def make_pipeline(self, wavpath):</font></div><div><font color="#990000"> if self.pipeline is not None:</font></div>
<div><font color="#990000"> self.pipeline.set_state(Gst.State.NULL)</font></div><div><font color="#990000"> del(self.pipeline)</font></div><div><font color="#990000"> </font></div><div><font color="#990000"> self.pipeline = Gst.Pipeline()</font></div>
<div><font color="#990000"> </font></div><div><font color="#990000"> file = Gst.ElementFactory.make("filesrc", "espeak")</font></div><div><font color="#990000"> wavparse = Gst.ElementFactory.make("wavparse", "wavparse")</font></div>
<div><font color="#990000"> audioconvert = Gst.ElementFactory.make("audioconvert", "audioconvert")</font></div><div><font color="#990000"> tee = Gst.ElementFactory.make('tee', "tee")</font></div>
<div><font color="#990000"> # FIXME: alsasink no more, pulseaudio causes:</font></div><div><font color="#990000"> # gst_object_unref: assertion `((GObject *) object)->ref_count > 0' failed</font></div>
<div><font color="#990000"> playsink = Gst.ElementFactory.make("playsink", "playsink")</font></div><div><font color="#990000"> queue1 = Gst.ElementFactory.make("queue", "queue1")</font></div>
<div><font color="#990000"> fakesink = Gst.ElementFactory.make("fakesink", "fakesink")</font></div><div><font color="#990000"> queue2 = Gst.ElementFactory.make("queue", "queue2")</font></div>
<div><font color="#990000"> </font></div><div><font color="#990000"> self.pipeline.add(file)</font></div><div><font color="#990000"> self.pipeline.add(wavparse)</font></div><div><font color="#990000"> self.pipeline.add(audioconvert)</font></div>
<div><font color="#990000"> self.pipeline.add(tee)</font></div><div><font color="#990000"> self.pipeline.add(queue1)</font></div><div><font color="#990000"> self.pipeline.add(playsink)</font></div><div>
<font color="#990000"> self.pipeline.add(queue2)</font></div><div><font color="#990000"> self.pipeline.add(fakesink)</font></div><div><font color="#990000"> </font></div><div><font color="#990000"> file.link(wavparse)</font></div>
<div><font color="#990000"> wavparse.link(tee)</font></div><div><font color="#990000"> </font></div><div><font color="#990000"> tee.link(queue1)</font></div><div><font color="#990000"> queue1.link(audioconvert)</font></div>
<div><font color="#990000"> audioconvert.link(playsink)</font></div><div><font color="#990000"> </font></div><div><font color="#990000"> tee.link(queue2)</font></div><div><font color="#990000"> queue2.link(fakesink)</font></div>
<div><font color="#990000"> </font></div><div><font color="#990000"> file.set_property("location", wavpath)</font></div><div><font color="#990000"> </font></div><div><font color="#990000"> fakesink.set_property('signal-handoffs', True)</font></div>
<div><font color="#990000"> fakesink.set_property('dump', True)</font></div><div><font color="#990000"> fakesink.connect('handoff', self.on_buffer)</font></div><div><font color="#990000"> </font></div>
<div><font color="#990000"> self._was_message = False</font></div><div><font color="#990000"> bus = self.pipeline.get_bus()</font></div><div><font color="#990000"> bus.add_signal_watch()</font></div><div>
<font color="#990000"> bus.connect('message', self.gstmessage_cb)</font></div><div><font color="#990000"> </font></div><div><font color="#990000"> self.pipeline.set_state(Gst.State.PLAYING)</font></div>
<div><font color="#990000"> </font></div><div><font color="#990000"> def gstmessage_cb(self, bus, message):</font></div><div><font color="#990000"> self._was_message = True</font></div><div><font color="#990000"> </font></div>
<div><font color="#990000"> if message.type == Gst.MessageType.WARNING:</font></div><div><font color="#990000"> def check_after_warnings():</font></div><div><font color="#990000"> if not self._was_message:</font></div>
<div><font color="#990000"> self.stop_sound_device()</font></div><div><font color="#990000"> return True</font></div><div><font color="#990000"> </font></div><div><font color="#990000"> logger.debug(message.type)</font></div>
<div><font color="#990000"> self._was_message = False</font></div><div><font color="#990000"> GObject.timeout_add(500, self._new_buffer, str(buffer))</font></div><div><font color="#990000"> </font></div>
<div><font color="#990000"> elif message.type == Gst.MessageType.EOS:</font></div><div><font color="#990000"> self.pipeline.set_state(Gst.State.NULL)</font></div><div><font color="#990000"> </font></div>
<div><font color="#990000"> elif message.type == Gst.MessageType.ERROR:</font></div><div><font color="#990000"> err, debug = message.parse_error()</font></div><div><font color="#990000"> logger.debug(err)</font></div>
<div><font color="#990000"> self.stop_sound_device()</font></div><div><font color="#990000"> </font></div><div><font color="#990000"> def on_buffer(self, element, buffer, pad):</font></div><div><font color="#990000"> GObject.timeout_add(100, self._new_buffer, str(buffer))</font></div>
<div><font color="#990000"> return True</font></div><div><font color="#990000"> </font></div><div><font color="#990000"> def _new_buffer(self, buf):</font></div><div><font color="#990000"> self.emit("new-buffer", buf)</font></div>
<div><font color="#990000"> return False</font></div><div><br></div>