📄 owng723.c
字号:
/* Write positions */
for ( i = 0 ; i < 4 ; i ++ ) {
pBitStream = Parm2Bits( Params->sPosition[i], pBitStream, 12 ) ;
}
/* Write Pamps */
for ( i = 0 ; i < 4 ; i ++ ) {
pBitStream = Parm2Bits( Params->sAmplitude[i], pBitStream, 4 ) ;
}
for ( i = 0 ; i < 160 ; i ++ )
pDstBitStream[i>>3] ^= Bits[i] << (i & 0x7) ;
}
LOCAL_ARRAY_FREE(short, Bits,192,encoderObj);
return;
}
LOCAL_ARRAY_FREE(short, Bits,192,encoderObj);
return;
}
void UpdateSineDetector(short *SineWaveDetector, short *isNotSineWave)
{
int i, x, lNumTimes;
*SineWaveDetector &= 0x7fff ;
*isNotSineWave = 1;
x= *SineWaveDetector;
lNumTimes = 0;
for ( i = 0 ; i < 15 ; i ++ ) {
lNumTimes += x&1;
x >>= 1;
}
if ( lNumTimes >= 14 ) /* Sine wave is detected*/
*isNotSineWave = -1;
}
/*Usage GenPostFiltTable(Tbl, 0.65); GenPostFiltTable(Tbl+10, 0.75); */
#define SATURATE_fs(dVal,dRez)\
if (dVal >= 0.0) dVal += 0.5;\
else dVal -= 0.5;\
dRez = (short)dVal;
static void GenPostFiltTable(short *Tbl, double dInit)
{
double dFac,dTmp;
int i;
dFac = dInit;
for(i=0;i<10;i++) {
dTmp = dFac*32768.f;
SATURATE_fs(dTmp,Tbl[i]);
dFac = dFac*dInit;
}
}
static __ALIGN32 CONST short PostFiltTable[2*G723_LPC_ORDER] = {
21299 , 13844,8999,5849,3802,2471,1606,1044, 679, 441 , /* Zero part */
24576,18432,13824,10368,7776,5832,4374,3281,2460,1845 , /* Pole part */
};
void PostFilter(G723Decoder_Obj* decoderObj, short *pSrcDstSignal, short *pSrcLPC )
{
int i, lTmp, lSignalEnergy, lSfs;
short sTmp;
LOCAL_ARRAY(short, FltCoef,2*G723_LPC_ORDER, decoderObj);
LOCAL_ARRAY(int, pFltSignal,G723_LPC_ORDER+G723_SBFR_LEN, decoderObj);
LOCAL_ARRAY(int, pAutoCorr,2, decoderObj);
LOCAL_ARRAY(short, pTmpVec,G723_SBFR_LEN, decoderObj);
/* Normalize the input speech vector. */
lSfs=3;
ippsAutoScale_16s(pSrcDstSignal, pTmpVec, (short) G723_SBFR_LEN, &lSfs ) ;
/* Compute the first two autocorrelation coefficients*/
ippsDotProd_16s32s_Sfs(pTmpVec,pTmpVec,G723_SBFR_LEN,pAutoCorr,0);
ippsDotProd_16s32s_Sfs(pTmpVec,pTmpVec+1,G723_SBFR_LEN-1,pAutoCorr+1,0);
/* Compute new reflection coefficient.*/
sTmp = pAutoCorr[0]>>15;
if ( sTmp ) {
sTmp = (pAutoCorr[1]>>1)/(sTmp);
}
/* Compute interpolated reflection coefficient use the new and previouse one.*/
lTmp = ((decoderObj->ReflectionCoeff << 2) - decoderObj->ReflectionCoeff + sTmp);
decoderObj->ReflectionCoeff = (lTmp+0x2)>>2;
sTmp = (decoderObj->ReflectionCoeff * SmoothCoeff)>>15;
sTmp &= 0xfffc ;
/* Compute FIR and IIR coefficients. Note the table can be generated using the GenPostFiltTable function */
ippsMul_NR_16s_Sfs(pSrcLPC,PostFiltTable,FltCoef,G723_LPC_ORDER,15);
ippsMul_NR_16s_Sfs(pSrcLPC,PostFiltTable+G723_LPC_ORDER,FltCoef+G723_LPC_ORDER,G723_LPC_ORDER,15);
/* 32s output needs for compensate filter */
for(i=0; i<G723_LPC_ORDER; i++){
pFltSignal[i] = decoderObj->PostFilterMem[G723_LPC_ORDER+i]<<16;
}
ippsIIR16s_G723_16s32s(FltCoef,pSrcDstSignal,&pFltSignal[G723_LPC_ORDER],decoderObj->PostFilterMem);
/* perform the tilt fitering. */
ippsTiltCompensation_G723_32s16s(sTmp, &pFltSignal[G723_LPC_ORDER-1], pSrcDstSignal);
/* Gain scaling. Section 3.9 */
/* Compute normalized signal energy.*/
sTmp = (short)(2*lSfs + 3);
if (sTmp < 0) {
lSignalEnergy = ShiftL_32s(pAutoCorr[0],(unsigned short)(-sTmp));
} else {
lSignalEnergy = pAutoCorr[0]>>sTmp;
}
ippsGainControl_G723_16s_I(lSignalEnergy,pSrcDstSignal,&decoderObj->PstFltGain);
LOCAL_ARRAY_FREE(short, pTmpVec,G723_SBFR_LEN, decoderObj);
LOCAL_ARRAY_FREE(int, pAutoCorr,2, decoderObj);
LOCAL_ARRAY_FREE(int, pFltSignal,G723_LPC_ORDER+G723_SBFR_LEN, decoderObj);
LOCAL_ARRAY_FREE(short, FltCoef,2*G723_LPC_ORDER, decoderObj);
return;
}
void LSPInterpolation(const short *pSrcLSP, const short *pSrcPrevLSP, short *pDstLPC)
{
pDstLPC[0] = 4096;
ippsInterpolateC_NR_G729_16s_Sfs(pSrcLSP,4096,pSrcPrevLSP,12288,&pDstLPC[1],G723_LPC_ORDER,14);
ippsLSFToLPC_G723_16s(&pDstLPC[1], &pDstLPC[1]);
pDstLPC[G723_LPC_ORDERP1] = 4096;
ippsInterpolateC_NR_G729_16s_Sfs(pSrcLSP,8192,pSrcPrevLSP,8192,&pDstLPC[1+G723_LPC_ORDERP1],G723_LPC_ORDER,14);
ippsLSFToLPC_G723_16s(&pDstLPC[1+G723_LPC_ORDERP1], &pDstLPC[1+G723_LPC_ORDERP1]);
pDstLPC[2*G723_LPC_ORDERP1] = 4096;
ippsInterpolateC_NR_G729_16s_Sfs(pSrcLSP,12288,pSrcPrevLSP,4096,&pDstLPC[1+2*G723_LPC_ORDERP1],G723_LPC_ORDER,14);
ippsLSFToLPC_G723_16s(&pDstLPC[1+2*G723_LPC_ORDERP1], &pDstLPC[1+2*G723_LPC_ORDERP1]);
pDstLPC[3*G723_LPC_ORDERP1] = 4096;
ippsCopy_16s(pSrcLSP,&pDstLPC[1+3*G723_LPC_ORDERP1],G723_LPC_ORDER);
ippsLSFToLPC_G723_16s(&pDstLPC[1+3*G723_LPC_ORDERP1], &pDstLPC[1+3*G723_LPC_ORDERP1]);
return;
}
static void GetAverScaleTable(short *pTbl)
{
int i;
double dTmp, dAlphaW=2.70375;
dTmp = 32768.f/((double)G723_HALFFRM_LEN);
SATURATE_fs(dTmp,pTbl[0]);
for(i=1;i<4;i++) {
dTmp = 32768.f*dAlphaW*dAlphaW/((double)i*(double)G723_FRM_LEN);
SATURATE_fs(dTmp,pTbl[i]);
}
return;
}
static __ALIGN32 CONST short AverScaleTbl_G723[4] = {273, 998,
499, 333}; /*This table can be generateg using GetAverScaleTable function.*/
static __ALIGN32 CONST int LogEnerLevel[3] = {2048, 18432, 231233};
static __ALIGN32 CONST short FirstCode[3] = {0, 32, 96};
void QuantSIDGain_G723_16s(const Ipp16s *pSrc, const Ipp16s *pSrcSfs, int len, int *pIndx)
{
short sTmp, sNseg, sNsegP1;
short j, m, k, expBase;
int lTmp1, lTmp2, lTmp3;
short sfs;
int i;
if(len == 0) {
/* Quantize energy */
sTmp = (*pSrcSfs)<<1;
sTmp = 16 - sTmp;
lTmp1 = MulC_32s(AverScaleTbl_G723[0], (*pSrc)<<sTmp);
} else {
/* Compute weighted average sum*/
sfs = pSrcSfs[0];
for(i=1; i<len; i++) {
if(pSrcSfs[i] < sfs) sfs = pSrcSfs[i];
}
for(i=0, lTmp1=0; i<len; i++) {
sTmp = pSrcSfs[i] - sfs;
sTmp = pSrc[i]>>sTmp;
sTmp = ((AverScaleTbl_G723[len]*sTmp)+0x4000)>>15;
lTmp1 += sTmp;
}
sTmp = 15 - sfs;
if(sTmp < 0) lTmp1 >>= (-sTmp);
else lTmp1 <<= sTmp;
}
*pIndx = 63;
if(lTmp1 < LogEnerLevel[2]) {
/* Compute segment number */
if(lTmp1 >= LogEnerLevel[1]) {
expBase = 4; sNseg = 2;
} else {
expBase = 3;
sNseg=(lTmp1 >= LogEnerLevel[0])?1:0;
}
sNsegP1 = sNseg + 1;
j = 1<<expBase;
k = j>>1;
/* Binary search */
for(i=0; i<expBase; i++) {
sTmp = FirstCode[sNseg] + (j<<sNsegP1);
lTmp2 = 2*sTmp * sTmp;
if(lTmp1 >= lTmp2) j += k;
else j -= k;
k >>= 1;
}
sTmp = FirstCode[sNseg] + (j<<sNsegP1);
lTmp2 = 2* sTmp * sTmp - lTmp1;
if(lTmp2 <= 0) {
m = j + 1;
sTmp = FirstCode[sNseg] + (m<<sNsegP1);
lTmp3 = lTmp1 - 2 * sTmp * sTmp;
if(lTmp2 > lTmp3) sTmp = (sNseg<<4) + j;
else sTmp = (sNseg<<4)+m;
} else {
m = j - 1;
sTmp = FirstCode[sNseg] + (m<<sNsegP1);
lTmp3 = lTmp1 - 2 * sTmp * sTmp;
if(lTmp2 < lTmp3) sTmp = (sNseg<<4) + j;
else sTmp = (sNseg<<4) + m;
}
*pIndx = sTmp;
}
return;
}
void DecodeSIDGain_G723_16s (int pIndx, Ipp16s *pGain)
{
short i, sNseg;
short sTmp;
sNseg = pIndx>>4;
if(sNseg == 3) sNseg = 2;
i = pIndx - (sNseg<<4);
sTmp = sNseg + 1;
sTmp = i<<sTmp;
sTmp += FirstCode[sNseg]; /* SidGain */
sTmp <<= 5; /* << 5 */
*pGain = sTmp;
return;
}
void FixedCodebookGain_G723_16s(const Ipp16s *pSrc1, const Ipp16s *pSrc2,
Ipp16s *pGainCoeff, int *pGainIdx, short *pAlignTmp)
{
short i;
short sNormCorr, sNormEnergy, sCorrSFS, sEnergySFS, sBestQntGain, sCurrGain;
int lCorr, lEnergy;
short sCurrDist, sMinDist;
ippsRShiftC_16s (pSrc2, 3, pAlignTmp, G723_SBFR_LEN); /* to avoid overflow */
ippsDotProd_16s32s_Sfs(pSrc1, pAlignTmp, G723_SBFR_LEN,&lCorr,0);
sBestQntGain = 0;
if(lCorr > 0) {
sCorrSFS = Norm_32s_I(&lCorr);
sNormCorr = lCorr>>17; /* Be sure sNormCorr < sNormEnergy */
ippsDotProd_16s32s_Sfs(pAlignTmp,pAlignTmp,G723_SBFR_LEN, &lEnergy,0);
sEnergySFS = Norm_32s_I(&lEnergy);
sNormEnergy = lEnergy>>16;
sCurrGain = (sNormEnergy > 0)? (sNormCorr<<15)/sNormEnergy : IPP_MAX_16S;/* compute sCurrGain = sNormCorr/sNormEnergy */
i = sCorrSFS - sEnergySFS + 5; /* Denormalization of division */
if(i < 0) sCurrGain = ShiftL_16s(sCurrGain, (unsigned short)(-i));
else
sCurrGain >>= i;
sBestQntGain = 0;
sMinDist = abs(sCurrGain + GainDBLvls[0]);
for ( i = 1; i <N_GAINS ; i ++ ) {
sCurrDist = abs(sCurrGain + GainDBLvls[i]);
if ( sCurrDist< sMinDist) { sMinDist = sCurrDist; sBestQntGain = i; }
}
}
*pGainCoeff = -GainDBLvls[sBestQntGain];
*pGainIdx = sBestQntGain;
}
void ExcitationResidual_G723_16s(const Ipp16s *pSrc1, const Ipp16s *pSrc2, Ipp16s *pSrcDst,G723Encoder_Obj *encoderObj)
{
int i;
LOCAL_ARRAY(int, lConv,G723_SBFR_LEN,encoderObj) ;
LOCAL_ARRAY(short, sNormConv,G723_SBFR_LEN,encoderObj) ;
ippsConvPartial_16s32s(pSrc1,pSrc2,lConv,G723_SBFR_LEN);
for ( i = 0 ; i < G723_SBFR_LEN ; i ++ ) {
sNormConv[i] = (-lConv[i] + 0x2000) >> 14;
}
ippsAdd_16s_I(sNormConv,pSrcDst,G723_SBFR_LEN);
LOCAL_ARRAY_FREE(short, sNormConv,G723_SBFR_LEN,encoderObj) ;
LOCAL_ARRAY_FREE(int, lConv,G723_SBFR_LEN,encoderObj) ;
}
#define COMBTBL_LINE_LEN (G723_SBFR_LEN/GRIDSIZE)
static __ALIGN32 CONST int CombTbl[N_PULSES*COMBTBL_LINE_LEN] =
{
118755, 98280, 80730, 65780, 53130, 42504, 33649, 26334, 20349, 15504,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -