/*---------------------------------------------------------------------------*/
/*
  File: saec.h

  Acoustic echo canceller.
*/
/*---------------------------------------------------------------------------*/

#include "platform.h"
#include "sdsputil.h"
#include "saec.h"

#define FILE_ "saec.cpp"

NAMESPACE_BEGIN

/*---------------------------------------------------------------------------*/

void softdsp_aec_init(t_softdsp_aec *p_aec, word frame_length, word tail_frames, word predelay_samples, word options,
    dword nominal_return_loss, word max_loop_gain, word noise_suppress_level)
{
    word i;

    p_aec->predelay_size = predelay_samples;
    p_aec->predelay_read_pos = 0;
    p_aec->predelay_write_pos = 0;
    for(i = 0; i < predelay_samples; i++) {
        p_aec->predelay_sample_buffer[i] = 0;
    }
    freqaec_init (&(p_aec->ec), frame_length, tail_frames, options, nominal_return_loss, max_loop_gain, noise_suppress_level);
}

void softdsp_aec_flush(t_softdsp_aec *p_aec, word preserve_filter_frames)
{
    word i;

    for(i = 0; i < p_aec->predelay_size; i++) {
        p_aec->predelay_sample_buffer[i] = 0;
    }
    freqaec_flush(&(p_aec->ec), preserve_filter_frames);
}

void softdsp_aec_s_exec(t_softdsp_aec *p_aec, const short *sin_samples, short *sout_samples, word sample_count)
{
    word sample_pos;

    for(sample_pos = 0; sample_pos < sample_count; sample_pos++) {
        sout_samples[sample_pos] = freqaec_exec (&(p_aec->ec), p_aec->predelay_sample_buffer[p_aec->predelay_read_pos], sin_samples[sample_pos]);
        p_aec->predelay_read_pos = (p_aec->predelay_read_pos < p_aec->predelay_size - 1) ? p_aec->predelay_read_pos + 1 : 0;
    }
}

void softdsp_aec_r_exec(t_softdsp_aec *p_aec, const short *rin_samples, short *rout_samples, word sample_count)
{
    word sample_pos;

    for(sample_pos = 0; sample_pos < sample_count; sample_pos++) {
        rout_samples[sample_pos] = freqaec_r_exec (&(p_aec->ec), rin_samples[sample_pos]);
        p_aec->predelay_sample_buffer[p_aec->predelay_write_pos] = rout_samples[sample_pos];
        p_aec->predelay_write_pos = (p_aec->predelay_write_pos < p_aec->predelay_size - 1) ? p_aec->predelay_write_pos + 1 : 0;
    }
}


NAMESPACE_END

/*---------------------------------------------------------------------------*/
