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>