www.pudn.com > AVS_M_ver10.rar > dec_new_stereo.c


/*
***********************************************************************
* COPYRIGHT AND WARRANTY INFORMATION
*
* Copyright 2007 Audio Video Coding Standard, Part ¢ú
*
* This software module was developed by AVS Audio sub-group
*
* DISCLAIMER OF WARRANTY
*
* These software programs are available to the users without any
* license fee or royalty on an "as is" basis. The AVS disclaims
* any and all warranties, whether express, implied, or statutory,
* including any implied warranties of merchantability or of fitness
* for a particular purpose. In no event shall the contributors or
* the AVS be liable for any incidental, punitive, or consequential
* damages of any kind whatsoever arising from the use of this program.
*
* This disclaimer of warranty extends to the user of this program
* and user's customers, employees, agents, transferees, successors,
* and assigns.
*
* The AVS does not represent or warrant that the program furnished
* hereunder are free of infringement of any third-party patents.
* Commercial implementations of AVS, including shareware, may be
* subject to royalty fees to patent holders. Information regarding
* the AVS patent policy is available from the AVS Web site at
* http://www.avs.org.cn
*
* THIS IS NOT A GRANT OF PATENT RIGHTS - SEE THE AVS PATENT POLICY.
************************************************************************
*/

#include <float.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "../include/amr_plus.h"
#include "../include/s_util.h"
#include "../include/table_decl.h"

/* NEW_STEREO */
/* TO BOTTOM OF THIS FILE */

// initial stereo struction and parameter
void init_new_stereo_decoder(NEW_STEREO_DATA_DEC *newStereo, float old_bitrate)
{
int i;

set_zero(newStereo->old_speech_mono, M+NEW_STEREO_DECODER_DELAY);
set_zero(newStereo->old_speech_left, 512-NEW_STEREO_DELAY);
set_zero(newStereo->old_speech_right, 512-NEW_STEREO_DELAY);

set_zero(newStereo->old_AqLF, 5*(M+1));
for (i = 0;i < 5;i++)
{
newStereo->old_AqLF[i*(M+1)]=1.0f;
}

newStereo->bitrate = old_bitrate;

if (old_bitrate <= 32.0f)
{
newStereo->lowfreq_end_num_l = 128;
newStereo->lowfreq_end_num_s = newStereo->lowfreq_end_num_l / 4;
}
else
{
newStereo->lowfreq_end_num_l = 192;
newStereo->lowfreq_end_num_s = newStereo->lowfreq_end_num_l / 4;
}

set_zero(newStereo->pre_left_gain, MF_GAIN_NUM);
set_zero(newStereo->pre_right_gain, MF_GAIN_NUM);

set_zero(newStereo->old_left_freq_gain, MF_GAIN_NUM);
set_zero(newStereo->old_right_freq_gain, MF_GAIN_NUM);

newStereo->isTransientFrame = 0;

newStereo->mem_ovlp_size_enc = 0;
newStereo->mem_ovlp_size_dec = 0;

#ifdef LOW_COMPLEXITY
set_zero(newStereo->mem_side_ovlp, L_OVLP);
set_zero(newStereo->mem_synth_side, M);
#else
set_zero(newStereo->mem_left_ovlp, L_OVLP);
set_zero(newStereo->mem_right_ovlp, L_OVLP);
#endif
set_zero(newStereo->mem_mono_error, 4);

set_zero(newStereo->mem_synth_left, M);
set_zero(newStereo->mem_synth_right, M);

set_zero(newStereo->old_mono_exc, HI_FILT_ORDER);
set_zero(newStereo->old_wh_q, HI_FILT_ORDER);
}

// decode wiener filter coefficients
static void dec_filt(int **prm,
float wh[],
float old_wh[],
int bfi,
const PMSVQ* filt_hi_pmsvq
)
{
pmsvq_inv(wh, prm, old_wh, bfi, filt_hi_pmsvq);
}

// high pass filter
static void hp1K_12k8(const float *orig_signal,
float *filted_signal,
float *mem,
int lg)
{
int i;
float x0, x1, x2;
float y0, y1, y2;

y1 = mem[0];
y2 = mem[1];
x0 = mem[2];
x1 = mem[3];

for (i = 0; i < lg; i++)
{
x2 = x1;
x1 = x0;
x0 = orig_signal[i];
y0 = y1 * 1.85229f + y2 * -0.86314f + x0 * 0.9278487343389f + x1 * -1.8556974686778f + x2 * 0.9278487343389f;
filted_signal[i] = y0;
y2 = y1;
y1 = y0;
}

mem[0] = ((y1 > 1e-10) | (y1 < -1e-10)) ? y1 : 0;
mem[1] = ((y2 > 1e-10) | (y2 < -1e-10)) ? y2 : 0;
mem[2] = ((x0 > 1e-10) | (x0 < -1e-10)) ? x0 : 0;
mem[3] = ((x1 > 1e-10) | (x1 < -1e-10)) ? x1 : 0;
}

