我有一个使用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/