/*
 * Project 25 IMBE Encoder/Decoder Fixed-Point implementation
 * Developed by Pavel Yazev E-mail: pyazev@gmail.com
 * Version 1.0 (c) Copyright 2009
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3, or (at your option)
 * any later version.
 *
 * The software is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this; see the file COPYING.  If not, write to the Free
 * Software Foundation, Inc., 51 Franklin Street, Boston, MA
 * 02110-1301, USA.
 */

#include "vocoder/imbe/typedef.h"
#include "vocoder/imbe/globals.h"
#include "vocoder/imbe/imbe.h"
#include "vocoder/imbe/basic_op.h"
#include "vocoder/imbe/aux_sub.h"
#include "vocoder/imbe/tbls.h"
#include "vocoder/imbe/dc_rmv.h"
#include "vocoder/imbe/pe_lpf.h"
#include "vocoder/imbe/pitch_est.h"
#include "vocoder/imbe/pitch_ref.h"
#include "vocoder/imbe/ch_encode.h"
#include "vocoder/imbe/imbe_vocoder.h"

// ---------------------------------------------------------------------------
//  Private Class Members
// ---------------------------------------------------------------------------

void imbe_vocoder::encode_init(void)
{
    v_zap(pitch_est_buf, PITCH_EST_BUF_SIZE);
    v_zap(pitch_ref_buf, PITCH_EST_BUF_SIZE);
    v_zap(pe_lpf_mem, PE_LPF_ORD);
    pitch_est_init();
    fft_init();
    dc_rmv_mem = 0;
    sa_encode_init();
    pitch_ref_init();
}

void imbe_vocoder::encode(IMBE_PARAM* imbe_param, Word16* frame_vector, Word16* snd)
{
    Word16 i;
    Word16* wr_ptr, *sig_ptr;

    for (i = 0; i < PITCH_EST_BUF_SIZE - FRAME; i++) {
        pitch_est_buf[i] = pitch_est_buf[i + FRAME];
        pitch_ref_buf[i] = pitch_ref_buf[i + FRAME];
    }

    dc_rmv(snd, &pitch_ref_buf[PITCH_EST_BUF_SIZE - FRAME], &dc_rmv_mem, FRAME);
    pe_lpf(&pitch_ref_buf[PITCH_EST_BUF_SIZE - FRAME], &pitch_est_buf[PITCH_EST_BUF_SIZE - FRAME], pe_lpf_mem, FRAME);

    pitch_est(imbe_param, pitch_est_buf);

    //
    // Speech windowing and FFT calculation
    //
    wr_ptr = (Word16*)wr;
    sig_ptr = &pitch_ref_buf[40];
    for (i = 146; i < 256; i++) {
        fft_buf[i].re = mult(*sig_ptr++, *wr_ptr++);
        fft_buf[i].im = 0;
    }
    fft_buf[0].re = *sig_ptr++;
    fft_buf[0].im = 0;
    wr_ptr--;
    for (i = 1; i < 111; i++) {
        fft_buf[i].re = mult(*sig_ptr++, *wr_ptr--);
        fft_buf[i].im = 0;
    }
    for (i = 111; i < 146; i++)
        fft_buf[i].re = fft_buf[i].im = 0;

    fft((Word16*)&fft_buf, FFTLENGTH, 1);

    pitch_ref(imbe_param, fft_buf);
    v_uv_det(imbe_param, fft_buf);
    sa_encode(imbe_param);
    encode_frame_vector(imbe_param, frame_vector);
}
