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; }
/* 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; }
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; }
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; }
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; }