📄 encg729fp.c
字号:
return APIG729_StsNoErr;
}
encoderObj->sCNGSeed = INIT_SEED_VAL;
encoderObj->prevPrevVADDec = encoderObj->prevVADDec;
encoderObj->prevVADDec = VADDecision;
ippsCopy_32f(&encoderObj->OldSpeechBuffer[FRM_LEN], &encoderObj->OldSpeechBuffer[0], SPEECH_BUFF_LEN-FRM_LEN);
ippsCopy_32f(&encoderObj->OldWeightedSpeechBuffer[FRM_LEN], &encoderObj->OldWeightedSpeechBuffer[0], PITCH_LAG_MAX);
ippsCopy_32f(&encoderObj->OldExcitationBuffer[FRM_LEN], &encoderObj->OldExcitationBuffer[0], PITCH_LAG_MAX+INTERPOL_LEN);
CLEAR_SCRATCH_MEMORY(encoderObj);
return APIG729_StsNoErr;
}
static void UpdateCNG(float *pSrcAutoCorr, int Vad, char *cngMem)
{
int i;
CNGmemory *cngState = (CNGmemory *)cngMem;
/* Update AutoCorrs */
for(i=0; i<(AUTOCORRS_SIZE-LPC_ORDERP1); i++) {
cngState->AutoCorrs[AUTOCORRS_SIZE - 1 - i] = cngState->AutoCorrs[AUTOCORRS_SIZE - LPC_ORDERP1 - 1 - i];
}
/* Save current AutoCorrs */
ippsCopy_32f(pSrcAutoCorr, cngState->AutoCorrs, LPC_ORDERP1);
cngState->lAutoCorrsCounter++;
if(cngState->lAutoCorrsCounter == CURRAUTOCORRS_NUM) {
cngState->lAutoCorrsCounter = 0;
if(Vad != 0) {
for(i=0; i<(SUMAUTOCORRS_SIZE-LPC_ORDERP1); i++) {
cngState->SumAutoCorrs[SUMAUTOCORRS_SIZE - 1 -i] = cngState->SumAutoCorrs[SUMAUTOCORRS_SIZE - LPC_ORDERP1 - 1 - i];
}
/* Compute new SumAutoCorrs */
for(i=0; i<LPC_ORDERP1; i++) {
cngState->SumAutoCorrs[i] = cngState->AutoCorrs[i]+cngState->AutoCorrs[LPC_ORDERP1+i];
}
}
}
return;
}
static void CNG(G729FPEncoder_Obj* encoderObj, float *pSrcExc, float *pDstIntLPC, int *pDstParam, G729Codec_Type mode)
{
LOCAL_ALIGN_ARRAY(32, float, curAcf, LPC_ORDERP1,encoderObj);
LOCAL_ALIGN_ARRAY(32, float, curCoeff, LPC_ORDERP1,encoderObj);
LOCAL_ALIGN_ARRAY(32, float, pastCoeff, LPC_ORDERP1,encoderObj);
LOCAL_ALIGN_ARRAY(32, char, tmpAlignVec, 60*sizeof(float)+6*sizeof(int),encoderObj);
LOCAL_ARRAY(float, bid, LPC_ORDERP1,encoderObj);
LOCAL_ARRAY(float, s_sumAcf, LPC_ORDERP1,encoderObj);
LOCAL_ARRAY(float, CurrLSP, LPC_ORDER,encoderObj);
LOCAL_ARRAY(float, tmpLSP, LPC_ORDER,encoderObj);
int i;
float *lpcCoeff, *OldQuantLSP, *old_A, *old_rc;
int currIgain, prevVADDec;
float energyq;
IppStatus sts;
float tmp;
CNGmemory *cngState = (CNGmemory *)encoderObj->cngMem;
prevVADDec = encoderObj->prevVADDec;
OldQuantLSP = encoderObj->OldQuantLSP;
old_A = encoderObj->OldForwardLPC;
old_rc = encoderObj->OldForwardRC;
/* Update Ener */
for(i = GAINS_NUM-1; i>=1; i--) {
cngState->Energies[i] = cngState->Energies[i-1];
}
/* Compute current Acfs */
for(i=0; i<LPC_ORDERP1; i++) {
curAcf[i] = cngState->AutoCorrs[i]+cngState->AutoCorrs[LPC_ORDERP1+i];
}
/* Compute LPC coefficients and residual energy */
if(curAcf[0] == 0.f) {
cngState->Energies[0] = 0.f; /* should not happen */
} else {
sts = ippsLevinsonDurbin_G729_32f(curAcf, LPC_ORDER, curCoeff, bid, &cngState->Energies[0]);
if(sts == ippStsOverflow) {
ippsCopy_32f(old_A,curCoeff,LPC_ORDER+1);
bid[0] = old_rc[0];
bid[1] = old_rc[1];
} else {
ippsCopy_32f(curCoeff,old_A,LPC_ORDER+1);
old_rc[0] = bid[0];
old_rc[1] = bid[1];
}
}
/* if first frame of silence => SID frame */
if(prevVADDec != 0) {
pDstParam[0] = 1;
cngState->lFrameCounter0 = 0;
cngState->lNumSavedEnergies = 1;
QuantSIDGain_G729B(cngState->Energies, cngState->lNumSavedEnergies, &energyq, &currIgain);
} else {
cngState->lNumSavedEnergies++;
CLIP_TO_UPLEVEL(cngState->lNumSavedEnergies,GAINS_NUM);
QuantSIDGain_G729B(cngState->Energies, cngState->lNumSavedEnergies, &energyq, &currIgain);
/* Compute stationarity of current filter versus reference filter.*/
/* Compute Itakura distance and compare to threshold */
ippsDotProd_32f(cngState->ReflectCoeffs,curAcf,LPC_ORDER+1,&tmp);
if(tmp > (cngState->Energies[0] * ITAKURATHRESH1)) cngState->lFltChangeFlag = 1;
/* compare energy difference between current frame and last frame */
if( (float)fabs(cngState->fPrevEnergy - energyq) > 2.0f) cngState->lFltChangeFlag = 1;
cngState->lFrameCounter0++;
if(cngState->lFrameCounter0 < N_MIN_SIM_RRAMES) {
pDstParam[0] = 0; /* no transmission */
} else {
if(cngState->lFltChangeFlag != 0) {
pDstParam[0] = 1; /* transmit SID frame */
} else {
pDstParam[0] = 0;
}
cngState->lFrameCounter0 = N_MIN_SIM_RRAMES;
}
}
if(pDstParam[0] == 1) {
/* Reset frame count and lFltChangeFlag */
cngState->lFrameCounter0 = 0;
cngState->lFltChangeFlag = 0;
/* Compute past average filter */
s_sumAcf[0] = cngState->SumAutoCorrs[0]+cngState->SumAutoCorrs[LPC_ORDERP1]+cngState->SumAutoCorrs[2*LPC_ORDERP1];
if(s_sumAcf[0] == 0.f) {
ippsZero_32f(pastCoeff,LPC_ORDERP1);
pastCoeff[0] = 1.f;
} else {
for(i=1; i<LPC_ORDERP1; i++) {
s_sumAcf[i] = cngState->SumAutoCorrs[i]+cngState->SumAutoCorrs[LPC_ORDERP1+i]+cngState->SumAutoCorrs[2*LPC_ORDERP1+i];
}
sts = ippsLevinsonDurbin_G729_32f(s_sumAcf, LPC_ORDER, pastCoeff, bid, &tmp);
if(sts == ippStsOverflow) {
ippsCopy_32f(old_A,pastCoeff,LPC_ORDER+1);
bid[0] = old_rc[0];
bid[1] = old_rc[1];
} else {
ippsCopy_32f(pastCoeff,old_A,LPC_ORDER+1);
old_rc[0] = bid[0];
old_rc[1] = bid[1];
}
}
/* Compute autocorrelation of LPC coefficients used for Itakura distance */
ippsCrossCorr_32f(pastCoeff, LPC_ORDER+1, pastCoeff, LPC_ORDER+1, cngState->ReflectCoeffs, LPC_ORDER+1, 0);
cngState->ReflectCoeffs[0] = cngState->ReflectCoeffs[0]/2;
/* Compute stationarity of current filter versus past average filter.*/
/* if stationary transmit average filter. */
/* Compute Itakura distance and compare to threshold */
ippsDotProd_32f(cngState->ReflectCoeffs,curAcf,LPC_ORDER+1,&tmp);
if(tmp <= (cngState->Energies[0] * ITAKURATHRESH2)) {
/* transmit old filter*/
lpcCoeff = pastCoeff;
} else {
/* transmit current filter => new ref. filter */
lpcCoeff = curCoeff;
/* Compute autocorrelation of LPC coefficients used for Itakura distance */
ippsCrossCorr_32f(curCoeff, LPC_ORDER+1, curCoeff, LPC_ORDER+1, cngState->ReflectCoeffs, LPC_ORDER+1, 0);
cngState->ReflectCoeffs[0] = cngState->ReflectCoeffs[0]/2;
}
/* Compute SID frame codes */
if(mode==G729A_CODEC)
ippsLPCToLSP_G729A_32f(lpcCoeff, OldQuantLSP, CurrLSP); /* From A(z) to lsp */
else
ippsLPCToLSP_G729_32f(lpcCoeff, OldQuantLSP, CurrLSP); /* From A(z) to lsp */
/* LSP quantization */
{
LOCAL_ARRAY(float, fTmpLSF, LPC_ORDER,encoderObj);
/* convert lsp to lsf */
ownACOS_G729_32f(CurrLSP, fTmpLSF, LPC_ORDER);
/* spacing to ~100Hz */
if (fTmpLSF[0] < LSF_LOW_LIMIT)
fTmpLSF[0] = LSF_LOW_LIMIT;
for (i=0 ; i < LPC_ORDER-1 ; i++) {
if (fTmpLSF[i+1]- fTmpLSF[i] < 2*LSF_DIST) fTmpLSF[i+1] = fTmpLSF[i]+ 2*LSF_DIST;
}
if (fTmpLSF[LPC_ORDER-1] > LSF_HI_LIMIT)
fTmpLSF[LPC_ORDER-1] = LSF_HI_LIMIT;
if (fTmpLSF[LPC_ORDER-1] < fTmpLSF[LPC_ORDER-2])
fTmpLSF[LPC_ORDER-2] = fTmpLSF[LPC_ORDER-1]- LSF_DIST;
ippsLSFQuant_G729B_32f(fTmpLSF, (float*)encoderObj->PrevFreq, cngState->SIDQuantLSP, &pDstParam[1]);
LOCAL_ARRAY_FREE(float, fTmpLSF, LPC_ORDER,encoderObj);
}
cngState->fPrevEnergy = energyq;
pDstParam[4] = currIgain;
cngState->fSIDGain = SIDGainTbl[currIgain];
}
/* Compute new excitation */
if(prevVADDec != 0) {
cngState->fCurrGain = cngState->fSIDGain;
} else {
cngState->fCurrGain *= GAIN_INT_FACTOR;
cngState->fCurrGain += INV_GAIN_INT_FACTOR * cngState->fSIDGain;
}
if(cngState->fCurrGain == 0.f) {
ippsZero_32f(pSrcExc,FRM_LEN);
UpdateExcErr_G729(0.f, SUBFR_LEN+1,encoderObj->ExcitationError);
UpdateExcErr_G729(0.f, SUBFR_LEN+1,encoderObj->ExcitationError);
} else {
ComfortNoiseExcitation_G729(cngState->fCurrGain, pSrcExc, &encoderObj->sCNGSeed, ENCODER, encoderObj->ExcitationError,NULL,tmpAlignVec);
}
ippsInterpolateC_G729_32f(OldQuantLSP, 0.5f, cngState->SIDQuantLSP, 0.5f, tmpLSP, LPC_ORDER);
ippsLSPToLPC_G729_32f(tmpLSP, pDstIntLPC);
ippsLSPToLPC_G729_32f(cngState->SIDQuantLSP, &pDstIntLPC[LPC_ORDER+1]);
ippsCopy_32f(cngState->SIDQuantLSP, OldQuantLSP, LPC_ORDER);
/* Update SumAutoCorrs if lAutoCorrsCounter = 0 */
if(cngState->lAutoCorrsCounter == 0) {
for(i=0; i<(SUMAUTOCORRS_SIZE-LPC_ORDERP1); i++) {
cngState->SumAutoCorrs[SUMAUTOCORRS_SIZE - 1 -i] = cngState->SumAutoCorrs[SUMAUTOCORRS_SIZE - LPC_ORDERP1 - 1 - i];
}
/* Compute new SumAutoCorrs */
for(i=0; i<LPC_ORDERP1; i++) {
cngState->SumAutoCorrs[i] = cngState->AutoCorrs[i]+cngState->AutoCorrs[LPC_ORDERP1+i];
}
}
LOCAL_ARRAY_FREE(float, tmpLSP, LPC_ORDER,encoderObj);
LOCAL_ARRAY_FREE(float, CurrLSP, LPC_ORDER,encoderObj);
LOCAL_ARRAY_FREE(float, s_sumAcf, LPC_ORDERP1,encoderObj);
LOCAL_ARRAY_FREE(float, bid, LPC_ORDERP1,encoderObj);
LOCAL_ALIGN_ARRAY_FREE(32, float, pastCoeff, LPC_ORDERP1,encoderObj);
LOCAL_ALIGN_ARRAY_FREE(32, float, curCoeff, LPC_ORDERP1,encoderObj);
LOCAL_ALIGN_ARRAY_FREE(32, float, curAcf, LPC_ORDERP1,encoderObj);
return;
}
static void UpdateVad_I(G729FPEncoder_Obj* encoderObj, float *Excitation, float *forwardLPC, float *WeightedSpeech,
float *gamma1, float *gamma2, float *pSynth,
float *pError, float *SpeechWnd, int* dst,G729Codec_Type codecType)
{
LOCAL_ALIGN_ARRAY(32, float, WeightedLPC1, BWD_LPC_ORDERP1,encoderObj); /* A(z) with spectral expansion */
LOCAL_ALIGN_ARRAY(32, float, WeightedLPC2, BWD_LPC_ORDERP1,encoderObj); /* A(z) with spectral expansion */
LOCAL_ALIGN_ARRAY(32, float, TargetVector, SUBFR_LEN,encoderObj);
LOCAL_ALIGN_ARRAY(32, float, forwardQntLPC, LPC_ORDERP1*2,encoderObj); /* A(z) forward quantized for the 2 subframes */
int i, j, NGamma, NSbfr;
CNG(encoderObj,Excitation, forwardQntLPC, dst,codecType);
encoderObj->prevPrevVADDec = encoderObj->prevVADDec;
encoderObj->prevVADDec = 0;
/* Update filters memory*/
for(NSbfr=0, NGamma = 0; NSbfr < FRM_LEN; NSbfr += SUBFR_LEN, NGamma++) {
WeightLPCCoeff_G729(forwardLPC, gamma1[NGamma], LPC_ORDER, WeightedLPC1);
WeightLPCCoeff_G729(forwardLPC, gamma2[NGamma], LPC_ORDER, WeightedLPC2);
ippsConvBiased_32f(WeightedLPC1,LPC_ORDER+1,&SpeechWnd[NSbfr],SUBFR_LEN+LPC_ORDER,&WeightedSpeech[NSbfr],SUBFR_LEN,LPC_ORDER);
ippsSynthesisFilter_G729_32f(WeightedLPC2, LPC_ORDER, &Weig
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -