Filter_Audio *new_filter_audio(uint32_t fs) { if (fs == 0) { return NULL; } Filter_Audio *f_a = calloc(sizeof(Filter_Audio), 1); if (!f_a) { return NULL; } f_a->fs = fs; if (fs != 16000) fs = 32000; init_highpass_filter_zam(&f_a->hpfa, 100, (float) f_a->fs); init_highpass_filter_zam(&f_a->hpfb, 100, (float) f_a->fs); unsigned int lowpass_filter_frequency = 12000; if (f_a->fs > (lowpass_filter_frequency * 2)) { init_lowpass_filter_zam(&f_a->lpfa, lowpass_filter_frequency, (float) f_a->fs); init_lowpass_filter_zam(&f_a->lpfb, lowpass_filter_frequency, (float) f_a->fs); f_a->lowpass_enabled = 1; } if (WebRtcAgc_Create(&f_a->gain_control) == -1) { free(f_a); return NULL; } if (WebRtcNsx_Create(&f_a->noise_sup_x) == -1) { WebRtcAgc_Free(f_a->gain_control); free(f_a); return NULL; } if (WebRtcAec_Create(&f_a->echo_cancellation) == -1) { WebRtcAgc_Free(f_a->gain_control); WebRtcNsx_Free(f_a->noise_sup_x); free(f_a); return NULL; } if (WebRtcVad_Create(&f_a->Vad_handle) == -1){ WebRtcAec_Free(f_a->echo_cancellation); WebRtcAgc_Free(f_a->gain_control); WebRtcNsx_Free(f_a->noise_sup_x); free(f_a); return NULL; } WebRtcAgc_config_t gain_config; gain_config.targetLevelDbfs = 1; gain_config.compressionGaindB = 20; gain_config.limiterEnable = kAgcTrue; if (WebRtcAgc_Init(f_a->gain_control, 0, 255, kAgcModeAdaptiveDigital, fs) == -1 || WebRtcAgc_set_config(f_a->gain_control, gain_config) == -1) { kill_filter_audio(f_a); return NULL; } if (WebRtcNsx_Init(f_a->noise_sup_x, fs) == -1 || WebRtcNsx_set_policy(f_a->noise_sup_x, 2) == -1) { kill_filter_audio(f_a); return NULL; } AecConfig echo_config; echo_config.nlpMode = kAecNlpAggressive; echo_config.skewMode = kAecFalse; echo_config.metricsMode = kAecFalse; echo_config.delay_logging = kAecFalse; if (WebRtcAec_Init(f_a->echo_cancellation, fs, f_a->fs) == -1 || WebRtcAec_set_config(f_a->echo_cancellation, echo_config) == -1) { kill_filter_audio(f_a); return NULL; } int vad_mode = 1; //Aggressiveness mode (0, 1, 2, or 3). if (WebRtcVad_Init(f_a->Vad_handle) == -1 || WebRtcVad_set_mode(f_a->Vad_handle,vad_mode) == -1){ kill_filter_audio(f_a); return NULL; } f_a->echo_enabled = 1; f_a->gain_enabled = 1; f_a->noise_enabled = 1; f_a->vad_enabled = 1; int quality = 4; if (f_a->fs != 16000) { f_a->downsampler = speex_resampler_init(1, f_a->fs, 32000, quality, 0); f_a->upsampler = speex_resampler_init(1, 32000, f_a->fs, quality, 0); /* quality doesn't need to be high for this one. */ quality = 0; f_a->downsampler_echo = speex_resampler_init(1, f_a->fs, 16000, quality, 0); if (!f_a->upsampler || !f_a->downsampler || !f_a->downsampler_echo) { kill_filter_audio(f_a); return NULL; } } return f_a; }
void KotiAEC_init(int16_t frame_size, int32_t sample_freq, AEC_CORE aec_core, int speex_filter_length, int16_t agc_mode, int16_t compression_gain_db, uint8_t limiter_enable, float snd_amplification) { int32_t speex_agc = 0; float speex_agc_level = 24000, speex_agc_level_tmp = 3000; int32_t speex_noise_suppress = -15; aec_core_used = aec_core; output_sound_amplification = snd_amplification; switch(aec_core) { #ifdef WEBRTC_AEC_CORE_ENABLED case WEBRTC_AEC: if(webrtc_aec_pty.webrtc_aec == NULL) { webrtc_aec_pty.frame_size = frame_size; webrtc_aec_pty.sample_freq = sample_freq; webrtc_aec_pty.sndcard_sample_freq = sample_freq; webrtc_aec_pty.sndcard_delay_ms = ((float)speex_filter_length/sample_freq) * 1000; if( WebRtcAec_Create(&webrtc_aec_pty.webrtc_aec) == 0) WebRtcAec_Init(webrtc_aec_pty.webrtc_aec, webrtc_aec_pty.sample_freq, webrtc_aec_pty.sndcard_sample_freq); if( WebRtcNsx_Create((NsxHandle**)&webrtc_aec_pty.webrtc_ns) == 0) { WebRtcNsx_Init((NsxHandle*)webrtc_aec_pty.webrtc_ns, webrtc_aec_pty.sample_freq); WebRtcNsx_set_policy((NsxHandle*)webrtc_aec_pty.webrtc_ns, 1); } if( WebRtcAgc_Create(&webrtc_aec_pty.webrtc_agc) == 0) { WebRtcAgc_Init(webrtc_aec_pty.webrtc_agc, 0, 255, agc_mode/*kAgcModeFixedDigital*/, webrtc_aec_pty.sample_freq); WebRtcAgc_config_t conf = {0, compression_gain_db, limiter_enable}; WebRtcAgc_set_config(webrtc_aec_pty.webrtc_agc, conf); } } else { WebRtcAec_Init(webrtc_aec_pty.webrtc_aec, webrtc_aec_pty.sample_freq, webrtc_aec_pty.sndcard_sample_freq); } break; case WEBRTC_AECM: if(webrtc_aecm_pty.webrtc_aec == NULL) { webrtc_aecm_pty.frame_size = frame_size; webrtc_aecm_pty.sample_freq = sample_freq; webrtc_aecm_pty.sndcard_sample_freq = sample_freq; webrtc_aecm_pty.sndcard_delay_ms = ((float)speex_filter_length/sample_freq) * 1000; // webrtc_aecm_pty.sndcard_delay_ms = speex_filter_length/frame_size; if( WebRtcAecm_Create(&webrtc_aecm_pty.webrtc_aec) == 0) WebRtcAecm_Init(webrtc_aecm_pty.webrtc_aec, webrtc_aecm_pty.sample_freq); if( WebRtcNsx_Create((NsxHandle**)&webrtc_aecm_pty.webrtc_ns) == 0) { WebRtcNsx_Init((NsxHandle*)webrtc_aecm_pty.webrtc_ns, webrtc_aecm_pty.sample_freq); WebRtcNsx_set_policy((NsxHandle*)webrtc_aecm_pty.webrtc_ns, 1); } if( WebRtcAgc_Create(&webrtc_aecm_pty.webrtc_agc) == 0) { WebRtcAgc_Init(webrtc_aecm_pty.webrtc_agc, 0, 255, agc_mode/*kAgcModeFixedDigital*/, webrtc_aecm_pty.sample_freq); WebRtcAgc_config_t conf = {0, compression_gain_db, limiter_enable}; WebRtcAgc_set_config(webrtc_aecm_pty.webrtc_agc, conf); } } break; #endif case SPEEX_AEC: default: #ifdef OLD_SPEEX_AEC if(speex_aec_pty.speex_echo_state == NULL && speex_aec_pty.speex_preprocess_state == NULL) { speex_aec_pty.frame_size = frame_size; speex_aec_pty.sample_freq = sample_freq; speex_aec_pty.filter_length = speex_filter_length; if(speex_aec_pty.filter_length < frame_size) speex_aec_pty.filter_length = frame_size*FILTER_LENGTH_MULTIPLE_OF_FRAME_SIZE; speex_aec_pty.speex_echo_state = speex_echo_state_init(frame_size, speex_aec_pty.filter_length); speex_aec_pty.speex_preprocess_state = speex_preprocess_state_init(frame_size, sample_freq); speex_echo_ctl((SpeexEchoState*)speex_aec_pty.speex_echo_state, SPEEX_ECHO_SET_SAMPLING_RATE, &speex_aec_pty.sample_freq); speex_aec_pty.nosie = (int32_t*) malloc( (frame_size+1) * sizeof(int32_t) ); } #else if(speex_aec_pty.speex_echo_state == NULL && speex_aec_pty.speex_preprocess_state == NULL) { speex_aec_pty.frame_size = frame_size; speex_aec_pty.sample_freq = sample_freq; speex_aec_pty.filter_length = speex_filter_length; if(speex_aec_pty.filter_length < frame_size) speex_aec_pty.filter_length = frame_size*FILTER_LENGTH_MULTIPLE_OF_FRAME_SIZE; speex_aec_pty.speex_echo_state = speex_echo_state_init(frame_size, speex_aec_pty.filter_length); speex_aec_pty.speex_preprocess_state = speex_preprocess_state_init(frame_size, sample_freq); speex_echo_ctl((SpeexEchoState*)speex_aec_pty.speex_echo_state, SPEEX_ECHO_SET_SAMPLING_RATE, &speex_aec_pty.sample_freq); speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_SET_ECHO_STATE, speex_aec_pty.speex_echo_state); speex_aec_pty.nosie = (int32_t*) malloc( (frame_size+1) * sizeof(int32_t) ); speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_SET_AGC, &speex_agc); speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_SET_AGC_LEVEL, &speex_agc_level); speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &speex_noise_suppress); speex_aec_pty.speex_preprocess_state_tmp = speex_preprocess_state_init(frame_size, sample_freq); speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state_tmp, SPEEX_PREPROCESS_SET_AGC, &speex_agc); speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state_tmp, SPEEX_PREPROCESS_SET_AGC_LEVEL, &speex_agc_level_tmp); speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state_tmp, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &speex_noise_suppress); // int32_t speex_vad = 1; // int32_t speex_vad_prob_start = 80; // int32_t speex_vad_prob_continue = 65; // speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_SET_VAD, &speex_vad); // speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_SET_PROB_START, // &speex_vad_prob_start); // speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_SET_PROB_CONTINUE, // &speex_vad_prob_continue); // int32_t tmp = -1; float tmp1 = 0.0f; // speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_DENOISE, &tmp); // printf("SPEEX_PREPROCESS_GET_DENOISE: %d\n", tmp); // speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_NOISE_SUPPRESS, &tmp); // printf("SPEEX_PREPROCESS_GET_NOISE_SUPPRESS: %d\n", tmp); // speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_AGC, &tmp); // printf("SPEEX_PREPROCESS_GET_AGC: %d\n", tmp); // speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_VAD, &tmp); // printf("SPEEX_PREPROCESS_GET_VAD: %d\n", tmp); // speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_PROB_START, &tmp); // printf("SPEEX_PREPROCESS_GET_PROB_START: %d\n", tmp); // speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_PROB_CONTINUE, &tmp); // printf("SPEEX_PREPROCESS_GET_PROB_CONTINUE: %d\n", tmp); // speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_AGC_LEVEL, &tmp1); // printf("SPEEX_PREPROCESS_GET_AGC_LEVEL: %f\n", tmp1); // speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_AGC_DECREMENT, &tmp); // printf("SPEEX_PREPROCESS_GET_AGC_DECREMENT: %d\n", tmp); // speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_AGC_INCREMENT, &tmp); // printf("SPEEX_PREPROCESS_GET_AGC_INCREMENT: %d\n", tmp); // speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_AGC_MAX_GAIN, &tmp); // printf("SPEEX_PREPROCESS_GET_AGC_MAX_GAIN: %d\n", tmp); // speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_AGC_GAIN, &tmp); // printf("SPEEX_PREPROCESS_GET_AGC_GAIN: %d\n", tmp); // speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_AGC_TARGET, &tmp); // printf("SPEEX_PREPROCESS_GET_AGC_TARGET: %d\n", tmp); // speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_AGC_LOUDNESS, &tmp); // printf("SPEEX_PREPROCESS_GET_AGC_LOUDNESS: %d\n", tmp); // speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_ECHO_SUPPRESS, &tmp); // printf("SPEEX_PREPROCESS_GET_ECHO_SUPPRESS: %d\n", tmp); // speex_preprocess_ctl((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE, &tmp); // printf("SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE: %d\n", tmp); } #endif break; } }