📄 adin-cut.c
字号:
trailing silence (shorter than tail margin length) (nc>0,rest_tail>0) The current trailing silence is shorter than the user- specified tail margin length, so the current samples should be processed now as same as the normal speech segment */ #ifdef TMP_FIX_200602 if (!adin_cut_on || is_valid_data == TRUE) {#else if( (!adin_cut_on || is_valid_data == TRUE)#ifdef HAVE_PTHREAD && (!enable_thread || !ignore_speech_while_recog || transfer_online_local)#endif ) {#endif if (nc > 0) { /* if we are in a trailing silence, decrease the counter to detect start of swapbuf[] above */ if (rest_tail < wstep) rest_tail = 0; else rest_tail -= wstep;#ifdef THREAD_DEBUG printf("%d processed, rest_tail=%d\n", wstep, rest_tail);#endif }#ifdef TMP_FIX_200602 if (ad_process != NULL#ifdef HAVE_PTHREAD && (!enable_thread || !ignore_speech_while_recog || transfer_online_local)#endif ) {#else if ( ad_process != NULL ) {#endif#ifdef THREAD_DEBUG printf("callback for input sample [%d-%d]\n", i, i+wstep);#endif /* call external function */ ad_process_ret = (*ad_process)(&(buffer[i]), wstep); switch(ad_process_ret) { case 1: /* segmentation notification from process callback */#ifdef HAVE_PTHREAD if (enable_thread) { /* in threaded mode, just stop transfer */ pthread_mutex_lock(&mutex); transfer_online = transfer_online_local = FALSE; pthread_mutex_unlock(&mutex); } else { /* in non-threaded mode, set end status and exit loop */ adin_purge(i+wstep); end_status = 1; goto break_input; } break;#else /* in non-threaded mode, set end status and exit loop */ adin_purge(i+wstep); end_status = 1; goto break_input;#endif case -1: /* error occured in callback */ /* set end status and exit loop */ end_status = -1; goto break_input; } } } } /* end of current segment processing */ if (adin_cut_on && is_valid_data && nc >= nc_max) { /*************************************/ /* process on, trailing silence over */ /* = end of input segment */ /*************************************/#ifdef THREAD_DEBUG printf("detect off\n");#endif /* end input by silence */ is_valid_data = FALSE; /* turn off processing */ sblen = 0;#ifdef HAVE_PTHREAD if (enable_thread) { /* just stop transfer */ pthread_mutex_lock(&mutex); transfer_online = transfer_online_local = FALSE; pthread_mutex_unlock(&mutex); } else { adin_purge(i+wstep); end_status = 1; goto break_input; }#else adin_purge(i+wstep); end_status = 1; goto break_input;#endif } /*********************************************************/ /* end of processing buffer[0..current_len] by wstep step */ /*********************************************************/ i += wstep; /* increment to next wstep samples */ } /* purge processed samples and update queue */ adin_purge(i); /* end of input by end of stream */ if (end_of_stream && bp == 0) break; }break_input: /****************/ /* pause input */ /****************/ /* stop speech input */ if (ad_pause != NULL) { if ((*ad_pause)() == FALSE) { j_printerr("Error: failed to pause recording\n"); end_status = -1; } } if (end_of_stream) { /* input already ends */ if (bp == 0) { /* rest buffer successfully flushed */ /* reset status */ if (adin_cut_on) end_count_zc_e(); need_init = TRUE; /* bufer status shoule be reset at next call */ } end_status = (bp) ? 1 : 0; } return(end_status);}#ifdef HAVE_PTHREAD/***********************//* threading functions *//***********************//*************************//* adin thread functions *//*************************//** * Callback for storing triggered samples to @a speech in A/D-in thread. * * @param now [in] triggered fragment * @param len [in] length of above * * @return always 0, to tell caller to continue recording. */static intadin_store_buffer(SP16 *now, int len){ if (speechlen + len > MAXSPEECHLEN) { /* just mark as overflowed, and continue this thread */ pthread_mutex_lock(&mutex); adinthread_buffer_overflowed = TRUE; pthread_mutex_unlock(&mutex); return(0); } pthread_mutex_lock(&mutex); memcpy(&(speech[speechlen]), now, len * sizeof(SP16)); speechlen += len; pthread_mutex_unlock(&mutex);#ifdef THREAD_DEBUG printf("input: stored %d samples, total=%d\n", len, speechlen);#endif /* output progress bar in dots */ /*if ((++dotcount) % 3 == 1) j_printerr(".");*/ return(0); /* continue */}/** * A/D-in thread main function: just call adin_cut() with storing function. * * @param dummy [in] a dummy data, not used. */voidadin_thread_input_main(void *dummy){ adin_cut(adin_store_buffer, NULL);}/** * Start new A/D-in thread, and also initialize buffer @a speech. * */static voidadin_thread_create(){ /* init storing buffer */ speechlen = 0; speech = (SP16 *)mymalloc(sizeof(SP16) * MAXSPEECHLEN); transfer_online = FALSE; /* tell adin-mic thread to wait at initial */ adinthread_buffer_overflowed = FALSE; if (pthread_mutex_init(&(mutex), NULL) != 0) { /* error */ j_error("Error: pthread: cannot initialize mutex\n"); } if (pthread_create(&adin_thread, NULL, (void *)adin_thread_input_main, NULL) != 0) { j_error("Error: pthread: failed to create AD-in thread\n"); } if (pthread_detach(adin_thread) != 0) { /* not join, run forever */ j_error("Error: pthread: failed to detach AD-in thread\n"); } j_printerr("AD-in thread created\n");}/****************************//* process thread functions *//****************************//* used for module mode: return value: -2 = input cancellation forced by control module *//** * @brief Main function of processing triggered samples at main thread. * * Wait for the new samples to be stored in @a speech by A/D-in thread, * and if found, process them. * * @param ad_process [in] function to process the recorded fragments * @param ad_check [in] function to be called periodically for checking * incoming user command in module mode. * * @return -2 when input terminated by result of the @a ad_check function, * -1 on error, 0 on end of stream, >0 if successfully segmented. */static intadin_thread_process(int (*ad_process)(SP16 *, int), int (*ad_check)()){ int prev_len, nowlen; int ad_process_ret; int i; boolean overflowed_p; boolean transfer_online_local; /* reset storing buffer --- input while recognition will be ignored */ pthread_mutex_lock(&mutex); /*if (speechlen == 0) transfer_online = TRUE;*/ /* tell adin-mic thread to start recording */ transfer_online = TRUE;#ifdef THREAD_DEBUG printf("process: reset, speechlen = %d, online=%d\n", speechlen, transfer_online);#endif pthread_mutex_unlock(&mutex); /* main processing loop */ prev_len = 0; for(;;) { /* get current length (locking) */ pthread_mutex_lock(&mutex); nowlen = speechlen; overflowed_p = adinthread_buffer_overflowed; transfer_online_local = transfer_online; pthread_mutex_unlock(&mutex); /* check if other input thread has overflowed */ if (overflowed_p) { j_printerr("Warning: too long input (> %d samples), segmented now\n", MAXSPEECHLEN); /* segment input here */ pthread_mutex_lock(&mutex); adinthread_buffer_overflowed = FALSE; speechlen = 0; transfer_online = transfer_online_local = FALSE; pthread_mutex_unlock(&mutex); return(1); /* return with segmented status */ } /* callback poll */ if (ad_check != NULL) { if ((i = (*ad_check)()) < 0) { if ((i == -1 && nowlen == 0) || i == -2) { pthread_mutex_lock(&mutex); transfer_online = transfer_online_local = FALSE; speechlen = 0; pthread_mutex_unlock(&mutex); return(-2); } } } if (prev_len < nowlen) {#ifdef THREAD_DEBUG printf("process: proceed [%d-%d]\n",prev_len, nowlen);#endif /* got new sample, process */ /* As the speech[] buffer is monotonously increase, content of speech buffer [prev_len..nowlen] would not alter in both threads So locking is not needed while processing. */ /*printf("main: read %d-%d\n", prev_len, nowlen);*/ if (ad_process != NULL) { ad_process_ret = (*ad_process)(&(speech[prev_len]), nowlen - prev_len);#ifdef THREAD_DEBUG printf("ad_process_ret=%d\n",ad_process_ret);#endif switch(ad_process_ret) { case 1: /* segmented */ /* segmented by callback function */ /* purge processed samples and keep transfering */ pthread_mutex_lock(&mutex); if(speechlen > nowlen) { memmove(buffer, &(buffer[nowlen]), (speechlen - nowlen) * sizeof(SP16)); speechlen = speechlen - nowlen; } else { speechlen = 0; } transfer_online = transfer_online_local = FALSE; pthread_mutex_unlock(&mutex); /* keep transfering */ return(1); /* return with segmented status */ case -1: /* error */ pthread_mutex_lock(&mutex); transfer_online = transfer_online_local = FALSE; pthread_mutex_unlock(&mutex); return(-1); /* return with error */ } } prev_len = nowlen; } else { if (transfer_online_local == FALSE) { /* segmented by zero-cross */ /* reset storing buffer for next input */ pthread_mutex_lock(&mutex); speechlen = 0; pthread_mutex_unlock(&mutex); break; } usleep(100000); /* wait = 0.1sec*/ } } /* as threading assumes infinite input */ /* return value should be 1 (segmented) */ return(1);}#endif /* HAVE_PTHREAD *//** * @brief Top function to start input processing * * If threading mode is enabled, this function simply enters to * adin_thread_process() to process triggered samples detected by * another running A/D-in thread. * * If threading mode is not available or disabled by either device requirement * or OS capability, this function simply calls adin_cut() to detect speech * segment from input device and process them concurrently by one process. * * @param ad_process [in] function to process the recorded fragments * @param ad_check [in] function to be called periodically for checking * incoming user command in module mode. * * @return the same as adin_thread_process() in threading mode, or * same as adin_cut() when non-threaded mode. */intadin_go(int (*ad_process)(SP16 *, int), int (*ad_check)()){#ifdef HAVE_PTHREAD if (enable_thread) { return(adin_thread_process(ad_process, ad_check)); }#endif return(adin_cut(ad_process, ad_check));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -