📄 owng729fp.c
字号:
{
int i, lTmp;
lTmp = 0;
for(i=0; i<12; i++) {
lTmp += Rand_16s(sCNGSeed);
}
lTmp >>= 7;
return((float)lTmp * 0.001953125f);
}
void ComfortNoiseExcitation_G729(float fCurrGain, float *exc, short *sCNGSeed, int flag_cod, float *ExcitationError, char *phdMem, char *pExtBuff)
{
float *pGaussianExc;
int *pos;
float *sign;
float *CurrentExcitation;
float fgp, fEner, fFact, fInterExc, k, discriminant, x1, x2, absMinRoot;
int i, n, pitchDelay, lFrac;
short sGp, sTmp1, sTmp2;
int *delayLine;
//double ener_tmp;
pGaussianExc = (float *)pExtBuff;
pos = (int *)(pExtBuff + SUBFR_LEN*sizeof(float));
sign = (float *)((char *)pos + 4*sizeof(int));
delayLine = (int *)((char *)sign + 4*sizeof(float));
/* Loop on subframes */
CurrentExcitation = exc;
for (n = 0; n < NUN_SUBFRAMES; n++) {
/* Fenerate random adaptive codebook and fixed codebook parameters */
sTmp1 = Rand_16s(sCNGSeed);
lFrac = (int)(sTmp1 & (short)0x0003) - 1;
if(lFrac == 2) lFrac = 0;
sTmp1 >>= 2;
pitchDelay = (int)(sTmp1 & (short)0x003F) + 40;
sTmp1 >>= 6;
sTmp2 = (short)(sTmp1 & (short)0x0007);
pos[0] = 5 * (int)sTmp2;
sTmp1 >>= 3;
sTmp2 = (short)(sTmp1 & (short)0x0001);
sign[0] = 2.f * (float)sTmp2 - 1.f;
sTmp1 >>= 1;
sTmp2 = (short)(sTmp1 & (short)0x0007);
pos[1] = 5 * (int)sTmp2 + 1;
sTmp1 >>= 3;
sTmp2 = (short)(sTmp1 & (short)0x0001);
sign[1] = 2.f * (float)sTmp2 - 1.f;
sTmp1 = Rand_16s(sCNGSeed);
sTmp2 = (short)(sTmp1 & (short)0x0007);
pos[2] = 5 * (int)sTmp2 + 1;
sTmp1 >>= 3;
sTmp2 = (short)(sTmp1 & (short)0x0001);
sign[2] = 2.f * (float)sTmp2 - 1.f;
sTmp1 >>= 1;
sTmp2 = (short)(sTmp1 & (short)0x000F);
pos[3] = (int)(sTmp2 & (short)0x0001) + 3; /* j+3*/
sTmp2 >>= 1;
sTmp2 &= (short)0x0007;
pos[3] += 5 * (int)sTmp2;
sTmp1 >>= 4;
sTmp2 = (short)(sTmp1 & (short)0x0001);
sign[3] = 2.f * (float)sTmp2 - 1.f;
sGp = (short)(Rand_16s(sCNGSeed) & (short)0x1FFF); /* < 0.5 */
fgp = (float)sGp / 16384.f;
/* Generate gaussian excitation */
/*ippsRandomNoiseExcitation_G729B_16s32f(sCNGSeed, excg, SUBFR_LEN);
ippsDotProd_32f64f(excg, excg, SUBFR_LEN,&ener_tmp);*/
fEner = 0.f;
for(i=0; i<SUBFR_LEN; i++) {
pGaussianExc[i] = gaussGen(sCNGSeed);
fEner += pGaussianExc[i] * pGaussianExc[i];
}
/* Compute fFact = 0.5 x fCurrGain * sqrt(40 / fEner) */
fFact = NORM_GAUSS * fCurrGain;
fFact /= (float)sqrt(fEner);
/* Multiply excg by fFact */
for(i=0; i<SUBFR_LEN; i++) {
pGaussianExc[i] *= fFact;
}
//ippsMulC_32f_I(fFact, excg, SUBFR_LEN);
/* generate random adaptive excitation */
delayLine[0] = pitchDelay;
delayLine[1] = lFrac;
ippsDecodeAdaptiveVector_G729_32f_I(delayLine, CurrentExcitation);
/* CurrentExcitation is an adaptive + gaussian excitation */
fEner = 0.f;
for(i=0; i<SUBFR_LEN; i++) {
CurrentExcitation[i] *= fgp;
CurrentExcitation[i] += pGaussianExc[i];
fEner += CurrentExcitation[i] * CurrentExcitation[i];
}
/* Compute fixed code gain */
/* Solve EQ(X) = 4 X**2 + 2 b X + c, where b = fInterExc*/
fInterExc = 0.f;
for(i=0; i<4; i++) {
fInterExc += CurrentExcitation[pos[i]] * sign[i];
}
/* Compute k = fCurrGain x fCurrGain x SUBFR_LEN */
k = fCurrGain * fCurrGain * SUBFR_LEN;
/* Compute discriminant = b^2 - 4*c, where c=fEner-k*/
discriminant = fInterExc * fInterExc - 4.f * (fEner - k);
if(discriminant < 0.f) {
/* adaptive excitation = 0 */
ippsCopy_32f(pGaussianExc, CurrentExcitation, SUBFR_LEN);
fInterExc = 0.f;
for(i=0; i<4; i++) {
fInterExc += CurrentExcitation[pos[i]] * sign[i];
}
/* Compute discriminant = b^2 - 4*c, where c = - k x (1- alpha^2)*/
discriminant = fInterExc * fInterExc + K_MUL_COEFF * k;
fgp = 0.f;
}
discriminant = (float)sqrt(discriminant);
/* First root*/
x1 = (discriminant - fInterExc) * 0.25f;
/* Second root*/
x2 = - (discriminant + fInterExc) * 0.25f;
absMinRoot = ((float)fabs(x1) < (float)fabs(x2)) ? x1 : x2;
if(absMinRoot >= 0.f) {
CLIP_TO_UPLEVEL(absMinRoot,CNG_MAX_GAIN);
} else {
CLIP_TO_LOWLEVEL(absMinRoot,(-CNG_MAX_GAIN));
}
/* Update cur_exc with ACELP excitation */
for(i=0; i<4; i++) {
CurrentExcitation[pos[i]] += absMinRoot * sign[i];
}
if(flag_cod != DECODER) UpdateExcErr_G729(fgp, pitchDelay,ExcitationError);
else {
if(absMinRoot >= 0.f) PhaseDispersionUpdate_G729D(fgp,absMinRoot,phdMem);
else PhaseDispersionUpdate_G729D(fgp,-absMinRoot,phdMem);
}
CurrentExcitation += SUBFR_LEN;
} /* end of loop on subframes */
return;
}
static __ALIGN32 CONST float fFact[GAINS_NUM+1] =
{(float)0.003125, (float)0.00078125, (float)0.000390625};
static int quantEnergy(float fEner, float *pDstQEnergy)
{
float fEnergydB;
int index;
if(fEner <= MIN_ENER) { /* MIN_ENER <=> -8dB */
*pDstQEnergy = (float)-12.;
return(0);
}
fEnergydB = (float)10. * (float)log10(fEner);
if(fEnergydB <= (float)-8.) {
*pDstQEnergy = (float)-12.;
return(0);
}
if(fEnergydB >= (float)65.) {
*pDstQEnergy = (float)66.;
return(31);
}
if(fEnergydB <= (float)14.) {
index = (int)((fEnergydB + (float)10.) * 0.25);
if (index < 1) index = 1;
*pDstQEnergy = (float)4. * (float)index - (float)8.;
return(index);
}
index = (int)((fEnergydB - (float)3.) * 0.5);
if (index < 6) index = 6;
*pDstQEnergy = (float)2. * (float)index + (float)4.;
return(index);
}
void QuantSIDGain_G729B(float *fEner, int lNumSavedEnergies, float *enerq, int *idx)
{
int i;
float averageEnergy;
/* Quantize energy saved for frame erasure case*/
if(lNumSavedEnergies == 0) {
averageEnergy = (*fEner) * fFact[0];
} else {
/* Compute weighted average of energies*/
averageEnergy = (float)0.;
for(i=0; i<lNumSavedEnergies; i++) {
averageEnergy += fEner[i];
}
averageEnergy *= fFact[lNumSavedEnergies];
}
*idx = quantEnergy(averageEnergy, enerq);
return;
}
static __ALIGN32 CONST float coef_G729[2][2] = {
{(float)31.134575,
(float) 1.612322},
{(float) 0.481389,
(float) 0.053056}
};
static __ALIGN32 CONST float thr1_G729[SIZECODEBOOK1-NUM_CAND1] = {
(float)0.659681,
(float)0.755274,
(float)1.207205,
(float)1.987740
};
static __ALIGN32 CONST float thr2_G729[SIZECODEBOOK2-NUM_CAND2] = {
(float)0.429912,
(float)0.494045,
(float)0.618737,
(float)0.650676,
(float)0.717949,
(float)0.770050,
(float)0.850628,
(float)0.932089
};
static __ALIGN32 CONST int map1_G729[SIZECODEBOOK1] = {
5, 1, 4, 7, 3, 0, 6, 2};
static __ALIGN32 CONST int map2_G729[SIZECODEBOOK2] = {
4, 6, 0, 2,12,14, 8,10,15,11, 9,13, 7, 3, 1, 5};
static __ALIGN32 CONST int imap1_G729[SIZECODEBOOK1] = {
5, 1, 7, 4, 2, 0, 6, 3};
static __ALIGN32 CONST int imap2_G729[SIZECODEBOOK2] = {
2,14, 3,13, 0,15, 1,12, 6,10, 7, 9, 4,11, 5, 8};
static __ALIGN32 CONST Ipp32f gbk1_G729[SIZECODEBOOK1][2] = {
{0.000010f, 0.185084f},
{0.094719f, 0.296035f},
{0.111779f, 0.613122f},
{0.003516f, 0.659780f},
{0.117258f, 1.134277f},
{0.197901f, 1.214512f},
{0.021772f, 1.801288f},
{0.163457f, 3.315700f}};
static __ALIGN32 CONST Ipp32f gbk2_G729[SIZECODEBOOK2][2] = {
{0.050466f, 0.244769f},
{0.121711f, 0.000010f},
{0.313871f, 0.072357f},
{0.375977f, 0.292399f},
{0.493870f, 0.593410f},
{0.556641f, 0.064087f},
{0.645363f, 0.362118f},
{0.706138f, 0.146110f},
{0.809357f, 0.397579f},
{0.866379f, 0.199087f},
{0.923602f, 0.599938f},
{0.925376f, 1.742757f},
{0.942028f, 0.029027f},
{0.983459f, 0.414166f},
{1.055892f, 0.227186f},
{1.158039f, 0.724592f}};
static __ALIGN32 CONST float coef_G729D[2][2] = {
{ 36.632507f, 2.514171f},
{ 0.399259f, 0.073709f}
};
static __ALIGN32 CONST float thr1_G729D[SIZECODEBOOK1_ANNEXD-NUM_CAND1_ANNEXD] = {
1.210869f,
2.401702f
};
static __ALIGN32 CONST float thr2_G729D[SIZECODEBOOK2_ANNEXD-NUM_CAND2_ANNEXD] = {
0.525915f,
0.767320f
};
static __ALIGN32 CONST int map1_G729D[SIZECODEBOOK1_ANNEXD] = { 0, 4, 6, 5, 2, 1, 7, 3 };
static __ALIGN32 CONST int map2_G729D[SIZECODEBOOK2_ANNEXD] = { 0, 4, 3, 7, 5, 1, 6, 2 };
static __ALIGN32 CONST int imap1_G729D[SIZECODEBOOK1_ANNEXD] = { 0, 5, 4, 7, 1, 3, 2, 6 };
static __ALIGN32 CONST int imap2_G729D[SIZECODEBOOK2_ANNEXD] = { 0, 5, 7, 2, 1, 4, 6, 3 };
static __ALIGN32 CONST float gbk1_G729D[SIZECODEBOOK1_ANNEXD][2] = {
{ 0.357003f, 0.00000f},
{ 0.178752f, 0.065771f},
{ 0.575276f, 0.166704f},
{ 0.370335f, 0.371903f},
{ 0.220734f, 0.411803f},
{ 0.193548f, 0.566385f},
{ 0.238962f, 0.785625f},
{ 0.304379f, 1.360714f}
};
static __ALIGN32 CONST float gbk2_G729D[SIZECODEBOOK2_ANNEXD][2] = {
{ 0.00000f, 0.254841f},
{ 0.243384f, 0.00000f},
{ 0.273293f, 0.447009f},
{ 0.480707f, 0.477384f},
{ 0.628117f, 0.694884f},
{ 0.660905f, 1.684719f},
{ 0.729735f, 0.655223f},
{ 1.002375f, 0.959743f}
};
static __ALIGN32 CONST float PredCoeff[4] = {
(float)0.68,
(float)0.58,
(float)0.34,
(float)0.19
};
static void GainCodebookPreselect_G729D(float *pBestGains, int *pCand, float fGainCode)
{
float x,y ;
x = (pBestGains[1]-(coef_G729D[0][0]*pBestGains[0]+coef_G729D[1][1])*fGainCode) * INV_COEF_ANNEXD ;
y = (coef_G729D[1][0]*(-coef_G729D[0][1]+pBestGains[0]*coef_G729D[0][0])*fGainCode
-coef_G729D[0][0]*pBestGains[1]) * INV_COEF_ANNEXD ;
if(fGainCode>(float)0.0){
/* pre select first index */
pCand[0] = 0 ;
do{
if(y>thr1_G729D[pCand[0]]*fGainCode) (pCand[0])++ ;
else break ;
} while((pCand[0])<(SIZECODEBOOK1_ANNEXD-NUM_CAND1_ANNEXD)) ;
/* pre select second index */
pCand[1] = 0 ;
do{
if(x>thr2_G729D[pCand[1]]*fGainCode) (pCand[1])++ ;
else break ;
} while((pCand[1])<(SIZECODEBOOK2_ANNEXD-NUM_CAND2_ANNEXD)) ;
}
else{
/* pre select first index */
pCand[0] = 0 ;
do{
if(y<thr1_G729D[pCand[0]]*fGainCode) (pCand[0])++ ;
else break ;
} while((pCand[0])<(SIZECODEBOOK1_ANNEXD-NUM_CAND1_ANNEXD)) ;
/* pre select second index */
pCand[1] = 0 ;
do{
if(x<thr2_G729D[pCand[1]]*fGainCode) (pCand[1])++ ;
else break ;
} while((pCand[1])<(SIZECODEBOOK2_ANNEXD-NUM_CAND2_ANNEXD)) ;
}
return ;
}
static void GainCodebookPreselect_G729(float *pBestGains, int *pCand, float fGainCode)
{
float x,y ;
x = (pBestGains[1]-(coef_G729[0][0]*pBestGains[0]+coef_G729[1][1])*fGainCode) * INV_COEF_BASE ;
y = (coef_G729[1][0]*(-coef_G729[0][1]+pBestGains[0]*coef_G729[0][0])*fGainCode
-coef_G729[0][0]*pBestGains[1]) * INV_COEF_BASE ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -