- initial import

This commit is contained in:
2018-06-05 11:05:37 +03:00
commit e1a4931375
4673 changed files with 1383093 additions and 0 deletions

View File

@@ -0,0 +1,443 @@
/*
ITU-T G.729A Speech Coder ANSI-C Source Code
Version 1.1 Last modified: September 1996
Copyright (c) 1996,
AT&T, France Telecom, NTT, Universite de Sherbrooke
All rights reserved.
*/
#include "g729_typedef.h"
#include "g729_basic_op.h"
#include "g729_oper_32b.h"
#include "g729_ld8a.h"
#include "g729_tab_ld8a.h"
#include "g729_taming.h"
void Gbk_presel (Word16 best_gain[], /* (i) [0] Q9 : unquantized pitch gain */
/* (i) [1] Q2 : unquantized code gain */
Word16 * cand1, /* (o) : index of best 1st stage vector */
Word16 * cand2, /* (o) : index of best 2nd stage vector */
Word16 gcode0 /* (i) Q4 : presearch for gain codebook */
);
/*---------------------------------------------------------------------------*
* Function Qua_gain *
* ~~~~~~~~~~~~~~~~~~ *
* Inputs: *
* code[] :Innovative codebook. *
* g_coeff[] :Correlations compute for pitch. *
* L_subfr :Subframe length. *
* *
* Outputs: *
* gain_pit :Quantized pitch gain. *
* gain_cod :Quantized code gain. *
* *
* Return: *
* Index of quantization. *
* *
*--------------------------------------------------------------------------*/
Word16
Qua_gain (CodState *coder,
Word16 code[], /* (i) Q13 :Innovative vector. */
Word16 g_coeff[], /* (i) :Correlations <xn y1> -2<y1 y1> */
/* <y2,y2>, -2<xn,y2>, 2<y1,y2> */
Word16 exp_coeff[], /* (i) :Q-Format g_coeff[] */
Word16 L_subfr, /* (i) :Subframe length. */
Word16 * gain_pit, /* (o) Q14 :Pitch gain. */
Word16 * gain_cod, /* (o) Q1 :Code gain. */
Word16 tameflag /* (i) : set to 1 if taming is needed */
)
{
Word16 i, j, index1, index2;
Word16 cand1, cand2;
Word16 exp, gcode0, exp_gcode0, gcode0_org, e_min;
Word16 nume, denom, inv_denom;
Word16 exp1, exp2, exp_nume, exp_denom, exp_inv_denom, sft, tmp;
Word16 g_pitch, g2_pitch, g_code, g2_code, g_pit_cod;
Word16 coeff[5], coeff_lsf[5];
Word16 exp_min[5];
Word32 L_gbk12;
Word32 L_tmp, L_dist_min, L_temp, L_tmp1, L_tmp2, L_acc, L_accb;
Word16 best_gain[2];
/* Gain predictor, Past quantized energies = -14.0 in Q10 */
/*---------------------------------------------------*
*- energy due to innovation -*
*- predicted energy -*
*- predicted codebook gain => gcode0[exp_gcode0] -*
*---------------------------------------------------*/
Gain_predict (coder->past_qua_en, code, L_subfr, &gcode0, &exp_gcode0);
/*-----------------------------------------------------------------*
* pre-selection *
*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*
* calculate best gain *
* *
* tmp = -1./(4.*coeff[0]*coeff[2]-coeff[4]*coeff[4]) ; *
* best_gain[0] = (2.*coeff[2]*coeff[1]-coeff[3]*coeff[4])*tmp ; *
* best_gain[1] = (2.*coeff[0]*coeff[3]-coeff[1]*coeff[4])*tmp ; *
* gbk_presel(best_gain,&cand1,&cand2,gcode0) ; *
* *
*-----------------------------------------------------------------*/
/*-----------------------------------------------------------------*
* tmp = -1./(4.*coeff[0]*coeff[2]-coeff[4]*coeff[4]) ; *
*-----------------------------------------------------------------*/
L_tmp1 = L_mult (g_coeff[0], g_coeff[2]);
exp1 = add (add (exp_coeff[0], exp_coeff[2]), 1 - 2);
L_tmp2 = L_mult (g_coeff[4], g_coeff[4]);
exp2 = add (add (exp_coeff[4], exp_coeff[4]), 1);
if (sub (exp1, exp2) > 0) {
L_tmp = L_sub (L_shr (L_tmp1, sub (exp1, exp2)), L_tmp2);
exp = exp2;
}
else {
L_tmp = L_sub (L_tmp1, L_shr (L_tmp2, sub (exp2, exp1)));
exp = exp1;
}
sft = norm_l (L_tmp);
denom = extract_h (L_shl (L_tmp, sft));
exp_denom = sub (add (exp, sft), 16);
inv_denom = div_s (16384, denom);
inv_denom = negate (inv_denom);
exp_inv_denom = sub (14 + 15, exp_denom);
/*-----------------------------------------------------------------*
* best_gain[0] = (2.*coeff[2]*coeff[1]-coeff[3]*coeff[4])*tmp ; *
*-----------------------------------------------------------------*/
L_tmp1 = L_mult (g_coeff[2], g_coeff[1]);
exp1 = add (exp_coeff[2], exp_coeff[1]);
L_tmp2 = L_mult (g_coeff[3], g_coeff[4]);
exp2 = add (add (exp_coeff[3], exp_coeff[4]), 1);
if (sub (exp1, exp2) > 0) {
L_tmp =
L_sub (L_shr (L_tmp1, add (sub (exp1, exp2), 1)), L_shr (L_tmp2, 1));
exp = sub (exp2, 1);
}
else {
L_tmp =
L_sub (L_shr (L_tmp1, 1), L_shr (L_tmp2, add (sub (exp2, exp1), 1)));
exp = sub (exp1, 1);
}
sft = norm_l (L_tmp);
nume = extract_h (L_shl (L_tmp, sft));
exp_nume = sub (add (exp, sft), 16);
sft = sub (add (exp_nume, exp_inv_denom), (9 + 16 - 1));
L_acc = L_shr (L_mult (nume, inv_denom), sft);
best_gain[0] = extract_h (L_acc); /*-- best_gain[0]:Q9 --*/
if (tameflag == 1) {
if (sub (best_gain[0], GPCLIP2) > 0)
best_gain[0] = GPCLIP2;
}
/*-----------------------------------------------------------------*
* best_gain[1] = (2.*coeff[0]*coeff[3]-coeff[1]*coeff[4])*tmp ; *
*-----------------------------------------------------------------*/
L_tmp1 = L_mult (g_coeff[0], g_coeff[3]);
exp1 = add (exp_coeff[0], exp_coeff[3]);
L_tmp2 = L_mult (g_coeff[1], g_coeff[4]);
exp2 = add (add (exp_coeff[1], exp_coeff[4]), 1);
if (sub (exp1, exp2) > 0) {
L_tmp =
L_sub (L_shr (L_tmp1, add (sub (exp1, exp2), 1)), L_shr (L_tmp2, 1));
exp = sub (exp2, 1);
}
else {
L_tmp =
L_sub (L_shr (L_tmp1, 1), L_shr (L_tmp2, add (sub (exp2, exp1), 1)));
exp = sub (exp1, 1);
}
sft = norm_l (L_tmp);
nume = extract_h (L_shl (L_tmp, sft));
exp_nume = sub (add (exp, sft), 16);
sft = sub (add (exp_nume, exp_inv_denom), (2 + 16 - 1));
L_acc = L_shr (L_mult (nume, inv_denom), sft);
best_gain[1] = extract_h (L_acc); /*-- best_gain[1]:Q2 --*/
/*--- Change Q-format of gcode0 ( Q[exp_gcode0] -> Q4 ) ---*/
if (sub (exp_gcode0, 4) >= 0) {
gcode0_org = shr (gcode0, sub (exp_gcode0, 4));
}
else {
L_acc = L_deposit_l (gcode0);
L_acc = L_shl (L_acc, sub ((4 + 16), exp_gcode0));
gcode0_org = extract_h (L_acc); /*-- gcode0_org:Q4 --*/
}
/*----------------------------------------------*
* - presearch for gain codebook - *
*----------------------------------------------*/
Gbk_presel (best_gain, &cand1, &cand2, gcode0_org);
/*---------------------------------------------------------------------------*
* *
* Find the best quantizer. *
* *
* dist_min = MAX_32; *
* for ( i=0 ; i<NCAN1 ; i++ ){ *
* for ( j=0 ; j<NCAN2 ; j++ ){ *
* g_pitch = gbk1[cand1+i][0] + gbk2[cand2+j][0]; *
* g_code = gcode0 * (gbk1[cand1+i][1] + gbk2[cand2+j][1]); *
* dist = g_pitch*g_pitch * coeff[0] *
* + g_pitch * coeff[1] *
* + g_code*g_code * coeff[2] *
* + g_code * coeff[3] *
* + g_pitch*g_code * coeff[4] ; *
* *
* if (dist < dist_min){ *
* dist_min = dist; *
* indice1 = cand1 + i ; *
* indice2 = cand2 + j ; *
* } *
* } *
* } *
* *
* g_pitch = Q13 *
* g_pitch*g_pitch = Q11:(13+13+1-16) *
* g_code = Q[exp_gcode0-3]:(exp_gcode0+(13-1)+1-16) *
* g_code*g_code = Q[2*exp_gcode0-21]:(exp_gcode0-3+exp_gcode0-3+1-16) *
* g_pitch*g_code = Q[exp_gcode0-5]:(13+exp_gcode0-3+1-16) *
* *
* term 0: g_pitch*g_pitch*coeff[0] ;exp_min0 = 13 +exp_coeff[0] *
* term 1: g_pitch *coeff[1] ;exp_min1 = 14 +exp_coeff[1] *
* term 2: g_code*g_code *coeff[2] ;exp_min2 = 2*exp_gcode0-21+exp_coeff[2] *
* term 3: g_code *coeff[3] ;exp_min3 = exp_gcode0 - 3+exp_coeff[3] *
* term 4: g_pitch*g_code *coeff[4] ;exp_min4 = exp_gcode0 - 4+exp_coeff[4] *
* *
*---------------------------------------------------------------------------*/
exp_min[0] = add (exp_coeff[0], 13);
exp_min[1] = add (exp_coeff[1], 14);
exp_min[2] = add (exp_coeff[2], sub (shl (exp_gcode0, 1), 21));
exp_min[3] = add (exp_coeff[3], sub (exp_gcode0, 3));
exp_min[4] = add (exp_coeff[4], sub (exp_gcode0, 4));
e_min = exp_min[0];
for (i = 1; i < 5; i++) {
if (sub (exp_min[i], e_min) < 0) {
e_min = exp_min[i];
}
}
/* align coeff[] and save in special 32 bit double precision */
for (i = 0; i < 5; i++) {
j = sub (exp_min[i], e_min);
L_tmp = L_deposit_h (g_coeff[i]);
L_tmp = L_shr (L_tmp, j); /* L_tmp:Q[exp_g_coeff[i]+16-j] */
L_Extract (L_tmp, &coeff[i], &coeff_lsf[i]); /* DPF */
}
/* Codebook search */
L_dist_min = MAX_32;
/* initialization used only to suppress Microsoft Visual C++ warnings */
index1 = cand1;
index2 = cand2;
if (tameflag == 1) {
for (i = 0; i < NCAN1; i++) {
for (j = 0; j < NCAN2; j++) {
g_pitch = add (gbk1[cand1 + i][0], gbk2[cand2 + j][0]); /* Q14 */
if (g_pitch < GP0999) {
L_acc = L_deposit_l (gbk1[cand1 + i][1]);
L_accb = L_deposit_l (gbk2[cand2 + j][1]); /* Q13 */
L_tmp = L_add (L_acc, L_accb);
tmp = extract_l (L_shr (L_tmp, 1)); /* Q12 */
g_code = mult (gcode0, tmp); /* Q[exp_gcode0+12-15] */
g2_pitch = mult (g_pitch, g_pitch); /* Q13 */
g2_code = mult (g_code, g_code); /* Q[2*exp_gcode0-6-15] */
g_pit_cod = mult (g_code, g_pitch); /* Q[exp_gcode0-3+14-15] */
L_tmp = Mpy_32_16 (coeff[0], coeff_lsf[0], g2_pitch);
L_tmp = L_add (L_tmp, Mpy_32_16 (coeff[1], coeff_lsf[1], g_pitch));
L_tmp = L_add (L_tmp, Mpy_32_16 (coeff[2], coeff_lsf[2], g2_code));
L_tmp = L_add (L_tmp, Mpy_32_16 (coeff[3], coeff_lsf[3], g_code));
L_tmp =
L_add (L_tmp, Mpy_32_16 (coeff[4], coeff_lsf[4], g_pit_cod));
L_temp = L_sub (L_tmp, L_dist_min);
if (L_temp < 0L) {
L_dist_min = L_tmp;
index1 = add (cand1, i);
index2 = add (cand2, j);
}
}
}
}
}
else {
for (i = 0; i < NCAN1; i++) {
for (j = 0; j < NCAN2; j++) {
g_pitch = add (gbk1[cand1 + i][0], gbk2[cand2 + j][0]); /* Q14 */
L_acc = L_deposit_l (gbk1[cand1 + i][1]);
L_accb = L_deposit_l (gbk2[cand2 + j][1]); /* Q13 */
L_tmp = L_add (L_acc, L_accb);
tmp = extract_l (L_shr (L_tmp, 1)); /* Q12 */
g_code = mult (gcode0, tmp); /* Q[exp_gcode0+12-15] */
g2_pitch = mult (g_pitch, g_pitch); /* Q13 */
g2_code = mult (g_code, g_code); /* Q[2*exp_gcode0-6-15] */
g_pit_cod = mult (g_code, g_pitch); /* Q[exp_gcode0-3+14-15] */
L_tmp = Mpy_32_16 (coeff[0], coeff_lsf[0], g2_pitch);
L_tmp = L_add (L_tmp, Mpy_32_16 (coeff[1], coeff_lsf[1], g_pitch));
L_tmp = L_add (L_tmp, Mpy_32_16 (coeff[2], coeff_lsf[2], g2_code));
L_tmp = L_add (L_tmp, Mpy_32_16 (coeff[3], coeff_lsf[3], g_code));
L_tmp = L_add (L_tmp, Mpy_32_16 (coeff[4], coeff_lsf[4], g_pit_cod));
L_temp = L_sub (L_tmp, L_dist_min);
if (L_temp < 0L) {
L_dist_min = L_tmp;
index1 = add (cand1, i);
index2 = add (cand2, j);
}
}
}
}
/* Read the quantized gain */
/*-----------------------------------------------------------------*
* *gain_pit = gbk1[indice1][0] + gbk2[indice2][0]; *
*-----------------------------------------------------------------*/
*gain_pit = add (gbk1[index1][0], gbk2[index2][0]); /* Q14 */
/*-----------------------------------------------------------------*
* *gain_code = (gbk1[indice1][1]+gbk2[indice2][1]) * gcode0; *
*-----------------------------------------------------------------*/
L_acc = L_deposit_l (gbk1[index1][1]);
L_accb = L_deposit_l (gbk2[index2][1]);
L_gbk12 = L_add (L_acc, L_accb); /* Q13 */
tmp = extract_l (L_shr (L_gbk12, 1)); /* Q12 */
L_acc = L_mult (tmp, gcode0); /* Q[exp_gcode0+12+1] */
L_acc = L_shl (L_acc, add (negate (exp_gcode0), (-12 - 1 + 1 + 16)));
*gain_cod = extract_h (L_acc); /* Q1 */
/*----------------------------------------------*
* update table of past quantized energies *
*----------------------------------------------*/
Gain_update (coder->past_qua_en, L_gbk12);
return (add (map1[index1] * (Word16) NCODE2, map2[index2]));
}
/*---------------------------------------------------------------------------*
* Function Gbk_presel *
* ~~~~~~~~~~~~~~~~~~~ *
* - presearch for gain codebook - *
*---------------------------------------------------------------------------*/
void
Gbk_presel (Word16 best_gain[], /* (i) [0] Q9 : unquantized pitch gain */
/* (i) [1] Q2 : unquantized code gain */
Word16 * cand1, /* (o) : index of best 1st stage vector */
Word16 * cand2, /* (o) : index of best 2nd stage vector */
Word16 gcode0 /* (i) Q4 : presearch for gain codebook */
)
{
Word16 acc_h;
Word16 sft_x, sft_y;
Word32 L_acc, L_preg, L_cfbg, L_tmp, L_tmp_x, L_tmp_y;
Word32 L_temp;
/*--------------------------------------------------------------------------*
x = (best_gain[1]-(coef[0][0]*best_gain[0]+coef[1][1])*gcode0) * inv_coef;
*--------------------------------------------------------------------------*/
L_cfbg = L_mult (coef[0][0], best_gain[0]); /* L_cfbg:Q20 -> !!y */
L_acc = L_shr (L_coef[1][1], 15); /* L_acc:Q20 */
L_acc = L_add (L_cfbg, L_acc);
acc_h = extract_h (L_acc); /* acc_h:Q4 */
L_preg = L_mult (acc_h, gcode0); /* L_preg:Q9 */
L_acc = L_shl (L_deposit_l (best_gain[1]), 7); /* L_acc:Q9 */
L_acc = L_sub (L_acc, L_preg);
acc_h = extract_h (L_shl (L_acc, 2)); /* L_acc_h:Q[-5] */
L_tmp_x = L_mult (acc_h, INV_COEF); /* L_tmp_x:Q15 */
/*--------------------------------------------------------------------------*
y = (coef[1][0]*(-coef[0][1]+best_gain[0]*coef[0][0])*gcode0
-coef[0][0]*best_gain[1]) * inv_coef;
*--------------------------------------------------------------------------*/
L_acc = L_shr (L_coef[0][1], 10); /* L_acc:Q20 */
L_acc = L_sub (L_cfbg, L_acc); /* !!x -> L_cfbg:Q20 */
acc_h = extract_h (L_acc); /* acc_h:Q4 */
acc_h = mult (acc_h, gcode0); /* acc_h:Q[-7] */
L_tmp = L_mult (acc_h, coef[1][0]); /* L_tmp:Q10 */
L_preg = L_mult (coef[0][0], best_gain[1]); /* L_preg:Q13 */
L_acc = L_sub (L_tmp, L_shr (L_preg, 3)); /* L_acc:Q10 */
acc_h = extract_h (L_shl (L_acc, 2)); /* acc_h:Q[-4] */
L_tmp_y = L_mult (acc_h, INV_COEF); /* L_tmp_y:Q16 */
sft_y = (14 + 4 + 1) - 16; /* (Q[thr1]+Q[gcode0]+1)-Q[L_tmp_y] */
sft_x = (15 + 4 + 1) - 15; /* (Q[thr2]+Q[gcode0]+1)-Q[L_tmp_x] */
if (gcode0 > 0) {
/*-- pre select codebook #1 --*/
*cand1 = 0;
do {
L_temp = L_sub (L_tmp_y, L_shr (L_mult (thr1[*cand1], gcode0), sft_y));
if (L_temp > 0L) {
(*cand1) = add (*cand1, 1);
}
else
break;
} while (sub ((*cand1), (NCODE1 - NCAN1)) < 0);
/*-- pre select codebook #2 --*/
*cand2 = 0;
do {
L_temp = L_sub (L_tmp_x, L_shr (L_mult (thr2[*cand2], gcode0), sft_x));
if (L_temp > 0L) {
(*cand2) = add (*cand2, 1);
}
else
break;
} while (sub ((*cand2), (NCODE2 - NCAN2)) < 0);
}
else {
/*-- pre select codebook #1 --*/
*cand1 = 0;
do {
L_temp = L_sub (L_tmp_y, L_shr (L_mult (thr1[*cand1], gcode0), sft_y));
if (L_temp < 0L) {
(*cand1) = add (*cand1, 1);
}
else
break;
} while (sub ((*cand1), (NCODE1 - NCAN1)));
/*-- pre select codebook #2 --*/
*cand2 = 0;
do {
L_temp = L_sub (L_tmp_x, L_shr (L_mult (thr2[*cand2], gcode0), sft_x));
if (L_temp < 0L) {
(*cand2) = add (*cand2, 1);
}
else
break;
} while (sub ((*cand2), (NCODE2 - NCAN2)));
}
return;
}