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 void
00138 adin_setup_param(ADIn *adin, Jconf *jconf)
00139 {
00140 float samples_in_msec;
00141 int freq;
00142
00143 if (jconf->detect.silence_cut < 2) {
00144 adin->adin_cut_on = (jconf->detect.silence_cut == 1) ? TRUE : FALSE;
00145 } else {
00146 adin->adin_cut_on = adin->silence_cut_default;
00147 }
00148 adin->strip_flag = jconf->preprocess.strip_zero_sample;
00149 adin->thres = jconf->detect.level_thres;
00150 #ifdef HAVE_PTHREAD
00151 if (jconf->input.speech_input == SP_MIC && jconf->decodeopt.segment) {
00152 adin->ignore_speech_while_recog = FALSE;
00153 } else {
00154 adin->ignore_speech_while_recog = TRUE;
00155 }
00156 #endif
00157 adin->need_zmean = jconf->preprocess.use_zmean;
00158
00159 freq = jconf->input.sfreq;
00160 samples_in_msec = (float) freq / (float)1000.0;
00161
00162 adin->c_length = (int)((float)jconf->detect.head_margin_msec * samples_in_msec);
00163
00164 adin->noise_zerocross = jconf->detect.zero_cross_num * adin->c_length / freq;
00165
00166 adin->nc_max = (int)((float)(jconf->detect.tail_margin_msec * samples_in_msec / (float)DEFAULT_WSTEP)) + 2;
00167 adin->sbsize = jconf->detect.tail_margin_msec * samples_in_msec + (adin->c_length * jconf->detect.zero_cross_num / 200);
00168 adin->c_offset = 0;
00169
00170 #ifdef HAVE_PTHREAD
00171 adin->transfer_online = FALSE;
00172 adin->speech = NULL;
00173 #endif
00174 adin->ds = NULL;
00175
00176
00177
00178
00179 adin->buffer = (SP16 *)mymalloc(sizeof(SP16) * MAXSPEECHLEN);
00180 adin->cbuf = (SP16 *)mymalloc(sizeof(SP16) * adin->c_length);
00181 adin->swapbuf = (SP16 *)mymalloc(sizeof(SP16) * adin->sbsize);
00182 if (adin->down_sample) {
00183 adin->io_rate = 3;
00184 adin->buffer48 = (SP16 *)mymalloc(sizeof(SP16) * MAXSPEECHLEN * adin->io_rate);
00185 }
00186 if (adin->adin_cut_on) {
00187 init_count_zc_e(&(adin->zc), adin->c_length);
00188 }
00189
00190 adin->need_init = TRUE;
00191
00192 adin->rehash = FALSE;
00193
00194 }
00195
00208 static void
00209 adin_purge(ADIn *a, int from)
00210 {
00211 if (from > 0 && a->current_len - from > 0) {
00212 memmove(a->buffer, &(a->buffer[from]), (a->current_len - from) * sizeof(SP16));
00213 }
00214 a->bp = a->current_len - from;
00215 }
00216
00289 static int
00290 adin_cut(int (*ad_process)(SP16 *, int, Recog *), int (*ad_check)(Recog *), Recog *recog)
00291 {
00292 ADIn *a;
00293 static int i;
00294 int ad_process_ret;
00295 int imax, len, cnt;
00296 int wstep;
00297 static int end_status;
00298 static boolean transfer_online_local;
00299 static int zc;
00300
00301 a = recog->adin;
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315 if (a->need_init) {
00316 a->bpmax = MAXSPEECHLEN;
00317 a->bp = 0;
00318 a->is_valid_data = FALSE;
00319
00320 if (a->adin_cut_on) {
00321 reset_count_zc_e(&(a->zc), a->thres, a->c_length, a->c_offset);
00322 }
00323 a->end_of_stream = FALSE;
00324 a->nc = 0;
00325 a->sblen = 0;
00326 a->need_init = FALSE;
00327 }
00328
00329
00330
00331
00332
00333 if (a->ad_resume != NULL) {
00334 if ((*(a->ad_resume))() == FALSE) return(-1);
00335 }
00336
00337 if (!a->adin_cut_on && a->is_valid_data == TRUE) {
00338 #ifdef HAVE_PTHREAD
00339 if (!a->enable_thread) callback_exec(CALLBACK_EVENT_SPEECH_START, recog);
00340 #else
00341 callback_exec(CALLBACK_EVENT_SPEECH_START, recog);
00342 #endif
00343 }
00344
00345
00346
00347
00348 for (;;) {
00349
00350
00351
00352
00353 if (a->end_of_stream) {
00354
00355 a->current_len = a->bp;
00356 } else {
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 if (a->down_sample) {
00373
00374 cnt = (*(a->ad_read))(a->buffer48, (a->bpmax - a->bp) * a->io_rate);
00375 } else {
00376 cnt = (*(a->ad_read))(&(a->buffer[a->bp]), a->bpmax - a->bp);
00377 }
00378 if (cnt < 0) {
00379
00380 if (cnt == -2) end_status = -1;
00381 else if (cnt == -1) end_status = 0;
00382
00383
00384
00385
00386 a->end_of_stream = TRUE;
00387 cnt = 0;
00388
00389 if (a->bp == 0) break;
00390 }
00391 if (a->down_sample && cnt != 0) {
00392
00393 cnt = ds48to16(&(a->buffer[a->bp]), a->buffer48, cnt, a->bpmax - a->bp, a->ds);
00394 if (cnt < 0) {
00395 jlog("ERROR: adin_cut: error in down sampling\n");
00396 end_status = -1;
00397 a->end_of_stream = TRUE;
00398 cnt = 0;
00399 if (a->bp == 0) break;
00400 }
00401 }
00402
00403
00404
00405
00406
00407
00408 if (cnt > 0) {
00409 callback_exec_adin(CALLBACK_ADIN_CAPTURED, recog, &(a->buffer[a->bp]), cnt);
00410 }
00411
00412
00413
00414
00415 if (cnt > 0) {
00416 if (a->strip_flag) {
00417
00418 len = strip_zero(&(a->buffer[a->bp]), cnt);
00419 if (len != cnt) cnt = len;
00420 }
00421 if (a->need_zmean) {
00422
00423 sub_zmean(&(a->buffer[a->bp]), cnt);
00424 }
00425 }
00426
00427
00428 a->current_len = a->bp + cnt;
00429 }
00430 #ifdef THREAD_DEBUG
00431 if (a->end_of_stream) {
00432 jlog("DEBUG: adin_cut: stream already ended\n");
00433 }
00434 if (cnt > 0) {
00435 jlog("DEBUG: adin_cut: get %d samples [%d-%d]\n", a->current_len - a->bp, a->bp, a->current_len);
00436 }
00437 #endif
00438
00439
00440
00441
00442
00443
00444
00445 if (ad_check != NULL
00446 #ifdef HAVE_PTHREAD
00447 && !a->enable_thread
00448 #endif
00449 ) {
00450
00451 if ((i = (*ad_check)(recog)) < 0) {
00452
00453 if (i == -2 ||
00454 (i == -1 && a->adin_cut_on && a->is_valid_data == FALSE) ||
00455 (i == -1 && !a->adin_cut_on && a->current_len == 0)) {
00456 end_status = -2;
00457 goto break_input;
00458 }
00459 }
00460 }
00461
00462
00463
00464
00465 if (a->current_len == 0) continue;
00466
00467
00468
00469
00470
00471 if (!a->adin_cut_on && a->is_valid_data == FALSE && a->current_len > 0) {
00472 a->is_valid_data = TRUE;
00473 #ifdef HAVE_PTHREAD
00474 if (!a->enable_thread) callback_exec(CALLBACK_EVENT_SPEECH_START, recog);
00475 #else
00476 callback_exec(CALLBACK_EVENT_SPEECH_START, recog);
00477 #endif
00478 }
00479
00480
00481
00482
00483
00484 wstep = DEFAULT_WSTEP;
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497 #ifdef HAVE_PTHREAD
00498 if (a->enable_thread) imax = a->current_len;
00499 else imax = (a->current_len < wstep) ? a->current_len : wstep;
00500 #else
00501 imax = (a->current_len < wstep) ? a->current_len : wstep;
00502 #endif
00503
00504
00505 if (wstep > a->current_len) wstep = a->current_len;
00506
00507 #ifdef THREAD_DEBUG
00508 jlog("DEBUG: process %d samples by %d step\n", imax, wstep);
00509 #endif
00510
00511 #ifdef HAVE_PTHREAD
00512 if (a->enable_thread) {
00513
00514 pthread_mutex_lock(&(a->mutex));
00515 transfer_online_local = a->transfer_online;
00516 pthread_mutex_unlock(&(a->mutex));
00517 }
00518 #endif
00519
00520
00521
00522
00523 i = 0;
00524 while (i + wstep <= imax) {
00525
00526 if (a->adin_cut_on) {
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537 zc = count_zc_e(&(a->zc), &(a->buffer[i]), wstep);
00538
00539 if (zc > a->noise_zerocross) {
00540
00541 if (a->is_valid_data == FALSE) {
00542
00543
00544
00545
00546 a->is_valid_data = TRUE;
00547 a->nc = 0;
00548 #ifdef THREAD_DEBUG
00549 jlog("DEBUG: detect on\n");
00550 #endif
00551 #ifdef HAVE_PTHREAD
00552 if (!a->enable_thread) callback_exec(CALLBACK_EVENT_SPEECH_START, recog);
00553 #else
00554 callback_exec(CALLBACK_EVENT_SPEECH_START, recog);
00555 #endif
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565 if ( ad_process != NULL
00566 #ifdef HAVE_PTHREAD
00567 && (!a->enable_thread || !a->ignore_speech_while_recog || transfer_online_local)
00568 #endif
00569 ) {
00570
00571 zc_copy_buffer(&(a->zc), a->cbuf, &len);
00572
00573
00574
00575
00576
00577 if (len - wstep > 0) {
00578 #ifdef THREAD_DEBUG
00579 jlog("DEBUG: callback for buffered samples (%d bytes)\n", len - wstep);
00580 #endif
00581 #ifdef HAVE_PTHREAD
00582 if (!a->enable_thread) callback_exec_adin(CALLBACK_ADIN_TRIGGERED, recog, a->cbuf, len - wstep);
00583 #else
00584 callback_exec_adin(CALLBACK_ADIN_TRIGGERED, recog, a->cbuf, len - wstep);
00585 #endif
00586 ad_process_ret = (*ad_process)(a->cbuf, len - wstep, recog);
00587 switch(ad_process_ret) {
00588 case 1:
00589 #ifdef HAVE_PTHREAD
00590 if (a->enable_thread) {
00591
00592 pthread_mutex_lock(&(a->mutex));
00593 a->transfer_online = transfer_online_local = FALSE;
00594 pthread_mutex_unlock(&(a->mutex));
00595 } else {
00596
00597 end_status = 2;
00598 adin_purge(a, i);
00599 goto break_input;
00600 }
00601 break;
00602 #else
00603
00604 end_status = 2;
00605 adin_purge(a, i);
00606 goto break_input;
00607 #endif
00608 case -1:
00609
00610 end_status = -1;
00611 goto break_input;
00612 }
00613 }
00614 }
00615
00616 } else {
00617
00618
00619
00620
00621 if (a->nc > 0) {
00622
00623
00624
00625
00626
00627 #ifdef THREAD_DEBUG
00628 jlog("DEBUG: re-triggered\n");
00629 #endif
00630
00631 a->nc = 0;
00632
00633 #ifdef TMP_FIX_200602
00634 if (ad_process != NULL
00635 #ifdef HAVE_PTHREAD
00636 && (!a->enable_thread || !a->ignore_speech_while_recog || transfer_online_local)
00637 #endif
00638 ) {
00639 #endif
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651 if (a->sblen > 0) {
00652 #ifdef THREAD_DEBUG
00653 jlog("DEBUG: callback for swapped %d samples\n", a->sblen);
00654 #endif
00655 #ifdef HAVE_PTHREAD
00656 if (!a->enable_thread) callback_exec_adin(CALLBACK_ADIN_TRIGGERED, recog, a->swapbuf, a->sblen);
00657 #else
00658 callback_exec_adin(CALLBACK_ADIN_TRIGGERED, recog, a->swapbuf, a->sblen);
00659 #endif
00660 ad_process_ret = (*ad_process)(a->swapbuf, a->sblen, recog);
00661 a->sblen = 0;
00662 switch(ad_process_ret) {
00663 case 1:
00664 #ifdef HAVE_PTHREAD
00665 if (a->enable_thread) {
00666
00667 pthread_mutex_lock(&(a->mutex));
00668 a->transfer_online = transfer_online_local = FALSE;
00669 pthread_mutex_unlock(&(a->mutex));
00670 } else {
00671
00672 end_status = 2;
00673 adin_purge(a, i);
00674 goto break_input;
00675 }
00676 break;
00677 #else
00678
00679 end_status = 2;
00680 adin_purge(a, i);
00681 goto break_input;
00682 #endif
00683 case -1:
00684
00685 end_status = -1;
00686 goto break_input;
00687 }
00688 }
00689 #ifdef TMP_FIX_200602
00690 }
00691 #endif
00692 }
00693 }
00694 } else if (a->is_valid_data == TRUE) {
00695
00696
00697
00698
00699
00700 #ifdef THREAD_DEBUG
00701 jlog("DEBUG: TRAILING SILENCE\n");
00702 #endif
00703 if (a->nc == 0) {
00704
00705 a->rest_tail = a->sbsize - a->c_length;
00706 a->sblen = 0;
00707 #ifdef THREAD_DEBUG
00708 jlog("DEBUG: start tail silence, rest_tail = %d\n", a->rest_tail);
00709 #endif
00710 }
00711
00712
00713 a->nc++;
00714 }
00715 }
00716
00717
00718
00719
00720
00721
00722 if (a->adin_cut_on && a->is_valid_data && a->nc > 0 && a->rest_tail == 0) {
00723
00724
00725
00726
00727
00728
00729
00730
00731 #ifdef THREAD_DEBUG
00732 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);
00733 #endif
00734 if (a->sblen + wstep > a->sbsize) {
00735 jlog("ERROR: adin_cut: swap buffer for re-triggering overflow\n");
00736 }
00737 memcpy(&(a->swapbuf[a->sblen]), &(a->buffer[i]), wstep * sizeof(SP16));
00738 a->sblen += wstep;
00739
00740 } else {
00741
00742
00743
00744
00745
00746
00747
00748 #ifdef TMP_FIX_200602
00749 if (!a->adin_cut_on || a->is_valid_data == TRUE) {
00750 #else
00751 if(
00752 (!a->adin_cut_on || a->is_valid_data == TRUE)
00753 #ifdef HAVE_PTHREAD
00754 && (!a->enable_thread || !a->ignore_speech_while_recog || transfer_online_local)
00755 #endif
00756 ) {
00757 #endif
00758 if (a->nc > 0) {
00759
00760
00761 if (a->rest_tail < wstep) a->rest_tail = 0;
00762 else a->rest_tail -= wstep;
00763 #ifdef THREAD_DEBUG
00764 jlog("DEBUG: %d processed, rest_tail=%d\n", wstep, a->rest_tail);
00765 #endif
00766 }
00767 #ifdef TMP_FIX_200602
00768 if (ad_process != NULL
00769 #ifdef HAVE_PTHREAD
00770 && (!a->enable_thread || !a->ignore_speech_while_recog || transfer_online_local)
00771 #endif
00772 ) {
00773
00774 #else
00775 if ( ad_process != NULL ) {
00776 #endif
00777 #ifdef THREAD_DEBUG
00778 jlog("DEBUG: callback for input sample [%d-%d]\n", i, i+wstep);
00779 #endif
00780
00781 #ifdef HAVE_PTHREAD
00782 if (!a->enable_thread) callback_exec_adin(CALLBACK_ADIN_TRIGGERED, recog, &(a->buffer[i]), wstep);
00783 #else
00784 callback_exec_adin(CALLBACK_ADIN_TRIGGERED, recog, &(a->buffer[i]), wstep);
00785 #endif
00786 ad_process_ret = (*ad_process)(&(a->buffer[i]), wstep, recog);
00787 switch(ad_process_ret) {
00788 case 1:
00789 #ifdef HAVE_PTHREAD
00790 if (a->enable_thread) {
00791
00792 pthread_mutex_lock(&(a->mutex));
00793 a->transfer_online = transfer_online_local = FALSE;
00794 pthread_mutex_unlock(&(a->mutex));
00795 } else {
00796
00797 adin_purge(a, i+wstep);
00798 end_status = 2;
00799 goto break_input;
00800 }
00801 break;
00802 #else
00803
00804 adin_purge(a, i+wstep);
00805 end_status = 2;
00806 goto break_input;
00807 #endif
00808 case -1:
00809
00810 end_status = -1;
00811 goto break_input;
00812 }
00813 }
00814 }
00815 }
00816
00817
00818 if (a->adin_cut_on && a->is_valid_data && a->nc >= a->nc_max) {
00819
00820
00821
00822
00823 #ifdef THREAD_DEBUG
00824 jlog("DEBUG: detect off\n");
00825 #endif
00826
00827 a->is_valid_data = FALSE;
00828 a->sblen = 0;
00829 #ifdef HAVE_PTHREAD
00830 if (a->enable_thread) {
00831 pthread_mutex_lock(&(a->mutex));
00832 a->transfer_online = transfer_online_local = FALSE;
00833 pthread_mutex_unlock(&(a->mutex));
00834 } else {
00835 adin_purge(a, i+wstep);
00836 end_status = 1;
00837 goto break_input;
00838 }
00839 #else
00840 adin_purge(a, i+wstep);
00841 end_status = 1;
00842 goto break_input;
00843 #endif
00844 }
00845
00846
00847
00848
00849 i += wstep;
00850 }
00851
00852
00853 adin_purge(a, i);
00854
00855
00856 if (a->end_of_stream && a->bp == 0) break;
00857 }
00858
00859 break_input:
00860
00861
00862
00863
00864
00865 if (a->ad_pause != NULL) {
00866 if ((*(a->ad_pause))() == FALSE) {
00867 jlog("ERROR: adin_cut: failed to pause recording\n");
00868 end_status = -1;
00869 }
00870 }
00871
00872
00873 #ifdef HAVE_PTHREAD
00874 if (!a->enable_thread) callback_exec(CALLBACK_EVENT_SPEECH_STOP, recog);
00875 #else
00876 callback_exec(CALLBACK_EVENT_SPEECH_STOP, recog);
00877 #endif
00878
00879 if (a->end_of_stream) {
00880 if (a->bp == 0) {
00881
00882 a->need_init = TRUE;
00883 }
00884 end_status = (a->bp) ? 1 : 0;
00885 }
00886
00887 return(end_status);
00888 }
00889
00890 #ifdef HAVE_PTHREAD
00891
00892
00893
00894
00895
00896
00897
00898
00913 static int
00914 adin_store_buffer(SP16 *now, int len, Recog *recog)
00915 {
00916 ADIn *a;
00917
00918 a = recog->adin;
00919 if (a->speechlen + len > MAXSPEECHLEN) {
00920
00921 pthread_mutex_lock(&(a->mutex));
00922 a->adinthread_buffer_overflowed = TRUE;
00923 pthread_mutex_unlock(&(a->mutex));
00924 return(0);
00925 }
00926 pthread_mutex_lock(&(a->mutex));
00927 memcpy(&(a->speech[a->speechlen]), now, len * sizeof(SP16));
00928 a->speechlen += len;
00929 pthread_mutex_unlock(&(a->mutex));
00930 #ifdef THREAD_DEBUG
00931 jlog("DEBUG: input: stored %d samples, total=%d\n", len, a->speechlen);
00932 #endif
00933
00934 return(0);
00935 }
00936
00947 static void
00948 adin_thread_input_main(void *dummy)
00949 {
00950 Recog *recog;
00951
00952 recog = dummy;
00953
00954 adin_cut(adin_store_buffer, NULL, recog);
00955 }
00956
00969 boolean
00970 adin_thread_create(Recog *recog)
00971 {
00972 pthread_t adin_thread;
00973 ADIn *a;
00974
00975 a = recog->adin;
00976
00977
00978 a->speech = (SP16 *)mymalloc(sizeof(SP16) * MAXSPEECHLEN);
00979 a->speechlen = 0;
00980
00981 a->transfer_online = FALSE;
00982 a->adinthread_buffer_overflowed = FALSE;
00983
00984 if (pthread_mutex_init(&(a->mutex), NULL) != 0) {
00985 jlog("ERROR: adin_thread_create: failed to initialize mutex\n");
00986 return FALSE;
00987 }
00988 if (pthread_create(&adin_thread, NULL, (void *)adin_thread_input_main, recog) != 0) {
00989 jlog("ERROR: adin_thread_create: failed to create AD-in thread\n");
00990 return FALSE;
00991 }
00992 if (pthread_detach(adin_thread) != 0) {
00993 jlog("ERROR: adin_thread_create: failed to detach AD-in thread\n");
00994 return FALSE;
00995 }
00996 jlog("STAT: AD-in thread created\n");
00997 return TRUE;
00998 }
00999
01000
01001
01002
01003
01028 static int
01029 adin_thread_process(int (*ad_process)(SP16 *, int, Recog *), int (*ad_check)(Recog *), Recog *recog)
01030 {
01031 int prev_len, nowlen;
01032 int ad_process_ret;
01033 int i;
01034 boolean overflowed_p;
01035 boolean transfer_online_local;
01036 boolean first_trig;
01037 ADIn *a;
01038
01039 a = recog->adin;
01040
01041
01042 pthread_mutex_lock(&(a->mutex));
01043
01044 a->transfer_online = TRUE;
01045 #ifdef THREAD_DEBUG
01046 jlog("DEBUG: process: reset, speechlen = %d, online=%d\n", a->speechlen, a->transfer_online);
01047 #endif
01048 pthread_mutex_unlock(&(a->mutex));
01049
01050
01051 prev_len = 0;
01052 first_trig = TRUE;
01053 for(;;) {
01054
01055 pthread_mutex_lock(&(a->mutex));
01056 nowlen = a->speechlen;
01057 overflowed_p = a->adinthread_buffer_overflowed;
01058 transfer_online_local = a->transfer_online;
01059 pthread_mutex_unlock(&(a->mutex));
01060
01061 if (overflowed_p) {
01062 jlog("WARNING: adin_thread_process: too long input (> %d samples), segmented now\n", MAXSPEECHLEN);
01063
01064 pthread_mutex_lock(&(a->mutex));
01065 a->adinthread_buffer_overflowed = FALSE;
01066 a->speechlen = 0;
01067 a->transfer_online = transfer_online_local = FALSE;
01068 pthread_mutex_unlock(&(a->mutex));
01069 if (!first_trig) callback_exec(CALLBACK_EVENT_SPEECH_STOP, recog);
01070 return(1);
01071 }
01072
01073 if (ad_check != NULL) {
01074 if ((i = (*(ad_check))(recog)) < 0) {
01075 if ((i == -1 && nowlen == 0) || i == -2) {
01076 pthread_mutex_lock(&(a->mutex));
01077 a->transfer_online = transfer_online_local = FALSE;
01078 a->speechlen = 0;
01079 pthread_mutex_unlock(&(a->mutex));
01080 if (!first_trig) callback_exec(CALLBACK_EVENT_SPEECH_STOP, recog);
01081 return(-2);
01082 }
01083 }
01084 }
01085 if (prev_len < nowlen) {
01086 #ifdef THREAD_DEBUG
01087 jlog("DEBUG: process: proceed [%d-%d]\n",prev_len, nowlen);
01088 #endif
01089
01090
01091
01092
01093
01094
01095
01096
01097 if (first_trig) {
01098 first_trig = FALSE;
01099 callback_exec(CALLBACK_EVENT_SPEECH_START, recog);
01100 }
01101 if (ad_process != NULL) {
01102 callback_exec_adin(CALLBACK_ADIN_TRIGGERED, recog, &(a->speech[prev_len]), nowlen - prev_len);
01103 ad_process_ret = (*ad_process)(&(a->speech[prev_len]), nowlen - prev_len, recog);
01104 #ifdef THREAD_DEBUG
01105 jlog("DEBUG: ad_process_ret=%d\n", ad_process_ret);
01106 #endif
01107 switch(ad_process_ret) {
01108 case 1:
01109
01110
01111 pthread_mutex_lock(&(a->mutex));
01112 if(a->speechlen > nowlen) {
01113 memmove(a->speech, &(a->speech[nowlen]), (a->speechlen - nowlen) * sizeof(SP16));
01114 a->speechlen -= nowlen;
01115 } else {
01116 a->speechlen = 0;
01117 }
01118 a->transfer_online = transfer_online_local = FALSE;
01119 pthread_mutex_unlock(&(a->mutex));
01120 if (!first_trig) callback_exec(CALLBACK_EVENT_SPEECH_STOP, recog);
01121
01122 return(2);
01123 case -1:
01124 pthread_mutex_lock(&(a->mutex));
01125 a->transfer_online = transfer_online_local = FALSE;
01126 pthread_mutex_unlock(&(a->mutex));
01127 if (!first_trig) callback_exec(CALLBACK_EVENT_SPEECH_STOP, recog);
01128 return(-1);
01129 }
01130 }
01131 if (a->rehash) {
01132
01133 pthread_mutex_lock(&(a->mutex));
01134 if (debug2_flag) jlog("STAT: adin_cut: rehash from %d to %d\n", a->speechlen, a->speechlen - prev_len);
01135 a->speechlen -= prev_len;
01136 nowlen -= prev_len;
01137 memmove(a->speech, &(a->speech[prev_len]), a->speechlen * sizeof(SP16));
01138 pthread_mutex_unlock(&(a->mutex));
01139 a->rehash = FALSE;
01140 }
01141 prev_len = nowlen;
01142 } else {
01143 if (transfer_online_local == FALSE) {
01144
01145
01146 pthread_mutex_lock(&(a->mutex));
01147 a->speechlen = 0;
01148 pthread_mutex_unlock(&(a->mutex));
01149 if (!first_trig) callback_exec(CALLBACK_EVENT_SPEECH_STOP, recog);
01150 break;
01151 }
01152 usleep(50000);
01153 }
01154 }
01155
01156
01157
01158 return(1);
01159 }
01160 #endif
01161
01162
01163
01164
01198 int
01199 adin_go(int (*ad_process)(SP16 *, int, Recog *), int (*ad_check)(Recog *), Recog *recog)
01200 {
01201 #ifdef HAVE_PTHREAD
01202 if (recog->adin->enable_thread) {
01203 return(adin_thread_process(ad_process, ad_check, recog));
01204 }
01205 #endif
01206 return(adin_cut(ad_process, ad_check, recog));
01207 }
01208
01227 boolean
01228 adin_standby(ADIn *a, int freq, void *arg)
01229 {
01230 if (a->need_zmean) zmean_reset();
01231 if (a->ad_standby != NULL) return(a->ad_standby(freq, arg));
01232 return TRUE;
01233 }
01250 boolean
01251 adin_begin(ADIn *a)
01252 {
01253 if (a->need_zmean) zmean_reset();
01254 if (a->ad_begin != NULL) return(a->ad_begin());
01255 return TRUE;
01256 }
01272 boolean
01273 adin_end(ADIn *a)
01274 {
01275 if (a->ad_end != NULL) return(a->ad_end());
01276 return TRUE;
01277 }
01278
01293 void
01294 adin_free_param(Recog *recog)
01295 {
01296 ADIn *a;
01297
01298 a = recog->adin;
01299
01300 if (a->ds) {
01301 ds48to16_free(a->ds);
01302 a->ds = NULL;
01303 }
01304 if (a->adin_cut_on) {
01305 free_count_zc_e(&(a->zc));
01306 }
01307 if (a->down_sample) {
01308 free(a->buffer48);
01309 }
01310 free(a->swapbuf);
01311 free(a->cbuf);
01312 free(a->buffer);
01313 #ifdef HAVE_PTHREAD
01314 if (a->speech) free(a->speech);
01315 #endif
01316 }
01317
01318