static void GetEstimatedSideExc(NEW_STEREO_DATA_DEC *newStereo,
int nIsTransient,
const float *mono_exc,
float *est_side_exc,
int est_len,
int *param)
{
int i;
float tmp_mono_exc[L_FRAME_PLUS+L_OVLP+HI_FILT_ORDER];
float filted_mono_exc[L_FRAME_PLUS+L_OVLP];
float *p_h;
float *x;
int *prm;

if (nIsTransient == 0)
{
prm = param;

newStereo->filt_hi_pmsvq = &amt;filt_hi_pmsvq7;

dec_filt(&amt;prm, newStereo->wiener_filter, newStereo->old_wh_q, 0, newStereo->filt_hi_pmsvq);
}
else
{
if (newStereo->bitrate < 32.0)
{
newStereo->filt_hi_pmsvq = &amt;filt_hi_pmsvq4;
}
else
{
newStereo->filt_hi_pmsvq = &amt;filt_hi_pmsvq7;
}

for (i = 0; i < 4; i++)
{
prm = param + i * 2; // maximum: 2 msvq stages (filt)

dec_filt(&amt;prm, &amt;newStereo->wiener_filter[i*HI_FILT_ORDER], newStereo->old_wh_q, 0, newStereo->filt_hi_pmsvq);
}
}

#if 1
hp1K_12k8(mono_exc, filted_mono_exc, newStereo->mem_mono_error, est_len);
#else
mvr2r(mono_exc, filted_mono_exc, est_len);
#endif

mvr2r(newStereo->old_mono_exc, tmp_mono_exc, HI_FILT_ORDER);
mvr2r(filted_mono_exc, tmp_mono_exc+HI_FILT_ORDER, est_len);
mvr2r(filted_mono_exc+L_FRAME_PLUS-HI_FILT_ORDER, newStereo->old_mono_exc, HI_FILT_ORDER);

p_h = newStereo->wiener_filter;
if (nIsTransient == 0)
{
/* set signal pointers */
x = tmp_mono_exc+HI_FILT_ORDER;

/* local synthesis */
fir_filt(p_h, HI_FILT_ORDER, x, est_side_exc, est_len);
}
else
{
int est_len_quick = est_len / 4;
for (i = 0; i < 4; i++)
{
/* set signal pointers */
x = tmp_mono_exc + HI_FILT_ORDER + i*256;

/* local synthesis */
fir_filt(p_h, HI_FILT_ORDER, x, est_side_exc+i*est_len_quick, est_len_quick);

p_h += HI_FILT_ORDER;
}
}
}

static void MakeFFTTransform(NEW_STEREO_DATA_DEC *newStereo,
int is_transient,
const float *est_side_ch,
const float *mono_ch,
float *mono_fft,
float *est_side_fft,
float *est_left_fft,
float *est_right_fft)
{
int i, w;
int L_frame, lext, lg;
float window[256];
int ovlp_size;
float est_xn_side[L_FRAME_PLUS+L_OVLP];
float xn_mono[L_FRAME_PLUS+L_OVLP];
// float est_side_fft[L_FRAME_PLUS+L_OVLP];

if (is_transient == 0) // smooth
{
mvr2r(est_side_ch, est_xn_side, L_FRAME_PLUS+L_OVLP);
mvr2r(mono_ch, xn_mono, L_FRAME_PLUS+L_OVLP);

lext = L_OVLP;
L_frame =L_FRAME_PLUS;

ovlp_size = newStereo->mem_ovlp_size_enc;
lg = L_frame + lext;
/* built window for overlaps section */
cos_window(window, ovlp_size, lext);

/* xn[] windowing for TCX overlap */
for (i = 0; i < ovlp_size; i++)
{
est_xn_side[i] *= window[i];
xn_mono[i] *= window[i];
}
for (i = 0; i < lext; i++)
{
est_xn_side[L_frame+i] *= window[ovlp_size+i];
xn_mono[L_frame+i] *= window[ovlp_size+i];
}

/*-----------------------------------------------------------*
* Compute the FFT of xn[]. *
* Coefficients (xri[]) order are *
* re[0], re[n/2], re[1], re[2], ... re[n/2-1], im[n/2-1] *
* Note that last FFT element (re[n/2]) is zeroed. *
*-----------------------------------------------------------*/
fft9(est_xn_side, est_side_fft, (short)lg);
est_side_fft[1] = 0.0f; /* freq bin at 6400 Hz zeroed */

fft9(xn_mono, mono_fft, (short)lg);
mono_fft[1] = 0.0f; /* freq bin at 6400 Hz zeroed */

newStereo->mem_ovlp_size_enc = L_OVLP;
}
else
{
lext = L_OVLP/4;
L_frame =L_FRAME_PLUS/4;
lg = L_frame + lext;

for (w = 0; w < 4; w++)
{
float *cur_est_side_fft = est_side_fft + w * lg;
float *cur_mono_fft = mono_fft + w * lg;

mvr2r(est_side_ch + w * lg, est_xn_side, lg); // correspond to ENCODER
mvr2r(mono_ch + w * L_frame, xn_mono, lg);

ovlp_size = newStereo->mem_ovlp_size_enc;

cos_window(window, ovlp_size, lext);

/* xn[] windowing for TCX overlap */
for (i = 0; i < ovlp_size; i++)
{
est_xn_side[i] *= window[i];
xn_mono[i] *= window[i];
}
for (i = 0; i < lext; i++)
{
est_xn_side[L_frame+i] *= window[ovlp_size+i];
xn_mono[L_frame+i] *= window[ovlp_size+i];
}

fft9(est_xn_side, cur_est_side_fft, (short)lg);
cur_est_side_fft[1] = 0.0f; /* freq bin at 6400 Hz zeroed */

fft9(xn_mono, cur_mono_fft, (short)lg);
cur_mono_fft[1] = 0.0f; /* freq bin at 6400 Hz zeroed */

newStereo->mem_ovlp_size_enc = L_OVLP/4;
}
}

// get left &amt; right signal
for (i = 0; i < L_FRAME_PLUS+L_OVLP; i++)
{
est_left_fft[i] = mono_fft[i] + est_side_fft[i];
est_right_fft[i] = mono_fft[i] - est_side_fft[i];
}
}

// decode gain of AVQ
static float d_gain_new_tcx(int index,
float code[],
int lcode
)
{
int i;
float tmp, gcode0, gcode;
/* energy */
tmp = 0.01f;
for(i=0; i<lcode; i++) {
tmp += code[i] * code[i];
}

gcode0 = (float)sqrt(tmp/((float)lcode));

gcode = (float)pow(10.0, ((float)index)/25.0) / gcode0;

return gcode;
}

static void MakeLowFreqDecoding(const float *mono_fft,
#ifdef LOW_COMPLEXITY
float *syn_side_fft,
#else
float *est_left_fft,
float *est_right_fft,
#endif
int low_freq_num,
int *prm)
{
int i;
float syn_side_fft_q[NEW_STEREO_LF_MAX_NUM_L];
float gain;

for (i = 0; i < low_freq_num; i++)
{
syn_side_fft_q[i] = (float)prm[i+1];
}
/*-----------------------------------------------------------*
* Compute inverse FFT for obtaining xnq[] without noise. *
* Coefficients (xri[]) order are *
* re[0], re[n/2], re[1], re[2], ... re[n/2-1], im[n/2-1] *
* Note that last FFT element (re[n/2]) is zeroed. *
*-----------------------------------------------------------*/
#ifdef NEW_TVC
adap_pulse_deemph(syn_side_fft_q,4*low_freq_num);
#else
adap_low_freq_deemph(syn_side_fft_q, 4*low_freq_num);
#endif

gain = d_gain_new_tcx(prm[0], syn_side_fft_q, low_freq_num);

#ifdef LOW_COMPLEXITY
for (i = 0; i < low_freq_num; i++)
{
syn_side_fft[i] = syn_side_fft_q[i] * gain;
}
#else
//multiply xriq[] by gain
for (i = 0; i < low_freq_num; i++)
{
float side_coef = syn_side_fft_q[i] * gain;

est_left_fft[i] = mono_fft[i] + side_coef;
est_right_fft[i] = mono_fft[i] - side_coef;
}
#endif
}

static void d_VQ_gain(float *x, const float *dico, int dim, int *index)
{
int j;

for (j = 0; j < dim; j++)
{
x[j] = dico[*index*dim+j];
}
}

static void MakeMidFreqDecoding(NEW_STEREO_DATA_DEC *newStereo,
const float *mono_fft,
#ifdef LOW_COMPLEXITY
float *syn_side_fft,
#endif
float *est_side_fft,
float *est_left_fft,
float *est_right_fft,
int mid_freq_num,
int w,
int gain_num,
int *param
)
{
int b, i;
int mid_psd_len = mid_freq_num / 2;
int gain_len = mid_psd_len / gain_num;

float tmpGain[HI_GAIN_ORDER];
float quant_left_gain[MF_GAIN_NUM];
float quant_right_gain[MF_GAIN_NUM];
float left_gain[MF_GAIN_NUM];
float right_gain[MF_GAIN_NUM];

if (newStereo->isTransientFrame == 0)
{
for (b = 0; b < gain_num; b++)
{
d_VQ_gain(tmpGain, dico_gain_side_hf_smooth, HI_GAIN_ORDER, param+b);

left_gain[b] = tmpGain[0] + cb_gain_hi_mean_smooth[0] + 0.5f*newStereo->pre_left_gain[b];
right_gain[b] = tmpGain[1] + cb_gain_hi_mean_smooth[1] + 0.5f*newStereo->pre_right_gain[b];

newStereo->pre_left_gain[b] = tmpGain[0] + 0.5f*newStereo->pre_left_gain[b];
newStereo->pre_right_gain[b] = tmpGain[1] + 0.5f*newStereo->pre_right_gain[b];
}
}
else
{
for (b = 0; b < gain_num; b++)
{
d_VQ_gain(tmpGain, dico_gain_side_hf_quick, HI_GAIN_ORDER, param+b);

left_gain[b] = tmpGain[0] + cb_gain_hi_mean_quick[0];
right_gain[b] = tmpGain[1] + cb_gain_hi_mean_quick[1];
}
}

for (b = 0; b < gain_num; b++)
{
#if 1 // smooth gains
if (newStereo->isTransientFrame == 0)
{
if (left_gain[b] > 0.0f)
{
left_gain[b] = min(left_gain[b], newStereo->old_left_freq_gain[b]+3.0f);
newStereo->old_left_freq_gain[b] = left_gain[b];
}
else
{
newStereo->old_left_freq_gain[b] = 0.0f;
}

if (right_gain[b] > 0.0f)
{
right_gain[b] = min(right_gain[b], newStereo->old_right_freq_gain[b]+3.0f);
newStereo->old_right_freq_gain[b] = right_gain[b];
}
else
{
newStereo->old_right_freq_gain[b] = 0.0f;
}
}
#endif
quant_left_gain[b] = (float)pow(10.0, 0.05*left_gain[b]);
quant_right_gain[b] = (float)pow(10.0, 0.05*right_gain[b]);
}

#ifdef LOW_COMPLEXITY
for (b = 0; b < gain_num; b++)
{
for (i = b * gain_len; i < (b+1) * gain_len; i++)
{
syn_side_fft[2*i] = quant_left_gain[b]*est_left_fft[2*i] - quant_right_gain[b]*est_right_fft[2*i];
syn_side_fft[2*i+1] = quant_left_gain[b]*est_left_fft[2*i+1] - quant_right_gain[b]*est_right_fft[2*i+1];
}
}
#else
for (b = 0; b < gain_num; b++)
{
for (i = b * gain_len; i < (b+1) * gain_len; i++)
{
est_left_fft[2*i] = quant_left_gain[b] * est_left_fft[2*i];
est_left_fft[2*i+1] = quant_left_gain[b] * est_left_fft[2*i+1];

est_right_fft[2*i] = quant_right_gain[b] * est_right_fft[2*i];
est_right_fft[2*i+1] = quant_right_gain[b] * est_right_fft[2*i+1];
}
}
#endif
}

static void MakeStereoDecoding(NEW_STEREO_DATA_DEC *newStereo,
int isTransientFrame,
float *mono_fft,
#ifdef LOW_COMPLEXITY
float *syn_side_fft,
#endif
float *est_side_fft,
float *est_left_fft,
float *est_right_fft,
int *param)
{
int low_freq_num;
int mid_freq_num;
int w, lg;
int *prm;
int gain_num;

prm = param + 8; // 8 mid-freq's gain

if (isTransientFrame == 0) // smooth frame
{
low_freq_num = newStereo->lowfreq_end_num_l;
mid_freq_num = L_FRAME_PLUS + L_OVLP - low_freq_num;
gain_num = MF_GAIN_NUM;

MakeLowFreqDecoding(mono_fft,
#ifdef LOW_COMPLEXITY
syn_side_fft,
#else
est_left_fft,
est_right_fft,
#endif
low_freq_num,
prm);

MakeMidFreqDecoding(newStereo,
mono_fft+low_freq_num,
#ifdef LOW_COMPLEXITY
syn_side_fft+low_freq_num,
#endif
est_side_fft+low_freq_num,
est_left_fft+low_freq_num,
est_right_fft+low_freq_num,
mid_freq_num,
0,
gain_num,
param);
}
else
{
lg = (L_FRAME_PLUS+L_OVLP)/4;
low_freq_num = newStereo->lowfreq_end_num_s;
mid_freq_num = lg - low_freq_num;
gain_num = MF_GAIN_NUM/4;

for (w = 0; w < 4; w++)
{
float *cur_est_left_fft = est_left_fft + w * lg;
float *cur_est_right_fft = est_right_fft + w * lg;
float *cur_mono_fft = mono_fft + w * lg;
float *cur_est_side_fft = est_side_fft + w * lg;
#ifdef LOW_COMPLEXITY
float *cur_syn_side_fft = syn_side_fft + w * lg;
#endif
int *cur_prm = prm + w * (1+low_freq_num+low_freq_num/8); //1 global gain

MakeLowFreqDecoding(cur_mono_fft,
#ifdef LOW_COMPLEXITY
cur_syn_side_fft,
#else
cur_est_left_fft,
cur_est_right_fft,
#endif
low_freq_num,
cur_prm);

MakeMidFreqDecoding(newStereo,
cur_mono_fft+low_freq_num,
#ifdef LOW_COMPLEXITY
cur_syn_side_fft+low_freq_num,
#endif
cur_est_side_fft+low_freq_num,
cur_est_left_fft+low_freq_num,
cur_est_right_fft+low_freq_num,
mid_freq_num,
w,
gain_num,
param+w*gain_num
);
}
}

}

