运行两个程序,每个程序并行有无限循环

时间:2014-09-16 14:01:05

标签: c loops for-loop parallel-processing

我有一个语音识别程序,它是一个基于连续的语音识别(来源: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之间进行通信,但我的语音识别不再提供输出。 :(

任何人都可以建议,如何平行运行这两个连续的程序?

1 个答案:

答案 0 :(得分:1)

循环的第一部分使用recvfromsendto函数。这些是阻止 I / O功能。也就是说,在收到或发送所请求的数据之前,他们不会返回。

通过将两个活动放在同一个循环中,您确保每个传入网络读取只能执行一个语音活动,相反,每个语音会话只能进行一次网络事务。

这个问题有两种解决方案:

  1. 为每个活动使用不同的主题或流程。

  2. 使用非阻塞I / O.

  3. 您可以通过将网络代码全部包装在一个大的if语句中来使网络代码无阻塞,该语句仅在select系统调用表明读取不会阻塞时才会运行。你可以通过调整cont_ad_read循环来阻止语音输入,我想(但是没有检查过)。

    但是,如果这个活动不相关(即,一个不依赖于另一个),我认为多个线程将是更好的选择。