int32_t WebRtcAec_Create(void **aecInst)
{
    aecpc_t *aecpc;
    if (aecInst == NULL) {
        return -1;
    }

    aecpc = malloc(sizeof(aecpc_t));
    *aecInst = aecpc;
    if (aecpc == NULL) {
        return -1;
    }

    if (WebRtcAec_CreateAec(&aecpc->aec) == -1) {
        WebRtcAec_Free(aecpc);
        aecpc = NULL;
        return -1;
    }

    if (WebRtcAec_CreateResampler(&aecpc->resampler) == -1) {
        WebRtcAec_Free(aecpc);
        aecpc = NULL;
        return -1;
    }
    // Create far-end pre-buffer. The buffer size has to be large enough for
    // largest possible drift compensation (kResamplerBufferSize) + "almost" an
    // FFT buffer (PART_LEN2 - 1).
    aecpc->far_pre_buf = WebRtc_CreateBuffer(PART_LEN2 + kResamplerBufferSize,
                                             sizeof(float));
    if (!aecpc->far_pre_buf) {
        WebRtcAec_Free(aecpc);
        aecpc = NULL;
        return -1;
    }

    aecpc->initFlag = 0;
    aecpc->lastError = 0;

#ifdef WEBRTC_AEC_DEBUG_DUMP
    aecpc->far_pre_buf_s16 = WebRtc_CreateBuffer(
        PART_LEN2 + kResamplerBufferSize, sizeof(int16_t));
    if (!aecpc->far_pre_buf_s16) {
        WebRtcAec_Free(aecpc);
        aecpc = NULL;
        return -1;
    }
    {
      char filename[64];
      sprintf(filename, "aec_buf%d.dat", webrtc_aec_instance_count);
      aecpc->bufFile = fopen(filename, "wb");
      sprintf(filename, "aec_skew%d.dat", webrtc_aec_instance_count);
      aecpc->skewFile = fopen(filename, "wb");
      sprintf(filename, "aec_delay%d.dat", webrtc_aec_instance_count);
      aecpc->delayFile = fopen(filename, "wb");
      webrtc_aec_instance_count++;
    }
#endif

    return 0;
}
示例#2
0
void kill_filter_audio(Filter_Audio *f_a)
{
    if (!f_a) {
        return;
    }

    WebRtcNsx_Free(f_a->noise_sup_x);
    WebRtcAgc_Free(f_a->gain_control);
    WebRtcAec_Free(f_a->echo_cancellation);
    WebRtcVad_Free(f_a->Vad_handle);
    speex_resampler_destroy(f_a->upsampler);
    speex_resampler_destroy(f_a->downsampler);
    speex_resampler_destroy(f_a->downsampler_echo);
    free(f_a);
}
void* WebRtcAec_Create() {
  Aec* aecpc = malloc(sizeof(Aec));

  if (!aecpc) {
    return NULL;
  }

  aecpc->aec = WebRtcAec_CreateAec();
  if (!aecpc->aec) {
    WebRtcAec_Free(aecpc);
    return NULL;
  }
  aecpc->resampler = WebRtcAec_CreateResampler();
  if (!aecpc->resampler) {
    WebRtcAec_Free(aecpc);
    return NULL;
  }
  // Create far-end pre-buffer. The buffer size has to be large enough for
  // largest possible drift compensation (kResamplerBufferSize) + "almost" an
  // FFT buffer (PART_LEN2 - 1).
  aecpc->far_pre_buf =
      WebRtc_CreateBuffer(PART_LEN2 + kResamplerBufferSize, sizeof(float));
  if (!aecpc->far_pre_buf) {
    WebRtcAec_Free(aecpc);
    return NULL;
  }

  aecpc->initFlag = 0;

#ifdef WEBRTC_AEC_DEBUG_DUMP
  aecpc->bufFile = aecpc->skewFile = aecpc->delayFile = NULL;
  OpenDebugFiles(aecpc, &webrtc_aec_instance_count);
#endif

  return aecpc;
}
示例#4
0
int EchoCancellationImpl::DestroyHandle(void* handle) const {
  assert(handle != NULL);
  return WebRtcAec_Free(static_cast<Handle*>(handle));
}
示例#5
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;
}
示例#6
0
void KotiAEC_destory()
{
    if(speex_aec_pty.speex_echo_state != NULL && speex_aec_pty.speex_preprocess_state != NULL)
    {
        speex_echo_state_destroy((SpeexEchoState*)speex_aec_pty.speex_echo_state);
        speex_preprocess_state_destroy((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state);

        if(speex_aec_pty.speex_preprocess_state_tmp)
            speex_preprocess_state_destroy((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state_tmp);

        if(speex_aec_pty.nosie)
            free(speex_aec_pty.nosie);

        speex_aec_pty.speex_echo_state = NULL;
        speex_aec_pty.speex_preprocess_state = NULL;
        speex_aec_pty.speex_preprocess_state_tmp = NULL;
        speex_aec_pty.frame_size = 0;
        speex_aec_pty.sample_freq = 0;
        speex_aec_pty.filter_length = 0;
        speex_aec_pty.nosie = NULL;
    }

#ifdef WEBRTC_AEC_CORE_ENABLED
    if(webrtc_aec_pty.webrtc_aec != NULL)
    {
        WebRtcAec_Free(webrtc_aec_pty.webrtc_aec);
        webrtc_aec_pty.webrtc_aec = NULL;
        webrtc_aec_pty.frame_size = 0;
        webrtc_aec_pty.sample_freq = 0;
        webrtc_aec_pty.sndcard_sample_freq = 0;

        if(webrtc_aec_pty.webrtc_ns)
        {
            WebRtcNsx_Free((NsxHandle*)webrtc_aec_pty.webrtc_ns);
            webrtc_aec_pty.webrtc_ns = NULL;
        }
        if(webrtc_aec_pty.webrtc_agc)
        {
            WebRtcAgc_Free(webrtc_aec_pty.webrtc_agc);
            webrtc_aec_pty.webrtc_agc = NULL;
        }
    }

    if(webrtc_aecm_pty.webrtc_aec != NULL)
    {
        WebRtcAecm_Free(webrtc_aecm_pty.webrtc_aec);
        webrtc_aecm_pty.webrtc_aec = NULL;
        webrtc_aecm_pty.frame_size = 0;
        webrtc_aecm_pty.sample_freq = 0;
        webrtc_aecm_pty.sndcard_sample_freq = 0;

        if(webrtc_aecm_pty.webrtc_ns)
        {
            WebRtcNsx_Free((NsxHandle*)webrtc_aecm_pty.webrtc_ns);
            webrtc_aecm_pty.webrtc_ns = NULL;
        }
        if(webrtc_aecm_pty.webrtc_agc)
        {
            WebRtcAgc_Free(webrtc_aecm_pty.webrtc_agc);
            webrtc_aecm_pty.webrtc_agc = NULL;
        }
    }
#endif
}