[Sugar-devel] gst-plugins-espeak port to gstreamer 1.0
Flavio Danesse
fdanesse at activitycentral.com
Mon Aug 20 16:28:04 EDT 2012
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.sugarlabs.org/archive/sugar-devel/attachments/20120820/9a366853/attachment.html>
More information about the Sugar-devel
mailing list