Exemple #1
0
int EchoCancellationImpl::ProcessRenderAudio(const AudioBuffer* audio) {
  if (!is_component_enabled()) {
    return apm_->kNoError;
  }

  assert(audio->samples_per_split_channel() <= 160);
  assert(audio->num_channels() == apm_->num_reverse_channels());

  int err = apm_->kNoError;

  // The ordering convention must be followed to pass to the correct AEC.
  size_t handle_index = 0;
  for (int i = 0; i < apm_->num_output_channels(); i++) {
    for (int j = 0; j < audio->num_channels(); j++) {
      Handle* my_handle = static_cast<Handle*>(handle(handle_index));
      err = WebRtcAec_BufferFarend(
          my_handle,
          audio->low_pass_split_data(j),
          static_cast<WebRtc_Word16>(audio->samples_per_split_channel()));

      if (err != apm_->kNoError) {
        return GetHandleError(my_handle);  // TODO(ajm): warning possible?
      }

      handle_index++;
    }
  }

  return apm_->kNoError;
}
Exemple #2
0
int speex_aec_playback_for_async(int16_t* farend, float snd_amplification)
{
    int ret_val = -1;
    switch(aec_core_used)
    {
#ifdef WEBRTC_AEC_CORE_ENABLED
    case WEBRTC_AEC:
        if(webrtc_aec_pty.webrtc_aec)
            ret_val = WebRtcAec_BufferFarend(webrtc_aec_pty.webrtc_aec, farend, webrtc_aec_pty.frame_size);
        break;
    case WEBRTC_AECM:
        if(webrtc_aecm_pty.webrtc_aec)
            ret_val = WebRtcAecm_BufferFarend(webrtc_aecm_pty.webrtc_aec, farend, webrtc_aecm_pty.frame_size);
        break;
#endif
    case SPEEX_AEC:
    default:
        if(speex_aec_pty.speex_echo_state)
        {
            speex_echo_playback((SpeexEchoState*)speex_aec_pty.speex_echo_state, farend);
    //        speex_preprocess_run((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state_tmp, farend);
            ret_val = 0;
        }
        break;
    }

    if(snd_amplification != 1.0f && snd_amplification > 0)
    {
        for(int i=0; i<speex_aec_pty.frame_size; ++i)
            farend[i] = farend[i]*snd_amplification;
    }

    return ret_val;
}
Exemple #3
0
int pass_audio_output(Filter_Audio *f_a, const int16_t *data, unsigned int samples)
{
    if (!f_a || (!f_a->echo_enabled && !f_a->gain_enabled)) {
        return -1;
    }

    unsigned int nsx_samples = f_a->fs / 100;
    if (!samples || (samples % nsx_samples) != 0) {
        return -1;
    }

    _Bool resample = 0;
    unsigned int resampled_samples = 0;
    if (f_a->fs != 16000) {
        samples = (samples / nsx_samples) * 160;
        nsx_samples = 160;
        resample = 1;
    }

    unsigned int temp_samples = samples;

    float *d_f = (float *)STACK_ALLOC( nsx_samples * sizeof(float) + nsx_samples * sizeof(int16_t) );

    while (temp_samples) {

        if (resample) {
            int16_t *d = (int16_t *)(d_f + nsx_samples);
            downsample_audio_echo_in(f_a, d, data + resampled_samples);

            if (WebRtcAgc_AddFarend(f_a->gain_control, d, nsx_samples) == -1)
                return -1;

            S16ToFloatS16(d, nsx_samples, d_f);
            resampled_samples += f_a->fs / 100;
        } else {
            S16ToFloatS16(data + (samples - temp_samples), nsx_samples, d_f);
        }

        if (WebRtcAec_BufferFarend(f_a->echo_cancellation, d_f, nsx_samples) == -1) {
            return -1;
        }

        temp_samples -= nsx_samples;
    }

    return 0;
}
Exemple #4
0
int KotiAEC_process(const int16_t* farend, const int16_t* nearend, int16_t* out)
{
    int ret = -1, i = 0, frame_size = 0;
    switch(aec_core_used)
    {
#ifdef WEBRTC_AEC_CORE_ENABLED
    case WEBRTC_AEC:
        if(farend)
            WebRtcAec_BufferFarend(webrtc_aec_pty.webrtc_aec, farend, webrtc_aec_pty.frame_size);
        if(!WebRtcAec_Process(webrtc_aec_pty.webrtc_aec, nearend, NULL, out, NULL, webrtc_aec_pty.frame_size,
                                   webrtc_aec_pty.sndcard_delay_ms, 0))
        {
            ret = 0;
        }

        if(webrtc_aec_pty.webrtc_ns)
        {
            WebRtcNsx_Process((NsxHandle*)webrtc_aec_pty.webrtc_ns, out, NULL, out, NULL);
            if(webrtc_aec_pty.frame_size == 160)
                WebRtcNsx_Process((NsxHandle*)webrtc_aec_pty.webrtc_ns, out+80, NULL, out+80, NULL);
        }

        if(webrtc_aec_pty.webrtc_agc)
        {
            int32_t out_c; uint8_t warn_status;
            WebRtcAgc_Process(webrtc_aec_pty.webrtc_agc, out, NULL, webrtc_aec_pty.frame_size, out, NULL, 32,
                              &out_c, 1, &warn_status);
        }

//        if(webrtc_aec_pty.webrtc_ns)
//        {
//            WebRtcNsx_Process((NsxHandle*)webrtc_aec_pty.webrtc_ns, out, NULL, out, NULL);
//            if(webrtc_aec_pty.frame_size == 160)
//                WebRtcNsx_Process((NsxHandle*)webrtc_aec_pty.webrtc_ns, out+80, NULL, out+80, NULL);
//        }

        frame_size = webrtc_aec_pty.frame_size;
        break;
    case WEBRTC_AECM:
/*
        if(farend)
            WebRtcAecm_BufferFarend(webrtc_aecm_pty.webrtc_aec, farend, webrtc_aecm_pty.frame_size);
        if(!WebRtcAecm_Process(webrtc_aecm_pty.webrtc_aec, nearend, NULL, out, webrtc_aecm_pty.frame_size,
                              webrtc_aecm_pty.sndcard_delay_ms))
        {
            ret = 0;
        }
*/

	memcpy(proc_tmp_buf, nearend, webrtc_aecm_pty.frame_size*2);
        if(webrtc_aecm_pty.webrtc_ns)
        {
            WebRtcNsx_Process((NsxHandle*)webrtc_aecm_pty.webrtc_ns, proc_tmp_buf, NULL, proc_tmp_buf, NULL);
            if(webrtc_aecm_pty.frame_size == 160)
                WebRtcNsx_Process((NsxHandle*)webrtc_aecm_pty.webrtc_ns, proc_tmp_buf+80, NULL, proc_tmp_buf+80, NULL);
        }

        if(webrtc_aecm_pty.webrtc_agc)
        {
            int32_t out_c; uint8_t warn_status;
            WebRtcAgc_Process(webrtc_aecm_pty.webrtc_agc, proc_tmp_buf, NULL, webrtc_aecm_pty.frame_size, proc_tmp_buf, NULL, 32,
                              &out_c, 1, &warn_status);
        }

	// AEC
        if(farend)
            WebRtcAecm_BufferFarend(webrtc_aecm_pty.webrtc_aec, farend, webrtc_aecm_pty.frame_size);
        if(!WebRtcAecm_Process(webrtc_aecm_pty.webrtc_aec, proc_tmp_buf, NULL, out, webrtc_aecm_pty.frame_size,
                              webrtc_aecm_pty.sndcard_delay_ms))
        {
            ret = 0;
        }

        frame_size = webrtc_aecm_pty.frame_size;
        break;
#endif
    case SPEEX_AEC:
    default:
#ifdef OLD_SPEEX_AEC
        speex_echo_cancel((SpeexEchoState*)speex_aec_pty.speex_echo_state, nearend, farend, out, speex_aec_pty.nosie);
        if(speex_preprocess((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, out, speex_aec_pty.nosie) == 1)
            ret = 0;
#else
        if(farend)
            speex_echo_cancellation((SpeexEchoState*)speex_aec_pty.speex_echo_state, nearend, farend, out);
        else
            speex_echo_capture((SpeexEchoState*)speex_aec_pty.speex_echo_state, nearend, out);
//        speex_preprocess_estimate_update((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, out);
        if(speex_preprocess_run((SpeexPreprocessState*)speex_aec_pty.speex_preprocess_state, out) == 1)
            ret = 0;
#endif

        frame_size = speex_aec_pty.frame_size;
        break;
    }

    // if the output sound needed amplify
    if(output_sound_amplification != 1.0f && output_sound_amplification > 0)
    {
        for(; i<frame_size; ++i)
            out[i] = out[i]*output_sound_amplification;
    }

    return ret;
}