⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adin-cut.c

📁 julius version 4.12.about sound recognition.
💻 C
📖 第 1 页 / 共 3 页
字号:
static intadin_store_buffer(SP16 *now, int len, Recog *recog){  ADIn *a;  a = recog->adin;  if (a->speechlen + len > MAXSPEECHLEN) {    /* just mark as overflowed, and continue this thread */    pthread_mutex_lock(&(a->mutex));    a->adinthread_buffer_overflowed = TRUE;    pthread_mutex_unlock(&(a->mutex));    return(0);  }  pthread_mutex_lock(&(a->mutex));  memcpy(&(a->speech[a->speechlen]), now, len * sizeof(SP16));  a->speechlen += len;  pthread_mutex_unlock(&(a->mutex));#ifdef THREAD_DEBUG  jlog("DEBUG: input: stored %d samples, total=%d\n", len, a->speechlen);#endif  return(0);			/* continue */}/** * <EN> * A/D-in thread main function. * </EN> * <JA> * A/D-in スレッドのメイン簇眶. * </JA> *  * @param dummy [in] a dummy data, not used. */static voidadin_thread_input_main(void *dummy){  Recog *recog;  int ret;  recog = dummy;  ret = adin_cut(adin_store_buffer, NULL, recog);  if (ret == -1) {		/* error */    jlog("Error: adin thread exit with error\n");  } else if (ret == 0) {	/* EOF */    jlog("Stat: adin thread end with EOF\n");  }  recog->adin->adinthread_ended = TRUE;  /* return to end this thread */}/** * <EN> * Start new A/D-in thread, and initialize buffer. * </EN> * <JA> * バッファを介袋步して A/D-in スレッドを倡幌する.  * </JA> * @param recog [in] engine instance * * @callergraph * @callgraph */booleanadin_thread_create(Recog *recog){  ADIn *a;  a = recog->adin;  /* init storing buffer */  a->speech = (SP16 *)mymalloc(sizeof(SP16) * MAXSPEECHLEN);  a->speechlen = 0;  a->transfer_online = FALSE; /* tell adin-mic thread to wait at initial */  a->adinthread_buffer_overflowed = FALSE;  a->adinthread_ended = FALSE;  if (pthread_mutex_init(&(a->mutex), NULL) != 0) { /* error */    jlog("ERROR: adin_thread_create: failed to initialize mutex\n");    return FALSE;  }  if (pthread_create(&(recog->adin->adin_thread), NULL, (void *)adin_thread_input_main, recog) != 0) {    jlog("ERROR: adin_thread_create: failed to create AD-in thread\n");    return FALSE;  }  if (pthread_detach(recog->adin->adin_thread) != 0) { /* not join, run forever */    jlog("ERROR: adin_thread_create: failed to detach AD-in thread\n");    return FALSE;  }  jlog("STAT: AD-in thread created\n");  return TRUE;}/** * <EN> * Delete A/D-in thread * </EN> * <JA> * A/D-in スレッドを姜位する * </JA> * @param recog [in] engine instance * * @callergraph * @callgraph */booleanadin_thread_cancel(Recog *recog){  ADIn *a;  int ret;  if (recog->adin->adinthread_ended) return TRUE;  ret = pthread_cancel(recog->adin->adin_thread);  if (ret == 0) {    jlog("STAT: AD-in thread deleted\n");  } else {    if (ret == ESRCH) {      jlog("STAT: adin_thread_cancel: no A/D-in thread\n");    } else {      jlog("Error: adin_thread_cancel: failed to cancel A/D-in thread\n");      return FALSE;    }  }  recog->adin->adinthread_ended = TRUE;  return TRUE;}/****************************//* process thread functions *//****************************//** * <EN> * @brief  Main processing function for thread mode. * * It waits for the new samples to be stored in @a speech by A/D-in thread, * and if found, process them.  The interface are the same as adin_cut(). * </EN> * <JA> * @brief  スレッドモ〖ド脱メイン簇眶 * * この簇眶は A/D-in スレッドによってサンプルが瘦赂されるのを略ち· * 瘦赂されたサンプルを界肌借妄していきます. 苞眶や手り猛は adin_cut() と * 票办です.  * </JA> *  * @param ad_process [in] function to process triggerted input. * @param ad_check [in] function to be called periodically. * @param recog [in] engine instance *  * @return 2 when input termination requested by ad_process(), 1 when * if detect end of an input segment (down trigger detected after up * trigger), 0 when reached end of input device, -1 on error, -2 when * input termination requested by ad_check(). */static intadin_thread_process(int (*ad_process)(SP16 *, int, Recog *), int (*ad_check)(Recog *), Recog *recog){  int prev_len, nowlen;  int ad_process_ret;  int i;  boolean overflowed_p;  boolean transfer_online_local;  boolean ended_p;  ADIn *a;  a = recog->adin;  /* reset storing buffer --- input while recognition will be ignored */  pthread_mutex_lock(&(a->mutex));  /*if (speechlen == 0) transfer_online = TRUE;*/ /* tell adin-mic thread to start recording */  a->transfer_online = TRUE;#ifdef THREAD_DEBUG  jlog("DEBUG: process: reset, speechlen = %d, online=%d\n", a->speechlen, a->transfer_online);#endif  pthread_mutex_unlock(&(a->mutex));  /* main processing loop */  prev_len = 0;  for(;;) {    /* get current length (locking) */    pthread_mutex_lock(&(a->mutex));    nowlen = a->speechlen;    overflowed_p = a->adinthread_buffer_overflowed;    transfer_online_local = a->transfer_online;    ended_p = a->adinthread_ended;    pthread_mutex_unlock(&(a->mutex));    /* check if thread is alive */    if (ended_p) {      /* adin thread has already exited, so return EOF to stop this input */      return(0);    }    /* check if other input thread has overflowed */    if (overflowed_p) {      jlog("WARNING: adin_thread_process: too long input (> %d samples), segmented now\n", MAXSPEECHLEN);      /* segment input here */      pthread_mutex_lock(&(a->mutex));      a->adinthread_buffer_overflowed = FALSE;      a->speechlen = 0;      a->transfer_online = transfer_online_local = FALSE;      pthread_mutex_unlock(&(a->mutex));      return(1);		/* return with segmented status */    }    /* callback poll */    if (ad_check != NULL) {      if ((i = (*(ad_check))(recog)) < 0) {	if ((i == -1 && nowlen == 0) || i == -2) {	  pthread_mutex_lock(&(a->mutex));	  a->transfer_online = transfer_online_local = FALSE;	  a->speechlen = 0;	  pthread_mutex_unlock(&(a->mutex));	  return(-2);	}      }    }    if (prev_len < nowlen) {#ifdef THREAD_DEBUG      jlog("DEBUG: 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.       */      /*jlog("DEBUG: main: read %d-%d\n", prev_len, nowlen);*/      if (ad_process != NULL) {	ad_process_ret = (*ad_process)(&(a->speech[prev_len]), nowlen - prev_len, recog);#ifdef THREAD_DEBUG	jlog("DEBUG: 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(&(a->mutex));	  if(a->speechlen > nowlen) {	    memmove(a->speech, &(a->speech[nowlen]), (a->speechlen - nowlen) * sizeof(SP16));	    a->speechlen -= nowlen;	  } else {	    a->speechlen = 0;	  }	  a->transfer_online = transfer_online_local = FALSE;	  pthread_mutex_unlock(&(a->mutex));	  /* keep transfering */	  return(2);		/* return with segmented status */	case -1:		/* error */	  pthread_mutex_lock(&(a->mutex));	  a->transfer_online = transfer_online_local = FALSE;	  pthread_mutex_unlock(&(a->mutex));	  return(-1);		/* return with error */	}      }      if (a->rehash) {	/* rehash */	pthread_mutex_lock(&(a->mutex));	if (debug2_flag) jlog("STAT: adin_cut: rehash from %d to %d\n", a->speechlen, a->speechlen - prev_len);	a->speechlen -= prev_len;	nowlen -= prev_len;	memmove(a->speech, &(a->speech[prev_len]), a->speechlen * sizeof(SP16));	pthread_mutex_unlock(&(a->mutex));	a->rehash = FALSE;      }      prev_len = nowlen;    } else {      if (transfer_online_local == FALSE) {	/* segmented by zero-cross */	/* reset storing buffer for next input */	pthread_mutex_lock(&(a->mutex));	a->speechlen = 0;	pthread_mutex_unlock(&(a->mutex));        break;      }      usleep(50000);   /* wait = 0.05sec*/                }  }  /* as threading assumes infinite input */  /* return value should be 1 (segmented) */  return(1);}#endif /* HAVE_PTHREAD *//** * <EN> * @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. * </EN> * <JA> * @brief  掐蜗借妄を乖うトップ簇眶 * * スレッドモ〖ドでは·この簇眶は adin_thead_process() を钙び叫し· * 润スレッドモ〖ドでは adin_cut() を木儡钙び叫す. 苞眶や手り猛は * adin_cut() と票办である.  * </JA> *  * @param ad_process [in] function to process triggerted input. * @param ad_check [in] function to be called periodically. * @param recog [in] engine instance *  * @return 2 when input termination requested by ad_process(), 1 when * if detect end of an input segment (down trigger detected after up * trigger), 0 when reached end of input device, -1 on error, -2 when * input termination requested by ad_check(). * * @callergraph * @callgraph *  */intadin_go(int (*ad_process)(SP16 *, int, Recog *), int (*ad_check)(Recog *), Recog *recog){  /* output listening start message */  callback_exec(CALLBACK_EVENT_SPEECH_READY, recog);#ifdef HAVE_PTHREAD  if (recog->adin->enable_thread) {    return(adin_thread_process(ad_process, ad_check, recog));  }#endif  return(adin_cut(ad_process, ad_check, recog));}/**  * <EN> * Call device-specific initialization. * </EN> * <JA> * デバイス巴赂の介袋步簇眶を钙び叫す.  * </JA> *  * @param a [in] A/D-in work area * @param freq [in] sampling frequency * @param arg [in] device-dependent argument *  * @return TRUE if succeeded, FALSE if failed. *  * @callergraph * @callgraph *  */booleanadin_standby(ADIn *a, int freq, void *arg){  if (a->need_zmean) zmean_reset();  if (a->ad_standby != NULL) return(a->ad_standby(freq, arg));  return TRUE;}/**  * <EN> * Call device-specific function to begin capturing of the audio stream. * </EN> * <JA> * 不の艰り哈みを倡幌するデバイス巴赂の簇眶を钙び叫す.  * </JA> *  * @param a [in] A/D-in work area *  * @return TRUE on success, FALSE on failure. *  * @callergraph * @callgraph *  */booleanadin_begin(ADIn *a){  if (debug2_flag && a->input_side_segment) jlog("Stat: adin_begin: skip\n");  if (a->input_side_segment == FALSE) {    if (a->need_zmean) zmean_reset();    if (a->ad_begin != NULL) return(a->ad_begin());  }  return TRUE;}/**  * <EN> * Call device-specific function to end capturing of the audio stream. * </EN> * <JA> * 不の艰り哈みを姜位するデバイス巴赂の簇眶を钙び叫す.  * </JA> *  * @param a [in] A/D-in work area *  * @return TRUE on success, FALSE on failure. * * @callergraph * @callgraph */booleanadin_end(ADIn *a){  if (debug2_flag && a->input_side_segment) jlog("Stat: adin_end: skip\n");  if (a->input_side_segment == FALSE) {    if (a->ad_end != NULL) return(a->ad_end());  }  return TRUE;}/**  * <EN> * Free memories of A/D-in work area. * </EN> * <JA> * 不艰り哈み脱ワ〖クエリアのメモリを倡庶する.  * </JA> *  * @param recog [in] engine instance * * @callergraph * @callgraph *  */voidadin_free_param(Recog *recog){  ADIn *a;  a = recog->adin;  if (a->ds) {    ds48to16_free(a->ds);    a->ds = NULL;  }  if (a->adin_cut_on) {    free_count_zc_e(&(a->zc));  }  if (a->down_sample) {    free(a->buffer48);  }  free(a->swapbuf);  free(a->cbuf);  free(a->buffer);#ifdef HAVE_PTHREAD  if (a->speech) free(a->speech);#endif}/* end of file */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -