📄 utilgsmamr.c
字号:
if(*vCountHangover > 20) {
if(ownGetMedianElements_GSMAMR(ltpGainHist, 9) > ltpLimit) prevVoiced = 1;
else prevVoiced = 0;
}
if(prevVoiced) *vVoiceHangover = 0;
else {
temp = (Ipp16s)(*vVoiceHangover + 1);
if(temp > 10) *vVoiceHangover = 10;
else *vVoiceHangover = temp;
}
return inbgNoise;
/* End of ownSourceChDetectorUpdate_GSMAMR() */
}
/*************************************************************************
Function: ownCalcUnFiltEnergy_GSMAMR
*************************************************************************/
void ownCalcUnFiltEnergy_GSMAMR(Ipp16s *pLPResVec, Ipp16s *pLTPExc, Ipp16s *code, Ipp16s gainPitch,
Ipp16s lenSubfr, Ipp16s *fracEnergyCoeff, Ipp16s *expEnergyCoeff, Ipp16s *ltpg)
{
Ipp32s s, TmpVal;
Ipp16s i, exp, tmp;
Ipp16s ltp_res_en, pred_gain;
Ipp16s ltpg_exp, ltpg_frac;
ippsDotProd_16s32s_Sfs(pLPResVec, pLPResVec, lenSubfr, &s, -1);
if (s < 400) {
fracEnergyCoeff[0] = 0;
expEnergyCoeff[0] = -15;
} else {
exp = Norm_32s_I(&s);
fracEnergyCoeff[0] = (Ipp16s)(s >> 16);
expEnergyCoeff[0] = (Ipp16s)(15 - exp);
}
ippsDotProd_16s32s_Sfs(pLTPExc, pLTPExc, lenSubfr, &s, -1);
exp = Norm_32s_I(&s);
fracEnergyCoeff[1] = (Ipp16s)(s >> 16);
expEnergyCoeff[1] = (Ipp16s)(15 - exp);
ippsDotProd_16s32s_Sfs(pLTPExc, code, lenSubfr, &s, -1);
exp = Norm_32s_I(&s);
fracEnergyCoeff[2] = (Ipp16s)(s >> 16);
expEnergyCoeff[2] = (Ipp16s)(2 - exp);
s = 0;
for (i = 0; i < lenSubfr; i++) {
TmpVal = pLTPExc[i] * gainPitch;
tmp = (Ipp16s)(pLPResVec[i] - (Ipp16s)((TmpVal + 0x2000) >> 14)); /* LTP residual, Q0 */
s += tmp * tmp;
}
exp = Norm_32s_I(&s);
ltp_res_en = (Ipp16s)(s >> 16);
exp = (Ipp16s)(16 - exp);
fracEnergyCoeff[3] = ltp_res_en;
expEnergyCoeff[3] = exp;
if(ltp_res_en > 0 && fracEnergyCoeff[0] != 0) {
pred_gain = (Ipp16s)(((fracEnergyCoeff[0] >> 1) << 15) / ltp_res_en);
exp = (Ipp16s)(exp - expEnergyCoeff[0]);
TmpVal = pred_gain << 16;
if(exp < -3) ShiftL_32s(TmpVal, (Ipp16s)(-(exp + 3)));
else TmpVal >>= (exp + 3);
ownLog2_GSMAMR(TmpVal, <pg_exp, <pg_frac);
TmpVal = ((ltpg_exp - 27) << 15) + ltpg_frac;
*ltpg = Cnvrt_NR_32s16s(TmpVal << 14);
}
else *ltpg = 0;
return;
/* End of ownCalcUnFiltEnergy_GSMAMR() */
}
/*************************************************************************
* Function: ownCalcFiltEnergy_GSMAMR
*************************************************************************/
void ownCalcFiltEnergy_GSMAMR(IppSpchBitRate rate, Ipp16s *pTargetPitchVec, Ipp16s *pTargetVec,
Ipp16s *pFltAdaptExc, Ipp16s *pFltVec, Ipp16s *fracEnergyCoeff,
Ipp16s *expEnergyCoeff, Ipp16s *optFracCodeGain, Ipp16s *optExpCodeGain)
{
Ipp16s g_coeff[4];
Ipp32s s, ener_init=1;
Ipp16s exp, frac;
Ipp16s pFltVecTmp[SUBFR_SIZE_GSMAMR];
Ipp16s gain;
if(rate == IPP_SPCHBR_7950 || rate == IPP_SPCHBR_4750) ener_init = 0;
ippsRShiftC_16s(pFltVec, 3, pFltVecTmp, SUBFR_SIZE_GSMAMR);
ippsAdaptiveCodebookGainCoeffs_GSMAMR_16s(pTargetPitchVec, pFltAdaptExc, &gain, g_coeff);
fracEnergyCoeff[0] = g_coeff[0];
expEnergyCoeff[0] = g_coeff[1];
//fracEnergyCoeff[1] = (g_coeff[2] == IPP_MIN_16S) ? IPP_MAX_16S : -g_coeff[2];/* coeff[1] = -2 xn y1 */
if(g_coeff[2] == IPP_MIN_16S) fracEnergyCoeff[1] = IPP_MAX_16S; /* coeff[1] = -2 xn y1 */
else fracEnergyCoeff[1] = (Ipp16s)(-g_coeff[2]);
expEnergyCoeff[1] = (Ipp16s)(g_coeff[3] + 1);
ippsDotProd_16s32s_Sfs(pFltVecTmp, pFltVecTmp, SUBFR_SIZE_GSMAMR, &s, -1);
s += ener_init;
exp = Norm_32s_I(&s);
fracEnergyCoeff[2] = (Ipp16s)(s >> 16);
expEnergyCoeff[2] = (Ipp16s)(-3 - exp);
ippsDotProd_16s32s_Sfs(pTargetPitchVec, pFltVecTmp, SUBFR_SIZE_GSMAMR, &s, -1);
s += ener_init;
exp = Norm_32s_I(&s);
s >>= 16;
//fracEnergyCoeff[3] = (s != IPP_MIN_16S)? -s : IPP_MAX_16S;
if(s != IPP_MIN_16S) fracEnergyCoeff[3] = (Ipp16s)(-s);
else fracEnergyCoeff[3] = IPP_MAX_16S;
expEnergyCoeff[3] = (Ipp16s)(7 - exp);
ippsDotProd_16s32s_Sfs(pFltAdaptExc, pFltVecTmp, SUBFR_SIZE_GSMAMR, &s, -1);
s += ener_init;
exp = Norm_32s_I(&s);
fracEnergyCoeff[4] = (Ipp16s)(s >> 16);
expEnergyCoeff[4] = (Ipp16s)(7 - exp);
if(rate == IPP_SPCHBR_4750 || rate == IPP_SPCHBR_7950) {
ippsDotProd_16s32s_Sfs( pTargetVec, pFltVecTmp, SUBFR_SIZE_GSMAMR, &s, -1);
s += ener_init;
exp = Norm_32s_I(&s);
frac = (Ipp16s)(s >> 16);
exp = (Ipp16s)(6 - exp);
if (frac <= 0) {
*optFracCodeGain = 0;
*optExpCodeGain = 0;
} else {
*optFracCodeGain = (Ipp16s)(((frac >> 1) << 15) / fracEnergyCoeff[2]);
*optExpCodeGain = (Ipp16s)(exp - expEnergyCoeff[2] - 14);
}
}
return;
/* End of ownCalcFiltEnergy_GSMAMR() */
}
/*************************************************************************
* Function: ownCalcTargetEnergy_GSMAMR
*************************************************************************/
void ownCalcTargetEnergy_GSMAMR(Ipp16s *pTargetPitchVec, Ipp16s *optExpCodeGain, Ipp16s *optFracCodeGain)
{
Ipp32s s;
Ipp16s exp;
ippsDotProd_16s32s_Sfs(pTargetPitchVec, pTargetPitchVec, SUBFR_SIZE_GSMAMR, &s, -1);
exp = Norm_32s_I(&s);
*optFracCodeGain = (Ipp16s)(s >> 16);
*optExpCodeGain = (Ipp16s)(16 - exp);
return;
/* End of ownCalcTargetEnergy_GSMAMR() */
}
/**************************************************************************
* Function: : A_Refl
* Convert from direct form coefficients to reflection coefficients
**************************************************************************/
void ownConvertDirectCoeffToReflCoeff_GSMAMR(Ipp16s *pDirectCoeff, Ipp16s *pReflCoeff)
{
Ipp16s i,j;
Ipp16s aState[LP_ORDER_SIZE];
Ipp16s bState[LP_ORDER_SIZE];
Ipp16s normShift, normProd;
Ipp16s scale, temp, mult;
Ipp32s const1;
Ipp32s TmpVal, TmpVal1, TmpVal2;
ippsCopy_16s(pDirectCoeff, aState, LP_ORDER_SIZE);
for (i = LP_ORDER_SIZE-1; i >= 0; i--) {
if(Abs_16s(aState[i]) >= 4096) goto ExitRefl;
pReflCoeff[i] = (Ipp16s)(aState[i] << 3);
TmpVal1 = 2 * pReflCoeff[i] * pReflCoeff[i];
TmpVal = IPP_MAX_32S - TmpVal1;
normShift = Norm_32s_Pos_I(&TmpVal);
scale = (Ipp16s)(14 - normShift);
normProd = Cnvrt_NR_32s16s(TmpVal);
mult = (Ipp16s)((16384 << 15) / normProd);
const1 = 1<<(scale - 1);
for (j = 0; j < i; j++) {
TmpVal = (aState[j] << 15) - (pReflCoeff[i] * aState[i-j-1]);
temp = (Ipp16s)((TmpVal + 0x4000) >> 15);
TmpVal1 = mult * temp;
TmpVal2 = (TmpVal1 + const1) >> scale;
if(TmpVal2 > 32767) goto ExitRefl;
bState[j] = (Ipp16s)TmpVal2;
}
ippsCopy_16s(bState, aState, i);
}
return;
ExitRefl:
ippsZero_16s(pReflCoeff, LP_ORDER_SIZE);
}
/**************************************************************************
* Function : ownScaleExcitation_GSMAMR
***************************************************************************/
void ownScaleExcitation_GSMAMR(Ipp16s *pInputSignal, Ipp16s *pOutputSignal)
{
Ipp16s exp;
Ipp16s gain_in, gain_out, g0;
Ipp32s i, s;
Ipp16s temp[SUBFR_SIZE_GSMAMR];
ippsDotProd_16s32s_Sfs(pOutputSignal, pOutputSignal, SUBFR_SIZE_GSMAMR, &s, 0);
if (s >= IPP_MAX_32S/2) {
ippsRShiftC_16s(pOutputSignal, 2, temp, SUBFR_SIZE_GSMAMR);
ippsDotProd_16s32s_Sfs(temp, temp, SUBFR_SIZE_GSMAMR, &s, -1);
} else s >>= 3;
if(s == 0) return;
exp = (Ipp16s)(Exp_32s_Pos(s) - 1);
gain_out = Cnvrt_NR_32s16s(s << exp);
ippsDotProd_16s32s_Sfs(pInputSignal, pInputSignal, SUBFR_SIZE_GSMAMR, &s, 0);
if (s >= IPP_MAX_32S/2) {
ippsRShiftC_16s(pInputSignal, 2, temp, SUBFR_SIZE_GSMAMR);
ippsDotProd_16s32s_Sfs(temp, temp, SUBFR_SIZE_GSMAMR, &s, -1);
} else s >>= 3;
if(s == 0) g0 = 0;
else {
i = Norm_32s_I(&s);
gain_in = Cnvrt_NR_32s16s(s);
exp = (Ipp16s)(exp - i);
s = ((gain_out << 15) / gain_in);
s = ShiftL_32s(s, 7);
if (exp < 0) s = ShiftL_32s(s, (Ipp16u)(-exp));
else s >>= exp;
ippsInvSqrt_32s_I(&s, 1);
g0 = Cnvrt_NR_32s16s(ShiftL_32s(s, 9));
}
for (i = 0; i < SUBFR_SIZE_GSMAMR; i++)
pOutputSignal[i] = (Ipp16s)(Mul16_32s(pOutputSignal[i] * g0) >> 16);
return;
/* End of ownScaleExcitation_GSMAMR() */
}
static const Ipp16s TablePredCoeff[NUM_PRED_TAPS] = {5571, 4751, 2785, 1556};
/* MEAN_ENER = 36.0/constant, constant = 20*Log10(2) */
#define MEAN_ENER_MR122 783741
static const Ipp16s TablePredCoeff_M122[NUM_PRED_TAPS] = {44, 37, 22, 12};
/*************************************************************************
* Function: ownPredEnergyMA_GSMAMR()
*************************************************************************/
void ownPredEnergyMA_GSMAMR(Ipp16s *a_PastQntEnergy, Ipp16s *a_PastQntEnergy_M122, IppSpchBitRate rate,
Ipp16s *code, Ipp16s *expGainCodeCB, Ipp16s *fracGainCodeCB, Ipp16s *expEnergyCoeff,
Ipp16s *fracEnergyCoeff)
{
Ipp32s ener_code, ener;
Ipp16s exp, frac;
ippsDotProd_16s32s_Sfs( code, code, SUBFR_SIZE_GSMAMR, &ener_code, -1);
if (rate == IPP_SPCHBR_12200) {
ener_code = 2 *((ener_code + 0x8000) >> 16) * 26214;
ownLog2_GSMAMR(ener_code, &exp, &frac);
ener_code = ((exp - 30) << 16) + (frac << 1);
ippsDotProd_16s32s_Sfs(a_PastQntEnergy_M122, TablePredCoeff_M122, NUM_PRED_TAPS, &ener, -1);
ener += MEAN_ENER_MR122;
ener = (ener - ener_code) >> 1; /* Q16 */
Unpack_32s(ener, expGainCodeCB, fracGainCodeCB);
} else {
Ipp32s TmpVal;
Ipp16s exp_code, predGainCB;
exp_code = Norm_32s_I(&ener_code);
ownLog2_GSMAMR_norm (ener_code, exp_code, &exp, &frac);
TmpVal = Mpy_32_16(exp, frac, -24660);
if(rate == IPP_SPCHBR_10200) TmpVal += 2 * 16678 * 64;
else if (rate == IPP_SPCHBR_7950) {
*fracEnergyCoeff = (Ipp16s) (ener_code>>16);
*expEnergyCoeff = (Ipp16s)(-11 - exp_code);
TmpVal += 2 * 17062 * 64;
} else if (rate == IPP_SPCHBR_7400) {
TmpVal += 2 * 32588 * 32;
} else if (rate == IPP_SPCHBR_6700) {
TmpVal += 2 * 32268 * 32;
} else { /* MR59, MR515, MR475 */
TmpVal += 2 * 16678 * 64;
}
TmpVal <<= 10;
ippsDotProd_16s32s_Sfs(a_PastQntEnergy, TablePredCoeff, NUM_PRED_TAPS, &ener, -1);
TmpVal += ener;
predGainCB = (Ipp16s)(TmpVal>>16);
if(rate == IPP_SPCHBR_7400) TmpVal = predGainCB * 5439;
else TmpVal = predGainCB * 5443;
TmpVal >>= 7;
Unpack_32s(TmpVal, expGainCodeCB, fracGainCodeCB);
}
return;
/* End of ownPredEnergyMA_GSMAMR() */
}
/*************************************************************************
* Function: ownCloseLoopFracPitchSearch_GSMAMR
***************************************************************************/
Ipp32s ownCloseLoopFracPitchSearch_GSMAMR(Ipp16s *vTimePrevSubframe, Ipp16s *a_GainHistory, IppSpchBitRate rate,
Ipp16s frameOffset, Ipp16s *pLoopPitchLags, Ipp16s *pImpResVec,
Ipp16s *pLTPExc, Ipp16s *pPredRes, Ipp16s *pTargetPitchVec, Ipp16s lspFlag,
Ipp16s *pTargetVec, Ipp16s *pFltAdaptExc, Ipp16s *pExpPitchDel,
Ipp16s *pFracPitchDel, Ipp16s *gainPitch, Ipp16s **ppAnalysisParam,
Ipp16s *gainPitchLimit)
{
Ipp16s i;
Ipp16s index;
Ipp32s TmpVal;
Ipp16s subfrNum;
Ipp16s sum = 0;
subfrNum = (Ipp16s)(frameOffset / SUBFR_SIZE_GSMAMR);
ippsAdaptiveCodebookSearch_GSMAMR_16s(pTargetPitchVec, pImpResVec, pLoopPitchLags,
vTimePrevSubframe, (pLTPExc - MAX_OFFSET),
pFracPitchDel, &index, pFltAdaptExc, subfrNum, rate);
ippsConvPartial_16s_Sfs(pLTPExc, pImpResVec, pFltAdaptExc, SUBFR_SIZE_GSMAMR, 12);
*pExpPitchDel = *vTimePrevSubframe;
*(*ppAnalysisParam)++ = index;
ippsAdaptiveCodebookGain_GSMAMR_16s(pTargetPitchVec, pFltAdaptExc, gainPitch);
if(rate == IPP_SPCHBR_12200) *gainPitch &= 0xfffC;
*gainPitchLimit = IPP_MAX_16S;
if((lspFlag != 0) && (*gainPitch > PITCH_GAIN_CLIP)) {
ippsSum_16s_Sfs(a_GainHistory, PG_NUM_FRAME, &sum, 0);
sum = (Ipp16s)(sum + (*gainPitch >> 3)); /* Division by 8 */
if(sum > PITCH_GAIN_CLIP) *gainPitchLimit = PITCH_GAIN_CLIP;
}
if ((rate == IPP_SPCHBR_4750) || (rate == IPP_SPCHBR_5150)) {
if(*gainPitch > 13926) *gainPitch = 13926;
} else {
if(sum > PITCH_GAIN_CLIP) *gainPitch = PITCH_GAIN_CLIP;
if(rate == IPP_SPCHBR_12200) {
index = ownQntGainPitch_M122_GSMAMR(*gainPitchLimit, *gainPitch);
*gainPitch = (Ipp16s)(TableQuantGainPitch[index] & 0xFFFC);
*(*ppAnalysisParam)++ = index;
}
}
/* update target vector und evaluate LTP residual
Algorithmically is equivalent to :
ippsMulC_16s_Sfs(pFltAdaptExc,*gainPitch,y1Tmp,SUBFR_SIZE_GSMAMR,14);
ippsMulC_16s_Sfs(pLTPExc,*gainPitch,excTmp,SUBFR_SIZE_GSMAMR,14);
ippsSub_16s(y1Tmp,pTargetPitchVec,pTargetVec,SUBFR_SIZE_GSMAMR);
ippsSub_16s_I(excTmp,pPredRes,SUBFR_SIZE_GSMAMR);
But !!! could not be used due to bitexactness.
*/
for (i = 0; i < SUBFR_SIZE_GSMAMR; i++) {
TmpVal = pFltAdaptExc[i] * *gainPitch;
pTargetVec[i] = (Ipp16s)(pTargetPitchVec[i] - (Ipp16s)(TmpVal >> 14));
TmpVal = pLTPExc[i] * *gainPitch;
pPredRes[i] = (Ipp16s)(pPredRes[i] - (Ipp16s)(TmpVal >> 14));
}
return 0;
/* End of ownCloseLoopFracPitchSearch_GSMAMR() */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -