www.pudn.com > AVS_M_ver10.rar > cod_tcx.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"

#ifdef PW_UPDATE
#ifdef NEW_TVC
void coder_tcx(
float A[], /* input: coefficients NxAz[M+1] */
float speech[], /* input: speech[-M..lg] */
float *mem_wsp, /* in/out: memory of target */
float *mem_wsyn, /* in/out: memory of quantized xn */
float synth[], /* in/out: synth[-M..lg] */
float exc[], /* output: exc[0..lg] */
float wovlp[], /* i/o: wovlp[0..127] */
int ovlp_size, /* input: 0, 64 or 128 (0=acelp) */
int L_frame, /* input: frame length */
int nb_bits, /* input: number of bits allowed */
int input_t, /* input: superframe edge indication */
int prm[],
float *mem_formant,
float *mem_tilt,
float *mem_formant_exc,
float *mem_tilt_exc)
{

int i, i_subfr, lext, lg, index,ovlp;
float gain, fac_ns,tmp;
float *p_A, Ap[M+1],Ap1[M+1],Ap2[M+1],Ap3[M+1];
float *xri, *xn, *xnq;
float gh, gg, qgband;
float window[256];

static int cnt = 1;
xn = synth;
xnq = xri = exc;


/*------ set length of overlap (lext) and length of encoded frame (lg) -----*/
lext = L_OVLP;
if (L_frame == (L_FRAME_PLUS/2)) {
lext = L_OVLP/2;
}
if (L_frame == (L_FRAME_PLUS/4)) {
lext = L_OVLP/4;
}
lg = L_frame + lext;
/* built window for overlaps section */
//这里对前帧是acelp时进行处理

if (ovlp_size==0)
{
lext=lext/2;
ovlp=lext;
//下面是对snr而设定的
/* set_zero(sp, 80);
set_zero(synthpost, 80);
set_zero(synth2, 64);*/
set_zero(xn, 1152);
}
else{
ovlp=ovlp_size;
}

cos_window(window, ovlp, lext);

//如果前帧是acelp 就进行如下的分解
if (ovlp_size==0){
if(input_t==0){
for(i=0; i<lext; i++){
xn[i]= 0;
}
}
else{
for(i=0; i<lext; i++){
xn[i]= wovlp[64-lext+i];
}
}
for (i=0; i<128; i++) {
wovlp[i] = 0.0;
}

}

/*-----------------------------------------------------------*
* Find target xn[] (weighted speech when prev mode is TCX) *
* Note that memory isn't updated in the overlap area. *
*-----------------------------------------------------------*/
//Perceptual Weighting
p_A = A;
if (ovlp_size==0){
for (i_subfr=0; i_subfr<L_frame; i_subfr+=L_SUBFR) {
paraChoose(p_A,&amt;gamma1,&amt;gamma2,&amt;gamma3);
E_LPC_a_weight(p_A, Ap1, gamma1, M);
E_LPC_a_weight(p_A, Ap2, gamma2, M);
E_LPC_a_weight(p_A, Ap3, gamma3, TILT_ORDER);
E_UTIL_residu(Ap1, &amt;speech[i_subfr], &amt;xn[i_subfr+lext], L_SUBFR);
E_UTIL_formant(&amt;xn[i_subfr+lext],Ap2,L_SUBFR,mem_formant);
E_UTIL_tilt(&amt;xn[i_subfr+lext],Ap3,L_SUBFR,mem_tilt);
p_A += (M+1);
}
}
else{
for (i_subfr=0; i_subfr<L_frame; i_subfr+=L_SUBFR) {
paraChoose(p_A,&amt;gamma1,&amt;gamma2,&amt;gamma3);
E_LPC_a_weight(p_A, Ap1, gamma1, M);
E_LPC_a_weight(p_A, Ap2, gamma2, M);
E_LPC_a_weight(p_A, Ap3, gamma3, TILT_ORDER);
E_UTIL_residu(Ap1, &amt;speech[i_subfr], &amt;xn[i_subfr], L_SUBFR);
E_UTIL_formant(&amt;xn[i_subfr],Ap2,L_SUBFR,mem_formant);
E_UTIL_tilt(&amt;xn[i_subfr],Ap3,L_SUBFR,mem_tilt);
p_A += (M+1);
}
}
/* overlap area (xn[L_frame..L_frame+lext]) */
paraChoose(p_A,&amt;gamma1,&amt;gamma2,&amt;gamma3);
E_LPC_a_weight(p_A, Ap1, gamma1, M);
E_LPC_a_weight(p_A, Ap2, gamma2, M);
E_LPC_a_weight(p_A, Ap3, gamma3, TILT_ORDER);
if (ovlp_size==0){
E_UTIL_residu(Ap1, &amt;speech[L_frame], &amt;xn[L_frame+lext], lext);
{
float mem_temp1[M],mem_temp2[TILT_ORDER];
mvr2r(mem_formant,mem_temp1,M);
mvr2r(mem_tilt,mem_temp2,TILT_ORDER);
E_UTIL_formant(&amt;xn[L_frame+lext],Ap2,lext,mem_temp1);
E_UTIL_tilt(&amt;xn[L_frame+lext],Ap3,lext,mem_temp2);
}
}
else{
E_UTIL_residu(Ap1, &amt;speech[L_frame], &amt;xn[L_frame], lext);
{
float mem_temp1[M],mem_temp2[TILT_ORDER];
mvr2r(mem_formant,mem_temp1,M);
mvr2r(mem_tilt,mem_temp2,TILT_ORDER);
E_UTIL_formant(&amt;xn[L_frame],Ap2,lext,mem_temp1);
E_UTIL_tilt(&amt;xn[L_frame],Ap3,lext,mem_temp2);
}
}

/* remove weighted ZIR when previous frame is ACELP */
if (ovlp_size == 0) {
for (i=0; i<lext; i++) {
xn[L_frame+lext+i] *= window[ovlp+i];
}
}
else{
for (i=0; i<ovlp; i++) {
xn[i] *= window[i];
}
for (i=0; i<lext; i++) {
xn[L_frame+i] *= window[ovlp+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(xn, xri, (short)lg);
xri[1] = 0.0; /* freq bin at 6400 Hz zeroed */

/* …… 预整形 模块 (开始) ……*/
/*-----------------------------------------------------------*
* Spectral algebraic quantization *
* with adaptive low pulse emphasis/deemphasis. *
* Noise factor is the average level of unquantized freq. *
*-----------------------------------------------------------*/
adap_pulse_emph(xri, lg);
nb_bits -= (3+7+7); /* fac_ns = 3 bits, gain = 7 bits */
/* remove also the redundancy bits of the TCX gain
TCX-40 -> 6 bits (in 2nd packet)
TCX-80 -> 9 bits (3 bits in 2nd, 3rd and 4th packet) */
if (L_frame == (L_FRAME_PLUS/2)) {
nb_bits -= 6;
}
if (L_frame == L_FRAME_PLUS) {
nb_bits -= 9;
}
fac_ns = AVQ_get_nf(xri, nb_bits, lg/8);
AVQ_gain_allocator(xri, lg, nb_bits, &amt;gh, &amt;gg);
/* high half quantization */
AVQ_cod(xri, prm+3, nb_bits, lg/8, &amt;gh, &amt;gg);

for(i=0; i<lg; i++) {
xri[i] = (float)prm[i+3];
}
prm[2] = AVQ_gband(gh, &amt;qgband);
for (i=0; i<lg/2; i++)
xri[i+lg/2] /= qgband;
adap_pulse_deemph(xri, lg);
/* …… 预整形 模块 (结束) ……*/
/* quantize noise factor (noise factor = 0.1 to 0.8) */
tmp = 8.0f - (10.0f*fac_ns);
index = (int)floor(tmp + 0.5);
if (index < 0) {
index = 0;
}
if (index > 7) {
index = 7;
}
prm[0] = index; /* fac_ns : 3 bits */

/*-----------------------------------------------------------*
* 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. *
*-----------------------------------------------------------*/
xri[1] = 0.0; /* freq bin at 6400 Hz zeroed */
ifft9(xri, xnq, (short)lg);
/*-----------------------------------------------------------*
* find and quantize gain, multiply xnq[] by gain. *
* windowing of xnq[] for TCX overlap. *
*-----------------------------------------------------------*/
gain = get_gain(xn, xnq, lg);
prm[1] = q_gain_tcx(xnq, lg, &amt;gain);
for (i=0; i<lg; i++) {
xnq[i] *= gain;
}

/* adaptive windowing on overlap (beginning and end of frame) */
if (ovlp_size ==0){
for (i=0; i<lext; i++) {
xnq[i+L_frame+lext] *= window[ovlp+i];
}
}
else{
for (i=0; i<ovlp; i++) {
xnq[i] *= window[i];
}

for (i=0; i<lext; i++) {
xnq[i+L_frame] *= window[ovlp+i];
}
}

/*-----------------------------------------------------------*
* TCX overlap and add. Update memory for next overlap. *
*-----------------------------------------------------------*/

if (ovlp_size ==0){
for (i=0; i<lext; i++) {
wovlp[i] = xnq[i+L_frame+lext];
}
}
else{
for (i=0; i<L_OVLP; i++) {
xnq[i] += wovlp[i];
}

/* save overlap for next frame */
for (i=0; i<lext; i++) {
wovlp[i] = xnq[i+L_frame];
}
}
for (i=lext; i<128; i++) {
wovlp[i] = 0.0;
}



/*-----------------------------------------------------------*
* find excitation and synthesis *
*-----------------------------------------------------------*/
//Perceptual Weighting
if (ovlp_size==0){
p_A = A;
for (i_subfr=0; i_subfr<L_frame; i_subfr+=L_SUBFR) {
paraChoose(p_A,&amt;gamma1,&amt;gamma2,&amt;gamma3);
E_LPC_a_weight(p_A, Ap1, gamma1, M);
E_LPC_a_weight(p_A, Ap2, gamma2, M);
E_LPC_a_weight(p_A, Ap3, gamma3, TILT_ORDER);
E_UTIL_detilt(&amt;xnq[i_subfr+lext],Ap3,L_SUBFR,mem_tilt_exc);
E_UTIL_deformant(&amt;xnq[i_subfr+lext],Ap2,L_SUBFR,mem_formant_exc);
E_UTIL_synthesis(Ap1, &amt;xnq[i_subfr+lext], &amt;synth[i_subfr], L_SUBFR, &amt;synth[i_subfr-M], 0);
E_UTIL_residu(p_A, &amt;synth[i_subfr], &amt;exc[i_subfr], L_SUBFR);
p_A += (M+1);
}
}
else{
p_A = A;
for (i_subfr=0; i_subfr<L_frame; i_subfr+=L_SUBFR) {
paraChoose(p_A,&amt;gamma1,&amt;gamma2,&amt;gamma3);
E_LPC_a_weight(p_A, Ap1, gamma1, M);
E_LPC_a_weight(p_A, Ap2, gamma2, M);
E_LPC_a_weight(p_A, Ap3, gamma3, TILT_ORDER);
E_UTIL_detilt(&amt;xnq[i_subfr],Ap3,L_SUBFR,mem_tilt_exc);
E_UTIL_deformant(&amt;xnq[i_subfr],Ap2,L_SUBFR,mem_formant_exc);
E_UTIL_synthesis(Ap1, &amt;xnq[i_subfr], &amt;synth[i_subfr], L_SUBFR, &amt;synth[i_subfr-M], 0);
E_UTIL_residu(p_A, &amt;synth[i_subfr], &amt;exc[i_subfr], L_SUBFR);
p_A += (M+1);
}
}

return;
}
#else
void coder_tcx(
float A[], /* input: coefficients NxAz[M+1] */
float speech[], /* input: speech[-M..lg] */
float *mem_wsp, /* in/out: memory of target */
float *mem_wsyn, /* in/out: memory of quantized xn */
float synth[], /* in/out: synth[-M..lg] */
float exc[], /* output: exc[0..lg] */
float wovlp[], /* i/o: wovlp[0..127] */
int ovlp_size, /* input: 0, 64 or 128 (0=acelp) */
int L_frame, /* input: frame length */
int nb_bits, /* input: number of bits allowed */
int prm[], /* output: tcx parameters */
float *mem_formant,
float *mem_tilt,
float *mem_formant_exc,
float *mem_tilt_exc)
{
int i, i_subfr, lext, lg, index;
float tmp, gain, fac_ns;
float *p_A, Ap[M+1],Ap1[M+1],Ap2[M+1],Ap3[M+1];
float *xri, *xn, *xnq;
float window[256];
xn = synth;
xnq = xri = exc;
/*------ set length of overlap (lext) and length of encoded frame (lg) -----*/
lext = L_OVLP;
if (L_frame == (L_FRAME_PLUS/2)) {
lext = L_OVLP/2;
}
if (L_frame == (L_FRAME_PLUS/4)) {
lext = L_OVLP/4;
}
lg = L_frame + lext;
/* built window for overlaps section */
cos_window(window, ovlp_size, lext);
/*-----------------------------------------------------------*
* Find target xn[] (weighted speech when prev mode is TCX) *
* Note that memory isn't updated in the overlap area. *
*-----------------------------------------------------------*/
//Perceptual Weighting
p_A = A;
for (i_subfr=0; i_subfr<L_frame; i_subfr+=L_SUBFR) {
paraChoose(p_A,&amt;gamma1,&amt;gamma2,&amt;gamma3);
E_LPC_a_weight(p_A, Ap1, gamma1, M);
E_LPC_a_weight(p_A, Ap2, gamma2, M);
E_LPC_a_weight(p_A, Ap3, gamma3, TILT_ORDER);
E_UTIL_residu(Ap1, &amt;speech[i_subfr], &amt;xn[i_subfr], L_SUBFR);
E_UTIL_formant(&amt;xn[i_subfr],Ap2,L_SUBFR,mem_formant);
E_UTIL_tilt(&amt;xn[i_subfr],Ap3,L_SUBFR,mem_tilt);

p_A += (M+1);
}
/* overlap area (xn[L_frame..L_frame+lext]) */
paraChoose(p_A,&amt;gamma1,&amt;gamma2,&amt;gamma3);
E_LPC_a_weight(p_A, Ap1, gamma1, M);
E_LPC_a_weight(p_A, Ap2, gamma2, M);
E_LPC_a_weight(p_A, Ap3, gamma3, TILT_ORDER);
E_UTIL_residu(Ap1, &amt;speech[L_frame], &amt;xn[L_frame], lext);
{
float mem_temp1[M],mem_temp2[TILT_ORDER];
mvr2r(mem_formant,mem_temp1,M);
mvr2r(mem_tilt,mem_temp2,TILT_ORDER);
E_UTIL_formant(&amt;xn[L_frame],Ap2,lext,mem_temp1);
E_UTIL_tilt(&amt;xn[L_frame],Ap3,lext,mem_temp2);
}

/* remove weighted ZIR when previous frame is ACELP */
if (ovlp_size == 0) {
for (i=0; i<(2*L_SUBFR); i++) {
xn[i] -= wovlp[i];
}
}
/* xn[] windowing for TCX overlap */
for (i=0; i<ovlp_size; i++) {
xn[i] *= window[i];
}
for (i=0; i<lext; i++) {
xn[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(xn, xri, (short)lg);
xri[1] = 0.0; /* freq bin at 6400 Hz zeroed */
/*-----------------------------------------------------------*
* Spectral algebraic quantization *
* with adaptive low frequency emphasis/deemphasis. *
* Noise factor is the average level of unquantized freq. *
*-----------------------------------------------------------*/
adap_low_freq_emph(xri, lg);
nb_bits -= (3+7); /* fac_ns = 3 bits, gain = 7 bits */
/* remove also the redundancy bits of the TCX gain
TCX-40 -> 6 bits (in 2nd packet)
TCX-80 -> 9 bits (3 bits in 2nd, 3rd and 4th packet) */
if (L_frame == (L_FRAME_PLUS/2)) {
nb_bits -= 6;
}
if (L_frame == L_FRAME_PLUS) {
nb_bits -= 9;
}
fac_ns = AVQ_cod(xri, prm+2, nb_bits, lg/8);
for(i=0; i<lg; i++) {
xri[i] = (float)prm[i+2];
}
adap_low_freq_deemph(xri, lg);
/* quantize noise factor (noise factor = 0.1 to 0.8) */
tmp = 8.0f - (10.0f*fac_ns);
index = (int)floor(tmp + 0.5);
if (index < 0) {
index = 0;
}
if (index > 7) {
index = 7;
}
prm[0] = index; /* fac_ns : 3 bits */
/*-----------------------------------------------------------*
* 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. *
*-----------------------------------------------------------*/
xri[1] = 0.0; /* freq bin at 6400 Hz zeroed */
ifft9(xri, xnq, (short)lg);
/*-----------------------------------------------------------*
* find and quantize gain, multiply xnq[] by gain. *
* windowing of xnq[] for TCX overlap. *
*-----------------------------------------------------------*/
gain = get_gain(xn, xnq, lg);
prm[1] = q_gain_tcx(xnq, lg, &amt;gain);
for (i=0; i<lg; i++) {
xnq[i] *= gain;
}
/* adaptive windowing on overlap (beginning and end of frame) */
for (i=0; i<ovlp_size; i++) {
xnq[i] *= window[i];
}
for (i=0; i<lext; i++) {
xnq[i+L_frame] *= window[ovlp_size+i];
}
/*-----------------------------------------------------------*
* TCX overlap and add. Update memory for next overlap. *
*-----------------------------------------------------------*/
for (i=0; i<L_OVLP; i++) {
xnq[i] += wovlp[i];
}
/* save overlap for next frame */
for (i=0; i<lext; i++) {
wovlp[i] = xnq[i+L_frame];
}
for (i=lext; i<L_OVLP; i++) {
wovlp[i] = 0.0;
}
/*-----------------------------------------------------------*
* find excitation and synthesis *
*-----------------------------------------------------------*/
//Perceptual Weighting
p_A = A;
for (i_subfr=0; i_subfr<L_frame; i_subfr+=L_SUBFR) {
paraChoose(p_A,&amt;gamma1,&amt;gamma2,&amt;gamma3);
E_LPC_a_weight(p_A, Ap1, gamma1, M);
E_LPC_a_weight(p_A, Ap2, gamma2, M);
E_LPC_a_weight(p_A, Ap3, gamma3, TILT_ORDER);

E_UTIL_detilt(&amt;xnq[i_subfr],Ap3,L_SUBFR,mem_tilt_exc);
E_UTIL_deformant(&amt;xnq[i_subfr],Ap2,L_SUBFR,mem_formant_exc);
E_UTIL_synthesis(Ap1, &amt;xnq[i_subfr], &amt;synth[i_subfr], L_SUBFR, &amt;synth[i_subfr-M], 0);
E_UTIL_residu(p_A, &amt;synth[i_subfr], &amt;exc[i_subfr], L_SUBFR);
p_A += (M+1);
}
return;
}
#endif
#endif

#ifndef PW_UPDATE
#ifdef NEW_TVC
void coder_tcx(
float A[], /* input: coefficients NxAz[M+1] */
float speech[], /* input: speech[-M..lg] */
float *mem_wsp, /* in/out: memory of target */
float *mem_wsyn, /* in/out: memory of quantized xn */
float synth[], /* in/out: synth[-M..lg] */
float exc[], /* output: exc[0..lg] */
float wovlp[], /* i/o: wovlp[0..127] */
int ovlp_size, /* input: 0, 64 or 128 (0=acelp) */
int L_frame, /* input: frame length */
int nb_bits, /* input: number of bits allowed */
int input_t, /* input: superframe edge indication */
int prm[])
{

int i, i_subfr, lext, lg, index,ovlp;

float gain, fac_ns,tmp;
float *p_A, Ap[M+1];
float *xri, *xn, *xnq;
float gh, gg, qgband;
float window[256];

static int cnt = 1;
xn = synth;
xnq = xri = exc;


/*------ set length of overlap (lext) and length of encoded frame (lg) -----*/
lext = L_OVLP;
if (L_frame == (L_FRAME_PLUS/2)) {
lext = L_OVLP/2;
}
if (L_frame == (L_FRAME_PLUS/4)) {
lext = L_OVLP/4;
}
lg = L_frame + lext;
/* built window for overlaps section */
//这里对前帧是acelp时进行处理

if (ovlp_size==0)
{
lext=lext/2;
ovlp=lext;
//下面是对snr而设定的
/* set_zero(sp, 80);
set_zero(synthpost, 80);
set_zero(synth2, 64);*/
set_zero(xn, 1152);
}
else{
ovlp=ovlp_size;
}

cos_window(window, ovlp, lext);

//如果前帧是acelp 就进行如下的分解
if (ovlp_size==0){
if(input_t==0){
for(i=0; i<lext; i++){
xn[i]= 0;
}
}
else{
for(i=0; i<lext; i++){
xn[i]= wovlp[64-lext+i];
}
}
for (i=0; i<128; i++) {
wovlp[i] = 0.0;
}

}

/*-----------------------------------------------------------*
* Find target xn[] (weighted speech when prev mode is TCX) *
* Note that memory isn't updated in the overlap area. *
*-----------------------------------------------------------*/
p_A = A;

if (ovlp_size==0){
for (i_subfr=0; i_subfr<L_frame; i_subfr+=L_SUBFR) {
E_LPC_a_weight(p_A, Ap, GAMMA1, M);
E_UTIL_residu(Ap, &amt;speech[i_subfr], &amt;xn[i_subfr+lext], L_SUBFR);
p_A += (M+1);
}
E_UTIL_deemph(&amt;xn[lext], TILT_FAC, L_frame, mem_wsp);
}
else{
for (i_subfr=0; i_subfr<L_frame; i_subfr+=L_SUBFR) {
E_LPC_a_weight(p_A, Ap, GAMMA1, M);
E_UTIL_residu(Ap, &amt;speech[i_subfr], &amt;xn[i_subfr], L_SUBFR);
p_A += (M+1);
}
E_UTIL_deemph(xn, TILT_FAC, L_frame, mem_wsp);
}
/* overlap area (xn[L_frame..L_frame+lext]) */
E_LPC_a_weight(p_A, Ap, GAMMA1, M);

if (ovlp_size==0){
E_UTIL_residu(Ap, &amt;speech[L_frame], &amt;xn[L_frame+lext], lext);
tmp = *mem_wsp;
E_UTIL_deemph(&amt;xn[L_frame+lext], TILT_FAC, lext, &amt;tmp);
}
else{
E_UTIL_residu(Ap, &amt;speech[L_frame], &amt;xn[L_frame], lext);
tmp = *mem_wsp;
E_UTIL_deemph(&amt;xn[L_frame], TILT_FAC, lext, &amt;tmp);

}

/* remove weighted ZIR when previous frame is ACELP */
if (ovlp_size == 0) {
for (i=0; i<lext; i++) {
xn[L_frame+lext+i] *= window[ovlp+i];
}
}
else{
for (i=0; i<ovlp; i++) {
xn[i] *= window[i];
}
for (i=0; i<lext; i++) {
xn[L_frame+i] *= window[ovlp+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(xn, xri, (short)lg);
xri[1] = 0.0; /* freq bin at 6400 Hz zeroed */

/* …… 预整形 模块 (开始) ……*/
/*-----------------------------------------------------------*
* Spectral algebraic quantization *
* with adaptive low pulse emphasis/deemphasis. *
* Noise factor is the average level of unquantized freq. *
*-----------------------------------------------------------*/
adap_pulse_emph(xri, lg);
nb_bits -= (3+7+7); /* fac_ns = 3 bits, gain = 7 bits */
/* remove also the redundancy bits of the TCX gain
TCX-40 -> 6 bits (in 2nd packet)
TCX-80 -> 9 bits (3 bits in 2nd, 3rd and 4th packet) */
if (L_frame == (L_FRAME_PLUS/2)) {
nb_bits -= 6;
}
if (L_frame == L_FRAME_PLUS) {
nb_bits -= 9;
}
fac_ns = AVQ_get_nf(xri, nb_bits, lg/8);
AVQ_gain_allocator(xri, lg, nb_bits, &amt;gh, &amt;gg);
//printf("gg = >f; gh = >f\r\n", gg, gh);
/* high half quantization */
AVQ_cod(xri, prm+3, nb_bits, lg/8, &amt;gh, &amt;gg);

for(i=0; i<lg; i++) {
xri[i] = (float)prm[i+3];
}
prm[2] = AVQ_gband(gh, &amt;qgband);
for (i=0; i<lg/2; i++)
xri[i+lg/2] /= qgband;
adap_pulse_deemph(xri, lg);
/* …… 预整形 模块 (结束) ……*/
/* quantize noise factor (noise factor = 0.1 to 0.8) */
tmp = 8.0f - (10.0f*fac_ns);
index = (int)floor(tmp + 0.5);
if (index < 0) {
index = 0;
}
if (index > 7) {
index = 7;
}
prm[0] = index; /* fac_ns : 3 bits */

/*-----------------------------------------------------------*
* 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. *
*-----------------------------------------------------------*/
xri[1] = 0.0; /* freq bin at 6400 Hz zeroed */
ifft9(xri, xnq, (short)lg);
/*-----------------------------------------------------------*
* find and quantize gain, multiply xnq[] by gain. *
* windowing of xnq[] for TCX overlap. *
*-----------------------------------------------------------*/
gain = get_gain(xn, xnq, lg);
prm[1] = q_gain_tcx(xnq, lg, &amt;gain);
for (i=0; i<lg; i++) {
xnq[i] *= gain;
}

/* adaptive windowing on overlap (beginning and end of frame) */
if (ovlp_size ==0){
for (i=0; i<lext; i++) {
xnq[i+L_frame+lext] *= window[ovlp+i];
}
}
else{
for (i=0; i<ovlp; i++) {
xnq[i] *= window[i];
}

for (i=0; i<lext; i++) {
xnq[i+L_frame] *= window[ovlp+i];
}
}

/*-----------------------------------------------------------*
* TCX overlap and add. Update memory for next overlap. *
*-----------------------------------------------------------*/

if (ovlp_size ==0){
for (i=0; i<lext; i++) {
wovlp[i] = xnq[i+L_frame+lext];
}
}
else{
for (i=0; i<L_OVLP; i++) {
xnq[i] += wovlp[i];
}

/* save overlap for next frame */
for (i=0; i<lext; i++) {
wovlp[i] = xnq[i+L_frame];
}
}
for (i=lext; i<128; i++) {
wovlp[i] = 0.0;
}



/*-----------------------------------------------------------*
* find excitation and synthesis *
*-----------------------------------------------------------*/
if (ovlp_size==0){
E_UTIL_f_preemph(&amt;xnq[lext], TILT_FAC, L_frame, mem_wsyn);
p_A = A;
for (i_subfr=0; i_subfr<L_frame; i_subfr+=L_SUBFR) {
E_LPC_a_weight(p_A, Ap, GAMMA1, M);
E_UTIL_synthesis(Ap, &amt;xnq[i_subfr+lext], &amt;synth[i_subfr], L_SUBFR, &amt;synth[i_subfr-M], 0);
E_UTIL_residu(p_A, &amt;synth[i_subfr], &amt;exc[i_subfr], L_SUBFR);
p_A += (M+1);
}
}
else{
E_UTIL_f_preemph(xnq, TILT_FAC, L_frame, mem_wsyn);
p_A = A;
for (i_subfr=0; i_subfr<L_frame; i_subfr+=L_SUBFR) {
E_LPC_a_weight(p_A, Ap, GAMMA1, M);
E_UTIL_synthesis(Ap, &amt;xnq[i_subfr], &amt;synth[i_subfr], L_SUBFR, &amt;synth[i_subfr-M], 0);
E_UTIL_residu(p_A, &amt;synth[i_subfr], &amt;exc[i_subfr], L_SUBFR);
p_A += (M+1);
}
}
return;
}
#else
void coder_tcx(
float A[], /* input: coefficients NxAz[M+1] */
float speech[], /* input: speech[-M..lg] */
float *mem_wsp, /* in/out: memory of target */
float *mem_wsyn, /* in/out: memory of quantized xn */
float synth[], /* in/out: synth[-M..lg] */
float exc[], /* output: exc[0..lg] */
float wovlp[], /* i/o: wovlp[0..127] */
int ovlp_size, /* input: 0, 64 or 128 (0=acelp) */
int L_frame, /* input: frame length */
int nb_bits, /* input: number of bits allowed */
int prm[]) /* output: tcx parameters */
{
int i, i_subfr, lext, lg, index;
float tmp, gain, fac_ns;
float *p_A, Ap[M+1],Ap1[M+1],Ap2[M+1],Ap3[M+1];
float *xri, *xn, *xnq;
float window[256];
xn = synth;
xnq = xri = exc;
/*------ set length of overlap (lext) and length of encoded frame (lg) -----*/
lext = L_OVLP;
if (L_frame == (L_FRAME_PLUS/2)) {
lext = L_OVLP/2;
}
if (L_frame == (L_FRAME_PLUS/4)) {
lext = L_OVLP/4;
}
lg = L_frame + lext;
/* built window for overlaps section */
cos_window(window, ovlp_size, lext);
/*-----------------------------------------------------------*
* Find target xn[] (weighted speech when prev mode is TCX) *
* Note that memory isn't updated in the overlap area. *
*-----------------------------------------------------------*/
p_A = A;
for (i_subfr=0; i_subfr<L_frame; i_subfr+=L_SUBFR) {
E_LPC_a_weight(p_A, Ap, GAMMA1, M);
E_UTIL_residu(Ap, &amt;speech[i_subfr], &amt;xn[i_subfr], L_SUBFR);
p_A += (M+1);
}
E_UTIL_deemph(xn, TILT_FAC, L_frame, mem_wsp);
/* overlap area (xn[L_frame..L_frame+lext]) */
E_LPC_a_weight(p_A, Ap, GAMMA1, M);
E_UTIL_residu(Ap, &amt;speech[L_frame], &amt;xn[L_frame], lext);
tmp = *mem_wsp;
E_UTIL_deemph(&amt;xn[L_frame], TILT_FAC, lext, &amt;tmp);
/* remove weighted ZIR when previous frame is ACELP */
if (ovlp_size == 0) {
for (i=0; i<(2*L_SUBFR); i++) {
xn[i] -= wovlp[i];
}
}
/* xn[] windowing for TCX overlap */
for (i=0; i<ovlp_size; i++) {
xn[i] *= window[i];
}
for (i=0; i<lext; i++) {
xn[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(xn, xri, (short)lg);
xri[1] = 0.0; /* freq bin at 6400 Hz zeroed */
/*-----------------------------------------------------------*
* Spectral algebraic quantization *
* with adaptive low frequency emphasis/deemphasis. *
* Noise factor is the average level of unquantized freq. *
*-----------------------------------------------------------*/
adap_low_freq_emph(xri, lg);
nb_bits -= (3+7); /* fac_ns = 3 bits, gain = 7 bits */
/* remove also the redundancy bits of the TCX gain
TCX-40 -> 6 bits (in 2nd packet)
TCX-80 -> 9 bits (3 bits in 2nd, 3rd and 4th packet) */
if (L_frame == (L_FRAME_PLUS/2)) {
nb_bits -= 6;
}
if (L_frame == L_FRAME_PLUS) {
nb_bits -= 9;
}
fac_ns = AVQ_cod(xri, prm+2, nb_bits, lg/8);
for(i=0; i<lg; i++) {
xri[i] = (float)prm[i+2];
}
adap_low_freq_deemph(xri, lg);
/* quantize noise factor (noise factor = 0.1 to 0.8) */
tmp = 8.0f - (10.0f*fac_ns);
index = (int)floor(tmp + 0.5);
if (index < 0) {
index = 0;
}
if (index > 7) {
index = 7;
}
prm[0] = index; /* fac_ns : 3 bits */
/*-----------------------------------------------------------*
* 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. *
*-----------------------------------------------------------*/
xri[1] = 0.0; /* freq bin at 6400 Hz zeroed */
ifft9(xri, xnq, (short)lg);
/*-----------------------------------------------------------*
* find and quantize gain, multiply xnq[] by gain. *
* windowing of xnq[] for TCX overlap. *
*-----------------------------------------------------------*/
gain = get_gain(xn, xnq, lg);
prm[1] = q_gain_tcx(xnq, lg, &amt;gain);
for (i=0; i<lg; i++) {
xnq[i] *= gain;
}
/* adaptive windowing on overlap (beginning and end of frame) */
for (i=0; i<ovlp_size; i++) {
xnq[i] *= window[i];
}
for (i=0; i<lext; i++) {
xnq[i+L_frame] *= window[ovlp_size+i];
}
/*-----------------------------------------------------------*
* TCX overlap and add. Update memory for next overlap. *
*-----------------------------------------------------------*/
for (i=0; i<L_OVLP; i++) {
xnq[i] += wovlp[i];
}
/* save overlap for next frame */
for (i=0; i<lext; i++) {
wovlp[i] = xnq[i+L_frame];
}
for (i=lext; i<L_OVLP; i++) {
wovlp[i] = 0.0;
}
/*-----------------------------------------------------------*
* find excitation and synthesis *
*-----------------------------------------------------------*/
E_UTIL_f_preemph(xnq, TILT_FAC, L_frame, mem_wsyn);
p_A = A;
for (i_subfr=0; i_subfr<L_frame; i_subfr+=L_SUBFR) {
E_LPC_a_weight(p_A, Ap, GAMMA1, M);
E_UTIL_synthesis(Ap, &amt;xnq[i_subfr], &amt;synth[i_subfr], L_SUBFR, &amt;synth[i_subfr-M], 0);
E_UTIL_residu(p_A, &amt;synth[i_subfr], &amt;exc[i_subfr], L_SUBFR);
p_A += (M+1);
}
return;
}
#endif
#endif