int EchoCancellationImpl::ConfigureHandle(void* handle) const { assert(handle != NULL); AecConfig config; config.metricsMode = metrics_enabled_; config.nlpMode = MapSetting(suppression_level_); config.skewMode = drift_compensation_enabled_; config.delay_logging = delay_logging_enabled_; return WebRtcAec_set_config(static_cast<Handle*>(handle), config); }
static int tdav_webrtc_denoise_open(tmedia_denoise_t* self, uint32_t frame_size, uint32_t sampling_rate) { tdav_webrtc_denoise_t *denoiser = (tdav_webrtc_denoise_t *)self; int ret; if(!denoiser){ TSK_DEBUG_ERROR("Invalid parameter"); return -1; } if(denoiser->AEC_inst || #if HAVE_SPEEX_DSP && PREFER_SPEEX_DENOISER denoiser->SpeexDenoiser_proc #else denoiser->NS_inst #endif ){ TSK_DEBUG_ERROR("Denoiser already initialized"); return -2; } denoiser->echo_tail = TSK_CLAMP(WEBRTC_MIN_ECHO_TAIL, TMEDIA_DENOISE(denoiser)->echo_tail, WEBRTC_MAX_ECHO_TAIL); TSK_DEBUG_INFO("echo_tail=%d", denoiser->echo_tail); denoiser->echo_skew = TMEDIA_DENOISE(denoiser)->echo_skew; denoiser->frame_size = frame_size; denoiser->sampling_rate = sampling_rate; // // AEC instance // if((ret = TDAV_WebRtcAec_Create(&denoiser->AEC_inst))){ TSK_DEBUG_ERROR("WebRtcAec_Create failed with error code = %d", ret); return ret; } if((ret = TDAV_WebRtcAec_Init(denoiser->AEC_inst, denoiser->sampling_rate, denoiser->sampling_rate))){ TSK_DEBUG_ERROR("WebRtcAec_Init failed with error code = %d", ret); return ret; } #if WEBRTC_AEC_AGGRESSIVE { AecConfig aecConfig; aecConfig.nlpMode = kAecNlpAggressive; aecConfig.skewMode = kAecTrue; aecConfig.metricsMode = kAecFalse; aecConfig.delay_logging = kAecFalse; if((ret = WebRtcAec_set_config(denoiser->AEC_inst, aecConfig))){ TSK_DEBUG_ERROR("WebRtcAec_set_config failed with error code = %d", ret); } } #endif // // Noise Suppression instance // if(TMEDIA_DENOISE(denoiser)->noise_supp_enabled){ #if HAVE_SPEEX_DSP && PREFER_SPEEX_DENOISER if((denoiser->SpeexDenoiser_proc = speex_preprocess_state_init(denoiser->frame_size, denoiser->sampling_rate))){ int i = 1; speex_preprocess_ctl(denoiser->SpeexDenoiser_proc, SPEEX_PREPROCESS_SET_DENOISE, &i); i = TMEDIA_DENOISE(denoiser)->noise_supp_level; speex_preprocess_ctl(denoiser->SpeexDenoiser_proc, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &i); } #else if((ret = TDAV_WebRtcNs_Create(&denoiser->NS_inst))){ TSK_DEBUG_ERROR("WebRtcNs_Create failed with error code = %d", ret); return ret; } if((ret = TDAV_WebRtcNs_Init(denoiser->NS_inst, denoiser->sampling_rate))){ TSK_DEBUG_ERROR("WebRtcNs_Init failed with error code = %d", ret); return ret; } #endif } // allocate temp buffer for record processing if(!(denoiser->temp_rec_out = tsk_realloc(denoiser->temp_rec_out, denoiser->frame_size * kSizeOfWord16))){ TSK_DEBUG_ERROR("Failed to allocate new buffer"); return -3; } TSK_DEBUG_INFO("WebRTC denoiser opened"); return ret; }
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; }
int32_t WebRtcAec_Init(void *aecInst, int32_t sampFreq, int32_t scSampFreq) { aecpc_t *aecpc = aecInst; AecConfig aecConfig; if (aecpc == NULL) { return -1; } if (sampFreq != 8000 && sampFreq != 16000 && sampFreq != 32000) { aecpc->lastError = AEC_BAD_PARAMETER_ERROR; return -1; } aecpc->sampFreq = sampFreq; if (scSampFreq < 1 || scSampFreq > 96000) { aecpc->lastError = AEC_BAD_PARAMETER_ERROR; return -1; } aecpc->scSampFreq = scSampFreq; // Initialize echo canceller core if (WebRtcAec_InitAec(aecpc->aec, aecpc->sampFreq) == -1) { aecpc->lastError = AEC_UNSPECIFIED_ERROR; return -1; } if (WebRtcAec_InitResampler(aecpc->resampler, aecpc->scSampFreq) == -1) { aecpc->lastError = AEC_UNSPECIFIED_ERROR; return -1; } if (WebRtc_InitBuffer(aecpc->far_pre_buf) == -1) { aecpc->lastError = AEC_UNSPECIFIED_ERROR; return -1; } WebRtc_MoveReadPtr(aecpc->far_pre_buf, -PART_LEN); // Start overlap. aecpc->initFlag = initCheck; // indicates that initialization has been done if (aecpc->sampFreq == 32000) { aecpc->splitSampFreq = 16000; } else { aecpc->splitSampFreq = sampFreq; } aecpc->skewFrCtr = 0; aecpc->activity = 0; aecpc->delayCtr = 0; aecpc->sum = 0; aecpc->counter = 0; aecpc->checkBuffSize = 1; aecpc->firstVal = 0; aecpc->ECstartup = 1; aecpc->bufSizeStart = 0; aecpc->checkBufSizeCtr = 0; aecpc->filtDelay = 0; aecpc->timeForDelayChange = 0; aecpc->knownDelay = 0; aecpc->lastDelayDiff = 0; aecpc->skew = 0; aecpc->resample = kAecFalse; aecpc->highSkewCtr = 0; aecpc->sampFactor = (aecpc->scSampFreq * 1.0f) / aecpc->splitSampFreq; // Sampling frequency multiplier (SWB is processed as 160 frame size). aecpc->rate_factor = aecpc->splitSampFreq / 8000; // Default settings. aecConfig.nlpMode = kAecNlpModerate; aecConfig.skewMode = kAecFalse; aecConfig.metricsMode = kAecFalse; aecConfig.delay_logging = kAecFalse; if (WebRtcAec_set_config(aecpc, aecConfig) == -1) { aecpc->lastError = AEC_UNSPECIFIED_ERROR; return -1; } #ifdef WEBRTC_AEC_DEBUG_DUMP if (WebRtc_InitBuffer(aecpc->far_pre_buf_s16) == -1) { aecpc->lastError = AEC_UNSPECIFIED_ERROR; return -1; } WebRtc_MoveReadPtr(aecpc->far_pre_buf_s16, -PART_LEN); // Start overlap. #endif return 0; }
int32_t WebRtcAec_Init(void* aecInst, int32_t sampFreq, int32_t scSampFreq) { Aec* aecpc = aecInst; AecConfig aecConfig; if (sampFreq != 8000 && sampFreq != 16000 && sampFreq != 32000 && sampFreq != 48000) { return AEC_BAD_PARAMETER_ERROR; } aecpc->sampFreq = sampFreq; if (scSampFreq < 1 || scSampFreq > 96000) { return AEC_BAD_PARAMETER_ERROR; } aecpc->scSampFreq = scSampFreq; // Initialize echo canceller core if (WebRtcAec_InitAec(aecpc->aec, aecpc->sampFreq) == -1) { return AEC_UNSPECIFIED_ERROR; } if (WebRtcAec_InitResampler(aecpc->resampler, aecpc->scSampFreq) == -1) { return AEC_UNSPECIFIED_ERROR; } WebRtc_InitBuffer(aecpc->far_pre_buf); WebRtc_MoveReadPtr(aecpc->far_pre_buf, -PART_LEN); // Start overlap. aecpc->initFlag = initCheck; // indicates that initialization has been done if (aecpc->sampFreq == 32000 || aecpc->sampFreq == 48000) { aecpc->splitSampFreq = 16000; } else { aecpc->splitSampFreq = sampFreq; } aecpc->delayCtr = 0; aecpc->sampFactor = (aecpc->scSampFreq * 1.0f) / aecpc->splitSampFreq; // Sampling frequency multiplier (SWB is processed as 160 frame size). aecpc->rate_factor = aecpc->splitSampFreq / 8000; aecpc->sum = 0; aecpc->counter = 0; aecpc->checkBuffSize = 1; aecpc->firstVal = 0; // We skip the startup_phase completely (setting to 0) if DA-AEC is enabled, // but not extended_filter mode. aecpc->startup_phase = WebRtcAec_extended_filter_enabled(aecpc->aec) || !WebRtcAec_delay_agnostic_enabled(aecpc->aec); aecpc->bufSizeStart = 0; aecpc->checkBufSizeCtr = 0; aecpc->msInSndCardBuf = 0; aecpc->filtDelay = -1; // -1 indicates an initialized state. aecpc->timeForDelayChange = 0; aecpc->knownDelay = 0; aecpc->lastDelayDiff = 0; aecpc->skewFrCtr = 0; aecpc->resample = kAecFalse; aecpc->highSkewCtr = 0; aecpc->skew = 0; aecpc->farend_started = 0; // Default settings. aecConfig.nlpMode = kAecNlpModerate; aecConfig.skewMode = kAecFalse; aecConfig.metricsMode = kAecFalse; aecConfig.delay_logging = kAecFalse; if (WebRtcAec_set_config(aecpc, aecConfig) == -1) { return AEC_UNSPECIFIED_ERROR; } return 0; }