#ifdef LOW_COMPLEXITY
static void MakeIFFTTransform(NEW_STEREO_DATA_DEC *newStereo,
int is_transient,
float *syn_side_fft,
float *syn_side_ch,
float *ovlp_side
)
{
int i, w;
int L_frame, lext, lg;
float window[256];
int ovlp_size;

if (is_transient == 0) // smooth
{
lext = L_OVLP;
L_frame =L_FRAME_PLUS;

ovlp_size = newStereo->mem_ovlp_size_dec;
lg = L_frame + lext;
/* built window for overlaps section */
cos_window(window, ovlp_size, lext);

syn_side_fft[1] = 0.0f;
ifft9(syn_side_fft, syn_side_ch, lg);

/* xn[] windowing for TCX overlap */
for (i = 0; i < ovlp_size; i++)
{
syn_side_ch[i] *= window[i];
}
for (i = 0; i < lext; i++)
{
syn_side_ch[L_frame+i] *= window[ovlp_size+i];
}

for (i = 0; i < L_OVLP; i++)
{
syn_side_ch[i] += ovlp_side[i];
}
/* save overlap for next frame */
for (i = 0; i < lext; i++)
{
ovlp_side[i] = syn_side_ch[i+L_frame];
}
for (i = lext; i < L_OVLP; i++)
{
ovlp_side[i] = 0.0f;
}

newStereo->mem_ovlp_size_dec = L_OVLP;
}
else
{
lext = L_OVLP/4;
L_frame =L_FRAME_PLUS/4;
lg = L_frame + lext;

for (w = 0; w < 4; w++)
{
float *cur_syn_side_fft = syn_side_fft + w * lg;
float *cur_syn_side_ch = syn_side_ch + w * L_frame;

ovlp_size = newStereo->mem_ovlp_size_dec;

cos_window(window, ovlp_size, lext);

cur_syn_side_fft[1] = 0.0f;
ifft9(cur_syn_side_fft, cur_syn_side_ch, lg);

/* xn[] windowing for TCX overlap */
for (i = 0; i < ovlp_size; i++)
{
cur_syn_side_ch[i] *= window[i];
}
for (i = 0; i < lext; i++)
{
cur_syn_side_ch[L_frame+i] *= window[ovlp_size+i];
}

for (i = 0; i < L_OVLP; i++)
{
cur_syn_side_ch[i] += ovlp_side[i];
}
/* save overlap for next frame */
for (i = 0; i < lext; i++)
{
ovlp_side[i] = cur_syn_side_ch[i+L_frame];
}
for (i = lext; i < L_OVLP; i++)
{
ovlp_side[i] = 0.0f;
}

newStereo->mem_ovlp_size_dec = L_OVLP/4;
}
}
}
#else // #ifdef LOW_COMPLEXITY
static void MakeIFFTTransform(NEW_STEREO_DATA_DEC *newStereo,
int is_transient,
float *syn_left_fft, // changed
float *syn_right_fft, // changed
float *syn_left_ch,
float *syn_right_ch,
float *ovlp_left,
float *ovlp_right
)
{
int i, w;
int L_frame, lext, lg;
float window[256];
int ovlp_size;

if (is_transient == 0) // smooth
{
lext = L_OVLP;
L_frame =L_FRAME_PLUS;

ovlp_size = newStereo->mem_ovlp_size_dec;
lg = L_frame + lext;
/* built window for overlaps section */
cos_window(window, ovlp_size, lext);

syn_left_fft[1] = 0.0f;
ifft9(syn_left_fft, syn_left_ch, lg);

syn_right_fft[1] = 0.0f;
ifft9(syn_right_fft, syn_right_ch, lg);

/* xn[] windowing for TCX overlap */
for (i = 0; i < ovlp_size; i++)
{
syn_left_ch[i] *= window[i];
syn_right_ch[i] *= window[i];
}
for (i = 0; i < lext; i++)
{
syn_left_ch[L_frame+i] *= window[ovlp_size+i];
syn_right_ch[L_frame+i] *= window[ovlp_size+i];
}

for (i = 0; i < L_OVLP; i++)
{
syn_left_ch[i] += ovlp_left[i];
syn_right_ch[i] += ovlp_right[i];
}
/* save overlap for next frame */
for (i = 0; i < lext; i++)
{
ovlp_left[i] = syn_left_ch[i+L_frame];
ovlp_right[i] = syn_right_ch[i+L_frame];
}
for (i = lext; i < L_OVLP; i++)
{
ovlp_left[i] = 0.0f;
ovlp_right[i] = 0.0f;
}

newStereo->mem_ovlp_size_dec = L_OVLP;
}
else
{
lext = L_OVLP/4;
L_frame =L_FRAME_PLUS/4;
lg = L_frame + lext;

for (w = 0; w < 4; w++)
{
float *cur_syn_left_fft = syn_left_fft + w * lg;
float *cur_syn_left_ch = syn_left_ch + w * L_frame;
float *cur_syn_right_fft = syn_right_fft + w * lg;
float *cur_syn_right_ch = syn_right_ch + w * L_frame;

ovlp_size = newStereo->mem_ovlp_size_dec;

cos_window(window, ovlp_size, lext);

cur_syn_left_fft[1] = 0.0f;
ifft9(cur_syn_left_fft, cur_syn_left_ch, lg);

cur_syn_right_fft[1] = 0.0f;
ifft9(cur_syn_right_fft, cur_syn_right_ch, lg);

/* xn[] windowing for TCX overlap */
for (i = 0; i < ovlp_size; i++)
{
cur_syn_left_ch[i] *= window[i];
cur_syn_right_ch[i] *= window[i];
}
for (i = 0; i < lext; i++)
{
cur_syn_left_ch[L_frame+i] *= window[ovlp_size+i];
cur_syn_right_ch[L_frame+i] *= window[ovlp_size+i];
}

for (i = 0; i < L_OVLP; i++)
{
cur_syn_left_ch[i] += ovlp_left[i];
cur_syn_right_ch[i] += ovlp_right[i];
}
/* save overlap for next frame */
for (i = 0; i < lext; i++)
{
ovlp_left[i] = cur_syn_left_ch[i+L_frame];
ovlp_right[i] = cur_syn_right_ch[i+L_frame];
}
for (i = lext; i < L_OVLP; i++)
{
ovlp_left[i] = 0.0f;
ovlp_right[i] = 0.0f;
}

newStereo->mem_ovlp_size_dec = L_OVLP/4;
}
}
}
#endif // #ifdef LOW_COMPLEXITY

