我有一个语音识别程序,它是一个基于连续的语音识别(来源: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之间进行通信,但我的语音识别不再提供输出。 :(
任何人都可以建议,如何平行运行这两个连续的程序?
答案 0 :(得分:1)
循环的第一部分使用recvfrom
和sendto
函数。这些是阻止 I / O功能。也就是说,在收到或发送所请求的数据之前,他们不会返回。
通过将两个活动放在同一个循环中,您确保每个传入网络读取只能执行一个语音活动,相反,每个语音会话只能进行一次网络事务。
这个问题有两种解决方案:
为每个活动使用不同的主题或流程。
使用非阻塞I / O.
您可以通过将网络代码全部包装在一个大的if
语句中来使网络代码无阻塞,该语句仅在select
系统调用表明读取不会阻塞时才会运行。你可以通过调整cont_ad_read
循环来阻止语音输入,我想(但是没有检查过)。
但是,如果这个活动不相关(即,一个不依赖于另一个),我认为多个线程将是更好的选择。