Question

I have an application that uses libespeak (version 1.47.11) to announce various status messages in a human-like voice.

This was working well until a new thread was introduced into the application. Now, commonly, the expected words are followed by gibberish. Occasionally these are the final syllables of a longer, previously announced message. Other times they're numbers or just stray letters.

My code resembles:

#include <espeak/speak_lib.h>

// ...

std::string message = "The rain in Spain falls mainly in the plain.";

espeak_Initialize(
  AUDIO_OUTPUT_PLAYBACK, // plays audio data asynchronously
  500,                   // length of buffers for synth function, in ms
  nullptr,               // dir containing espeak-data, or null for default
  0);                    // options are mostly for phoneme callbacks, so 0

espeak_ERROR err = espeak_Synth(
  message.c_str(),   // text
  message.size(),    // size
  0,                 // position to start from
  POS_CHARACTER,     // whether above 0 pos is chars/word/sentences
  message.size(),    // end position, 0 indicating no end
  espeakCHARS_AUTO | // flags: AUTO      8 bit or UTF8 automatically
  espeakENDPAUSE,    //        ENDPAUSE  sentence pause at end of text
  nullptr,           // message identifier given to callback (unused)
  nullptr);          // user data, passed to the callback function (unused)

if (err != EE_OK)
  cerr << "Error synthesising speech" << endl;

// Wait until everything has been spoken
espeak_Synchronize();

I tried allocating a large, zeroed buffer and copying my string into it before passing it off to libespeak, but it didn't help.

The scope of these calls persists as the call to espeak_Synchronize blocks until speech completes, so nothing is deleting the message string. It's as though libespeak is ignoring the length I'm requesting.

Note that if I shorten the size argument (the second one) then the spoken string is truncated.

Note too that I'm only calling libespeak from a single thread within my multithreaded application.

Was it helpful?

Solution

I found a solution to this problem which doesn't explain why speech was failing before, but does make speech sound as expected. And actually the code reads a little better now too.

Instead of using AUDIO_OUTPUT_PLAYBACK for asynchronous playback and then waiting for speech to finish via espeak_Synchronize, use AUDIO_OUTPUT_SYNCH_PLAYBACK for synchronous playback and remove the final call (it doesn't hurt, but is no longer needed.)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top