daisy / pipeline

Super-project that aggregates all Pipeline related code, provides a common tracker for Pipeline related issues and holds the Pipeline website
http://daisy.github.io/pipeline
20 stars 20 forks source link

Getting the List of Voices for eSpeak Fails with Espeak-NG #704

Open emassey0135 opened 10 months ago

emassey0135 commented 10 months ago

Expected Behavior

I tried to run the EPUB Enhancer script (epub3-to-epub3) on an EPUB with TTS enabled on Linux using the command-line interface.

Actual Behavior

The Espeak engine failed to activate because getting the list of voices failed, so all sentences failed to be spoken and the resulting EPUB had no audio.

Steps to Reproduce

  1. Make sure eSpeak-NG is installed and can be found on the system path as espeak (create a symbolic link if necessary)
  2. Make sure eSpeak has a higher priority than any other TTS
  3. From the cli directory of the Pipeline, run "./dp2 epub3-to-epub3 --source {epub} --tts true -o {output directory} --include-tts-log true [--tts-config {TTs configuration file}]"

Details

The problem seems to be in the regular expression that extracts details about voices from the output of the espeak command for a specific language, specifically when it extracts the gender. The error is traced to line 133 of modules/tts/tts-adapters/tts-adapter-espeak/src/main/java/org/daisy/pipeline/tts/espeak/impl/ESpeakEngine.java. The part that causes the error is "mr.group("gender").trim().toLowerCase()". Above this line the locale is matched successfully, so I think there must be a slight difference between how the old eSpeak prints the gender in the voice table and how eSpeak-NG does. The regular expression string that mr is created using is "^\\s*[0-9]+\\s+(?[-a-z]+)\\s+(?[FfMm-]\\s+)?(?[^ ]+)". I tried changing the regular expression to make it match the output of Espeak-NG, but I could not fix the issue. The last one I tried is "^\\s*[0-9]+\\s+(?[-a-zA-Z0-9]+)\\s+-*\\/*(?[FfMm]\\s+)(?[^ ]+)".

Environment

Logs

Logs

bertfrees commented 10 months ago

Thanks for the report! I can not currently install espeak-ng on my (older) macOS, so would appreciate if someone could further diagnose the issue or assist me with it.

Could you perhaps send me the output of the --voices command, so that I can try to fix the regex that way?

emassey0135 commented 10 months ago

I included the output of "espeak --voices" in the Gist I linked to. Its in the file named espeak-ng-voices.txt, and it shows up under the big log file. Here is a direct link to the file.

bertfrees commented 9 months ago

Sorry, should have seen that file before.

I think this regex should work:

"^\\s*[0-9]+\\s+(?<locale>[-a-zA-Z0-9]+)\\s+((--/)?(?<gender>[FfMm-])\\s+)?(?<name>[^ ]+)"

Below, change mr.group("gender") into Optional.ofNullable(mr.group("gender")).orElse("m") to avoid the NullPointerException. The .trim() can also be dropped with the new regex.

The regex should probably be further improved, because I presume instead of the "--" an action age can be listed?

emassey0135 commented 1 week ago

I apologize for taking so long to respond to this; I got distracted with other things and forgot about figuring this out. I started working on this again a few weeks ago, and when I applied the changes you suggested and added java.util.Optional to the imports, Pipeline successfully enumerated the voices, but I got another error when it tried to actually synthesize the speech. However, after that I started having issues with my Linux install on my laptop, so I cannot access the logs right now. When I get a working Linux install again I will try to diagnose the issue further and send the logs.

bertfrees commented 1 week ago

OK thank you.

emassey0135 commented 3 days ago

The error I am getting is "timeout (0 seconds) fired while speaking with espeak". For some reason, DAISY Pipeline seems to be giving eSpeak 0 seconds to speak some sentences. In the TTS log, there are lines like these: "".

When the timeout is not 0, it is anywhere from 1 to 12 seconds from the lines I looked at. Also, I tried this with the original eSpeak as well as eSpeak NG, and got the same result, so there must be a pre-existing bug in the eSpeak TTS adapter unless I am configuring it wrong somehow. Changing org.daisy.pipeline.tts.threads.number to 1 does not help.

Where is this timeout calculated? Is audio encoding happening too fast for eSpeak to keep up, so the Pipeline doesn't give it any time to speak?

Here are my new log files