// wlei [20070601]
static void dec_stereo(
int param_stereo[],
float *speech_mono,
float *speech_right,
float AqLF[],
NEW_STEREO_DATA_DEC *newStereo)
{
int i_subfr, k;
float *p_Aq;
float mono_exc[L_FRAME_PLUS+L_OVLP];
float left_exc[L_FRAME_PLUS+L_OVLP];
float right_exc[L_FRAME_PLUS+L_OVLP];
float est_side_exc[L_FRAME_PLUS+L_OVLP];
int *prm = NULL;

//////////////////////////////////////////////////////////////////////////
newStereo->isTransientFrame = param_stereo[0];
//////////////////////////////////////////////////////////////////////////

// get mono lf exc
// get old mono lf exc
p_Aq = newStereo->old_AqLF;
E_UTIL_residu(p_Aq, &amt;speech_mono[0], &amt;mono_exc[0], L_SUBFR/2);
p_Aq += (M+1);
for (i_subfr = L_SUBFR/2; i_subfr < 4*L_SUBFR+L_SUBFR/2; i_subfr+=L_SUBFR)
{
E_UTIL_residu(p_Aq, &amt;speech_mono[i_subfr], &amt;mono_exc[i_subfr], L_SUBFR);
p_Aq += (M+1);
}

// get mono lf exc, forced delay 288 in order to synchonize with decoder
p_Aq = AqLF;
for (i_subfr = L_SUBFR/2+4*L_SUBFR; i_subfr < L_FRAME_PLUS+L_SUBFR/2+L_SUBFR; i_subfr+=L_SUBFR)
{
E_UTIL_residu(p_Aq, &amt;speech_mono[i_subfr], &amt;mono_exc[i_subfr], L_SUBFR);
p_Aq += (M+1);
}
E_UTIL_residu(p_Aq, &amt;speech_mono[L_FRAME_PLUS+L_SUBFR/2+L_SUBFR], &amt;mono_exc[L_FRAME_PLUS+L_SUBFR/2+L_SUBFR], L_SUBFR/2);

// signal estimation
prm = param_stereo + 1;
// prm = tmp_param_stereo + 1;
GetEstimatedSideExc(newStereo, newStereo->isTransientFrame, mono_exc, est_side_exc, L_FRAME_PLUS+L_OVLP, prm);


// time-frequency transform
MakeFFTTransform(newStereo,
newStereo->isTransientFrame,
est_side_exc,
mono_exc,
newStereo->mono_fft,
newStereo->est_side_fft,
newStereo->est_left_fft,
newStereo->est_right_fft);

// reconstruct low-frequency and mid-frequency
prm = param_stereo + (1+8); // 1: signal type; 8: wiener VQ
MakeStereoDecoding(newStereo,
newStereo->isTransientFrame,
newStereo->mono_fft,
#ifdef LOW_COMPLEXITY
newStereo->syn_side_fft,
#endif
newStereo->est_side_fft,
newStereo->est_left_fft,
newStereo->est_right_fft,
prm);

#ifdef LOW_COMPLEXITY
//////////////////////////////////////////////////////////////////////////
// module 315
//////////////////////////////////////////////////////////////////////////
MakeIFFTTransform(newStereo,
newStereo->isTransientFrame,
newStereo->syn_side_fft,
right_exc, // side_exc
newStereo->mem_side_ovlp);

// get real left_exc and right_exc
for (k = 0; k < L_FRAME_PLUS; k++)
{
left_exc[k] = mono_exc[k] + right_exc[k];
right_exc[k] = mono_exc[k] - right_exc[k];
}

p_Aq = newStereo->old_AqLF;
syn_filt(p_Aq, M, &amt;left_exc[0], &amt;left_exc[0], L_SUBFR/2, newStereo->mem_synth_left, 1);
syn_filt(p_Aq, M, &amt;right_exc[0], &amt;right_exc[0], L_SUBFR/2, newStereo->mem_synth_right, 1);

p_Aq += (M+1);
for (i_subfr = L_SUBFR/2; i_subfr < 4*L_SUBFR+L_SUBFR/2; i_subfr+=L_SUBFR)
{
syn_filt(p_Aq, M, &amt;left_exc[i_subfr], &amt;left_exc[i_subfr], L_SUBFR, newStereo->mem_synth_left, 1);
syn_filt(p_Aq, M, &amt;right_exc[i_subfr], &amt;right_exc[i_subfr], L_SUBFR, newStereo->mem_synth_right, 1);
p_Aq += (M+1);
}

p_Aq = AqLF;
for (i_subfr = 4*L_SUBFR+L_SUBFR/2; i_subfr < L_FRAME_PLUS-L_SUBFR/2; i_subfr+=L_SUBFR)
{
syn_filt(p_Aq, M, &amt;left_exc[i_subfr], &amt;left_exc[i_subfr], L_SUBFR, newStereo->mem_synth_left, 1);
syn_filt(p_Aq, M, &amt;right_exc[i_subfr], &amt;right_exc[i_subfr], L_SUBFR, newStereo->mem_synth_right, 1);
p_Aq += (M+1);
}
syn_filt(p_Aq, M, &amt;left_exc[L_FRAME_PLUS-L_SUBFR/2], &amt;left_exc[L_FRAME_PLUS-L_SUBFR/2],
L_SUBFR/2, newStereo->mem_synth_left, 1);
syn_filt(p_Aq, M, &amt;right_exc[L_FRAME_PLUS-L_SUBFR/2], &amt;right_exc[L_FRAME_PLUS-L_SUBFR/2],
L_SUBFR/2, newStereo->mem_synth_right, 1);

mvr2r(&amt;AqLF[11*(M+1)], newStereo->old_AqLF, 5*(M+1));

#else //#ifdef LOW_COMPLEXITY
// frequency-time transform
MakeIFFTTransform(newStereo,
newStereo->isTransientFrame,
newStereo->est_left_fft,
newStereo->est_right_fft,
left_exc,
right_exc,
newStereo->mem_left_ovlp,
newStereo->mem_right_ovlp);

// synthesis filter
p_Aq = newStereo->old_AqLF;
syn_filt(p_Aq, M, &amt;left_exc[0], &amt;left_exc[0], L_SUBFR/2, newStereo->mem_synth_left, 1);
syn_filt(p_Aq, M, &amt;right_exc[0], &amt;right_exc[0], L_SUBFR/2, newStereo->mem_synth_right, 1);

p_Aq += (M+1);
for (i_subfr = L_SUBFR/2; i_subfr < 4*L_SUBFR+L_SUBFR/2; i_subfr+=L_SUBFR)
{
syn_filt(p_Aq, M, &amt;left_exc[i_subfr], &amt;left_exc[i_subfr], L_SUBFR, newStereo->mem_synth_left, 1);
syn_filt(p_Aq, M, &amt;right_exc[i_subfr], &amt;right_exc[i_subfr], L_SUBFR, newStereo->mem_synth_right, 1);
p_Aq += (M+1);
}

p_Aq = AqLF;
for (i_subfr = 4*L_SUBFR+L_SUBFR/2; i_subfr < L_FRAME_PLUS-L_SUBFR/2; i_subfr+=L_SUBFR)
{
syn_filt(p_Aq, M, &amt;left_exc[i_subfr], &amt;left_exc[i_subfr], L_SUBFR, newStereo->mem_synth_left, 1);
syn_filt(p_Aq, M, &amt;right_exc[i_subfr], &amt;right_exc[i_subfr], L_SUBFR, newStereo->mem_synth_right, 1);
p_Aq += (M+1);
}
syn_filt(p_Aq, M, &amt;left_exc[L_FRAME_PLUS-L_SUBFR/2], &amt;left_exc[L_FRAME_PLUS-L_SUBFR/2],
L_SUBFR/2, newStereo->mem_synth_left, 1);
syn_filt(p_Aq, M, &amt;right_exc[L_FRAME_PLUS-L_SUBFR/2], &amt;right_exc[L_FRAME_PLUS-L_SUBFR/2],
L_SUBFR/2, newStereo->mem_synth_right, 1);

mvr2r(&amt;AqLF[11*(M+1)], newStereo->old_AqLF, 5*(M+1));
#endif // #ifdef LOW_COMPLEXITY

for (k = 0; k < L_FRAME_PLUS; k++)
{
speech_mono[k] = left_exc[k];
speech_right[k] = right_exc[k];
}
}

void dec_new_stereo_side(
int param_stereo[], // (i)stereo bits stream
float *sig_left, // (o) decoded right channel
float *synth, // (i) decoded mono channel; (o) decoded left channel
float AqLF[], // (i) quantized predictive coefficients of mono channel
int StbrMode, // wlei [20070601]
NEW_STEREO_DATA_DEC *newStereo) // (i) stereo struction
{
float *speech_mono;
float old_speech_mono[M+L_FRAME_PLUS+NEW_STEREO_DECODER_DELAY];
float speech_right[L_FRAME_PLUS];

speech_mono = old_speech_mono + M;

mvr2r(newStereo->old_speech_mono, old_speech_mono, M+NEW_STEREO_DECODER_DELAY);
mvr2r(synth, speech_mono+NEW_STEREO_DECODER_DELAY, L_FRAME_PLUS);
mvr2r(old_speech_mono+L_FRAME_PLUS, newStereo->old_speech_mono, M+NEW_STEREO_DECODER_DELAY);

if (StbrMode < 0) // wlei[20070601]
{
mvr2r(speech_mono, speech_right, L_FRAME_PLUS);
}
else
{
dec_stereo(param_stereo, speech_mono, speech_right, AqLF, newStereo);
}

mvr2r(newStereo->old_speech_left, sig_left, NEW_STEREO_DECODER_COMP);
mvr2r(speech_mono, sig_left+NEW_STEREO_DECODER_COMP, L_FRAME_PLUS-NEW_STEREO_DECODER_COMP);
mvr2r(speech_mono+L_FRAME_PLUS-NEW_STEREO_DECODER_COMP, newStereo->old_speech_left, NEW_STEREO_DECODER_COMP);

mvr2r(newStereo->old_speech_right, synth, NEW_STEREO_DECODER_COMP);
mvr2r(speech_right, synth+NEW_STEREO_DECODER_COMP, L_FRAME_PLUS-NEW_STEREO_DECODER_COMP);
mvr2r(speech_right+L_FRAME_PLUS-NEW_STEREO_DECODER_COMP, newStereo->old_speech_right, NEW_STEREO_DECODER_COMP);
}

static int pack4bits_d(int nbits, short *ptr, int *prm)
{
int i;
i=0;
while (nbits > 4)
{
prm[i] = bin2int(4, ptr);
ptr += 4;
nbits -= 4;
i++;
}
prm[i] = bin2int(nbits, ptr);
i++;
return(i);
}

