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

📄 adin-cut.c

📁 julius version 4.12.about sound recognition.
💻 C
📖 第 1 页 / 共 3 页
字号:
    /*************************************************/    /* this function is mainly for periodic checking of incoming command       in module mode */    /* in threaded mode, this will be done in process thread, not here in adin thread */    if (ad_check != NULL#ifdef HAVE_PTHREAD	&& !a->enable_thread#endif	) {      /* if ad_check() returns value < 0, termination of speech input is required */      if ((i = (*ad_check)(recog)) < 0) { /* -1: soft termination -2: hard termination */	//	if ((i == -1 && current_len == 0) || i == -2) { 	if (i == -2 ||	    (i == -1 && a->is_valid_data == FALSE)) {	  end_status = -2;	/* recognition terminated by outer function */	  /* execute callback */	  if (a->current_len > 0) {	    callback_exec(CALLBACK_EVENT_SPEECH_STOP, recog);	  }	  a->need_init = TRUE; /* bufer status shoule be reset at next call */	  goto break_input;	}      }    }    /***********************************************************************/    /* if no data has got but not end of stream, repeat next input samples */    /***********************************************************************/    if (a->current_len == 0) continue;    /* When not adin_cut mode, all incoming data is valid.       So is_valid_data should be set to TRUE when some input first comes       till this input ends.  So, if some data comes, set is_valid_data to       TRUE here. */     if (!a->adin_cut_on && a->is_valid_data == FALSE && a->current_len > 0) {      a->is_valid_data = TRUE;      callback_exec(CALLBACK_EVENT_SPEECH_START, recog);    }    /******************************************************/    /* prepare for processing samples in temporary buffer */    /******************************************************/        wstep = DEFAULT_WSTEP;	/* process unit (should be smaller than cycle buffer) */    /* imax: total length that should be processed at one ad_read() call */    /* if in real-time mode and not threaded, recognition process        will be called and executed as the ad_process() callback within       this function.  If the recognition speed is over the real time,       processing all the input samples at the loop below may result in the       significant delay of getting next input, that may result in the buffer       overflow of the device (namely a microphone device will suffer from       this). So, in non-threaded mode, in order to avoid buffer overflow and       input frame dropping, we will leave here by processing        only one segment [0..wstep], and leave the rest in the temporary buffer.    */#ifdef HAVE_PTHREAD    if (a->enable_thread) imax = a->current_len; /* process whole */    else imax = (a->current_len < wstep) ? a->current_len : wstep; /* one step */#else    imax = (a->current_len < wstep) ? a->current_len : wstep;	/* one step */#endif        /* wstep: unit length for the loop below */    if (wstep > a->current_len) wstep = a->current_len;#ifdef THREAD_DEBUG    jlog("DEBUG: process %d samples by %d step\n", imax, wstep);#endif#ifdef HAVE_PTHREAD    if (a->enable_thread) {      /* get transfer status to local */      pthread_mutex_lock(&(a->mutex));      transfer_online_local = a->transfer_online;      pthread_mutex_unlock(&(a->mutex));    }#endif    /*********************************************************/    /* start processing buffer[0..current_len] by wstep step */    /*********************************************************/    i = 0;    while (i + wstep <= imax) {      if (a->adin_cut_on) {	/********************/	/* check triggering */	/********************/	/* the cycle buffer in count_zc_e() holds the last	   samples of (head_margin) miliseconds, and the zerocross	   over the threshold level are counted within the cycle buffer */		/* store the new data to cycle buffer and update the count */	/* return zero-cross num in the cycle buffer */	zc = count_zc_e(&(a->zc), &(a->buffer[i]), wstep);		if (zc > a->noise_zerocross) { /* now triggering */	  	  if (a->is_valid_data == FALSE) {	    /*****************************************************/	    /* process off, trigger on: detect speech triggering */	    /*****************************************************/	    a->is_valid_data = TRUE;   /* start processing */	    a->nc = 0;#ifdef THREAD_DEBUG	    jlog("DEBUG: detect on\n");#endif	    /* record time */	    a->last_trigger_sample = a->total_captured_len - a->current_len + i + wstep - a->zc.valid_len;	    callback_exec(CALLBACK_EVENT_SPEECH_START, recog);	    /****************************************/	    /* flush samples stored in cycle buffer */	    /****************************************/	    /* (last (head_margin) msec samples */	    /* if threaded mode, processing means storing them to speech[].	       if ignore_speech_while_recog is on (default), ignore the data	       if transfer is offline (=while processing second pass).	       Else, datas are stored even if transfer is offline */	    if ( ad_process != NULL#ifdef HAVE_PTHREAD		 && (!a->enable_thread || !a->ignore_speech_while_recog || transfer_online_local)#endif		 ) {	      /* copy content of cycle buffer to cbuf */	      zc_copy_buffer(&(a->zc), a->cbuf, &len);	      /* Note that the last 'wstep' samples are the same as		 the current samples 'buffer[i..i+wstep]', and		 they will be processed later.  So, here only the samples		 cbuf[0...len-wstep] will be processed	      */	      if (len - wstep > 0) {#ifdef THREAD_DEBUG		jlog("DEBUG: callback for buffered samples (%d bytes)\n", len - wstep);#endif#ifdef ENABLE_PLUGIN		plugin_exec_adin_triggered(a->cbuf, len - wstep);#endif		callback_exec_adin(CALLBACK_ADIN_TRIGGERED, recog, a->cbuf, len - wstep);		ad_process_ret = (*ad_process)(a->cbuf, len - wstep, recog);		switch(ad_process_ret) {		case 1:		/* segmentation notification from process callback */#ifdef HAVE_PTHREAD		  if (a->enable_thread) {		    /* in threaded mode, just stop transfer */		    pthread_mutex_lock(&(a->mutex));		    a->transfer_online = transfer_online_local = FALSE;		    pthread_mutex_unlock(&(a->mutex));		  } else {		    /* in non-threaded mode, set end status and exit loop */		    end_status = 2;		    adin_purge(a, i);		    goto break_input;		  }		  break;#else		  /* in non-threaded mode, set end status and exit loop */		  end_status = 2;		  adin_purge(a, i);		  goto break_input;#endif		case -1:		/* error occured in callback */		  /* set end status and exit loop */		  end_status = -1;		  goto break_input;		}	      }	    }	    	  } else {		/* is_valid_data == TRUE */	    /******************************************************/	    /* process on, trigger on: we are in a speech segment */	    /******************************************************/	    	    if (a->nc > 0) {	      	      /*************************************/	      /* re-triggering in trailing silence */	      /*************************************/	      #ifdef THREAD_DEBUG	      jlog("DEBUG: re-triggered\n");#endif	      /* reset noise counter */	      a->nc = 0;#ifdef TMP_FIX_200602	      if (ad_process != NULL#ifdef HAVE_PTHREAD		  && (!a->enable_thread || !a->ignore_speech_while_recog || transfer_online_local)#endif		  ) {#endif	      	      /*************************************************/	      /* process swap buffer stored while tail silence */	      /*************************************************/	      /* In trailing silence, the samples within the tail margin length		 will be processed immediately, but samples after the tail		 margin will not be processed, instead stored in swapbuf[].		 If re-triggering occurs while in the trailing silence,		 the swapped samples should be processed now to catch up		 with current input	      */	      if (a->sblen > 0) {#ifdef THREAD_DEBUG		jlog("DEBUG: callback for swapped %d samples\n", a->sblen);#endif#ifdef ENABLE_PLUGIN		plugin_exec_adin_triggered(a->swapbuf, a->sblen);#endif		callback_exec_adin(CALLBACK_ADIN_TRIGGERED, recog, a->swapbuf, a->sblen);		ad_process_ret = (*ad_process)(a->swapbuf, a->sblen, recog);		a->sblen = 0;		switch(ad_process_ret) {		case 1:		/* segmentation notification from process callback */#ifdef HAVE_PTHREAD		  if (a->enable_thread) {		    /* in threaded mode, just stop transfer */		    pthread_mutex_lock(&(a->mutex));		    a->transfer_online = transfer_online_local = FALSE;		    pthread_mutex_unlock(&(a->mutex));		  } else {		    /* in non-threaded mode, set end status and exit loop */		    end_status = 2;		    adin_purge(a, i);		    goto break_input;		  }		  break;#else		  /* in non-threaded mode, set end status and exit loop */		  end_status = 2;		  adin_purge(a, i);		  goto break_input;#endif		case -1:		/* error occured in callback */		  /* set end status and exit loop */		  end_status = -1;		  goto break_input;		}	      }#ifdef TMP_FIX_200602	      }#endif	    }	  } 	} else if (a->is_valid_data == TRUE) {	  	  /*******************************************************/	  /* process on, trigger off: processing tailing silence */	  /*******************************************************/	  #ifdef THREAD_DEBUG	  jlog("DEBUG: TRAILING SILENCE\n");#endif	  if (a->nc == 0) {	    /* start of tail silence: prepare valiables for start swapbuf[] */	    a->rest_tail = a->sbsize - a->c_length;	    a->sblen = 0;#ifdef THREAD_DEBUG	    jlog("DEBUG: start tail silence, rest_tail = %d\n", a->rest_tail);#endif	  }	  /* increment noise counter */	  a->nc++;	}      }	/* end of triggering handlers */                  /********************************************************************/      /* process the current segment buffer[i...i+wstep] if process == on */      /********************************************************************/            if (a->adin_cut_on && a->is_valid_data && a->nc > 0 && a->rest_tail == 0) {		/* The current trailing silence is now longer than the user-	   specified tail margin length, so the current samples	   should not be processed now.  But if 're-triggering'	   occurs in the trailing silence later, they should be processed	   then.  So we just store the overed samples in swapbuf[] and	   not process them now */	#ifdef THREAD_DEBUG	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);#endif	if (a->sblen + wstep > a->sbsize) {	  jlog("ERROR: adin_cut: swap buffer for re-triggering overflow\n");	}	memcpy(&(a->swapbuf[a->sblen]), &(a->buffer[i]), wstep * sizeof(SP16));	a->sblen += wstep;	      } else {	/* we are in a normal speech segment (nc == 0), or	   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 (!a->adin_cut_on || a->is_valid_data == TRUE) {#else	if(	   (!a->adin_cut_on || a->is_valid_data == TRUE)#ifdef HAVE_PTHREAD	   && (!a->enable_thread || !a->ignore_speech_while_recog || transfer_online_local)#endif	   ) {#endif	  if (a->nc > 0) {	    /* if we are in a trailing silence, decrease the counter to detect	     start of swapbuf[] above */	    if (a->rest_tail < wstep) a->rest_tail = 0;	    else a->rest_tail -= wstep;#ifdef THREAD_DEBUG	    jlog("DEBUG: %d processed, rest_tail=%d\n", wstep, a->rest_tail);#endif	  }#ifdef TMP_FIX_200602	  if (ad_process != NULL#ifdef HAVE_PTHREAD	      && (!a->enable_thread || !a->ignore_speech_while_recog || transfer_online_local)#endif	      ) {#else	  if ( ad_process != NULL ) {#endif#ifdef THREAD_DEBUG	    jlog("DEBUG: callback for input sample [%d-%d]\n", i, i+wstep);#endif	    /* call external function */#ifdef ENABLE_PLUGIN	    plugin_exec_adin_triggered(&(a->buffer[i]), wstep);#endif	    callback_exec_adin(CALLBACK_ADIN_TRIGGERED, recog, &(a->buffer[i]), wstep);	    ad_process_ret = (*ad_process)(&(a->buffer[i]), wstep, recog);	    switch(ad_process_ret) {	    case 1:		/* segmentation notification from process callback */#ifdef HAVE_PTHREAD	      if (a->enable_thread) {		/* in threaded mode, just stop transfer */		pthread_mutex_lock(&(a->mutex));		a->transfer_online = transfer_online_local = FALSE;		pthread_mutex_unlock(&(a->mutex));	      } else {		/* in non-threaded mode, set end status and exit loop */		adin_purge(a, i+wstep);		end_status = 2;		goto break_input;	      }	      break;#else	      /* in non-threaded mode, set end status and exit loop */	      adin_purge(a, i+wstep);	      end_status = 2;	      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 (a->adin_cut_on && a->is_valid_data && a->nc >= a->nc_max) {	/*************************************/	/* process on, trailing silence over */	/* = end of input segment            */	/*************************************/#ifdef THREAD_DEBUG	jlog("DEBUG: detect off\n");#endif	/* end input by silence */	a->is_valid_data = FALSE;	/* turn off processing */	a->sblen = 0;	callback_exec(CALLBACK_EVENT_SPEECH_STOP, recog);#ifdef HAVE_PTHREAD	if (a->enable_thread) { /* just stop transfer */	  pthread_mutex_lock(&(a->mutex));	  a->transfer_online = transfer_online_local = FALSE;	  pthread_mutex_unlock(&(a->mutex));	} else {	  adin_purge(a, i+wstep);	  end_status = 1;	  goto break_input;	}#else	adin_purge(a, 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(a, i);    /* end of input by end of stream */    if (a->end_of_stream && a->bp == 0) break;  }break_input:  /****************/  /* pause input */  /****************/  if (a->end_of_stream) {			/* input already ends */    /* execute callback */    callback_exec(CALLBACK_EVENT_SPEECH_STOP, recog);    if (a->bp == 0) {		/* rest buffer successfully flushed */      /* reset status */      a->need_init = TRUE;		/* bufer status shoule be reset at next call */    }    end_status = (a->bp) ? 1 : 0;  }    return(end_status);}#ifdef HAVE_PTHREAD/***********************//* threading functions *//***********************//*************************//* adin thread functions *//*************************//** * <EN> * Callback to store triggered samples within A/D-in thread. * </EN> * <JA> * A/D-in スレッドにてトリガした掐蜗サンプルを瘦赂するコ〖ルバック. * </JA> *  * @param now [in] triggered fragment * @param len [in] length of above * @param recog [in] engine instance *  * @return always 0, to tell caller to just continue the input */

⌨️ 快捷键说明

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