📄 utilgsmamr.c
字号:
prevVoiced = 0;
if(ownGetMedianElements_GSMAMR(<pGainHist[4], 5) > ltpLimit) prevVoiced = 1;
if(*vCountHangover > 20) {
if(ownGetMedianElements_GSMAMR(ltpGainHist, 9) > ltpLimit) prevVoiced = 1;
else prevVoiced = 0;
}
if(prevVoiced) *vVoiceHangover = 0;
else {
temp = *vVoiceHangover + 1;
if(temp > 10) *vVoiceHangover = 10;
else *vVoiceHangover = temp;
}
return inbgNoise;
/* End of ownSourceChDetectorUpdate_GSMAMR() */
}
/*************************************************************************
Function: ownCalcUnFiltEnergy_GSMAMR
*************************************************************************/
void ownCalcUnFiltEnergy_GSMAMR(short *pLPResVec, short *pLTPExc, short *code, short gainPitch,
short lenSubfr, short *fracEnergyCoeff, short *expEnergyCoeff, short *ltpg)
{
int s, TmpVal;
short i, exp, tmp;
short ltp_res_en, pred_gain;
short 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] = (short)(s >> 16);
expEnergyCoeff[0] = 15 - exp;
}
ippsDotProd_16s32s_Sfs(pLTPExc, pLTPExc, lenSubfr, &s, -1);
exp = Norm_32s_I(&s);
fracEnergyCoeff[1] = (short)(s >> 16);
expEnergyCoeff[1] = 15 - exp;
ippsDotProd_16s32s_Sfs(pLTPExc, code, lenSubfr, &s, -1);
exp = Norm_32s_I(&s);
fracEnergyCoeff[2] = (short)(s >> 16);
expEnergyCoeff[2] = 2 - exp;
s = 0;
for (i = 0; i < lenSubfr; i++) {
TmpVal = pLTPExc[i] * gainPitch;
tmp = pLPResVec[i] - (short)((TmpVal + 0x2000) >> 14); /* LTP residual, Q0 */
s += tmp * tmp;
}
exp = Norm_32s_I(&s);
ltp_res_en = (short)(s >> 16);
exp = 16 - exp;
fracEnergyCoeff[3] = ltp_res_en;
expEnergyCoeff[3] = exp;
if(ltp_res_en > 0 && fracEnergyCoeff[0] != 0) {
pred_gain = ((fracEnergyCoeff[0] >> 1) << 15) / ltp_res_en;
exp -= expEnergyCoeff[0];
TmpVal = pred_gain << 16;
if(exp < -3) ShiftL_32s(TmpVal, (short)(-(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, short *pTargetPitchVec, short *pTargetVec,
short *pFltAdaptExc, short *pFltVec, short *fracEnergyCoeff,
short *expEnergyCoeff, short *optFracCodeGain, short *optExpCodeGain)
{
short g_coeff[4];
int s, ener_init=1;
short exp, frac;
short pFltVecTmp[SUBFR_SIZE_GSMAMR];
short 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 */
expEnergyCoeff[1] = g_coeff[3] + 1;
ippsDotProd_16s32s_Sfs(pFltVecTmp, pFltVecTmp, SUBFR_SIZE_GSMAMR, &s, -1);
s += ener_init;
exp = Norm_32s_I(&s);
fracEnergyCoeff[2] = (short)(s >> 16);
expEnergyCoeff[2] = -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;
expEnergyCoeff[3] = 7 - exp;
ippsDotProd_16s32s_Sfs(pFltAdaptExc, pFltVecTmp, SUBFR_SIZE_GSMAMR, &s, -1);
s += ener_init;
exp = Norm_32s_I(&s);
fracEnergyCoeff[4] = (short)(s >> 16);
expEnergyCoeff[4] = 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 = (short)(s >> 16);
exp = 6 - exp;
if (frac <= 0) {
*optFracCodeGain = 0;
*optExpCodeGain = 0;
} else {
*optFracCodeGain = ((frac >> 1) << 15) / fracEnergyCoeff[2];
*optExpCodeGain = exp - expEnergyCoeff[2] - 14;
}
}
return;
/* End of ownCalcFiltEnergy_GSMAMR() */
}
/*************************************************************************
* Function: ownCalcTargetEnergy_GSMAMR
*************************************************************************/
void ownCalcTargetEnergy_GSMAMR(short *pTargetPitchVec, short *optExpCodeGain, short *optFracCodeGain)
{
int s;
short exp;
ippsDotProd_16s32s_Sfs(pTargetPitchVec, pTargetPitchVec, SUBFR_SIZE_GSMAMR, &s, -1);
exp = Norm_32s_I(&s);
*optFracCodeGain = (short)(s >> 16);
*optExpCodeGain = 16 - exp;
return;
/* End of ownCalcTargetEnergy_GSMAMR() */
}
/**************************************************************************
* Function: : A_Refl
* Convert from direct form coefficients to reflection coefficients
**************************************************************************/
void ownConvertDirectCoeffToReflCoeff_GSMAMR(short *pDirectCoeff, short *pReflCoeff)
{
short i,j;
short aState[LP_ORDER_SIZE];
short bState[LP_ORDER_SIZE];
short normShift, normProd;
short scale, temp, mult;
int const1;
int 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] = aState[i] << 3;
TmpVal1 = 2 * pReflCoeff[i] * pReflCoeff[i];
TmpVal = IPP_MAX_32S - TmpVal1;
normShift = Norm_32s_Pos_I(&TmpVal);
scale = 14 - normShift;
normProd = Cnvrt_NR_32s16s(TmpVal);
mult = (16384 << 15) / normProd;
const1 = 1<<(scale - 1);
for (j = 0; j < i; j++) {
TmpVal = (aState[j] << 15) - (pReflCoeff[i] * aState[i-j-1]);
temp = (short)((TmpVal + 0x4000) >> 15);
TmpVal1 = mult * temp;
TmpVal2 = (TmpVal1 + const1) >> scale;
if(TmpVal2 > 32767) goto ExitRefl;
bState[j] = (short)TmpVal2;
}
ippsCopy_16s(bState, aState, i);
}
return;
ExitRefl:
ippsZero_16s(pReflCoeff, LP_ORDER_SIZE);
}
/**************************************************************************
* Function : ownScaleExcitation_GSMAMR
***************************************************************************/
void ownScaleExcitation_GSMAMR(short *pInputSignal, short *pOutputSignal)
{
short exp;
short gain_in, gain_out, g0;
int i, s;
short 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 = 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 -= i;
s = ((gain_out << 15) / gain_in);
s = ShiftL_32s(s, 7);
if (exp < 0) s = ShiftL_32s(s, (unsigned short)(-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] = (short)(Mul16_32s(pOutputSignal[i] * g0) >> 16);
return;
/* End of ownScaleExcitation_GSMAMR() */
}
static const short TablePredCoeff[NUM_PRED_TAPS] = {5571, 4751, 2785, 1556};
/* MEAN_ENER = 36.0/constant, constant = 20*Log10(2) */
#define MEAN_ENER_MR122 783741
static const short TablePredCoeff_M122[NUM_PRED_TAPS] = {44, 37, 22, 12};
/*************************************************************************
* Function: ownPredEnergyMA_GSMAMR()
*************************************************************************/
void ownPredEnergyMA_GSMAMR(short *a_PastQntEnergy, short *a_PastQntEnergy_M122, IppSpchBitRate rate,
short *code, short *expGainCodeCB, short *fracGainCodeCB, short *expEnergyCoeff,
short *fracEnergyCoeff)
{
int ener_code, ener;
short 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 */
L_Extract(ener, expGainCodeCB, fracGainCodeCB);
} else {
int TmpVal;
short exp_code, predGainCB;
exp_code = Norm_32s_I(&ener_code);
ownLog2_GSMAMR_norm (ener_code, exp_code, &exp, &frac);
TmpVal = Mul16s_32s(exp, frac, -24660);
if(rate == IPP_SPCHBR_10200) TmpVal += 2 * 16678 * 64;
else if (rate == IPP_SPCHBR_7950) {
*fracEnergyCoeff = (short) (ener_code>>16);
*expEnergyCoeff = -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 = (short)(TmpVal>>16);
if(rate == IPP_SPCHBR_7400) TmpVal = predGainCB * 5439;
else TmpVal = predGainCB * 5443;
TmpVal >>= 7;
L_Extract(TmpVal, expGainCodeCB, fracGainCodeCB);
}
return;
/* End of ownPredEnergyMA_GSMAMR() */
}
/*************************************************************************
* Function: ownCloseLoopFracPitchSearch_GSMAMR
***************************************************************************/
int ownCloseLoopFracPitchSearch_GSMAMR(short *vTimePrevSubframe, short *a_GainHistory, IppSpchBitRate rate,
short frameOffset, short *pLoopPitchLags, short *pImpResVec,
short *pLTPExc, short *pPredRes, short *pTargetPitchVec, short lspFlag,
short *pTargetVec, short *pFltAdaptExc, short *pExpPitchDel,
short *pFracPitchDel, short *gainPitch, short **ppAnalysisParam,
short *gainPitchLimit)
{
short i;
short index;
int TmpVal;
short subfrNum;
short sum = 0;
subfrNum = 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 += *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 = 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] = pTargetPitchVec[i] - (short)(TmpVal >> 14);
TmpVal = pLTPExc[i] * *gainPitch;
pPredRes[i] -= (short)(TmpVal >> 14);
}
return 0;
/* End of ownCloseLoopFracPitchSearch_GSMAMR() */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -