Esempio n. 1
0
static int do_level_callback()
{
	static struct timeval last = {0,0};
	struct timeval now;
	float input_db;
	float output_db;

	now = iax_tvnow();

	if ( last.tv_sec != 0 && iaxci_usecdiff(&now, &last) < 100000 )
		return 0;

	last = now;

	/* if input has not been processed in the last second, set to silent */
	input_db = iaxci_usecdiff(&now, &timeLastInput) < 1000000 ?
			vol_to_db(input_level) : AUDIO_ENCODE_SILENCE_DB;

	/* if output has not been processed in the last second, set to silent */
	output_db = iaxci_usecdiff(&now, &timeLastOutput) < 1000000 ?
		vol_to_db(output_level) : AUDIO_ENCODE_SILENCE_DB;

	iaxci_do_levels_callback(input_db, output_db);

	return 0;
}
Esempio n. 2
0
/* just get the current input/output volumes, and return them. */
int iaxc_get_inout_volumes(int *input, int *output) {
  if(input) 
    *input = (int)vol_to_db(input_level);
  if(output)
    *output = (int)vol_to_db(output_level);

  return 0;
}
Esempio n. 3
0
static int do_level_callback()
{
    static struct timeval last = {0,0};
    struct timeval now;
	double input_db;
	double output_db;

    gettimeofday(&now,NULL); 
    if(last.tv_sec != 0 && iaxc_usecdiff(&now,&last) < 100000) return 0;

    last = now;

	/* if input has not been processed in the last second, set to silent */
	input_db = ( iaxc_usecdiff( &now, &timeLastInput ) < 1000000 ) 
		? vol_to_db( input_level ) : -99.9;

	/* if output has not been processed in the last second, set to silent */
	output_db = ( iaxc_usecdiff( &now, &timeLastOutput ) < 1000000 ) 
		? vol_to_db( output_level ) : -99.9;

    iaxc_do_levels_callback((float) input_db, (float) output_db);

    return 0;
}
Esempio n. 4
0
int iaxc_input_postprocess(void *audio, int len, int rate)
{
    double volume;
    static double lowest_volume = 1;
    int silent=0;

    if(!st || (speex_state_size != len) || (speex_state_rate != rate)) {
	if(st) speex_preprocess_state_destroy(st);
	st = speex_preprocess_state_init(len,rate);
	speex_state_size = len;
	speex_state_rate = rate;
	iaxc_set_speex_filters();
    }

    calculate_level(audio, len, &input_level);

    /* only preprocess if we're interested in VAD, AGC, or DENOISE */
    if((iaxc_filters & (IAXC_FILTER_DENOISE | IAXC_FILTER_AGC)) || iaxc_silence_threshold > 0)
	silent = !speex_preprocess(st, audio, NULL);

    /* Analog AGC: Bring speex AGC gain out to mixer, with lots of hysteresis */
    /* use a higher continuation threshold for AAGC than for VAD itself */
    if(!silent && 
	(iaxc_silence_threshold != 0) &&
	(iaxc_filters & IAXC_FILTER_AGC) && 
	(iaxc_filters & IAXC_FILTER_AAGC) && 
	(st->speech_prob > .20)
	) {
      static int i;
      double level;


      i++;

      if((i&0x3f) == 0) {
	  float loudness = st->loudness2;
	  if((loudness > 8000) || (loudness < 4000)) {
	    level =  iaxc_input_level_get();
	    /* fprintf(stderr, "loudness = %f, level = %f\n", loudness, level); */
	    /* lower quickly if we're really too hot */
	     if((loudness > 16000) && (level > 0.5)) {
		   /* fprintf(stderr, "lowering quickly level\n"); */
		   iaxc_input_level_set(level - 0.2);
	     } 
	     /* lower less quickly if we're a bit too hot */
	     else if((loudness > 8000) && (level >= 0.15)) {
		   /* fprintf(stderr, "lowering slowly level\n"); */
		   iaxc_input_level_set(level - 0.1);
	     }
	     /* raise slowly if we're cold */
	     else if((loudness < 4000) && (level <= 0.9)) {
		   /* fprintf(stderr, "raising level\n"); */
		   iaxc_input_level_set(level + 0.1);
	     }
	  }
      }
    }


    /* this is ugly.  Basically just don't get volume level if speex thought
     * we were silent.  just set it to 0 in that case */
    if(iaxc_silence_threshold > 0 && silent)
	input_level = 0;

    do_level_callback();

    volume = vol_to_db(input_level);

    if(volume < lowest_volume) lowest_volume = volume;

    if(iaxc_silence_threshold > 0)
	return silent;
    else
	return volume < iaxc_silence_threshold;
}
Esempio n. 5
0
static int input_postprocess(void *audio, int len, int rate)
{
	static float lowest_volume = 1.0f;
	float volume;
	int silent = 0;

	if ( !st || speex_state_size != len || speex_state_rate != rate )
	{
		if (st)
			speex_preprocess_state_destroy(st);
		st = speex_preprocess_state_init(len,rate);
		speex_state_size = len;
		speex_state_rate = rate;
		set_speex_filters();
	}

	calculate_level((short *)audio, len, &input_level);

	/* only preprocess if we're interested in VAD, AGC, or DENOISE */
	if ( (iaxci_filters & (IAXC_FILTER_DENOISE | IAXC_FILTER_AGC)) ||
			iaxci_silence_threshold > 0.0f )
		silent = !speex_preprocess(st, (spx_int16_t *)audio, NULL);

	/* Analog AGC: Bring speex AGC gain out to mixer, with lots of hysteresis */
	/* use a higher continuation threshold for AAGC than for VAD itself */
	if ( !silent &&
	     iaxci_silence_threshold != 0.0f &&
	     (iaxci_filters & IAXC_FILTER_AGC) &&
	     (iaxci_filters & IAXC_FILTER_AAGC)
	   )
	{
		static int i = 0;

		i++;

		if ( (i & 0x3f) == 0 )
		{
			float loudness;
#ifdef SPEEX_PREPROCESS_GET_AGC_LOUDNESS
			speex_preprocess_ctl(st, SPEEX_PREPROCESS_GET_AGC_LOUDNESS, &loudness);
#else
			loudness = st->loudness2;
#endif
			if ( loudness > 8000.0f || loudness < 4000.0f )
			{
				const float level = iaxc_input_level_get();

				if ( loudness > 16000.0f && level > 0.5f )
				{
					/* lower quickly if we're really too hot */
					iaxc_input_level_set(level - 0.2f);
				}
				else if ( loudness > 8000.0f && level >= 0.15f )
				{
					/* lower less quickly if we're a bit too hot */
					iaxc_input_level_set(level - 0.1f);
				}
				else if ( loudness < 4000.0f && level <= 0.9f )
				{
					/* raise slowly if we're cold */
					iaxc_input_level_set(level + 0.1f);
				}
			}
		}
	}

	/* This is ugly. Basically just don't get volume level if speex thought
	 * we were silent. Just set it to 0 in that case */
	if ( iaxci_silence_threshold > 0.0f && silent )
		input_level = 0.0f;

	do_level_callback();

	volume = vol_to_db(input_level);

	if ( volume < lowest_volume )
		lowest_volume = volume;

	if ( iaxci_silence_threshold > 0.0f )
		return silent;
	else
		return volume < iaxci_silence_threshold;
}