【发布时间】:2014-11-10 07:50:30
【问题描述】:
我有一个基于连续语音识别的语音识别程序(来源:CMU SPHINX) 它包含一个无限循环,如下所示;
for (;;) {
wait for start of next utterance;
decode utterance until silence of at least 1 sec observed;
print utterance result;
}
// Partial code where i tried to do the both operation -----
recognize_from_microphone()
{
ad_rec_t *ad;
int16 adbuf[4096];
int32 k, ts, rem;
char const *hyp;
char const *uttid;
cont_ad_t *cont;
char word[256];
int counter_correct;
int Nummer1, Nummer2, Nummer3, Nummer4,id;
int token = 500;
struct sockaddr_in my_addr, cli_addr[2],cli_temp;
int sockfd;
socklen_t slen[2],slen_temp;
slen[0]=sizeof(cli_addr[0]);
slen[1]=sizeof(cli_addr[1]);
slen_temp = sizeof(cli_temp);
char buf[BUFLEN];
int clients = 0;
int client_port[2];
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");
/* Initialize continuous listening module */
if ((cont = cont_ad_init(ad, ad_read)) == NULL)
E_FATAL("Failed to initialize voice activity detection\n");
if (ad_start_rec(ad) < 0)
E_FATAL("Failed to start recording\n");
if (cont_ad_calib(cont) < 0)
E_FATAL("Failed to calibrate voice activity detection\n");
printf("\n\n");
system("setterm -bold on");
if ((sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))==-1)
{
printf("test\n");
err("socket");
}else{
printf("Server : Socket() successful\n");
}
bzero(&my_addr, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(PORT);
my_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(sockfd, (struct sockaddr* ) &my_addr, sizeof(my_addr))==-1)
{
err("bind");
}else{
printf("Server : bind() successful\n");
}
for (;;) {
//receive
printf("Receiving...\n");
if (recvfrom(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&cli_temp, &slen_temp)==-1) {
err("recvfrom()");
}
if (clients==0) {
cli_addr[0] = cli_temp;
//get client 0 port
client_port[0] = ntohs(cli_addr[0].sin_port);
clients++;
printf("Client 0 connected. Port: %d\n",client_port[0]);
sendto(sockfd, "You are the first client.", 24, 0, (struct sockaddr*)&cli_temp, slen_temp);
}else if (clients==1) {
//new or existing
if (client_port[0]==ntohs(cli_temp.sin_port)) {
//send back to client 0 that nobody else connected yet
sendto(sockfd, "You are the first client.", 24, 0, (struct sockaddr*)&cli_addr[0], slen[0]);
printf("Only client\n");
}else
{
//new connection
cli_addr[1] = cli_temp;
client_port[1] = ntohs(cli_addr[1].sin_port);
clients++;
printf("Second client\n");
sendto(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&cli_addr[0], slen[0]);
}
}else{
//there are 2 clients connected here. If we get an error from the sendto then we decrement clients
if (client_port[0]==ntohs(cli_temp.sin_port)) {
//client 0 talking send to client 1
printf("Sedning message to client 1\n");
if (sendto(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&cli_addr[1], slen[1])==-1)
{
clients--;
err("sendto()");
}
}else {
//client 1 talking send to client 0
printf("Sending message to client 0\n");
if (sendto(sockfd, buf, BUFLEN, 0, (struct sockaddr*)&cli_addr[0], slen[1])==-1)
{
clients--;
err("sendto()");
}
}
}
/* Indicate listening for next utterance */
//printf("\nTrainguard Terminal is hearing you ....\n");
fflush(stdout);
fflush(stderr);
/* Wait data for next utterance */
while ((k = cont_ad_read(cont, adbuf, 4096)) == 0)
sleep_msec(100);
if (k < 0)
E_FATAL("Failed to read audio\n");
/*
* Non-zero amount of data received; start recognition of new utterance.
* NULL argument to uttproc_begin_utt => automatic generation of utterance-id.
*/
if (ps_start_utt(ps, NULL) < 0)
E_FATAL("Failed to start utterance\n");
ps_process_raw(ps, adbuf, k, FALSE, FALSE);
//printf(" message - regarding the process begins \n");
fflush(stdout);
/* Note timestamp for this first block of data */
ts = cont->read_ts;
/* Decode utterance until end (marked by a "long" silence, >1sec) */
for (;;) {
/* Read non-silence audio data, if any, from continuous listening module */
if ((k = cont_ad_read(cont, adbuf, 4096)) < 0)
E_FATAL("Failed to read audio\n");
if (k == 0) {
/*
* No speech data available; check current timestamp with most recent
* speech to see if more than 1 sec elapsed. If so, end of utterance.
*/
if ((cont->read_ts - ts) > DEFAULT_SAMPLES_PER_SEC / 4)
break;
}
else {
/* New speech data received; note current timestamp */
ts = cont->read_ts;
}
/*
* Decode whatever data was read above.
*/
rem = ps_process_raw(ps, adbuf, k, FALSE, FALSE);
/* If no work to be done, sleep a bit */
if ((rem == 0) && (k == 0))
sleep_msec(20);
}
/*
* Utterance ended; flush any accumulated, unprocessed A/D data and stop
* listening until current utterance completely decoded
*/
ad_stop_rec(ad);
while (ad_read(ad, adbuf, 4096) >= 0);
cont_ad_reset(cont);
//printf("Processing...\n");
fflush(stdout);
/* Finish decoding, obtain and print result */
ps_end_utt(ps);
hyp = ps_get_hyp(ps, NULL, &uttid);
//printf("%s: %s\n", uttid, hyp);
fflush(stdout);
/* Exit if the word spoken was "THATS ALL". Change string in strcmp() for another phrase. */
if (hyp) {
sscanf(hyp, "%s", word);
if (strcmp(hyp, "LASCHE FAHRPLAN") == 0 &&(token==500) ) {
counter_correct = counter_correct + 1;
printf("LASCHE FAHRPLAN \n");
printf("score %d/%s \n",counter_correct,uttid);
}
}
/* Resume A/D recording for next utterance */
if (ad_start_rec(ad) < 0)
E_FATAL("ad_start_rec failed\n");
}
cont_ad_close(cont);
close(sockfd);
}
// Code ends here
我有另一个服务器-客户端程序,它也包含一个无限循环。它接受来自客户端 A 的数据并将其发送给客户端 B。它还将客户端 B 的特定信息发送给客户端 A。
我想将它们两者结合起来,以便它接受来自客户端 A 的数据并将它们发送给客户端 B,并将来自客户端 B 的特定信息发送给客户端 A。除了当特定命令被告知时,来自客户端的消息A将被修改并发送给客户端B。
我结合了这两个程序,因为它们具有共同的无限循环类型,但是尽管我在客户端 A 和客户端 B 之间正确通信,但我的语音识别不再提供输出。 :(
谁能建议,如何并行运行这两个基于连续的程序?
【问题讨论】:
-
您需要描述如何将它们组合在一起。同样重要的是要说明哪些操作可以“阻止”,哪些不能。
-
您应该尝试将您的代码简化为一个最小的示例。我认为正确的答案是使用套接字和ASIO,但问题太宽泛了。
-
您可以查看
select和poll函数及其用法! -
@ams 请看更新版本语音识别全码是here
-
如果你把printf放回去,你看到它打印
"Trainguard Terminal is hearing you ...."了吗?
标签: c loops for-loop parallel-processing