📄 g7231_cod_cng.c
字号:
#include "typedef.h"
#include "G7231_cst_lbc.h"
#include "G7231_tab_lbc.h"
#include "G7231_util_lbc.h"
#include "G7231_basop.h"
#include "G7231_lsp.h"
#include "G7231_lpc.h"
#include "G7231_util_cng.h"
#include "G7231_cod_cng.h"
#include "G7231_vad.h"
#include "G7231_coder.h"
#include "intrindefs.h"
static void G7231ComputePastAvFilter(Word16 *Coeff);
static void G7231CalcRC(Word16 *Coeff, Word16 *RC, Word16 *shRC);
static Flag G7231LpcDiff(Word16 *RC, Word16 shRC, Word16 *Acf, Word16 alpha);
G7231CODCNGDEF G7231CodCng;
void G7231Init_Cod_Cng(void)
{
int i;
G7231CodCng.CurGain = 0;
for(i=0; i< G7231SizAcf; i++) G7231CodCng.Acf[i] = 0;
for(i=0; i <= G7231NbAvAcf; i++) G7231CodCng.ShAcf[i] = 40;
for(i=0; i < G7231LpcOrder; i++) G7231CodCng.SidLpc[i] = 0;
G7231CodCng.PastFtyp = 1;
G7231CodCng.RandSeed = 12345;
return;
}
void G7231Cod_Cng(Word16 *DataExc, Word16 *Ftyp, G7231LINEDEF *Line, Word16 *QntLpc)
{
Word16 curCoeff[G7231LpcOrder];
Word16 curQGain;
Word16 temp;
int i;
for(i=G7231NbAvGain-1; i>=1; i--) {
G7231CodCng.Ener[i] = G7231CodCng.Ener[i-1];
}
G7231CodCng.Ener[0] = G7231Durbin(curCoeff, &G7231CodCng.Acf[1], G7231CodCng.Acf[0], &temp);
if(G7231CodCng.PastFtyp == 1) {
*Ftyp = 2;
G7231CodCng.NbEner = 1;
curQGain = G7231Qua_SidGain(G7231CodCng.Ener, G7231CodCng.ShAcf, G7231CodCng.NbEner);
}
else {
G7231CodCng.NbEner++;
if(G7231CodCng.NbEner > G7231NbAvGain) G7231CodCng.NbEner = G7231NbAvGain;
curQGain = G7231Qua_SidGain(G7231CodCng.Ener, G7231CodCng.ShAcf, G7231CodCng.NbEner);
if(G7231LpcDiff(G7231CodCng.RC, G7231CodCng.ShRC, G7231CodCng.Acf, *G7231CodCng.Ener) == 0)
{
*Ftyp = 2;
}
else {
temp = G7231abs_s(G7231sub(curQGain, G7231CodCng.IRef));
if(temp > G7231ThreshGain) {
*Ftyp = 2;
}
else {
*Ftyp = 0;
}
}
}
if(*Ftyp == 2) {
G7231ComputePastAvFilter(G7231CodCng.SidLpc) ;
if ( !G7231VadStat.Aen ) {
for(i=0; i<G7231LpcOrder; i++) G7231VadStat.NLpc[i] = G7231CodCng.SidLpc[i];
}
G7231CalcRC(G7231CodCng.SidLpc , G7231CodCng.RC, &G7231CodCng.ShRC);
if(G7231LpcDiff(G7231CodCng.RC, G7231CodCng.ShRC, G7231CodCng.Acf, *G7231CodCng.Ener) == 0){
for(i=0; i<G7231LpcOrder; i++) {
G7231CodCng.SidLpc[i] = curCoeff[i];
}
G7231CalcRC(curCoeff, G7231CodCng.RC, &G7231CodCng.ShRC);
}
G7231AtoLsp(G7231CodCng.LspSid, G7231CodCng.SidLpc, G7231CodStat.PrevLsp);
Line->LspId = G7231Lsp_Qnt(G7231CodCng.LspSid, G7231CodStat.PrevLsp);
G7231Lsp_Inq(G7231CodCng.LspSid, G7231CodStat.PrevLsp, Line->LspId, 0);
Line->Sfs[0].Mamp = curQGain;
G7231CodCng.IRef = curQGain;
G7231CodCng.SidGain = G7231Dec_SidGain(G7231CodCng.IRef);
}
if(G7231CodCng.PastFtyp == 1) {
G7231CodCng.CurGain = G7231CodCng.SidGain;
}
else {
G7231CodCng.CurGain = G7231extract_h(G7231L_add( G7231L_mult(G7231CodCng.CurGain,0x7000),
G7231L_mult(G7231CodCng.SidGain,0x1000) ) ) ;
}
G7231Calc_Exc_Rand_En(G7231CodCng.CurGain, G7231CodStat.PrevExc, DataExc,
&G7231CodCng.RandSeed, Line);
G7231Lsp_Int(QntLpc, G7231CodCng.LspSid, G7231CodStat.PrevLsp);
for (i=0; i < G7231LpcOrder ; i++) {
G7231CodStat.PrevLsp[i] = G7231CodCng.LspSid[i];
}
G7231CodCng.PastFtyp = *Ftyp;
return;
}
void G7231Update_Acf(Word16 *Acf_sf, Word16 *ShAcf_sf)
{
int i, i_subfr;
Word16 *ptr1, *ptr2;
Word32 L_temp[G7231LpcOrderP1];
Word16 sh1, temp;
Word32 L_acc0;
ptr2 = G7231CodCng.Acf + G7231SizAcf;
ptr1 = ptr2 - G7231LpcOrderP1;
for(i=G7231LpcOrderP1; i<G7231SizAcf; i++) *(--ptr2) = *(--ptr1);
for(i=G7231NbAvAcf; i>=1; i--) G7231CodCng.ShAcf[i] = G7231CodCng.ShAcf[i-1];
sh1 = ShAcf_sf[0];
for(i_subfr=1; i_subfr<G7231SubFrames; i_subfr++) {
if(ShAcf_sf[i_subfr] < sh1) sh1 = ShAcf_sf[i_subfr];
}
sh1 = G7231add(sh1, 14);
for(i=0; i<= G7231LpcOrder; i++) L_temp[i] = 0;
ptr2 = Acf_sf;
for(i_subfr=0; i_subfr<G7231SubFrames; i_subfr++) {
temp = G7231sub(sh1, ShAcf_sf[i_subfr]);
for(i=0; i <= G7231LpcOrder; i++) {
L_acc0 = G7231L_deposit_l(*ptr2++);
L_acc0 = G7231L_shl(L_acc0, temp);
L_temp[i] = G7231L_add(L_temp[i], L_acc0);
}
}
temp = G7231norm_l(L_temp[0]);
temp = G7231sub(16, temp);
if(temp < 0) temp = 0;
for(i=0; i <= G7231LpcOrder; i++) {
G7231CodCng.Acf[i] = G7231extract_l(G7231L_shr(L_temp[i],temp));
}
G7231CodCng.ShAcf[0] = G7231sub(sh1, temp);
return;
}
void G7231ComputePastAvFilter(Word16 *Coeff)
{
int i, j;
Word16 *ptr_Acf;
Word32 L_sumAcf[G7231LpcOrderP1];
Word16 Corr[G7231LpcOrder], Err;
Word16 sh1, temp;
Word32 L_acc0;
sh1 = G7231CodCng.ShAcf[1];
for(i=2; i <= G7231NbAvAcf; i ++) {
temp = G7231CodCng.ShAcf[i];
if(temp < sh1) sh1 = temp;
}
sh1 = G7231add(sh1, 14);
for(j=0; j <= G7231LpcOrder; j++) L_sumAcf[j] = 0;
ptr_Acf = G7231CodCng.Acf + G7231LpcOrderP1;
for(i=1; i <= G7231NbAvAcf; i ++) {
temp = G7231sub(sh1, G7231CodCng.ShAcf[i]);
for(j=0; j <= G7231LpcOrder; j++) {
L_acc0 = G7231L_deposit_l(*ptr_Acf++);
L_acc0 = G7231L_shl(L_acc0, temp);
L_sumAcf[j] = G7231L_add(L_sumAcf[j], L_acc0);
}
}
temp = G7231norm_l(L_sumAcf[0]);
temp = G7231sub(16, temp);
if(temp < 0) temp = 0;
Err = G7231extract_l(G7231L_shr(L_sumAcf[0],temp));
for(i=1; i<G7231LpcOrderP1; i++) {
Corr[i-1] = G7231extract_l(G7231L_shr(L_sumAcf[i],temp));
}
G7231Durbin(Coeff, Corr, Err, &temp);
return;
}
void G7231CalcRC(Word16 *Coeff, Word16 *RC, Word16 *ShRC)
{
int i, j;
Word16 sh1;
Word32 L_acc;
L_acc = 0L;
for(j=0; j<G7231LpcOrder; j++) {
L_acc = G7231L_mac(L_acc, Coeff[j], Coeff[j]);
}
L_acc = G7231L_shr(L_acc, 1);
L_acc = G7231L_add(L_acc, 0x04000000L);
sh1 = G7231norm_l(L_acc) - (Word16)2;
L_acc = G7231L_shl(L_acc, sh1);
RC[0] = G7231round(L_acc);
for(i=1; i<=G7231LpcOrder; i++) {
L_acc = G7231L_mult( (Word16) 0xE000, Coeff[i-1]);
for(j=0; j<G7231LpcOrder-i; j++) {
L_acc = G7231L_mac(L_acc, Coeff[j], Coeff[j+i]);
}
L_acc = G7231L_shl(L_acc, sh1);
RC[i] = G7231round(L_acc);
}
*ShRC = sh1;
return;
}
Flag G7231LpcDiff(Word16 *RC, Word16 ShRC, Word16 *ptrAcf, Word16 alpha)
{
Word32 L_temp0, L_temp1;
Word16 temp;
int i;
Flag diff;
L_temp0 = 0L;
for(i=0; i<=G7231LpcOrder; i++) {
temp = G7231shr(ptrAcf[i], 2); /* + 2 margin bits */
L_temp0 = G7231L_mac(L_temp0, RC[i], temp);
}
temp = G7231mult_r(alpha, G7231FracThresh);
L_temp1 = G7231L_add((Word32)temp, (Word32)alpha);
temp = G7231add(ShRC, 9); /* 9 = Lpc_justif. * 2 - 15 - 2 */
L_temp1 = G7231L_shl(L_temp1, temp);
if(L_temp0 < L_temp1) diff = 1;
else diff = 0;
return(diff);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -