Quit before end of the synth

Asked by Phyks on 2014-02-26

Hi,

I've just found python-espeak to call directly espeak from a python script, without a system call, but I have some problem with it : the script quit and returns before the end of the synth call.

I have to add a sleep(5) after the espeak.synth call, to be sure that it will have time to finish. This is not convenient at all, as I don't have fixed length texts to synth and thus, can't determine a fixed time to sleep.

Is there any way to solve this problem ?

Thanks,
--
Phyks

Question information

Language:
English Edit question
Status:
Solved
For:
python-espeak Edit question
Assignee:
No assignee Edit question
Solved by:
Phyks
Solved:
2014-03-30
Last query:
2014-03-30
Last reply:
2014-03-30
Launchpad Janitor (janitor) said : #1

This question was expired because it remained in the 'Open' state without activity for the last 15 days.

Phyks (s-spam-u) said : #2

I don't know if this project is still alive (but it is very useful !) ? So, I try to bump this issue once, hoping that it is the case.

Siegfried Gevatter (rainct) said : #4

Hi,

Sorry for the late answer.

The espeak library was designed for asynchronous use, if you want to know when it's finished speaking you'll have to set a SynthCallback.

For instance:

import time
from espeak import espeak
from espeak import core as espeak_core

def synth(*args):
    done_synth = [False]
    def cb(event, pos, length):
        if event == espeak_core.event_MSG_TERMINATED:
            done_synth[0] = True
    espeak.set_SynthCallback(cb)
    r = espeak.synth(*args)
    while r and not done_synth[0]:
        time.sleep(0.05)
    return r

Or using a proper mainloop (eg. from GLib):

import time
from espeak import espeak
from espeak import core as espeak_core
from gi.repository import GLib

def synth(*args):
    mainloop = GLib.MainLoop()
    def cb(event, pos, length):
        if event == espeak_core.event_MSG_TERMINATED:
            mainloop.quit()
    espeak.set_SynthCallback(cb)
    if espeak.synth(*args):
        mainloop.run()
        return True
    return False

(Which reminds me that these set_SynthCallback and espeak_core.event_MSG_TERMINATED are terrible, I should clean up the API some day.)

Siegfried Gevatter (rainct) said : #5

[Changing status]

Phyks (s-spam-u) said : #6

Ok, thank you for this example !