我有一个使用libespeak(1.47.11版)以类人的声音宣布各种状态消息的应用程序。

在将新线程引入应用程序之前,此方法一直运行良好。现在,通常情况下,预期的单词后跟胡言乱语。有时,这些是较长的,先前宣布的消息的最后音节。其他时候,它们是数字或只是流浪字母。

我的代码类似于:

#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();


我尝试分配一个大的,归零的缓冲区并将我的字符串复制到该缓冲区中,然后再传递给libespeak,但这没有帮助。

这些调用的范围会随着对espeak_Synchronize的调用而阻塞,直到语音结束为止,因此没有什么可以删除message字符串。好像libespeak忽略了我要的长度。

请注意,如果我缩短size参数(第二个参数),则语音字符串将被截断。

还要注意,我只从多线程应用程序中的单个线程调用libespeak。

最佳答案

我找到了解决该问题的方法,该方法不能解释语音为什么以前失败了,但是可以使语音听起来像预期的那样。实际上,代码现在也读得更好。

与其使用AUDIO_OUTPUT_PLAYBACK进行异步播放,然后等待通过espeak_Synchronize的语音结束,不如使用AUDIO_OUTPUT_SYNCH_PLAYBACK进行同步播放并删除最终呼叫(这不会造成伤害,但不再需要。)

关于c++ - 在消息末尾说出额外的音节,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21536545/

10-12 03:52
查看更多