A very nice feature provided by the gstreamer espeak plugin is the signals at the begining of the words,<div>useful to highlight every spoken word. </div><div><br></div><div>Also, is true we can use espeak with the command line, but if we can avoid calling another process,</div>
<div>I think is better.</div><div><br></div><div>Gonzalo</div><div><br><div class="gmail_quote">On Mon, Aug 20, 2012 at 5:28 PM, Flavio Danesse <span dir="ltr"><<a href="mailto:fdanesse@activitycentral.com" target="_blank">fdanesse@activitycentral.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><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" target="_blank">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" target="_blank">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>
<br>_______________________________________________<br>
Sugar-devel mailing list<br>
<a href="mailto:Sugar-devel@lists.sugarlabs.org">Sugar-devel@lists.sugarlabs.org</a><br>
<a href="http://lists.sugarlabs.org/listinfo/sugar-devel" target="_blank">http://lists.sugarlabs.org/listinfo/sugar-devel</a><br>
<br></blockquote></div><br></div>