【问题标题】:Running two programs each having infinite loops in parallel并行运行两个程序,每个程序都有无限循环
【发布时间】: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,但问题太宽泛了。
  • 您可以查看selectpoll 函数及其用法!
  • @ams 请看更新版本语音识别全码是here
  • 如果你把printf放回去,你看到它打印"Trainguard Terminal is hearing you ...."了吗?

标签: c loops for-loop parallel-processing


【解决方案1】:

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

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

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

  1. 为每个活动使用不同的线程或进程。

  2. 使用非阻塞 I/O。

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

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

【讨论】:

  • 非常感谢。客户端A和客户端B应该相互通信..只有当一个命令被识别时,它才应该修改一些数据并将其发送给客户端B。多线程?您的意思是使用 posix/pthread 概念吗?你能分享一个链接我在哪里可以找到一个很好的套接字线程示例?再次感谢
  • 在线程之间共享数据很容易——你只需要小心锁定。有很多例子的好地方here。 ;-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多