예제 #1
0
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);
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #5
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;
  }