void dec_prm_new_stereo(int bad_frame[], /* (i) : bfi for 4 frames (bad_frame[4]) */
short serial[], /* (i) : serial bits stream */
int nbits_pack, /* (i) : number of bits per packet of 20ms*/
int nbits_bwe, /* (i) : number of BWE bits per 20ms */
int param[], /* (o) : decoded parameters */
int brMode,
NEW_STEREO_DATA_DEC *newStereo)
{
int nbits, *prm;
int k;
int nbits_AVQ[NB_DIV];
int prm_AVQ[NBITS_MAX+N_PACK_MAX];
short *ptr;
float tmp_prm[NBITS_MAX+N_PACK_MAX];
int i,j,n_pack;
int si_bits = 16;
int signal_type;

int lowfreq_end_num_l = newStereo->lowfreq_end_num_l;
int lowfreq_end_num_s = newStereo->lowfreq_end_num_s;
/*----------------------------------------------------------*
* Set number of bits used for stereo (per packet of 20 ms) *
* When stereo is transmitted, the bit ordering is: *
* serial: mode (2bits), core, stereo, 2xBWE(2x16bits) *
*----------------------------------------------------------*/
nbits = (StereoNbits[brMode] + (2*nbits_bwe))/4;

ptr = serial + nbits_pack - nbits;
signal_type = bin2int(1, ptr);

if (signal_type == 0) // smooth type
{
k = 0;
prm = param + 17; // skip to AVQ param
n_pack = 4;
nbits_AVQ[0] = ((StereoNbits[brMode])/4)-1-4-3-5-5; //
nbits_AVQ[1] = ((StereoNbits[brMode])/4)-1-7-5-5;
nbits_AVQ[2] = ((StereoNbits[brMode])/4)-5-5;
nbits_AVQ[3] = ((StereoNbits[brMode])/4)-5-5;

/* set pointer to bit stream */
ptr = serial + (k+1)*nbits_pack - nbits;

/* encode first 20 ms frame */
param[0] = bin2int(1, ptr); ptr += 1; // signal type
param[1] = bin2int(4, ptr); ptr += 4; // 1st FIR coef
param[2] = bin2int(3, ptr); ptr += 3; // 2nd FIR coef
param[9] = bin2int(5, ptr); ptr += 5; // 1st mid-freq's gain
param[10]= bin2int(5, ptr); ptr += 5; // 2nd mid-freq's gain
j = pack4bits_d(nbits_AVQ[0], ptr, prm_AVQ);// AVQ

/* set pointer to bit stream */
ptr = serial + (k+2)*nbits_pack - nbits;

/* encode second 20 ms frame */
ptr += 1; // unused bits
param[17] = bin2int(7, ptr); ptr += 7; // global gain
param[11] = bin2int(5, ptr); ptr += 5; // 3rd mid-freq's gain
param[12] = bin2int(5, ptr); ptr += 5; // 4th mid-freq's gain
j += pack4bits_d(nbits_AVQ[1], ptr, prm_AVQ+j);

/* set pointer to bit stream */
ptr = serial + (k+3)*nbits_pack - nbits;

/* encode third 20 ms frame */
param[13] = bin2int(5, ptr); ptr += 5; // 5th mid-freq's gain
param[14] = bin2int(5, ptr); ptr += 5; // 6th mid-freq's gain
j += pack4bits_d(nbits_AVQ[2], ptr, prm_AVQ+j);

/* set pointer to bit stream */
ptr = serial + (k+4)*nbits_pack - nbits;
/* encode forth 20 ms frame */
param[15] = bin2int(5, ptr); ptr += 5; // 7th mid-freq's gain
param[16] = bin2int(5, ptr); ptr += 5; // 8th mid-freq's gain
pack4bits_d(nbits_AVQ[3], ptr, prm_AVQ+j);

AVQ_demuxdec(n_pack, prm_AVQ, nbits_AVQ, tmp_prm, lowfreq_end_num_l/8, bad_frame);
/* convert to integer */
for (i = 0;i < lowfreq_end_num_l; i++)
{
prm[i+1] = (int)tmp_prm[i];
}
}
else
{
// side information
// 1st packet
/* set pointer to bit stream */
ptr = serial + nbits_pack - nbits;
param[0] = bin2int(1, ptr); ptr += 1; // signal type
if (newStereo->bitrate < 32.0f)
{
param[1] = bin2int(4, ptr); ptr += 4; // 1st FIR coef
}
else
{
param[1] = bin2int(4, ptr); ptr += 4; // 1st FIR coef
param[2] = bin2int(3, ptr); ptr += 3; // 2nd FIR coef
}
param[9] = bin2int(5, ptr); ptr += 5; // 1st mid-freq's gain
param[10] = bin2int(5, ptr); ptr += 5; // 2nd mid-freq's gain

// 2nd packet
ptr = serial + 2*nbits_pack - nbits;
ptr += 1; // reserved bit
if (newStereo->bitrate < 32.0f)
{
param[3] = bin2int(4, ptr); ptr += 4; // 1st FIR coef
}
else
{
param[3] = bin2int(4, ptr); ptr += 4; // 1st FIR coef
param[4] = bin2int(3, ptr); ptr += 3; // 2nd FIR coef
}
param[11] = bin2int(5, ptr); ptr += 5; // 5th mid-freq's gain
param[12] = bin2int(5, ptr); ptr += 5; // 6th mid-freq's gain

// 3rd packet
ptr = serial + 3*nbits_pack - nbits;
ptr += 1; // reserved bit
if (newStereo->bitrate < 32.0f)
{
param[5] = bin2int(4, ptr); ptr += 4; // 1st FIR coef
}
else
{
param[5] = bin2int(4, ptr); ptr += 4; // 1st FIR coef
param[6] = bin2int(3, ptr); ptr += 3; // 2nd FIR coef
}
param[13] = bin2int(5, ptr); ptr += 5; // 7th mid-freq's gain
param[14] = bin2int(5, ptr); ptr += 5; // 8th mid-freq's gain

// 4th packet
ptr = serial + 4*nbits_pack - nbits;
ptr += 1; // reserved bit
if (newStereo->bitrate < 32.0f)
{
param[7] = bin2int(4, ptr); ptr += 4; // 1st FIR coef
}
else
{
param[7] = bin2int(4, ptr); ptr += 4; // 1st FIR coef
param[8] = bin2int(3, ptr); ptr += 3; // 2nd FIR coef
}
param[15] = bin2int(5, ptr); ptr += 5; // 7th mid-freq's gain
param[16] = bin2int(5, ptr); ptr += 5; // 8th mid-freq's gain

if (newStereo->bitrate < 32.0f)
{
si_bits = 15;
}
else
{
si_bits = 18;
}

prm = param + 17; // 17 side info used

// core (SplitVQ + global gain)
for (k = 0; k < 4; k++) // 4 packets
{
n_pack = 1;
nbits_AVQ[0] = ((StereoNbits[brMode])/4) - si_bits - 7; // 7 global gain

/* set pointer to bit stream */
ptr = serial + (k+1)*nbits_pack - nbits + si_bits;

prm[0] = bin2int(7, ptr); ptr += 7; // global gain

pack4bits_d(nbits_AVQ[0], ptr, prm_AVQ);

/* demultiplex and decode */
AVQ_demuxdec(n_pack, prm_AVQ, nbits_AVQ, tmp_prm, lowfreq_end_num_s/8, bad_frame+k);
/* convert to integer */
for (i = 0;i < lowfreq_end_num_s; i++)
{
prm[i+1] = (int)tmp_prm[i];
}

// ptr += nbits_AVQ[0];
prm += (1+(lowfreq_end_num_s+lowfreq_end_num_s/8));
}
}

return;
}

/* END_NEW_STEREO */
/* FROM TOP OF THIS FILE */