C++ 如何确定espeak是否结束了演讲?

C++ 如何确定espeak是否结束了演讲?,c++,pocketsphinx,espeak,C++,Pocketsphinx,Espeak,我想在我的程序中使用。我想知道espeak什么时候停止讲话。是否有任何标志或函数需要检查 让我们来考虑一下这是我的程序: Line 1 espeak Line 2 当我执行这段代码时,espeak开始说hello,这是espeak,但在它结束之前,代码的第2行被执行了,我不喜欢这样。我正在寻找一种方法来暂停节目,直到espeak结束讲话 编辑: 这是我的完整代码,我使用pocketsphinx识别用户所说的话,然后将其保存在char*hyp中,并通过espeak by speech函数传递 s

我想在我的程序中使用。我想知道espeak什么时候停止讲话。是否有任何标志或函数需要检查

让我们来考虑一下这是我的程序:

Line 1
espeak
Line 2
当我执行这段代码时,espeak开始说hello,这是espeak,但在它结束之前,代码的第2行被执行了,我不喜欢这样。我正在寻找一种方法来暂停节目,直到espeak结束讲话

编辑: 这是我的完整代码,我使用pocketsphinx识别用户所说的话,然后将其保存在char*hyp中,并通过espeak by speech函数传递

static ps_decoder_t *ps;
static cmd_ln_t *config;
static FILE *rawfd;

espeak_POSITION_TYPE position_type;
espeak_AUDIO_OUTPUT output;
char *path=NULL;
int Buflength = 1000, Options=0;
void* user_data;
char Voice[] = {"English"};
char text2[30] = {"this is a english test"};
unsigned int Size,position=0, end_position=0, flags=espeakCHARS_AUTO, *unique_identifier;
t_espeak_callback *SynthCallback;
espeak_PARAMETER Parm;
//char* text;

static void initFuncs()
{

    output = AUDIO_OUTPUT_PLAYBACK;
    espeak_Initialize(output, Buflength, path, Options ); 
    espeak_SetVoiceByName(Voice);
    const char *langNativeString = "en";
    espeak_VOICE voice;
    memset(&voice, 0, sizeof(espeak_VOICE));
        voice.languages = langNativeString;
        voice.name = "US";
        voice.variant = 2;
        voice.gender = 1;
        espeak_SetVoiceByProperties(&voice);

}

static void sleep_msec(int32 ms)
{

    struct timeval tmo;

    tmo.tv_sec = 0;
    tmo.tv_usec = ms * 1000;

    select(0, NULL, NULL, NULL, &tmo);

}

static void speech(char* hyp)
{

    Size = strlen(hyp)+1;
    espeak_Synth( hyp, Size, position, position_type, end_position, flags,unique_identifier, user_data );
    espeak_Synchronize( );

}

static void recognize_from_microphone()
{
    ad_rec_t *ad;
    int16 adbuf[2048];
    uint8 utt_started, in_speech;
    int32 k;
    char  *hyp;

    if ((ad = ad_open_dev(cmd_ln_str_r(config, "-adcdev"),(int) cmd_ln_float32_r(config,"-samprate"))) == NULL)
        E_FATAL("Failed to open audio device\n");
    if (ad_start_rec(ad) < 0)
        E_FATAL("Failed to start recording\n");

    if (ps_start_utt(ps) < 0)
        E_FATAL("Failed to start utterance\n");

    utt_started = FALSE;
    E_INFO("Ready....\n");

    for (;;) {

        ad_start_rec(ad);

        if ((k = ad_read(ad, adbuf, 2048)) < 0)
            E_FATAL("Failed to read audio\n");
        ps_process_raw(ps, adbuf, k, FALSE, FALSE);
        in_speech = ps_get_in_speech(ps);
        if (in_speech && !utt_started) {
            utt_started = TRUE;
            E_INFO("Listening...\n");
        }
        if (!in_speech && utt_started) {

            ps_end_utt(ps);
            hyp = (char*)ps_get_hyp(ps, NULL );
            if (hyp != NULL) {

                ad_stop_rec(ad);
                speech(hyp);
                printf("%s\n", hyp); 
                fflush(stdout);
            }

            if (ps_start_utt(ps) < 0)
                E_FATAL("Failed to start utterance\n");
            utt_started = FALSE;
            E_INFO("Ready....\n");

        }

    }//for loop
    ad_close(ad);
}

int main(int argc, char *argv[])
{
    initFuncs();

    config = cmd_ln_init(NULL, ps_args(), TRUE,
                 "-hmm", MODELDIR "/en-us/en-us",
                     "-lm", MODELDIR "/en-us/en-us.lm.bin",
                     "-dict", MODELDIR "/en-us/cmudict-en-us.dict",
                     NULL);
    ps = ps_init(config);
        recognize_from_microphone();

    ps_free(ps);
    cmd_ln_free_r(config);

    return 0;
}

我修改了你代码中的espeak部分。在此代码中,espeak在第2行开始之前完成。还实现了回调功能。您正在按名称和属性设置语音。也许这是个问题。您使用的是c样式的字符串,而不是std::string。可能您计算的字符串长度错误。我不知道您的代码中的问题在哪里,但以下代码已将其修复:

#include <string>
#include <iostream>
#include <espeak/speak_lib.h>

espeak_POSITION_TYPE position_type(POS_CHARACTER);
espeak_AUDIO_OUTPUT output(AUDIO_OUTPUT_PLAYBACK);
void* user_data;
std::string voice("English");
std::string text("this is a english test");
unsigned int Size(0);
unsigned int position(0);
unsigned int end_position(0);
unsigned int flags(espeakCHARS_AUTO);
unsigned int* unique_identifier;

static void initFuncs() {
  espeak_Initialize(output, 0, 0, 0);
  espeak_SetVoiceByName(voice.c_str());
}

int SynthCallback(short *wav, int numsamples, espeak_EVENT *events) {
  std::cout << "Callback: ";
  for (unsigned int i(0); events[i].type != espeakEVENT_LIST_TERMINATED; i++) {
    if (i != 0) {
      std::cout << ", ";
    }
    switch (events[i].type) {
      case espeakEVENT_LIST_TERMINATED:
        std::cout << "espeakEVENT_LIST_TERMINATED";
        break;
      case espeakEVENT_WORD:
        std::cout << "espeakEVENT_WORD";
        break;
      case espeakEVENT_SENTENCE:
        std::cout << "espeakEVENT_SENTENCE";
        break;
      case espeakEVENT_MARK:
        std::cout << "espeakEVENT_MARK";
        break;
      case espeakEVENT_PLAY:
        std::cout << "espeakEVENT_PLAY";
        break;
      case espeakEVENT_END:
        std::cout << "espeakEVENT_END";
        break;
      case espeakEVENT_MSG_TERMINATED:
        std::cout << "espeakEVENT_MSG_TERMINATED";
        break;
      case espeakEVENT_PHONEME:
        std::cout << "espeakEVENT_PHONEME";
        break;
      case espeakEVENT_SAMPLERATE:
        std::cout << "espeakEVENT_SAMPLERATE";
        break;
      default:
        break;
    }
  }
  std::cout << std::endl;
  return 0;
}

static void speech(std::string hyp) {
    Size = hyp.length();
    espeak_SetSynthCallback(SynthCallback);
    espeak_Synth(hyp.c_str(), Size, position, position_type, end_position, flags,unique_identifier, user_data );
    espeak_Synchronize( );
}

int main() {
  initFuncs();
  std::cout << "Start" << std::endl;
  speech(text.c_str());
  std::cout << "End" << std::endl;
  return 0;
}

控制台输出的定时与音频输出相匹配。当您使用C++时,您应该使用它的工具和特性,如字符串、COUT,而不是PrtTf和智能指针,以避免类似的问题。

可以将MSGY终止事件发布为最后一个事件。它可以通知呼叫程序清除与消息相关的用户数据。因此,如果必须停止合成,则会为每个带有MSG_TERMINATED事件的挂起消息调用回调函数。来自@ThomasSablik:我编辑了我的问题并添加了完整的代码。我试图在代码中使用'if-espeak_EVENT_TYPE==espeakEVENT_MSG_TERMINATED'行,但它给了我错误错误错误:如果espeak_EVENT_TYPE==espeakEVENT_MSG_TERMINATED,则在'=='标记之前应该有一个主表达式,如果espeak_EVENT_==espeakEVENT_MSG_TERMINATED,对不起,我到现在还没有,我现在想读你的答案。谢谢你,希望它能工作。我测试了你的代码,但我认为有问题。我感兴趣的事情是这样的:1.Pocketsphenx识别一个单词并将其存储在hyp中。2.我通过语音功能将hyp传递给espeak。3.语音功能暂停后,espeak读取hyp和其余代码。但是,当我必须在espeak_Synth之前调用espeak_SetSynth回调时,我无法在步骤3中达到我的目的,并且在espeak结束讲话之前,程序不会暂停!使用espeak_SetSynthCallback,可以为espeak_Synth设置回调函数。当事件espeakEVENT\u MSG\u终止时,回调函数将启动其余代码。这意味着,espeak结束讲话,您可以继续您的节目。
Start
Callback: espeakEVENT_SENTENCE
Callback: espeakEVENT_WORD
Callback: espeakEVENT_WORD
Callback: espeakEVENT_WORD
Callback: espeakEVENT_WORD
Callback: espeakEVENT_WORD
Callback: espeakEVENT_END
Callback: espeakEVENT_MSG_TERMINATED
End