Как использовать espeak_EVENT_TYPE; - PullRequest
0 голосов
/ 28 апреля 2018

Я ищу способ узнать, когда espeak закончил, он говорит. Кто-то сказал использовать espeakEVENT_MSG_TERMINATED. Но когда я пытаюсь поместить эту часть в мой код, это дает мне эту ошибку:

#include <espeak/speak_lib.h>

espeak_EVENT_TYPE;

    if( espeak_EVENT_TYPE == espeakEVENT_MSG_TERMINATED)
    {
    do something;
    }

application.cpp: 31: 1: ошибка: объявление ничего не объявляет [-fpermissive] espeak_EVENT_TYPE; ^ application.cpp: в функции 'Void speech (char *)': application.cpp: 116: 27: ошибка: ожидается первичное выражение перед токеном ‘==’ if (espeak_EVENT_TYPE == espeakEVENT_MSG_TERMINATED)

РЕДАКТИРОВАТЬ: я использую этот простой код для использования espeak:

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


espeak_POSITION_TYPE position_type;
espeak_AUDIO_OUTPUT output;
char *path=NULL;
int Buflength = 1000, Options=0;
void* user_data;
t_espeak_callback *SynthCallback;
espeak_PARAMETER Parm;



char Voice[] = {"English"};


char text[30] = {"this is an english text"};
unsigned int Size,position=0, end_position=0, flags=espeakCHARS_AUTO, *unique_identifier;




int main(int argc, char* argv[] ) 
{
    output = AUDIO_OUTPUT_PLAYBACK;
    espeak_Initialize(output, Buflength, path, AUDIO_OUTPUT_SYNCHRONOUS ); //Options ); 
    espeak_SetVoiceByName(Voice);
    const char *langNativeString = "en";
    espeak_VOICE voice = {0};
  //  memset(&voice, 0, sizeof(espeak_VOICE));
        voice.languages = langNativeString;
        voice.name = "US";
        voice.variant = 2;
        voice.gender = 1;
        espeak_SetVoiceByProperties(&voice);
    Size = strlen(text)+1;    

    espeak_Synth( text, Size, position, position_type, end_position, flags,unique_identifier, user_data );
    espeak_Synchronize( );

    return 0;
}

Edit2:

#include <stdio.h>
#include <string.h>
#include <assert.h>

#include <sphinxbase/err.h>
#include <sphinxbase/ad.h>

#include <espeak/speak_lib.h>
#include <string>
#include <iostream>
using namespace std;

#include "pocketsphinx.h"
static ps_decoder_t *ps;
static cmd_ln_t *config;
static FILE *rawfd;

ad_rec_t *ad;

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

static void initFuncs()
{

    output = AUDIO_OUTPUT_PLAYBACK;
    espeak_Initialize(output, Buflength, path, AUDIO_OUTPUT_SYNCHRONOUS ); 
    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);

}

int receive_espeak_events(short *wav, int numsamples, espeak_EVENT *event)
{
    while (event->type != espeakEVENT_LIST_TERMINATED) {
        if (event->type == espeakEVENT_MSG_TERMINATED) {
            /* do something */
            ad_start_rec(ad);
        }
        ++event; // Examine the next event.
    }
    return 0; // Continue speaking.
}

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_SetSynthCallback(receive_espeak_events);
    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=0;

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

        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) 
            {
///////////////////I am passing hyp to espeak heere ////////////////////
             ad_stop_rec(ad);
             speech(hyp);

                printf("%s\n",hyp);
                fflush(stdout);
            //    sleep_msec(3000);

            }

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

        }
    }//for
    ad_close(ad);
}

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

                 config = cmd_ln_init(NULL, ps_args(), TRUE,
                 "-hmm", "/home/m/myrobot3/robot/model_parameters/robot.cd_cont_1000",
                     "-lm","/home/m/myrobot3/robot/etc/robot.lm.bin",
                     "-dict", "/home/m/myrobot3/robot/etc/robot.dic",
                     NULL);

    ps = ps_init(config);
    recognize_from_microphone();

    ps_free(ps);
    cmd_ln_free_r(config);

    return 0;
}

ОШИБКА:

FATAL: "application.cpp", строка 163: не удалось прочитать аудио

1 Ответ

0 голосов
/ 28 апреля 2018
espeak_EVENT_TYPE;

Эта строка не имеет смысла для компилятора. espeak_EVENT_TYPE - это тип данных. Это не переменная, которую можно сравнить со значением типа espeakEVENT_MSG_TERMINATED. Чтобы объявить переменную, синтаксис должен быть:

espeak_EVENT_TYPE an_event_type {};
if (an_event_type == espeakEVENT_MSG_TERMINATED) {
/* ... */

Однако, если мы сделаем это, то переменная an_event_type, которую мы только что создали, фактически не будет содержать никакой информации о каком-либо реальном событии espeak. И это, конечно, не скажет ничего о том, закончено ли какое-либо фактическое сообщение или нет.

Получение информации о реальном событии от espeak

Чтобы получить информацию о том, завершено ли сообщение, программе необходимо получить переменную типа espeak_EVENT_TYPE из библиотеки espeak.

Просматривая этот заголовок , espeak_EVENT_TYPE используется как часть структуры espeak_EVENT. Для получения уведомлений espeak_EVENT необходимо написать функцию, которая будет вызываться библиотекой espeak. (Это называется функцией обратного вызова). Затем функция обратного вызова регистрируется в библиотеке путем вызова espeak_SetSynthCallback.

Из того же заголовка прототип функции обратного вызова должен выглядеть следующим образом:

int SynthCallback (короткие * wav, int numsamples, espeak_EVENT * события);

wav: данные речевого звука, которые были созданы. НОЛЬ указывает на то, что синтез завершен.

numsamples: количество записей в wav. Это число может варьироваться, может быть меньше, чем значение, подразумеваемое параметром buflength, заданным в> espeak_Initialize, и иногда может быть равно нулю (что НЕ указывает конец синтеза).

events: массив элементов espeak_EVENT, которые указывают слово и события предложения, а также происхождение if и элементы в тексте. Список событий заканчивается событием типа> = 0.

Обратный вызов возвращает: 0 = продолжить синтез, 1 = прервать синтез.

Для этого нам нужна функция, которая перебирает переменную events, как если бы она была массивом, до тех пор, пока не встретит событие типа 0. Затем функция должна вернуть 0, чтобы продолжить речевые действия.

int receive_espeak_events(short *wav, int numsamples, espeak_EVENT *event)
{
    while (event->type != espeakEVENT_LIST_TERMINATED) {
        if (event->type == espeakEVENT_MSG_TERMINATED) {
            /* do something */
        }
        ++event; // Examine the next event.
    }
    return 0; // Continue speaking.
}

Чтобы заставить espeak вызывать эту функцию, передайте функцию в espeak_SetSynthCallback перед началом любых операций синтеза.

espeak_SetSynthCallback(receive_espeak_events);
...