[Sugar-devel] gst-plugins-espeak port to gstreamer 1.0

Gonzalo Odiard gonzalo at laptop.org
Mon Aug 20 21:30:00 EDT 2012


A very nice feature provided by the gstreamer espeak plugin is the signals
at the begining of the words,
useful to highlight every spoken word.

Also, is true we can use espeak with the command line, but if we can avoid
calling another process,
I think is better.

Gonzalo

On Mon, Aug 20, 2012 at 5:28 PM, Flavio Danesse <
fdanesse at activitycentral.com> wrote:

> 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:
> Check it out at: http://git.sugarlabs.org/speak/mainline
>
> 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._was_message = False
>
>     def speak(self, status, text):
>         # 175 is default value, min is 80
>         rate = 60 + int(((175 - 80) * 2) * status.rate / RATE_MAX)
>         wavpath = "/tmp/speak.wav"
>
>         subprocess.call(["espeak", "-w", wavpath, "-p", str(status.pitch),
>                 "-s", str(rate), "-v", status.voice.name, text],
>                 stdout=subprocess.PIPE)
>
>         self.stop_sound_device()
>
>         self.make_pipeline(wavpath)
>
>     def restart_sound_device(self):
>         try:
>             self.pipeline.set_state(Gst.State.NULL)
>             self.pipeline.set_state(Gst.State.READY)
>             self.pipeline.set_state(Gst.State.PLAYING)
>         except:
>             pass
>
>     def stop_sound_device(self):
>         if self.pipeline is None:
>             return
>         try:
>             self.pipeline.set_state(Gst.State.NULL)
>             self.pipeline.set_state(Gst.State.READY)
>             self._new_buffer('')
>         except:
>             pass
>
>     def make_pipeline(self, wavpath):
>         if self.pipeline is not None:
>             self.pipeline.set_state(Gst.State.NULL)
>             del(self.pipeline)
>
>         self.pipeline = Gst.Pipeline()
>
>         file = Gst.ElementFactory.make("filesrc", "espeak")
>         wavparse = Gst.ElementFactory.make("wavparse", "wavparse")
>         audioconvert = Gst.ElementFactory.make("audioconvert",
> "audioconvert")
>         tee = Gst.ElementFactory.make('tee', "tee")
>         # FIXME: alsasink no more, pulseaudio causes:
>         # gst_object_unref: assertion `((GObject *) object)->ref_count >
> 0' failed
>         playsink = Gst.ElementFactory.make("playsink", "playsink")
>         queue1 = Gst.ElementFactory.make("queue", "queue1")
>         fakesink = Gst.ElementFactory.make("fakesink", "fakesink")
>         queue2 = Gst.ElementFactory.make("queue", "queue2")
>
>         self.pipeline.add(file)
>         self.pipeline.add(wavparse)
>         self.pipeline.add(audioconvert)
>         self.pipeline.add(tee)
>         self.pipeline.add(queue1)
>         self.pipeline.add(playsink)
>         self.pipeline.add(queue2)
>         self.pipeline.add(fakesink)
>
>         file.link(wavparse)
>         wavparse.link(tee)
>
>         tee.link(queue1)
>         queue1.link(audioconvert)
>         audioconvert.link(playsink)
>
>         tee.link(queue2)
>         queue2.link(fakesink)
>
>         file.set_property("location", wavpath)
>
>         fakesink.set_property('signal-handoffs', True)
>         fakesink.set_property('dump', True)
>         fakesink.connect('handoff', self.on_buffer)
>
>         self._was_message = False
>         bus = self.pipeline.get_bus()
>         bus.add_signal_watch()
>         bus.connect('message', self.gstmessage_cb)
>
>         self.pipeline.set_state(Gst.State.PLAYING)
>
>     def gstmessage_cb(self, bus, message):
>         self._was_message = True
>
>         if message.type == Gst.MessageType.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 == Gst.MessageType.EOS:
>             self.pipeline.set_state(Gst.State.NULL)
>
>         elif message.type == Gst.MessageType.ERROR:
>             err, debug = message.parse_error()
>             logger.debug(err)
>             self.stop_sound_device()
>
>     def on_buffer(self, element, buffer, pad):
>         GObject.timeout_add(100, self._new_buffer, str(buffer))
>         return True
>
>     def _new_buffer(self, buf):
>         self.emit("new-buffer", buf)
>         return False
>
>
> _______________________________________________
> Sugar-devel mailing list
> Sugar-devel at lists.sugarlabs.org
> http://lists.sugarlabs.org/listinfo/sugar-devel
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.sugarlabs.org/archive/sugar-devel/attachments/20120820/12e3e607/attachment.html>


More information about the Sugar-devel mailing list