00001
00101
00102
00103
00104
00105
00106
00107
00108 #include <julius/julius.h>
00109 #ifdef HAVE_PTHREAD
00110 #include <pthread.h>
00111 #endif
00112
00114 #undef THREAD_DEBUG
00116 #define TMP_FIX_200602
00117
00137 boolean
00138 adin_setup_param(ADIn *adin, Jconf *jconf)
00139 {
00140 float samples_in_msec;
00141 int freq;
00142
00143 if (jconf->input.sfreq <= 0) {
00144 jlog("ERROR: adin_setup_param: going to set smpfreq to %d\n", jconf->input.sfreq);
00145 return FALSE;
00146 }
00147 if (jconf->detect.silence_cut < 2) {
00148 adin->adin_cut_on = (jconf->detect.silence_cut == 1) ? TRUE : FALSE;
00149 } else {
00150 adin->adin_cut_on = adin->silence_cut_default;
00151 }
00152 adin->strip_flag = jconf->preprocess.strip_zero_sample;
00153 adin->thres = jconf->detect.level_thres;
00154 #ifdef HAVE_PTHREAD
00155 if (adin->enable_thread && jconf->decodeopt.segment) {
00156 adin->ignore_speech_while_recog = FALSE;
00157 } else {
00158 adin->ignore_speech_while_recog = TRUE;
00159 }
00160 #endif
00161 adin->need_zmean = jconf->preprocess.use_zmean;
00162
00163 freq = jconf->input.sfreq;
00164 samples_in_msec = (float) freq / (float)1000.0;
00165
00166 adin->c_length = (int)((float)jconf->detect.head_margin_msec * samples_in_msec);
00167
00168 adin->noise_zerocross = jconf->detect.zero_cross_num * adin->c_length / freq;
00169
00170 adin->nc_max = (int)((float)(jconf->detect.tail_margin_msec * samples_in_msec / (float)DEFAULT_WSTEP)) + 2;
00171 adin->sbsize = jconf->detect.tail_margin_msec * samples_in_msec + (adin->c_length * jconf->detect.zero_cross_num / 200);
00172 adin->c_offset = 0;
00173
00174 #ifdef HAVE_PTHREAD
00175 adin->transfer_online = FALSE;
00176 adin->speech = NULL;
00177 #endif
00178
00179
00180
00181
00182 adin->buffer = (SP16 *)mymalloc(sizeof(SP16) * MAXSPEECHLEN);
00183 adin->cbuf = (SP16 *)mymalloc(sizeof(SP16) * adin->c_length);
00184 adin->swapbuf = (SP16 *)mymalloc(sizeof(SP16) * adin->sbsize);
00185 if (adin->down_sample) {
00186 adin->io_rate = 3;
00187 adin->buffer48 = (SP16 *)mymalloc(sizeof(SP16) * MAXSPEECHLEN * adin->io_rate);
00188 }
00189 if (adin->adin_cut_on) {
00190 init_count_zc_e(&(adin->zc), adin->c_length);
00191 }
00192
00193 adin->need_init = TRUE;
00194
00195 adin->rehash = FALSE;
00196
00197 adin->total_captured_len = 0;
00198
00199 return TRUE;
00200
00201 }
00202
00215 static void
00216 adin_purge(ADIn *a, int from)
00217 {
00218 if (from > 0 && a->current_len - from > 0) {
00219 memmove(a->buffer, &(a->buffer[from]), (a->current_len - from) * sizeof(SP16));
00220 }
00221 a->bp = a->current_len - from;
00222 }
00223
00296 static int
00297 adin_cut(int (*ad_process)(SP16 *, int, Recog *), int (*ad_check)(Recog *), Recog *recog)
00298 {
00299 ADIn *a;
00300 int i;
00301 int ad_process_ret;
00302 int imax, len, cnt;
00303 int wstep;
00304 int end_status;
00305 boolean transfer_online_local;
00306 int zc;
00307
00308 a = recog->adin;
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322 if (a->need_init) {
00323 a->bpmax = MAXSPEECHLEN;
00324 a->bp = 0;
00325 a->is_valid_data = FALSE;
00326
00327 if (a->adin_cut_on) {
00328 reset_count_zc_e(&(a->zc), a->thres, a->c_length, a->c_offset);
00329 }
00330 a->end_of_stream = FALSE;
00331 a->nc = 0;
00332 a->sblen = 0;
00333 a->need_init = FALSE;
00334 }
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346 for (;;) {
00347
00348
00349
00350
00351 if (a->end_of_stream) {
00352
00353 a->current_len = a->bp;
00354 } else {
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370 if (a->down_sample) {
00371
00372 cnt = (*(a->ad_read))(a->buffer48, (a->bpmax - a->bp) * a->io_rate);
00373 } else {
00374 cnt = (*(a->ad_read))(&(a->buffer[a->bp]), a->bpmax - a->bp);
00375 }
00376 if (cnt < 0) {
00377
00378 switch(cnt) {
00379 case -1:
00380 a->input_side_segment = FALSE;
00381 end_status = 0;
00382 break;
00383 case -2:
00384 a->input_side_segment = FALSE;
00385 end_status = -1;
00386 break;
00387 case -3:
00388 a->input_side_segment = TRUE;
00389 end_status = 0;
00390 }
00391
00392
00393
00394
00395 a->end_of_stream = TRUE;
00396 cnt = 0;
00397
00398 if (a->bp == 0) break;
00399 }
00400 if (a->down_sample && cnt != 0) {
00401
00402 cnt = ds48to16(&(a->buffer[a->bp]), a->buffer48, cnt, a->bpmax - a->bp, a->ds);
00403 if (cnt < 0) {
00404 jlog("ERROR: adin_cut: error in down sampling\n");
00405 end_status = -1;
00406 a->end_of_stream = TRUE;
00407 cnt = 0;
00408 if (a->bp == 0) break;
00409 }
00410 }
00411
00412
00413
00414
00415
00416
00417 if (cnt > 0) {
00418 #ifdef ENABLE_PLUGIN
00419 plugin_exec_adin_captured(&(a->buffer[a->bp]), cnt);
00420 #endif
00421 callback_exec_adin(CALLBACK_ADIN_CAPTURED, recog, &(a->buffer[a->bp]), cnt);
00422
00423 a->total_captured_len += cnt;
00424 }
00425
00426
00427
00428
00429 if (cnt > 0) {
00430 if (a->strip_flag) {
00431
00432 len = strip_zero(&(a->buffer[a->bp]), cnt);
00433 if (len != cnt) cnt = len;
00434 }
00435 if (a->need_zmean) {
00436
00437 sub_zmean(&(a->buffer[a->bp]), cnt);
00438 }
00439 }
00440
00441
00442 a->current_len = a->bp + cnt;
00443 }
00444 #ifdef THREAD_DEBUG
00445 if (a->end_of_stream) {
00446 jlog("DEBUG: adin_cut: stream already ended\n");
00447 }
00448 if (cnt > 0) {
00449 jlog("DEBUG: adin_cut: get %d samples [%d-%d]\n", a->current_len - a->bp, a->bp, a->current_len);
00450 }
00451 #endif
00452
00453
00454
00455
00456
00457
00458
00459 if (ad_check != NULL
00460 #ifdef HAVE_PTHREAD
00461 && !a->enable_thread
00462 #endif
00463 ) {
00464
00465 if ((i = (*ad_check)(recog)) < 0) {
00466
00467 if (i == -2 ||
00468 (i == -1 && a->is_valid_data == FALSE)) {
00469 end_status = -2;
00470
00471 if (a->current_len > 0) {
00472 callback_exec(CALLBACK_EVENT_SPEECH_STOP, recog);
00473 }
00474 a->need_init = TRUE;
00475 goto break_input;
00476 }
00477 }
00478 }
00479
00480
00481
00482
00483 if (a->current_len == 0) continue;
00484
00485
00486
00487
00488
00489 if (!a->adin_cut_on && a->is_valid_data == FALSE && a->current_len > 0) {
00490 a->is_valid_data = TRUE;
00491 callback_exec(CALLBACK_EVENT_SPEECH_START, recog);
00492 }
00493
00494
00495
00496
00497
00498 wstep = DEFAULT_WSTEP;
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511 #ifdef HAVE_PTHREAD
00512 if (a->enable_thread) imax = a->current_len;
00513 else imax = (a->current_len < wstep) ? a->current_len : wstep;
00514 #else
00515 imax = (a->current_len < wstep) ? a->current_len : wstep;
00516 #endif
00517
00518
00519 if (wstep > a->current_len) wstep = a->current_len;
00520
00521 #ifdef THREAD_DEBUG
00522 jlog("DEBUG: process %d samples by %d step\n", imax, wstep);
00523 #endif
00524
00525 #ifdef HAVE_PTHREAD
00526 if (a->enable_thread) {
00527
00528 pthread_mutex_lock(&(a->mutex));
00529 transfer_online_local = a->transfer_online;
00530 pthread_mutex_unlock(&(a->mutex));
00531 }
00532 #endif
00533
00534
00535
00536
00537 i = 0;
00538 while (i + wstep <= imax) {
00539
00540 if (a->adin_cut_on) {
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551 zc = count_zc_e(&(a->zc), &(a->buffer[i]), wstep);
00552
00553 if (zc > a->noise_zerocross) {
00554
00555 if (a->is_valid_data == FALSE) {
00556
00557
00558
00559 a->is_valid_data = TRUE;
00560 a->nc = 0;
00561 #ifdef THREAD_DEBUG
00562 jlog("DEBUG: detect on\n");
00563 #endif
00564
00565 a->last_trigger_sample = a->total_captured_len - a->current_len + i + wstep - a->zc.valid_len;
00566 callback_exec(CALLBACK_EVENT_SPEECH_START, recog);
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576 if ( ad_process != NULL
00577 #ifdef HAVE_PTHREAD
00578 && (!a->enable_thread || !a->ignore_speech_while_recog || transfer_online_local)
00579 #endif
00580 ) {
00581
00582 zc_copy_buffer(&(a->zc), a->cbuf, &len);
00583
00584
00585
00586
00587
00588 if (len - wstep > 0) {
00589 #ifdef THREAD_DEBUG
00590 jlog("DEBUG: callback for buffered samples (%d bytes)\n", len - wstep);
00591 #endif
00592 #ifdef ENABLE_PLUGIN
00593 plugin_exec_adin_triggered(a->cbuf, len - wstep);
00594 #endif
00595 callback_exec_adin(CALLBACK_ADIN_TRIGGERED, recog, a->cbuf, len - wstep);
00596 ad_process_ret = (*ad_process)(a->cbuf, len - wstep, recog);
00597 switch(ad_process_ret) {
00598 case 1:
00599 #ifdef HAVE_PTHREAD
00600 if (a->enable_thread) {
00601
00602 pthread_mutex_lock(&(a->mutex));
00603 a->transfer_online = transfer_online_local = FALSE;
00604 pthread_mutex_unlock(&(a->mutex));
00605 } else {
00606
00607 end_status = 2;
00608 adin_purge(a, i);
00609 goto break_input;
00610 }
00611 break;
00612 #else
00613
00614 end_status = 2;
00615 adin_purge(a, i);
00616 goto break_input;
00617 #endif
00618 case -1:
00619
00620 end_status = -1;
00621 goto break_input;
00622 }
00623 }
00624 }
00625
00626 } else {
00627
00628
00629
00630
00631 if (a->nc > 0) {
00632
00633
00634
00635
00636
00637 #ifdef THREAD_DEBUG
00638 jlog("DEBUG: re-triggered\n");
00639 #endif
00640
00641 a->nc = 0;
00642
00643 #ifdef TMP_FIX_200602
00644 if (ad_process != NULL
00645 #ifdef HAVE_PTHREAD
00646 && (!a->enable_thread || !a->ignore_speech_while_recog || transfer_online_local)
00647 #endif
00648 ) {
00649 #endif
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661 if (a->sblen > 0) {
00662 #ifdef THREAD_DEBUG
00663 jlog("DEBUG: callback for swapped %d samples\n", a->sblen);
00664 #endif
00665 #ifdef ENABLE_PLUGIN
00666 plugin_exec_adin_triggered(a->swapbuf, a->sblen);
00667 #endif
00668 callback_exec_adin(CALLBACK_ADIN_TRIGGERED, recog, a->swapbuf, a->sblen);
00669 ad_process_ret = (*ad_process)(a->swapbuf, a->sblen, recog);
00670 a->sblen = 0;
00671 switch(ad_process_ret) {
00672 case 1:
00673 #ifdef HAVE_PTHREAD
00674 if (a->enable_thread) {
00675
00676 pthread_mutex_lock(&(a->mutex));
00677 a->transfer_online = transfer_online_local = FALSE;
00678 pthread_mutex_unlock(&(a->mutex));
00679 } else {
00680
00681 end_status = 2;
00682 adin_purge(a, i);
00683 goto break_input;
00684 }
00685 break;
00686 #else
00687
00688 end_status = 2;
00689 adin_purge(a, i);
00690 goto break_input;
00691 #endif
00692 case -1:
00693
00694 end_status = -1;
00695 goto break_input;
00696 }
00697 }
00698 #ifdef TMP_FIX_200602
00699 }
00700 #endif
00701 }
00702 }
00703 } else if (a->is_valid_data == TRUE) {
00704
00705
00706
00707
00708
00709 #ifdef THREAD_DEBUG
00710 jlog("DEBUG: TRAILING SILENCE\n");
00711 #endif
00712 if (a->nc == 0) {
00713
00714 a->rest_tail = a->sbsize - a->c_length;
00715 a->sblen = 0;
00716 #ifdef THREAD_DEBUG
00717 jlog("DEBUG: start tail silence, rest_tail = %d\n", a->rest_tail);
00718 #endif
00719 }
00720
00721
00722 a->nc++;
00723 }
00724 }
00725
00726
00727
00728
00729
00730
00731 if (a->adin_cut_on && a->is_valid_data && a->nc > 0 && a->rest_tail == 0) {
00732
00733
00734
00735
00736
00737
00738
00739
00740 #ifdef THREAD_DEBUG
00741 jlog("DEBUG: tail silence over, store to swap buffer (nc=%d, rest_tail=%d, sblen=%d-%d)\n", a->nc, a->rest_tail, a->sblen, a->sblen+wstep);
00742 #endif
00743 if (a->sblen + wstep > a->sbsize) {
00744 jlog("ERROR: adin_cut: swap buffer for re-triggering overflow\n");
00745 }
00746 memcpy(&(a->swapbuf[a->sblen]), &(a->buffer[i]), wstep * sizeof(SP16));
00747 a->sblen += wstep;
00748
00749 } else {
00750
00751
00752
00753
00754
00755
00756
00757 #ifdef TMP_FIX_200602
00758 if (!a->adin_cut_on || a->is_valid_data == TRUE) {
00759 #else
00760 if(
00761 (!a->adin_cut_on || a->is_valid_data == TRUE)
00762 #ifdef HAVE_PTHREAD
00763 && (!a->enable_thread || !a->ignore_speech_while_recog || transfer_online_local)
00764 #endif
00765 ) {
00766 #endif
00767 if (a->nc > 0) {
00768
00769
00770 if (a->rest_tail < wstep) a->rest_tail = 0;
00771 else a->rest_tail -= wstep;
00772 #ifdef THREAD_DEBUG
00773 jlog("DEBUG: %d processed, rest_tail=%d\n", wstep, a->rest_tail);
00774 #endif
00775 }
00776 #ifdef TMP_FIX_200602
00777 if (ad_process != NULL
00778 #ifdef HAVE_PTHREAD
00779 && (!a->enable_thread || !a->ignore_speech_while_recog || transfer_online_local)
00780 #endif
00781 ) {
00782
00783 #else
00784 if ( ad_process != NULL ) {
00785 #endif
00786 #ifdef THREAD_DEBUG
00787 jlog("DEBUG: callback for input sample [%d-%d]\n", i, i+wstep);
00788 #endif
00789
00790 #ifdef ENABLE_PLUGIN
00791 plugin_exec_adin_triggered(&(a->buffer[i]), wstep);
00792 #endif
00793 callback_exec_adin(CALLBACK_ADIN_TRIGGERED, recog, &(a->buffer[i]), wstep);
00794 ad_process_ret = (*ad_process)(&(a->buffer[i]), wstep, recog);
00795 switch(ad_process_ret) {
00796 case 1:
00797 #ifdef HAVE_PTHREAD
00798 if (a->enable_thread) {
00799
00800 pthread_mutex_lock(&(a->mutex));
00801 a->transfer_online = transfer_online_local = FALSE;
00802 pthread_mutex_unlock(&(a->mutex));
00803 } else {
00804
00805 adin_purge(a, i+wstep);
00806 end_status = 2;
00807 goto break_input;
00808 }
00809 break;
00810 #else
00811
00812 adin_purge(a, i+wstep);
00813 end_status = 2;
00814 goto break_input;
00815 #endif
00816 case -1:
00817
00818 end_status = -1;
00819 goto break_input;
00820 }
00821 }
00822 }
00823 }
00824
00825
00826 if (a->adin_cut_on && a->is_valid_data && a->nc >= a->nc_max) {
00827
00828
00829
00830
00831 #ifdef THREAD_DEBUG
00832 jlog("DEBUG: detect off\n");
00833 #endif
00834
00835 a->is_valid_data = FALSE;
00836 a->sblen = 0;
00837 callback_exec(CALLBACK_EVENT_SPEECH_STOP, recog);
00838 #ifdef HAVE_PTHREAD
00839 if (a->enable_thread) {
00840 pthread_mutex_lock(&(a->mutex));
00841 a->transfer_online = transfer_online_local = FALSE;
00842 pthread_mutex_unlock(&(a->mutex));
00843 } else {
00844 adin_purge(a, i+wstep);
00845 end_status = 1;
00846 goto break_input;
00847 }
00848 #else
00849 adin_purge(a, i+wstep);
00850 end_status = 1;
00851 goto break_input;
00852 #endif
00853 }
00854
00855
00856
00857
00858 i += wstep;
00859 }
00860
00861
00862 adin_purge(a, i);
00863
00864
00865 if (a->end_of_stream && a->bp == 0) break;
00866 }
00867
00868 break_input:
00869
00870
00871
00872
00873 if (a->end_of_stream) {
00874
00875 callback_exec(CALLBACK_EVENT_SPEECH_STOP, recog);
00876 if (a->bp == 0) {
00877
00878 a->need_init = TRUE;
00879 }
00880 end_status = (a->bp) ? 1 : 0;
00881 }
00882
00883 return(end_status);
00884 }
00885
00886 #ifdef HAVE_PTHREAD
00887
00888
00889
00890
00891
00892
00893
00894
00909 static int
00910 adin_store_buffer(SP16 *now, int len, Recog *recog)
00911 {
00912 ADIn *a;
00913
00914 a = recog->adin;
00915 if (a->speechlen + len > MAXSPEECHLEN) {
00916
00917 pthread_mutex_lock(&(a->mutex));
00918 a->adinthread_buffer_overflowed = TRUE;
00919 pthread_mutex_unlock(&(a->mutex));
00920 return(0);
00921 }
00922 pthread_mutex_lock(&(a->mutex));
00923 memcpy(&(a->speech[a->speechlen]), now, len * sizeof(SP16));
00924 a->speechlen += len;
00925 pthread_mutex_unlock(&(a->mutex));
00926 #ifdef THREAD_DEBUG
00927 jlog("DEBUG: input: stored %d samples, total=%d\n", len, a->speechlen);
00928 #endif
00929
00930 return(0);
00931 }
00932
00943 static void
00944 adin_thread_input_main(void *dummy)
00945 {
00946 Recog *recog;
00947 int ret;
00948
00949 recog = dummy;
00950
00951 ret = adin_cut(adin_store_buffer, NULL, recog);
00952
00953 if (ret == -1) {
00954 jlog("Error: adin thread exit with error\n");
00955 } else if (ret == 0) {
00956 jlog("Stat: adin thread end with EOF\n");
00957 }
00958 recog->adin->adinthread_ended = TRUE;
00959
00960
00961 }
00962
00975 boolean
00976 adin_thread_create(Recog *recog)
00977 {
00978 ADIn *a;
00979
00980 a = recog->adin;
00981
00982
00983 a->speech = (SP16 *)mymalloc(sizeof(SP16) * MAXSPEECHLEN);
00984 a->speechlen = 0;
00985
00986 a->transfer_online = FALSE;
00987 a->adinthread_buffer_overflowed = FALSE;
00988 a->adinthread_ended = FALSE;
00989
00990 if (pthread_mutex_init(&(a->mutex), NULL) != 0) {
00991 jlog("ERROR: adin_thread_create: failed to initialize mutex\n");
00992 return FALSE;
00993 }
00994 if (pthread_create(&(recog->adin->adin_thread), NULL, (void *)adin_thread_input_main, recog) != 0) {
00995 jlog("ERROR: adin_thread_create: failed to create AD-in thread\n");
00996 return FALSE;
00997 }
00998 if (pthread_detach(recog->adin->adin_thread) != 0) {
00999 jlog("ERROR: adin_thread_create: failed to detach AD-in thread\n");
01000 return FALSE;
01001 }
01002 jlog("STAT: AD-in thread created\n");
01003 return TRUE;
01004 }
01005
01018 boolean
01019 adin_thread_cancel(Recog *recog)
01020 {
01021 ADIn *a;
01022 int ret;
01023
01024 if (recog->adin->adinthread_ended) return TRUE;
01025
01026 ret = pthread_cancel(recog->adin->adin_thread);
01027 if (ret == 0) {
01028 jlog("STAT: AD-in thread deleted\n");
01029 } else {
01030 if (ret == ESRCH) {
01031 jlog("STAT: adin_thread_cancel: no A/D-in thread\n");
01032 } else {
01033 jlog("Error: adin_thread_cancel: failed to cancel A/D-in thread\n");
01034 return FALSE;
01035 }
01036 }
01037 recog->adin->adinthread_ended = TRUE;
01038 return TRUE;
01039 }
01040
01041
01042
01043
01044
01069 static int
01070 adin_thread_process(int (*ad_process)(SP16 *, int, Recog *), int (*ad_check)(Recog *), Recog *recog)
01071 {
01072 int prev_len, nowlen;
01073 int ad_process_ret;
01074 int i;
01075 boolean overflowed_p;
01076 boolean transfer_online_local;
01077 boolean ended_p;
01078 ADIn *a;
01079
01080 a = recog->adin;
01081
01082
01083 pthread_mutex_lock(&(a->mutex));
01084
01085 a->transfer_online = TRUE;
01086 #ifdef THREAD_DEBUG
01087 jlog("DEBUG: process: reset, speechlen = %d, online=%d\n", a->speechlen, a->transfer_online);
01088 #endif
01089 pthread_mutex_unlock(&(a->mutex));
01090
01091
01092 prev_len = 0;
01093 for(;;) {
01094
01095 pthread_mutex_lock(&(a->mutex));
01096 nowlen = a->speechlen;
01097 overflowed_p = a->adinthread_buffer_overflowed;
01098 transfer_online_local = a->transfer_online;
01099 ended_p = a->adinthread_ended;
01100 pthread_mutex_unlock(&(a->mutex));
01101
01102 if (ended_p) {
01103
01104 return(0);
01105 }
01106
01107 if (overflowed_p) {
01108 jlog("WARNING: adin_thread_process: too long input (> %d samples), segmented now\n", MAXSPEECHLEN);
01109
01110 pthread_mutex_lock(&(a->mutex));
01111 a->adinthread_buffer_overflowed = FALSE;
01112 a->speechlen = 0;
01113 a->transfer_online = transfer_online_local = FALSE;
01114 pthread_mutex_unlock(&(a->mutex));
01115 return(1);
01116 }
01117
01118 if (ad_check != NULL) {
01119 if ((i = (*(ad_check))(recog)) < 0) {
01120 if ((i == -1 && nowlen == 0) || i == -2) {
01121 pthread_mutex_lock(&(a->mutex));
01122 a->transfer_online = transfer_online_local = FALSE;
01123 a->speechlen = 0;
01124 pthread_mutex_unlock(&(a->mutex));
01125 return(-2);
01126 }
01127 }
01128 }
01129 if (prev_len < nowlen) {
01130 #ifdef THREAD_DEBUG
01131 jlog("DEBUG: process: proceed [%d-%d]\n",prev_len, nowlen);
01132 #endif
01133
01134
01135
01136
01137
01138
01139
01140 if (ad_process != NULL) {
01141 ad_process_ret = (*ad_process)(&(a->speech[prev_len]), nowlen - prev_len, recog);
01142 #ifdef THREAD_DEBUG
01143 jlog("DEBUG: ad_process_ret=%d\n", ad_process_ret);
01144 #endif
01145 switch(ad_process_ret) {
01146 case 1:
01147
01148
01149 pthread_mutex_lock(&(a->mutex));
01150 if(a->speechlen > nowlen) {
01151 memmove(a->speech, &(a->speech[nowlen]), (a->speechlen - nowlen) * sizeof(SP16));
01152 a->speechlen -= nowlen;
01153 } else {
01154 a->speechlen = 0;
01155 }
01156 a->transfer_online = transfer_online_local = FALSE;
01157 pthread_mutex_unlock(&(a->mutex));
01158
01159 return(2);
01160 case -1:
01161 pthread_mutex_lock(&(a->mutex));
01162 a->transfer_online = transfer_online_local = FALSE;
01163 pthread_mutex_unlock(&(a->mutex));
01164 return(-1);
01165 }
01166 }
01167 if (a->rehash) {
01168
01169 pthread_mutex_lock(&(a->mutex));
01170 if (debug2_flag) jlog("STAT: adin_cut: rehash from %d to %d\n", a->speechlen, a->speechlen - prev_len);
01171 a->speechlen -= prev_len;
01172 nowlen -= prev_len;
01173 memmove(a->speech, &(a->speech[prev_len]), a->speechlen * sizeof(SP16));
01174 pthread_mutex_unlock(&(a->mutex));
01175 a->rehash = FALSE;
01176 }
01177 prev_len = nowlen;
01178 } else {
01179 if (transfer_online_local == FALSE) {
01180
01181
01182 pthread_mutex_lock(&(a->mutex));
01183 a->speechlen = 0;
01184 pthread_mutex_unlock(&(a->mutex));
01185 break;
01186 }
01187 usleep(50000);
01188 }
01189 }
01190
01191
01192
01193 return(1);
01194 }
01195 #endif
01196
01197
01198
01199
01233 int
01234 adin_go(int (*ad_process)(SP16 *, int, Recog *), int (*ad_check)(Recog *), Recog *recog)
01235 {
01236
01237 callback_exec(CALLBACK_EVENT_SPEECH_READY, recog);
01238 #ifdef HAVE_PTHREAD
01239 if (recog->adin->enable_thread) {
01240 return(adin_thread_process(ad_process, ad_check, recog));
01241 }
01242 #endif
01243 return(adin_cut(ad_process, ad_check, recog));
01244 }
01245
01264 boolean
01265 adin_standby(ADIn *a, int freq, void *arg)
01266 {
01267 if (a->need_zmean) zmean_reset();
01268 if (a->ad_standby != NULL) return(a->ad_standby(freq, arg));
01269 return TRUE;
01270 }
01287 boolean
01288 adin_begin(ADIn *a)
01289 {
01290 if (debug2_flag && a->input_side_segment) jlog("Stat: adin_begin: skip\n");
01291 if (a->input_side_segment == FALSE) {
01292 if (a->need_zmean) zmean_reset();
01293 if (a->ad_begin != NULL) return(a->ad_begin());
01294 }
01295 return TRUE;
01296 }
01312 boolean
01313 adin_end(ADIn *a)
01314 {
01315 if (debug2_flag && a->input_side_segment) jlog("Stat: adin_end: skip\n");
01316 if (a->input_side_segment == FALSE) {
01317 if (a->ad_end != NULL) return(a->ad_end());
01318 }
01319 return TRUE;
01320 }
01321
01336 void
01337 adin_free_param(Recog *recog)
01338 {
01339 ADIn *a;
01340
01341 a = recog->adin;
01342
01343 if (a->ds) {
01344 ds48to16_free(a->ds);
01345 a->ds = NULL;
01346 }
01347 if (a->adin_cut_on) {
01348 free_count_zc_e(&(a->zc));
01349 }
01350 if (a->down_sample) {
01351 free(a->buffer48);
01352 }
01353 free(a->swapbuf);
01354 free(a->cbuf);
01355 free(a->buffer);
01356 #ifdef HAVE_PTHREAD
01357 if (a->speech) free(a->speech);
01358 #endif
01359 }
01360
01361