Я пытаюсь распознать голоса с микрофона по pocketsphinx
и передать его через espeak
, чтобы сказать, что он распознал в режиме реального времени / непрерывной речи (я имею в виду, что пользователь произносит слово / предложение, карманный сфинкс распознает его и собирает он внутри char* hyp
, затем передает функцию hyp
в speech()
, которая использует espeak
, чтобы сказать, что находится внутри hyp
. Но я не знаю, почему я получаю
Не удалось прочитать аудио
В этой части кода:
if ((k = ad_read(ad, adbuf, 2048)) < 0)
E_FATAL("Failed to read audio\n");
Это полный код:
static ps_decoder_t *ps;
static cmd_ln_t *config;
static FILE *rawfd;
ad_rec_t *ad;
char *hyp;
espeak_POSITION_TYPE position_type;
espeak_AUDIO_OUTPUT output;
char *path=NULL;
int Buflength = 2048, 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 after_speech()
{
espeak_Synth( hyp, Size, position, position_type, end_position, flags,unique_identifier, user_data );
espeak_Synchronize( );
ad_start_rec(ad);
}
int receive_espeak_events(short *wav, int numsamples, espeak_EVENT *event)
{
while (event->type != espeakEVENT_LIST_TERMINATED)
{
if (event->type == espeakEVENT_MSG_TERMINATED)
{
after_speech();
}
++event;
}
return 0;
}
static void initFuncs()
{
espeak_Initialize(output, Buflength, path, AUDIO_OUTPUT_PLAYBACK ); //AUDIO_OUTPUT_SYNCHRONOUS ); //Options );
espeak_SetVoiceByName(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_SetSynthCallback(receive_espeak_events);
}
static void recognize_from_microphone()
{
int16 adbuf[2048];
uint8 utt_started, in_speech;
int32 k;
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)
{
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 loop
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;
}
ПРИМЕЧАНИЕ: я использовал espeak_SetSynthCallback(receive_espeak_events);
, потому что я должен pause
прослушивать новые голоса карманного сфинкса, пока espeak
не прекратит говорить о предыдущем распознанном голосе. Поэтому я попытался ad_stop_rec(ad);
после нахождения нового hyp()
внутри цикла for(;;)
, затем попытался ad_start_rec(ad);
, когда espeakEVENT_MSG_TERMINATED
произошло внутри обратного вызова receive_espeak_events
.