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