1 /*/////////////////////////////////////////////////////////////////////////////
2 //
3 //                  INTEL CORPORATION PROPRIETARY INFORMATION
4 //     This software is supplied under the terms of a license agreement or
5 //     nondisclosure agreement with Intel Corporation and may not be copied
6 //     or disclosed except in accordance with the terms of that agreement.
7 //          Copyright(c) 2004-2012 Intel Corporation. All Rights Reserved.
8 //
9 //     Intel(R) Integrated Performance Primitives
10 //     USC - Unified Speech Codec interface library
11 //
12 // By downloading and installing USC codec, you hereby agree that the
13 // accompanying Materials are being provided to you under the terms and
14 // conditions of the End User License Agreement for the Intel(R) Integrated
15 // Performance Primitives product previously accepted by you. Please refer
16 // to the file ippEULA.rtf or ippEULA.txt located in the root directory of your Intel(R) IPP
17 // product installation for more information.
18 //
19 // A speech coding standards promoted by ITU, ETSI, 3GPP and other
20 // organizations. Implementations of these standards, or the standard enabled
21 // platforms may require licenses from various entities, including
22 // Intel Corporation.
23 //
24 //
25 // Purpose: G.729 floating-point speech codec: internal functions.
26 //
27 */
28 
29 #include <math.h>
30 #include "vadg729fp.h"
31 #include "aux_fnxs.h"
32 #include "owng729fp.h"
33 
34 #define         sqr(a)          ((a)*(a))
35 
36 /* Hamming_cos window for LPC analysis.           */
37 
38 static __ALIGN32 CONST Ipp32f HammingWindow[WINDOW_LEN] = {        /* hamming-cosine window */
39 0.08000000f, 0.08005703f, 0.08022812f, 0.08051321f,
40 0.08091225f, 0.08142514f, 0.08205172f, 0.08279188f,
41 0.08364540f, 0.08461212f, 0.08569173f, 0.08688401f,
42 0.08818865f, 0.08960532f, 0.09113365f, 0.09277334f,
43 0.09452391f, 0.09638494f, 0.09835598f, 0.10043652f,
44 0.10262608f, 0.10492408f, 0.10732999f, 0.10984316f,
45 0.11246302f, 0.11518890f, 0.11802010f, 0.12095598f,
46 0.12399574f, 0.12713866f, 0.13038395f, 0.13373083f,
47 0.13717847f, 0.14072597f, 0.14437246f, 0.14811710f,
48 0.15195890f, 0.15589692f, 0.15993017f, 0.16405767f,
49 0.16827843f, 0.17259133f, 0.17699537f, 0.18148938f,
50 0.18607232f, 0.19074300f, 0.19550033f, 0.20034306f,
51 0.20527001f, 0.21027996f, 0.21537170f, 0.22054392f,
52 0.22579536f, 0.23112471f, 0.23653066f, 0.24201185f,
53 0.24756692f, 0.25319457f, 0.25889328f, 0.26466170f,
54 0.27049842f, 0.27640197f, 0.28237087f, 0.28840363f,
55 0.29449883f, 0.30065489f, 0.30687031f, 0.31314352f,
56 0.31947297f, 0.32585713f, 0.33229437f, 0.33878314f,
57 0.34532180f, 0.35190874f, 0.35854232f, 0.36522087f,
58 0.37194279f, 0.37870640f, 0.38550997f, 0.39235184f,
59 0.39923036f, 0.40614375f, 0.41309035f, 0.42006844f,
60 0.42707625f, 0.43411207f, 0.44117412f, 0.44826069f,
61 0.45537004f, 0.46250033f, 0.46964988f, 0.47681686f,
62 0.48399949f, 0.49119604f, 0.49840465f, 0.50562358f,
63 0.51285106f, 0.52008528f, 0.52732444f, 0.53456670f,
64 0.54181033f, 0.54905349f, 0.55629444f, 0.56353134f,
65 0.57076240f, 0.57798582f, 0.58519983f, 0.59240264f,
66 0.59959245f, 0.60676748f, 0.61392599f, 0.62106609f,
67 0.62818617f, 0.63528436f, 0.64235890f, 0.64940804f,
68 0.65643007f, 0.66342324f, 0.67038584f, 0.67731601f,
69 0.68421221f, 0.69107264f, 0.69789559f, 0.70467937f,
70 0.71142232f, 0.71812278f, 0.72477907f, 0.73138952f,
71 0.73795253f, 0.74446648f, 0.75092971f, 0.75734061f,
72 0.76369762f, 0.76999915f, 0.77624369f, 0.78242958f,
73 0.78855544f, 0.79461962f, 0.80062068f, 0.80655706f,
74 0.81242740f, 0.81823015f, 0.82396388f, 0.82962728f,
75 0.83521879f, 0.84073710f, 0.84618086f, 0.85154873f,
76 0.85683930f, 0.86205131f, 0.86718345f, 0.87223446f,
77 0.87720311f, 0.88208807f, 0.88688827f, 0.89160240f,
78 0.89622939f, 0.90076804f, 0.90521723f, 0.90957582f,
79 0.91384280f, 0.91801709f, 0.92209762f, 0.92608339f,
80 0.92997342f, 0.93376678f, 0.93746245f, 0.94105959f,
81 0.94455731f, 0.94795465f, 0.95125085f, 0.95444512f,
82 0.95753652f, 0.96052444f, 0.96340811f, 0.96618676f,
83 0.96885973f, 0.97142631f, 0.97388595f, 0.97623801f,
84 0.97848189f, 0.98061699f, 0.98264289f, 0.98455900f,
85 0.98636484f, 0.98806006f, 0.98964417f, 0.99111670f,
86 0.99247742f, 0.99372596f, 0.99486196f, 0.99588519f,
87 0.99679530f, 0.99759221f, 0.99827564f, 0.99884540f,
88 0.99930143f, 0.99964350f, 0.99987161f, 0.99998569f,
89 1.00000000f, 0.99921930f, 0.99687845f, 0.99298108f,
90 0.98753333f, 0.98054361f, 0.97202289f, 0.96198452f,
91 0.95044410f, 0.93741965f, 0.92293155f, 0.90700239f,
92 0.88965708f, 0.87092263f, 0.85082841f, 0.82940567f,
93 0.80668795f, 0.78271067f, 0.75751126f, 0.73112911f,
94 0.70360541f, 0.67498308f, 0.64530689f, 0.61462307f,
95 0.58297962f, 0.55042595f, 0.51701277f, 0.48279238f,
96 0.44781810f, 0.41214463f, 0.37582767f, 0.33892387f,
97 0.30149087f, 0.26358715f, 0.22527184f, 0.18660481f,
98 0.14764643f, 0.10845750f, 0.06909923f, 0.02963307f};
99 
ownAutoCorr_G729_32f(Ipp32f * pSrc,Ipp32s len,Ipp32f * pDst,Ipp32f * pExtBuff)100 void ownAutoCorr_G729_32f(Ipp32f *pSrc, Ipp32s len, Ipp32f *pDst, Ipp32f *pExtBuff)
101 {
102    ippsMul_32f(pSrc, HammingWindow, pExtBuff, WINDOW_LEN);
103 
104    ippsAutoCorr_32f(pExtBuff, WINDOW_LEN, pDst, len+1);
105 
106    if (pDst[0]<(Ipp32f)1.0) pDst[0]=(Ipp32f)1.0;
107 
108    return;
109 }
110 
ownACOS_G729_32f(Ipp32f * pSrc,Ipp32f * pDst,Ipp32s len)111 void ownACOS_G729_32f(Ipp32f *pSrc, Ipp32f *pDst, Ipp32s len)
112 {
113 
114    Ipp32s i;
115 
116    for (i=0; i<len; i++ )
117       pDst[i] = (Ipp32f)acos(pSrc[i]);
118    return;
119 }
120 
ownCOS_G729_32f(Ipp32f * pSrc,Ipp32f * pDst,Ipp32s len)121 void ownCOS_G729_32f(Ipp32f *pSrc, Ipp32f *pDst, Ipp32s len)
122 {
123 
124    Ipp32s i;
125 
126    for (i=0; i<len; i++ )
127       pDst[i] = (Ipp32f)cos(pSrc[i]);
128    return;
129 }
130 
131 
ownAdaptiveCodebookGainCoeff_G729_32f(Ipp32f * pSrcTargetVector,Ipp32f * pSrcFltAdaptivCdbkVec,Ipp32f * pDstCorrCoeff,Ipp32s len)132 Ipp32f ownAdaptiveCodebookGainCoeff_G729_32f(Ipp32f *pSrcTargetVector, Ipp32f *pSrcFltAdaptivCdbkVec,
133                Ipp32f *pDstCorrCoeff, Ipp32s len)
134 {
135     Ipp32f fCorr, fEnergy, fGain;
136     Ipp64f sum;
137 
138     /* energy of filtered excitation */
139     ippsDotProd_32f64f(pSrcFltAdaptivCdbkVec, pSrcFltAdaptivCdbkVec, len, &sum);
140     fEnergy = (Ipp32f)(sum + 0.01);
141 
142     ippsDotProd_32f64f(pSrcTargetVector, pSrcFltAdaptivCdbkVec, len, &sum);
143     fCorr = (Ipp32f)sum;
144 
145     pDstCorrCoeff[0] = fEnergy;
146     pDstCorrCoeff[1] = -2.0f*fCorr +0.01f;
147 
148     /* find pitch fGain and bound it by [0,1.2] */
149 
150     fGain = fCorr/fEnergy;
151 
152     CLIP_TO_LOWLEVEL(fGain,0.f);
153     CLIP_TO_UPLEVEL(fGain,GAIN_PIT_MAX);
154 
155     return fGain;
156 }
157 
158 
WeightLPCCoeff_G729(Ipp32f * pSrcLPC,Ipp32f valWeightingFactor,Ipp32s len,Ipp32f * pDstWeightedLPC)159 void WeightLPCCoeff_G729(Ipp32f *pSrcLPC, Ipp32f valWeightingFactor, Ipp32s len, Ipp32f *pDstWeightedLPC)
160 {
161   Ipp32f fFactor;
162   Ipp32s i;
163 
164   pDstWeightedLPC[0]=pSrcLPC[0];
165   fFactor=valWeightingFactor;
166   for (i = 1; i < len; i++)
167   {
168     pDstWeightedLPC[i] = fFactor*pSrcLPC[i];
169     fFactor *= valWeightingFactor;
170   }
171   pDstWeightedLPC[len] = fFactor*pSrcLPC[len];
172   return;
173 }
174 
AdaptiveCodebookGainCoeff_G729_32f(Ipp32f * pSrcTargetVector,Ipp32f * pSrcFltAdaptiveCodebookVector,Ipp32f * pSrcFltInnovation,Ipp32f * pDstCoeff)175 void AdaptiveCodebookGainCoeff_G729_32f( Ipp32f *pSrcTargetVector, Ipp32f *pSrcFltAdaptiveCodebookVector,
176                                          Ipp32f *pSrcFltInnovation, Ipp32f *pDstCoeff)
177 {
178    Ipp64f sum;
179 
180    ippsDotProd_32f64f(pSrcFltInnovation, pSrcFltInnovation, SUBFR_LEN, &sum);
181    pDstCoeff[2] = (Ipp32f)(sum + 0.01);
182 
183    ippsDotProd_32f64f(pSrcTargetVector, pSrcFltInnovation, SUBFR_LEN, &sum);
184    pDstCoeff[3] = (Ipp32f)(-2.0*(sum + 0.01));
185 
186    ippsDotProd_32f64f(pSrcFltAdaptiveCodebookVector, pSrcFltInnovation, SUBFR_LEN, &sum);
187    pDstCoeff[4] = (Ipp32f)(2.0*(sum + 0.01));
188 
189    return;
190 
191 }
192 
ownAdaptiveCodebookSearch_G729A_32f(Ipp32f * pSrcExc,Ipp32f * pSrcTargetVector,Ipp32f * pSrcImpulseResponse,Ipp32s minPitchDelay,Ipp32s maxPitchDelay,Ipp32s nSbfr,Ipp32s * fracPartPitchDelay,Ipp32f * pExtBuff)193 Ipp32s ownAdaptiveCodebookSearch_G729A_32f(Ipp32f *pSrcExc, Ipp32f *pSrcTargetVector, Ipp32f *pSrcImpulseResponse,
194   Ipp32s minPitchDelay, Ipp32s maxPitchDelay, Ipp32s nSbfr, Ipp32s *fracPartPitchDelay, Ipp32f *pExtBuff)
195 {
196   Ipp32s  pitchPeriod;
197   Ipp32f *pCorr;
198   Ipp32f *pTmpExcitation;
199   Ipp64f  corr, max;
200   Ipp32s delayLine[2];
201 
202   pCorr = &pExtBuff[0];
203   pTmpExcitation = &pExtBuff[SUBFR_LEN];
204 
205   /* Compute  correlations of input response with the target vector.*/
206 
207   ippsCrossCorr_32f(pSrcImpulseResponse, SUBFR_LEN, pSrcTargetVector, SUBFR_LEN, pCorr,  SUBFR_LEN, 0);
208 
209   /* Find maximum integer delay */
210 
211   ippsCrossCorrLagMax_32f64f(pCorr, &pSrcExc[-maxPitchDelay], SUBFR_LEN, maxPitchDelay-minPitchDelay, &max, &pitchPeriod);
212   pitchPeriod = (maxPitchDelay-minPitchDelay-pitchPeriod) + minPitchDelay;
213 
214   /* Test fractions */
215 
216   /* Fraction 0 */
217   delayLine[0] = pitchPeriod;
218   delayLine[1] = 0;
219   ippsDecodeAdaptiveVector_G729_32f_I(delayLine, pSrcExc);
220   ippsDotProd_32f64f( pCorr, pSrcExc, SUBFR_LEN, &max);
221   *fracPartPitchDelay = 0;
222 
223   /* If first subframe and lag > 84 do not search fractional pitch */
224 
225   if( (nSbfr == 0) && (pitchPeriod > 84) )
226     return pitchPeriod;
227 
228   ippsCopy_32f(pSrcExc, pTmpExcitation, SUBFR_LEN);
229 
230   /* Fraction -1/3 */
231 
232   delayLine[1] = -1;
233 
234   ippsDecodeAdaptiveVector_G729_32f_I(delayLine, pSrcExc);
235   ippsDotProd_32f64f( pCorr, pSrcExc, SUBFR_LEN, &corr);
236   if(corr > max){
237     max = corr;
238     *fracPartPitchDelay = -1;
239     ippsCopy_32f(pSrcExc, pTmpExcitation, SUBFR_LEN);
240   }
241 
242   /* Fraction +1/3 */
243 
244   delayLine[1] = 1;
245   ippsDecodeAdaptiveVector_G729_32f_I(delayLine, pSrcExc);
246   ippsDotProd_32f64f( pCorr, pSrcExc, SUBFR_LEN, &corr);
247   if(corr > max){
248     *fracPartPitchDelay = 1;
249   }
250   else
251     ippsCopy_32f(pTmpExcitation, pSrcExc, SUBFR_LEN);
252 
253   return pitchPeriod;
254 }
255 
ExtractBitsG729FP(const Ipp8u ** pBits,Ipp32s * nBit,Ipp32s Count)256 Ipp32s  ExtractBitsG729FP( const Ipp8u **pBits, Ipp32s *nBit, Ipp32s Count )
257 {
258     Ipp32s  i ;
259     Ipp32s  Rez = 0L ;
260 
261     for ( i = 0 ; i < Count ; i ++ ){
262         Ipp32s  fTmp ;
263         fTmp = ((*pBits)[(i + *nBit)>>3] >> (7 - ((i + *nBit) & 0x0007)) ) & 1;
264         Rez <<= 1 ;
265         Rez += fTmp ;
266     }
267 
268     *pBits += (Count + *nBit)>>3;
269     *nBit = (Count + *nBit) & 0x0007;
270 
271     return Rez ;
272 }
273 
PWGammaFactor_G729(Ipp32f * pGamma1,Ipp32f * pGamma2,Ipp32f * pIntLSF,Ipp32f * CurrLSF,Ipp32f * ReflectCoeff,Ipp32s * isFlat,Ipp32f * PrevLogAreaRatioCoeff)274 void PWGammaFactor_G729(Ipp32f *pGamma1, Ipp32f *pGamma2, Ipp32f *pIntLSF, Ipp32f *CurrLSF,
275                    Ipp32f *ReflectCoeff, Ipp32s   *isFlat, Ipp32f *PrevLogAreaRatioCoeff)
276 {
277    Ipp32f   logAreaRatioCoeff[4];
278    Ipp32f  *logAreaRatioCoeffNew;
279    Ipp32f  *lsf;
280    Ipp32f   minDist, fTmp;
281    Ipp32s   i, k;
282 
283    logAreaRatioCoeffNew = &logAreaRatioCoeff[2];
284 
285    /* Convert reflection coefficients to the Log Area Ratio coefficient*/
286    for (i=0; i<2; i++)
287       logAreaRatioCoeffNew[i] = (Ipp32f)log10( (Ipp64f)( ( 1.0f + ReflectCoeff[i]) / (1.0f - ReflectCoeff[i])));
288 
289    /* Interpolation of lar for the 1st subframe */
290    for (i=0; i<2; i++) {
291       logAreaRatioCoeff[i] = 0.5f * (logAreaRatioCoeffNew[i] + PrevLogAreaRatioCoeff[i]);
292       PrevLogAreaRatioCoeff[i] = logAreaRatioCoeffNew[i];
293    }
294 
295    for (k=0; k<2; k++) {    /* LOOP : gamma2 for 1st to 2nd subframes */
296       if (*isFlat != 0) {
297          if ((logAreaRatioCoeff[2*k] <LAR_THRESH1 )&&(logAreaRatioCoeff[2*k+1] > LAR_THRESH3)) *isFlat = 0;
298       } else {
299          if ((logAreaRatioCoeff[2*k] > LAR_THRESH2)||(logAreaRatioCoeff[2*k+1] < LAR_THRESH4)) *isFlat = 1;
300       }
301 
302       if (*isFlat == 0) {
303          /* Second criterion based on the minimum distance between two successives lsfs. */
304          pGamma1[k] = GAMMA1_TILTED;
305          if (k == 0) lsf = pIntLSF;
306          else lsf = CurrLSF;
307 
308          minDist = lsf[1] - lsf[0];
309          for (i=1; i<LPC_ORDER-1; i++) {
310             fTmp = lsf[i+1] - lsf[i];
311             if (fTmp < minDist) minDist = fTmp;
312          }
313 
314          pGamma2[k] =  GAMMA2_TILTED_SCALE * minDist + GAMMA2_TILTED_SHIFT;
315 
316          if (pGamma2[k] > GAMMA2_TILTED_MAX) pGamma2[k] = GAMMA2_TILTED_MAX;
317          if (pGamma2[k] < GAMMA2_TILTED_MIN) pGamma2[k] = GAMMA2_TILTED_MIN;
318       } else {
319          pGamma1[k] = GAMMA1_FLAT;
320          pGamma2[k] = GAMMA2_FLAT;
321       }
322    }
323    return;
324 }
325 
326 
CodewordImpConv_G729_32f(Ipp32s index,const Ipp32f * pSrc1,const Ipp32f * pSrc2,Ipp32f * pDst)327 void CodewordImpConv_G729_32f(Ipp32s index, const Ipp32f *pSrc1,const Ipp32f *pSrc2,Ipp32f *pDst)
328 {
329    Ipp32s i;
330    Ipp32s lPos0, lPos1, lPos2, lPos3; /* position*/
331    Ipp32s lSign0, lSign1, lSign2, lSign3;     /*signs: 1,-1*/
332 
333    lPos0 = index & 0x7;
334    lPos1 = (index>>3) & 0x7;
335    lPos2 = (index>>6) & 0x7;
336    lPos3 = index>>9;
337 
338    lPos0 = (lPos0<<2)+lPos0;                      /* lPos0*5;*/
339    lPos1 = (lPos1<<2)+lPos1+1;                    /* 1+lPos1*5;*/
340    lPos2 = (lPos2<<2)+lPos2+2;                    /* 2+lPos2*5;*/
341    lPos3 = ((lPos3>>1)<<2)+(lPos3>>1)+(lPos3&1)+3;  /* 3+(lPos3>>1)*5+(lPos3&1);*/
342 
343    if (lPos0>lPos1) {i=lPos0; lPos0=lPos1; lPos1=i; }
344    if (lPos2>lPos3) {i=lPos2; lPos2=lPos3; lPos3=i; }
345    if (lPos0>lPos2) {i=lPos0; lPos0=lPos2; lPos2=i; }
346    if (lPos1>lPos3) {i=lPos1; lPos1=lPos3; lPos3=i; }
347    if (lPos1>lPos2) {i=lPos1; lPos1=lPos2; lPos2=i; }
348 
349    lSign0 = (pSrc1[lPos0] > 0)? 1:-1;
350    lSign1 = (pSrc1[lPos1] > 0)? 1:-1;
351    lSign2 = (pSrc1[lPos2] > 0)? 1:-1;
352    lSign3 = (pSrc1[lPos3] > 0)? 1:-1;
353 
354    for (i=0; i<lPos0; i++)
355       pDst[i]=0;
356    for (; i<lPos1; i++)
357       pDst[i]=lSign0*pSrc2[i-lPos0];
358    for (; i<lPos2; i++)
359       pDst[i]=lSign0*pSrc2[i-lPos0]+lSign1*pSrc2[i-lPos1];
360    for (; i<lPos3; i++)
361       pDst[i]=lSign0*pSrc2[i-lPos0]+lSign1*pSrc2[i-lPos1]+lSign2*pSrc2[i-lPos2];
362    for (; i<SUBFR_LEN; i++)
363       pDst[i]=lSign0*pSrc2[i-lPos0]+lSign1*pSrc2[i-lPos1]+lSign2*pSrc2[i-lPos2]+lSign3*pSrc2[i-lPos3];
364 }
365 
MSDGetSize(Ipp32s * pDstSize)366 void MSDGetSize(Ipp32s *pDstSize)
367 {
368    *pDstSize = sizeof(CNGmemory);
369    return;
370 }
371 
MSDInit(Ipp8s * msdMem)372 void MSDInit(Ipp8s *msdMem)
373 {
374    MusDetectMemory *msdState = (MusDetectMemory *)msdMem;
375 
376    ippsZero_16s((Ipp16s*)msdState,sizeof(MusDetectMemory)>>1) ;
377    ippsZero_32f(msdState->MeanRC,10);
378    msdState->lMusicCounter=0;
379    msdState->fMusicCounter=0.0f;
380    msdState->lZeroMusicCounter=0;
381    msdState->fMeanPitchGain =0.5f;
382    msdState->lPFlagCounter=0;
383    msdState->fMeanPFlagCounter=0.0;
384    msdState->lConscPFlagCounter=0;
385    msdState->lRCCounter=0;
386    msdState->fMeanFullBandEnergy =0.0f;
387 
388    return;
389 
390 }
391 
MusicDetection_G729E_32f(G729FPEncoder_Obj * encoderObj,G729Codec_Type codecType,Ipp32f Energy,Ipp32f * ReflectCoeff,Ipp32s * VadDecision,Ipp32f LLenergy,Ipp8s * msdMem,Ipp32f * pExtBuff)392 void MusicDetection_G729E_32f(G729FPEncoder_Obj *encoderObj, G729Codec_Type codecType, Ipp32f Energy,
393                               Ipp32f *ReflectCoeff, Ipp32s *VadDecision, Ipp32f LLenergy, Ipp8s *msdMem,Ipp32f *pExtBuff)
394 {
395 
396     Ipp32s i;
397     Ipp32f fSum1, fSum2,fStandartDeviation;
398     Ipp16s VoicingStrenght1, VoicingStrenght2, VoicingStrenght;
399     Ipp32f fError, fEnergy , fSpectralDifference, *pTmpVec;
400     Ipp32f fThreshold;
401     MusDetectMemory *msdState = (MusDetectMemory *)msdMem;
402 
403     pTmpVec = &pExtBuff[0]; /*10 elements*/
404 
405     fError = 1.0f;
406     for (i=0; i< 4; i++) fError *= (1.0f - ReflectCoeff[i]*ReflectCoeff[i]);
407     ippsSub_32f(msdState->MeanRC, ReflectCoeff, pTmpVec, 10);
408     ippsDotProd_32f(pTmpVec, pTmpVec, 10, &fSpectralDifference);
409 
410     fEnergy = 10.0f*(Ipp32f)log10(fError*Energy/240.0f +IPP_MINABS_32F);
411 
412     if( *VadDecision == VAD_NOISE ){
413        ippsInterpolateC_G729_32f(msdState->MeanRC, 0.9f, ReflectCoeff, 0.1f, msdState->MeanRC, 10);
414        msdState->fMeanFullBandEnergy = 0.9f * msdState->fMeanFullBandEnergy + 0.1f * fEnergy;
415     }
416 
417     fSum1 = 0.0f;
418     fSum2 = 0.0f;
419     for(i=0; i<5; i++){
420         fSum1 += (Ipp32f) encoderObj->LagBuffer[i];
421         fSum2 +=  encoderObj->PitchGainBuffer[i];
422     }
423 
424     fSum1 = fSum1/5.0f;
425     fSum2 = fSum2/5.0f;
426     fStandartDeviation =0.0f;
427     for(i=0; i<5; i++) fStandartDeviation += sqr(((Ipp32f) encoderObj->LagBuffer[i] - fSum1));
428     fStandartDeviation = (Ipp32f)sqrt(fStandartDeviation/4.0f);
429 
430     msdState->fMeanPitchGain = 0.8f * msdState->fMeanPitchGain + 0.2f * fSum2;
431     /* See I.5.1.1 Pitch lag smoothness and voicing strenght indicator.*/
432     if ( codecType == G729D_CODEC)
433         fThreshold = 0.73f;
434     else
435         fThreshold = 0.63f;
436 
437     if ( msdState->fMeanPitchGain > fThreshold)
438         VoicingStrenght2 = 1;
439     else
440         VoicingStrenght2 = 0;
441 
442     if ( fStandartDeviation < 1.30f && msdState->fMeanPitchGain > 0.45f )
443         VoicingStrenght1 = 1;
444     else
445         VoicingStrenght1 = 0;
446 
447     VoicingStrenght= (Ipp16s)( ((Ipp16s)encoderObj->prevVADDec & (Ipp16s)(VoicingStrenght1 | VoicingStrenght2))| (Ipp16s)(VoicingStrenght2));
448 
449     if( ReflectCoeff[1] <= 0.45f && ReflectCoeff[1] >= 0.0f && msdState->fMeanPitchGain < 0.5f)
450         msdState->lRCCounter++;
451     else
452         msdState->lRCCounter =0;
453 
454     if( encoderObj->prevLPCMode== 1 && (*VadDecision == VAD_VOICE))
455         msdState->lMusicCounter++;
456 
457     if ((encoderObj->sFrameCounter%64) == 0 ){
458         if( encoderObj->sFrameCounter == 64)
459             msdState->fMusicCounter = (Ipp32f)msdState->lMusicCounter;
460         else
461             msdState->fMusicCounter = 0.9f*msdState->fMusicCounter + 0.1f*(Ipp32f)msdState->lMusicCounter;
462     }
463 
464     if( msdState->lMusicCounter == 0)
465         msdState->lZeroMusicCounter++;
466     else
467         msdState->lZeroMusicCounter = 0;
468 
469     if( msdState->lZeroMusicCounter > 500 || msdState->lRCCounter > 150) msdState->fMusicCounter = 0.0f;
470 
471     if ((encoderObj->sFrameCounter%64) == 0)
472         msdState->lMusicCounter = 0;
473 
474     if( VoicingStrenght== 1 )
475         msdState->lPFlagCounter++;
476 
477     if ((encoderObj->sFrameCounter%64) == 0 ){
478         if( encoderObj->sFrameCounter == 64)
479             msdState->fMeanPFlagCounter = (Ipp32f)msdState->lPFlagCounter;
480         else{
481             if( msdState->lPFlagCounter > 25)
482                 msdState->fMeanPFlagCounter = 0.98f * msdState->fMeanPFlagCounter + 0.02f * msdState->lPFlagCounter;
483             else if( msdState->lPFlagCounter > 20)
484                 msdState->fMeanPFlagCounter = 0.95f * msdState->fMeanPFlagCounter + 0.05f * msdState->lPFlagCounter;
485             else
486                 msdState->fMeanPFlagCounter = 0.90f * msdState->fMeanPFlagCounter + 0.10f * msdState->lPFlagCounter;
487         }
488     }
489 
490     if( msdState->lPFlagCounter == 0)
491         msdState->lConscPFlagCounter++;
492     else
493         msdState->lConscPFlagCounter = 0;
494 
495     if( msdState->lConscPFlagCounter > 100 || msdState->lRCCounter > 150) msdState->fMeanPFlagCounter = 0.0f;
496 
497     if ((encoderObj->sFrameCounter%64) == 0)
498         msdState->lPFlagCounter = 0;
499 
500     if (codecType == G729E_CODEC){
501         if( fSpectralDifference > 0.15f && (fEnergy -msdState->fMeanFullBandEnergy)> 4.0f && (LLenergy> 50.0) )
502             *VadDecision =VAD_VOICE;
503         else if( (fSpectralDifference > 0.38f || (fEnergy -msdState->fMeanFullBandEnergy)> 4.0f  ) && (LLenergy> 50.0f))
504             *VadDecision =VAD_VOICE;
505         else if( (msdState->fMeanPFlagCounter >= 10.0f || msdState->fMusicCounter >= 5.0f || encoderObj->sFrameCounter < 64)&& (LLenergy> 7.0))
506             *VadDecision =VAD_VOICE;
507     }
508     return;
509 }
510 
PitchTracking_G729FPE(Ipp32s * pitchDelay,Ipp32s * fracPitchDelay,Ipp32s * prevPitchDelay,Ipp32s * stat_N,Ipp32s * lStatPitch2PT,Ipp32s * lStatFracPT)511 void PitchTracking_G729FPE(Ipp32s *pitchDelay, Ipp32s *fracPitchDelay, Ipp32s *prevPitchDelay, Ipp32s *stat_N,
512                          Ipp32s *lStatPitch2PT, Ipp32s *lStatFracPT)
513 {
514     Ipp32s pitchDistance, minDist, lPitchMult;
515     Ipp32s j, distSign;
516 
517     pitchDistance = (*pitchDelay) - (*prevPitchDelay);
518     if(pitchDistance < 0) {
519         distSign = 0;
520         pitchDistance = - pitchDistance;
521     } else {
522         distSign = 1;
523     }
524 
525     /* Test pitch stationarity */
526     if (pitchDistance < 5) {
527         (*stat_N)++;
528         if (*stat_N > 7) *stat_N = 7 ;
529         *lStatPitch2PT = *pitchDelay;
530         *lStatFracPT = *fracPitchDelay;
531     } else {
532         /* Find multiples or sub-multiples */
533         minDist =  pitchDistance;
534         if( distSign == 0) {
535             lPitchMult = 2 * (*pitchDelay);
536             for (j=2; j<5; j++) {
537                 pitchDistance = abs(lPitchMult - (*prevPitchDelay));
538                 if (pitchDistance <= minDist) {
539                     minDist = pitchDistance;
540                 }
541                 lPitchMult += (*pitchDelay);
542             }
543         } else {
544             lPitchMult = 2 * (*prevPitchDelay);
545             for (j=2; j<5; j++) {
546                 pitchDistance = abs(lPitchMult - (*pitchDelay));
547                 if (pitchDistance <= minDist) {
548                     minDist = pitchDistance;
549                 }
550                 lPitchMult += (*prevPitchDelay);
551             }
552         }
553         if (minDist < 5) {   /* Multiple or sub-multiple detected */
554             if (*stat_N > 0) {
555                 *pitchDelay      = *lStatPitch2PT;
556                 *fracPitchDelay = *lStatFracPT;
557             }
558             *stat_N -= 1;
559             if (*stat_N < 0) *stat_N = 0 ;
560         } else {
561             *stat_N = 0;    /* No (sub-)multiple detected  => Pitch transition */
562             *lStatPitch2PT = *pitchDelay;
563             *lStatFracPT = *fracPitchDelay;
564         }
565     }
566 
567     *prevPitchDelay = *pitchDelay;
568 
569     return;
570 }
571 
OpenLoopPitchSearch_G729_32f(const Ipp32f * pSrc,Ipp32s * lBestLag)572 void OpenLoopPitchSearch_G729_32f(const Ipp32f *pSrc, Ipp32s* lBestLag)
573 {
574    Ipp32f fTmp;
575    Ipp64f dTmp;
576 
577    Ipp32f fMax1, fMax2, fMax3;
578    Ipp32s max1Idx, max2Idx, max3Idx;
579 
580    /*  Find a maximum for three sections and compare the maxima
581        of each section by favoring small lag.      */
582 
583    /*  First section:  lag delay = PITCH_LAG_MAX to 80                   */
584    ippsAutoCorrLagMax_32f(pSrc, FRM_LEN, 80,PITCH_LAG_MAX+1, &fMax1, &max1Idx);
585    /*  Second section: lag delay = 79 to 40                              */
586    ippsAutoCorrLagMax_32f(pSrc, FRM_LEN, 40,80, &fMax2, &max2Idx);
587    /*  Third section:  lag delay = 39 to 20                              */
588    ippsAutoCorrLagMax_32f(pSrc, FRM_LEN, PITCH_LAG_MIN,40, &fMax3, &max3Idx);
589 
590    ippsDotProd_32f64f(&pSrc[-max1Idx], &pSrc[-max1Idx], FRM_LEN, &dTmp);
591    fTmp = (Ipp32f) (1.0f / sqrt(dTmp+0.01f));
592    fMax1 = (Ipp32f)(fMax1) * fTmp;        /* max/sqrt(energy)  */
593 
594    ippsDotProd_32f64f(&pSrc[-max2Idx], &pSrc[-max2Idx], FRM_LEN, &dTmp);
595 
596    fTmp = (Ipp32f) (1.0f / sqrt(dTmp+0.01));
597    fMax2 = (Ipp32f)(fMax2) * fTmp; /* max/sqrt(energy)  */
598 
599    /* Calc energy */
600    ippsDotProd_32f64f(&pSrc[-max3Idx], &pSrc[-max3Idx], FRM_LEN, &dTmp);
601    /* 1/sqrt(energy)    */
602    fTmp = 1.0f / (Ipp32f)sqrt(dTmp+0.01);
603    fMax3 = (Ipp32f)(fMax3) * fTmp;        /* max/sqrt(energy)  */
604 
605    /* Compare the 3 sections maxima and choose the small one. */
606    if ( fMax1 * PITCH_THRESH < fMax2 ) {
607       fMax1 = fMax2;
608       max1Idx = max2Idx;
609    }
610 
611    if ( fMax1 * PITCH_THRESH < fMax3 )  max1Idx = max3Idx;
612 
613    *lBestLag = max1Idx;
614 
615    return;
616 }
617 
TestErrorContribution_G729(Ipp32s valPitchDelay,Ipp32s valFracPitchDelay,Ipp32f * ExcErr)618 Ipp32s TestErrorContribution_G729(Ipp32s valPitchDelay, Ipp32s valFracPitchDelay, Ipp32f *ExcErr)
619 {
620 
621     Ipp32s j, lTmp, l1, l2, lTaming;
622     Ipp32f maxErrExc;
623 
624     lTmp = (valFracPitchDelay > 0) ? (valPitchDelay+1) : valPitchDelay;
625 
626     j = lTmp - SUBFR_LEN - INTER_PITCH_LEN;
627     if(j < 0) j = 0;
628     l1 =  (Ipp32s) (j * INV_SUBFR_LEN);
629 
630     j = lTmp + INTER_PITCH_LEN - 2;
631     l2 =  (Ipp32s) (j * INV_SUBFR_LEN);
632 
633     maxErrExc = -1.f;
634     lTaming = 0 ;
635     for(j=l2; j>=l1; j--) {
636         if(ExcErr[j] > maxErrExc) maxErrExc = ExcErr[j];
637     }
638     if(maxErrExc > THRESH_ERR) {
639         lTaming = 1;
640     }
641     return(lTaming);
642 }
643 
UpdateExcErr_G729(Ipp32f valPitchGain,Ipp32s valPitchDelay,Ipp32f * pExcErr)644 void UpdateExcErr_G729(Ipp32f valPitchGain, Ipp32s valPitchDelay, Ipp32f *pExcErr)
645 {
646     Ipp32s i, l1, l2, n;
647     Ipp32f fMax, fTmp;
648 
649     fMax = -1.f;
650 
651     n = valPitchDelay- SUBFR_LEN;
652     if(n < 0) {
653         fTmp = 1.f + valPitchGain * pExcErr[0];
654         if(fTmp > fMax) fMax = fTmp;
655         fTmp = 1.f + valPitchGain * fTmp;
656         if(fTmp > fMax) fMax = fTmp;
657     } else {
658         l1 = (Ipp32s) (n * INV_SUBFR_LEN);
659 
660         i = valPitchDelay - 1;
661         l2 = (Ipp32s) (i * INV_SUBFR_LEN);
662 
663         for(i = l1; i <= l2; i++) {
664             fTmp = 1.f + valPitchGain * pExcErr[i];
665             if(fTmp > fMax) fMax = fTmp;
666         }
667     }
668 
669     for(i=3; i>=1; i--) pExcErr[i] = pExcErr[i-1];
670     pExcErr[0] = fMax;
671 
672     return;
673 }
674 
isBackwardModeDominant_G729(Ipp32s * isBackwardModeDominant,Ipp32s LPCMode,Ipp32s * pCounterBackward,Ipp32s * pCounterForward)675 void isBackwardModeDominant_G729(Ipp32s *isBackwardModeDominant, Ipp32s LPCMode, Ipp32s *pCounterBackward, Ipp32s *pCounterForward)
676 {
677 
678     Ipp32s lTmp, lCounter;
679 
680     if (LPCMode == 0) (*pCounterForward)++;
681     else (*pCounterBackward)++;
682 
683     lCounter = *pCounterBackward + *pCounterForward;
684 
685     if (lCounter == 100) {
686         lCounter = lCounter >> 1;
687         *pCounterBackward = (*pCounterBackward) >> 1;
688         *pCounterForward = (*pCounterForward) >> 1;
689     }
690 
691     *isBackwardModeDominant = 0;
692     if (lCounter >= 10) {
693         lTmp = (*pCounterForward) << 2;
694         if (*pCounterBackward > lTmp) *isBackwardModeDominant = 1;
695     }
696 
697     return;
698 }
699 
CalcEnergy_dB_G729(Ipp32f * pSrc,Ipp32s len)700 Ipp32f CalcEnergy_dB_G729(Ipp32f *pSrc, Ipp32s len)
701 {
702    Ipp64f  dEnergy;
703    Ipp32f fEnergydB;
704    Ipp32s n, k, lTmp;
705 
706    ippsDotProd_32f64f(pSrc, pSrc, len, &dEnergy);
707    dEnergy += 0.0001;
708    fEnergydB = (Ipp32f)log10(dEnergy);
709    n = (Ipp32s) (fEnergydB * INVERSE_LOG2);
710    if(n >= 4) {
711       if(dEnergy > 2147483647.) dEnergy = 93.1814;
712       else {
713          k = (Ipp32s)dEnergy;
714          lTmp = -(1 << (n-4));
715          k &= lTmp;
716          dEnergy = 10. * log10((Ipp32f)k);
717       }
718    }
719    else dEnergy = 0.005;
720 
721    return (Ipp32f)dEnergy;
722 }
723 
InterpolatedBackwardFilter_G729(Ipp32f * pSrcDstLPCBackwardFlt,Ipp32f * pSrcPrevFilter,Ipp32f * pSrcDstIntCoeff)724 void InterpolatedBackwardFilter_G729(Ipp32f *pSrcDstLPCBackwardFlt, Ipp32f *pSrcPrevFilter, Ipp32f *pSrcDstIntCoeff)
725 {
726     Ipp32s i;
727     Ipp32f s1, s2;
728     Ipp32f *pBwdLPC;
729     Ipp32f fIntFactor;
730 
731     pBwdLPC = pSrcDstLPCBackwardFlt + BWD_LPC_ORDERP1;
732 
733     /* Calculate the interpolated filters  */
734     fIntFactor = *pSrcDstIntCoeff - 0.1f;
735     if( fIntFactor < 0) fIntFactor = 0;
736 
737     for (i=0; i<BWD_LPC_ORDERP1; i++) {
738         s1 = pBwdLPC[i] * (1.f - fIntFactor);
739         s2 = pSrcPrevFilter[i] * fIntFactor;
740         pBwdLPC[i] = s1 + s2;
741     }
742     //ippsInterpolateC_G729_32f(pBwdLPC, (1.f - fIntFactor), pSrcPrevFilter, fIntFactor, pBwdLPC, BWD_LPC_ORDERP1);
743 
744     for (i=0; i<BWD_LPC_ORDERP1; i++) {
745         pSrcDstLPCBackwardFlt[i] = 0.5f * (pBwdLPC[i] + pSrcPrevFilter[i]);
746     }
747     //ippsInterpolateC_G729_32f(pBwdLPC, 0.5f, pSrcPrevFilter, 0.5f, pBwdLPC, BWD_LPC_ORDERP1);
748 
749     *pSrcDstIntCoeff = fIntFactor;
750     return;
751 }
752 
753 /* anti-sparseness post-processing */
754 static __ALIGN32 CONST Ipp32f ImpLow[SUBFR_LEN]={
755    0.4483f, 0.3515f, 0.0387f,-0.0843f,-0.1731f, 0.2293f,-0.0011f,
756    -0.0857f,-0.0928f, 0.1472f, 0.0901f,-0.2571f, 0.1155f, 0.0444f,
757    0.0665f,-0.2636f, 0.2457f,-0.0642f,-0.0444f, 0.0237f, 0.0338f,
758    -0.0728f, 0.0688f,-0.0111f,-0.0206f,-0.0642f, 0.1845f,-0.1734f,
759    0.0327f, 0.0953f,-0.1544f, 0.1621f,-0.0711f,-0.1138f, 0.2113f,
760    -0.1187f, 0.0206f,-0.0542f, 0.0009f,0.3096f
761 };
762 
763 static __ALIGN32 CONST Ipp32f ImpMiddle[SUBFR_LEN]={
764    0.9239f, 0.1169f, -0.1232f, 0.0907f, -0.0320f, -0.0306f, 0.0756f,
765    -0.0929f, 0.0859f, -0.0681f, 0.0535f, -0.0492f, 0.0523f, -0.0542f,
766    0.0471f, -0.0308f, 0.0131f, -0.0052f, 0.0144f, -0.0386f, 0.0664f,
767    -0.0826f, 0.0770f, -0.0495f, 0.0105f, 0.0252f, -0.0467f, 0.0526f,
768    -0.0506f, 0.0519f, -0.0630f, 0.0807f, -0.0934f, 0.0884f, -0.0604f,
769    0.0170f, 0.0238f, -0.0418f, 0.0257f, 0.0200f
770 };
771 
772 static __ALIGN32 CONST Ipp32f ImpHigh[SUBFR_LEN]={
773    1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
774    0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
775    0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
776    0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f
777 };
778 
779 
PHDGetSize(Ipp32s * pDstSize)780 void PHDGetSize(Ipp32s *pDstSize)
781 {
782    *pDstSize = sizeof(PHDmemory);
783    return;
784 }
785 
PHDInit(Ipp8s * phdMem)786 void PHDInit(Ipp8s *phdMem)
787 {
788    PHDmemory *phdState = (PHDmemory *)phdMem;
789 
790    ippsZero_32f(phdState->gainMem,6);
791    phdState->prevDispState = 0;
792    phdState->prevCbGain = 0.;
793    phdState->onset = 0;
794 }
795 
PhaseDispersionUpdate_G729D(Ipp32f valPitchGain,Ipp32f valCodebookGain,Ipp8s * phdMem)796 void PhaseDispersionUpdate_G729D(Ipp32f valPitchGain, Ipp32f valCodebookGain, Ipp8s *phdMem)
797 {
798     Ipp32s i;
799     PHDmemory *phdState = (PHDmemory *)phdMem;
800 
801     for (i = 5; i > 0; i--) phdState->gainMem[i] = phdState->gainMem[i-1];
802     phdState->gainMem[0] = valPitchGain;
803     phdState->prevDispState = 2;
804     phdState->prevCbGain = valCodebookGain;
805     phdState->onset = 0;
806 
807     return;
808 }
809 
PhaseDispersion_G729D(Ipp32f * pSrcExcSignal,Ipp32f * pDstFltExcSignal,Ipp32f valCodebookGain,Ipp32f valPitchGain,Ipp32f * pSrcDstInnovation,Ipp8s * phdMem,Ipp8s * pExtBuff)810 void PhaseDispersion_G729D(Ipp32f *pSrcExcSignal, Ipp32f *pDstFltExcSignal, Ipp32f valCodebookGain,
811                            Ipp32f valPitchGain, Ipp32f *pSrcDstInnovation, Ipp8s *phdMem,Ipp8s *pExtBuff)
812 {
813     Ipp32s  i;
814     PHDmemory *phdState = (PHDmemory *)phdMem;
815 
816     Ipp32f *pScaledLTP;
817     Ipp32f *pMemory;
818     Ipp32s *pPos;
819     Ipp32s numNonZeroElem, nPulse, i1, lPos;
820     Ipp32s phDispState;
821     const Ipp32f *pTable=NULL;
822 
823     pScaledLTP = (Ipp32f *)pExtBuff;
824     pMemory = (Ipp32f *)(pExtBuff + SUBFR_LEN*sizeof(Ipp32f));
825     pPos = (Ipp32s *)(pMemory + SUBFR_LEN*sizeof(Ipp32f));
826 
827     /* anti-sparseness post-processing */
828     ippsAdaptiveCodebookContribution_G729_32f(valCodebookGain, pSrcDstInnovation, pSrcExcSignal, pScaledLTP);
829     ippsCopy_32f(pSrcDstInnovation,pMemory,SUBFR_LEN);
830     ippsZero_32f(pSrcDstInnovation,SUBFR_LEN);
831 
832     numNonZeroElem=0;
833     for (i=0; i<SUBFR_LEN; i++) {
834         if (pMemory[i]) /*Can't change to if(fabs(pMemory[i]) < IPP_MINABS_32F)*/
835             pPos[numNonZeroElem++] = i;
836     }
837     if (valPitchGain <= 0.6f) {
838         phDispState = 0;
839     } else if ( (valPitchGain > 0.6f) && (valPitchGain < 0.9f) ) {
840         phDispState = 1;
841     } else {
842         phDispState = 2;
843     }
844 
845     for (i = 5; i > 0; i--) {
846         phdState->gainMem[i]=phdState->gainMem[i-1];
847     }
848     phdState->gainMem[0] = valPitchGain;
849 
850     if (valCodebookGain > 2.0f * phdState->prevCbGain)
851         phdState->onset = 2;
852     else {
853         if (phdState->onset) phdState->onset -= 1;
854     }
855 
856     i1=0;
857     for (i = 0; i < 6; i++) {
858         if (phdState->gainMem[i] < 0.6f) i1 += 1;
859     }
860     if (i1 > 2 && !phdState->onset) phDispState = 0;
861 
862     if (phDispState - phdState->prevDispState > 1 && !phdState->onset) phDispState -= 1;
863 
864     if (phdState->onset) {
865         if (phDispState < 2) phDispState++;
866     }
867 
868     phdState->prevDispState=phDispState;
869     phdState->prevCbGain = valCodebookGain;
870 
871     if (phDispState == 0) {
872        pTable = ImpLow;
873     } else if (phDispState == 1) {
874        pTable = ImpMiddle;
875     } else if (phDispState == 2) {
876        pTable = ImpHigh;
877     }
878 
879     for (nPulse=0; nPulse<numNonZeroElem; nPulse++) {
880       lPos = pPos[nPulse];
881       for (i=lPos; i<SUBFR_LEN; i++)
882          pSrcDstInnovation[i] += pMemory[lPos] * pTable[i-lPos];
883       for (i=0; i < lPos; i++)
884          pSrcDstInnovation[i] += pMemory[lPos] * pTable[SUBFR_LEN-lPos+i];
885     }
886 
887     ippsAdaptiveCodebookContribution_G729_32f(-valCodebookGain, pSrcDstInnovation, pScaledLTP, pDstFltExcSignal);
888 
889     return;
890 }
891 
GlobalStationnarityAdaptation_G729E(G729FPEncoder_Obj * encoderObj,Ipp32f valBackwardPredGain,Ipp32f valForwardPredGain,Ipp32s valLPCMode)892 static void GlobalStationnarityAdaptation_G729E(G729FPEncoder_Obj* encoderObj, Ipp32f valBackwardPredGain, Ipp32f valForwardPredGain, Ipp32s valLPCMode)
893 {
894     Ipp16s sTmp;
895     /* First adaptation based on previous backward / forward decisions */
896     if (valLPCMode == 1) { /* Backward stationnary mode */
897 
898         (encoderObj->sBWDStatInd)++;
899         CLIP_TO_UPLEVEL(encoderObj->sBWDStatInd,21);
900         if(encoderObj->sValBWDStatInd < 32517) encoderObj->sValBWDStatInd  += 250;
901         else encoderObj->sValBWDStatInd = 32767;
902 
903         /* after 20 backward frames => increase stat */
904         if (encoderObj->sBWDStatInd == 20) {
905             if(encoderObj->sGlobalStatInd < 30267) encoderObj->sGlobalStatInd += 2500;
906             else encoderObj->sGlobalStatInd = 32767;
907         }
908         else if (encoderObj->sBWDStatInd > 20) encoderObj->sGlobalStatInd += 500;
909 
910     }
911 
912     else if ((valLPCMode == 0)&&(encoderObj->prevLPCMode == 1)) { /* Backward -> Forward transition */
913 
914         /* Transition occurs after less than 20 backward frames => decrease stat */
915         if (encoderObj->sBWDStatInd < 20) {
916             sTmp = (Ipp16s)(5000 - encoderObj->sValBWDStatInd);
917             encoderObj->sGlobalStatInd = (Ipp16s)(encoderObj->sGlobalStatInd-sTmp);
918         }
919 
920         /* Reset consecutive backward frames counter */
921         encoderObj->sBWDStatInd = 0;
922         encoderObj->sValBWDStatInd = 0;
923 
924     }
925 
926     /* Second adaptation based on prediction gains */
927 
928     if (encoderObj->sGlobalStatInd < 13000) {
929 
930         if      (valBackwardPredGain > valForwardPredGain + TH4) encoderObj->sGlobalStatInd += 3200;
931         else if (valBackwardPredGain > valForwardPredGain + TH3) encoderObj->sGlobalStatInd += 2400;
932         else if (valBackwardPredGain > valForwardPredGain + TH2) encoderObj->sGlobalStatInd += 1600;
933         else if (valBackwardPredGain > valForwardPredGain + TH1) encoderObj->sGlobalStatInd +=  800;
934         else if (valBackwardPredGain > valForwardPredGain)       encoderObj->sGlobalStatInd +=  400;
935 
936     }
937 
938     if      (valBackwardPredGain < valForwardPredGain -  TH5) encoderObj->sGlobalStatInd -= 6400;
939     else if (valBackwardPredGain < valForwardPredGain -  TH4) encoderObj->sGlobalStatInd -= 3200;
940     else if (valBackwardPredGain < valForwardPredGain -  TH3) encoderObj->sGlobalStatInd -= 1600;
941     else if (valBackwardPredGain < valForwardPredGain -  TH2) encoderObj->sGlobalStatInd -=  800;
942     else if (valBackwardPredGain < valForwardPredGain -  TH1) encoderObj->sGlobalStatInd -=  400;
943 
944     CLIP_TO_UPLEVEL(encoderObj->sGlobalStatInd,32000);
945     CLIP_TO_LOWLEVEL(encoderObj->sGlobalStatInd,0);
946     return;
947 }
948 
SetLPCMode_G729FPE(G729FPEncoder_Obj * encoderObj,Ipp32f * pSrcSignal,Ipp32f * pSrcForwardLPCFilter,Ipp32f * pSrcBackwardLPCFilter,Ipp32s * pDstLPCMode,Ipp32f * pSrcLSP,Ipp32f * pExtBuff)949 void SetLPCMode_G729FPE(G729FPEncoder_Obj* encoderObj, Ipp32f *pSrcSignal, Ipp32f *pSrcForwardLPCFilter,
950                       Ipp32f *pSrcBackwardLPCFilter, Ipp32s *pDstLPCMode, Ipp32f *pSrcLSP,Ipp32f *pExtBuff)
951 {
952 
953     Ipp32s  i;
954     Ipp32f *pLPCFlt, *PPtr;
955     Ipp32f fGap, forwardPredGain, backwardPredGain, intBackwardPredGain;
956     Ipp32f LSPThreshold, LSPDist, fTmp;
957     Ipp32f ener_DB_pSrcSignal;
958 
959     PPtr = &pExtBuff[0]; /*FRM_LEN elements*/
960 
961     ener_DB_pSrcSignal = CalcEnergy_dB_G729(pSrcSignal, FRM_LEN);
962 
963     pLPCFlt = pSrcBackwardLPCFilter + BWD_LPC_ORDERP1;
964     /* Calc backward filter prediction gain (without interpolation ) */
965     ippsConvBiased_32f(pLPCFlt,BWD_LPC_ORDER+1,pSrcSignal,FRM_LEN+BWD_LPC_ORDER,PPtr,FRM_LEN,BWD_LPC_ORDER);
966     backwardPredGain = ener_DB_pSrcSignal - CalcEnergy_dB_G729(PPtr, FRM_LEN);
967 
968     /* Interpolated backward filter for the first sub-frame       */
969     InterpolatedBackwardFilter_G729(pSrcBackwardLPCFilter, encoderObj->PrevFlt, &encoderObj->fInterpolationCoeff);
970 
971     /* Calc interpolated backward filter prediction gain */
972     ippsConvBiased_32f(pSrcBackwardLPCFilter,BWD_LPC_ORDER+1,pSrcSignal,SUBFR_LEN+BWD_LPC_ORDER,PPtr,SUBFR_LEN,BWD_LPC_ORDER);
973     ippsConvBiased_32f(pLPCFlt,BWD_LPC_ORDER+1,&pSrcSignal[SUBFR_LEN],SUBFR_LEN+BWD_LPC_ORDER,&PPtr[SUBFR_LEN],SUBFR_LEN,BWD_LPC_ORDER);
974     intBackwardPredGain = ener_DB_pSrcSignal - CalcEnergy_dB_G729(PPtr, FRM_LEN);
975 
976     /* Calc forward filter prediction gain */
977     ippsConvBiased_32f(pSrcForwardLPCFilter,LPC_ORDER+1,pSrcSignal,SUBFR_LEN+LPC_ORDER,PPtr,SUBFR_LEN,LPC_ORDER);
978     ippsConvBiased_32f(&pSrcForwardLPCFilter[LPC_ORDERP1],LPC_ORDER+1,&pSrcSignal[SUBFR_LEN],SUBFR_LEN+LPC_ORDER,&PPtr[SUBFR_LEN],SUBFR_LEN,LPC_ORDER);
979     forwardPredGain = ener_DB_pSrcSignal - CalcEnergy_dB_G729(PPtr, FRM_LEN);
980 
981     /* Choose: backward/forward mode.*/
982     /* 1st criterion with prediction gains. The global stationarity index
983          is used to adapt the threshold value " GAP ".*/
984 
985     /* Do the threshold adaptation according to the global stationarity indicator */
986     fGap = (Ipp32f)(encoderObj->sGlobalStatInd) * GAP_FACT;
987     fGap += 1.f;
988 
989     if ( (intBackwardPredGain > forwardPredGain - fGap)&& (backwardPredGain > forwardPredGain - fGap)&&
990          (backwardPredGain > 0.f)               && (intBackwardPredGain > 0.f) ) *pDstLPCMode = 1;
991     else *pDstLPCMode = 0;
992 
993     if (encoderObj->sGlobalStatInd < 13000) *pDstLPCMode = 0; /* => Forward mode imposed */
994 
995     /* 2nd criterion with a distance between 2 successive LSP vectors */
996     /* Computation of the LPC distance */
997     LSPDist = 0;
998     for(i=0; i<LPC_ORDER; i++){
999         fTmp = encoderObj->OldLSP[i] - pSrcLSP[i];
1000         LSPDist += fTmp * fTmp;
1001     }
1002 
1003     /* Adaptation of the LSPs thresholds */
1004     if (encoderObj->sGlobalStatInd < 32000) {
1005         LSPThreshold = 0.f;
1006     }
1007     else {
1008         LSPThreshold = 0.03f;
1009     }
1010 
1011     /* Switching backward -> forward forbidden in case of a LPC stationnary */
1012     if ((LSPDist < LSPThreshold) &&(*pDstLPCMode == 0)&&(encoderObj->prevLPCMode == 1)
1013          &&(backwardPredGain > 0.f)&&(intBackwardPredGain > 0.f)) {
1014         *pDstLPCMode = 1;
1015     }
1016 
1017     /* Low energy frame => Forward mode chosen */
1018 
1019     if (ener_DB_pSrcSignal < THRES_ENERGY) {
1020         *pDstLPCMode = 0;
1021         if (encoderObj->sGlobalStatInd > 13000) encoderObj->sGlobalStatInd = 13000;
1022     }
1023     else isBackwardModeDominant_G729(&encoderObj->isBWDDominant, *pDstLPCMode,&encoderObj->sBWDFrmCounter,&encoderObj->sFWDFrmCounter);
1024 
1025     /* Adaptation of the global stationarity indicator */
1026     if (ener_DB_pSrcSignal >= THRES_ENERGY) GlobalStationnarityAdaptation_G729E(encoderObj,backwardPredGain, forwardPredGain, *pDstLPCMode);
1027     if(*pDstLPCMode == 0) encoderObj->fInterpolationCoeff = 1.1f;
1028     return;
1029 }
1030 
NormalizedCorrelation(Ipp32f * pSrcExc,Ipp32f * pSrcTargetVector,Ipp32f * pSrcImpulseResponse,Ipp32s len,Ipp32s lagMin,Ipp32s lagMax,Ipp32f * pDstCorr,Ipp32f * pTmpFltPastExc)1031 static void NormalizedCorrelation(Ipp32f *pSrcExc, Ipp32f *pSrcTargetVector, Ipp32f *pSrcImpulseResponse,
1032                                   Ipp32s len, Ipp32s lagMin, Ipp32s lagMax, Ipp32f *pDstCorr, Ipp32f *pTmpFltPastExc)
1033 {
1034    Ipp32s i, k;
1035    Ipp64f dEnergy, dTmp;
1036 
1037    k = -lagMin;
1038 
1039    ippsConvBiased_32f( &pSrcExc[k], len , pSrcImpulseResponse, len ,  pTmpFltPastExc, len ,0);
1040 
1041    /* loop for every possible period */
1042    for (i = lagMin; i < lagMax; i++) {
1043       /* Compute energy of pFltExc[] */
1044       ippsDotProd_32f64f(pTmpFltPastExc, pTmpFltPastExc, len, &dEnergy);
1045 
1046       /* Compute correlation between pSrcTargetVector[] and pFltExc[] */
1047       ippsDotProd_32f64f(pSrcTargetVector, pTmpFltPastExc, len, &dTmp);
1048 
1049       /* Normalize correlation = correlation * (1/sqrt(energy)) */
1050       pDstCorr[i] = (Ipp32f)(dTmp)/((Ipp32f)sqrt(dEnergy+0.01));
1051 
1052       /* modify the filtered excitation pFltExc[] for the next iteration */
1053       k--;
1054       ippsFilteredExcitation_G729_32f( pSrcImpulseResponse, pTmpFltPastExc, len, pSrcExc[k]);
1055    }
1056 
1057    /* Compute energy of pFltExc[] */
1058    ippsDotProd_32f64f(pTmpFltPastExc, pTmpFltPastExc, len, &dEnergy);
1059 
1060    /* Compute correlation between pSrcTargetVector[] and pFltExc[] */
1061    ippsDotProd_32f64f(pSrcTargetVector, pTmpFltPastExc, len, &dTmp);
1062 
1063    /* Normalize correlation = correlation * (1/sqrt(energy)) */
1064    pDstCorr[lagMax] = (Ipp32f)(dTmp)/((Ipp32f)sqrt(dEnergy+0.01));
1065 
1066    return;
1067 
1068 }
1069 
1070 static __ALIGN32 CONST Ipp32f ReorderInter_3[2*3*INTERPOL4_LEN] = {
1071  0.015738f,-0.047624f, 0.084078f, 0.900839f,
1072  0.084078f,-0.047624f, 0.015738f, 0.000000f,
1073  0.000000f, 0.016285f,-0.105570f, 0.760084f,
1074  0.424082f,-0.121120f, 0.031217f,-0.005925f,
1075 -0.005925f, 0.031217f,-0.121120f, 0.424082f,
1076  0.760084f,-0.105570f, 0.016285f, 0.000000f
1077 };
1078 
Interpolation_3(Ipp32f * pSrc,Ipp32s lFrac)1079 static Ipp32f Interpolation_3(Ipp32f *pSrc, Ipp32s lFrac)
1080 {
1081    Ipp32s i;
1082    Ipp32f sum, *x1;
1083    const Ipp32f *c;
1084 
1085    x1 = &pSrc[-(INTERPOL4_LEN-1)];
1086    if (lFrac < 0) {
1087       x1--;
1088       lFrac += UP_SAMPLING;
1089    }
1090    c = &ReorderInter_3[2*INTERPOL4_LEN*lFrac];
1091 
1092    sum = 0.0f;
1093    for(i=0; i< 2*INTERPOL4_LEN; i++)
1094       sum+= x1[i] * c[i];
1095 
1096    return sum;
1097 }
1098 
AdaptiveCodebookSearch_G729_32f(Ipp32f * pSrcExc,Ipp32f * pSrcTargetVector,Ipp32f * pSrcImpulseResponse,Ipp32s len,Ipp32s minLag,Ipp32s maxLag,Ipp32s valSubframeNum,Ipp32s * pDstFracPitch,G729Codec_Type codecType,Ipp32f * pExtBuff)1099 Ipp32s AdaptiveCodebookSearch_G729_32f(Ipp32f *pSrcExc, Ipp32f *pSrcTargetVector, Ipp32f *pSrcImpulseResponse, Ipp32s len,
1100                         Ipp32s minLag, Ipp32s maxLag, Ipp32s valSubframeNum, Ipp32s *pDstFracPitch, G729Codec_Type codecType,Ipp32f *pExtBuff)
1101 {
1102    Ipp32s i, lFracPart;
1103    Ipp32s lBestLag, lMin, lMax;
1104    Ipp32f max;
1105    Ipp32f fIntCorr;
1106    Ipp32f *pFltExc;     /* filtered past excitation */
1107    Ipp32f *pCorr;
1108    Ipp32s midLag;
1109 
1110    pFltExc = &pExtBuff[0];
1111 
1112    /* Find interval to compute normalized correlation */
1113    lMin = minLag - INTERPOL4_LEN;
1114    lMax = maxLag + INTERPOL4_LEN;
1115 
1116    pCorr = &pExtBuff[SUBFR_LEN - lMin]; /*Actually (10+2*INTERPOL4_LEN) from [SUBFR_LEN]. pCorr[lMin:lMax]*/
1117 
1118    /* Compute normalized correlation between target and filtered excitation */
1119    NormalizedCorrelation(pSrcExc, pSrcTargetVector, pSrcImpulseResponse, len, lMin, lMax, pCorr,pFltExc);
1120 
1121    /* find integer pitch */
1122    max = pCorr[minLag];
1123    lBestLag  = minLag;
1124 
1125    for(i= minLag+1; i<=maxLag; i++) {
1126       if( pCorr[i] >= max) {
1127          max = pCorr[i];
1128          lBestLag = i;
1129       }
1130    }
1131 
1132    /* If first subframe and lBestLag > 84 do not search fractionnal pitch */
1133 
1134    if( (valSubframeNum == 0) && (lBestLag > 84) ) {
1135       *pDstFracPitch = 0;
1136       return(lBestLag);
1137    }
1138 
1139    /* test the fractions around lBestLag and choose the one which maximizes the interpolated normalized correlation */
1140 
1141    if (codecType == G729D_CODEC) {    /* 6.4 kbps */
1142       if (valSubframeNum == 0) {
1143          max  = Interpolation_3(&pCorr[lBestLag], -2);
1144          lFracPart = -2;
1145 
1146          for (i = -1; i <= 2; i++) {
1147             fIntCorr = Interpolation_3(&pCorr[lBestLag], i);
1148             if(fIntCorr > max) {
1149                max = fIntCorr;
1150                lFracPart = i;
1151             }
1152          }
1153       } else {
1154          midLag = maxLag - 4;
1155          if ((lBestLag == midLag - 1) || lBestLag == midLag) {
1156             max  = Interpolation_3(&pCorr[lBestLag], -2);
1157             lFracPart = -2;
1158 
1159             for (i = -1; i <= 2; i++) {
1160                fIntCorr = Interpolation_3(&pCorr[lBestLag], i);
1161                if(fIntCorr > max) {
1162                   max = fIntCorr;
1163                   lFracPart = i;
1164                }
1165             }
1166          } else if (lBestLag == midLag - 2) {
1167             max  = Interpolation_3(&pCorr[lBestLag], 0);
1168             lFracPart = 0;
1169 
1170             for (i = 1; i <= 2; i++) {
1171                fIntCorr = Interpolation_3(&pCorr[lBestLag], i);
1172                if(fIntCorr > max) {
1173                   max = fIntCorr;
1174                   lFracPart = i;
1175                }
1176             }
1177          } else if (lBestLag == midLag + 1) {
1178             max  = Interpolation_3(&pCorr[lBestLag], -2);
1179             lFracPart = -2;
1180 
1181             for (i = -1; i <= 0; i++) {
1182                fIntCorr = Interpolation_3(&pCorr[lBestLag], i);
1183                if(fIntCorr > max) {
1184                   max = fIntCorr;
1185                   lFracPart = i;
1186                }
1187             }
1188          } else
1189             lFracPart = 0;
1190       }
1191    } else {
1192       max  = Interpolation_3(&pCorr[lBestLag], -2);
1193       lFracPart = -2;
1194 
1195       for (i = -1; i <= 2; i++) {
1196          fIntCorr = Interpolation_3(&pCorr[lBestLag], i);
1197          if(fIntCorr > max) {
1198             max = fIntCorr;
1199             lFracPart = i;
1200          }
1201       }
1202    }
1203 
1204    /* limit the fraction value in the interval [-1,0,1] */
1205 
1206    if (lFracPart == -2) {
1207       lFracPart = 1;
1208       lBestLag -= 1;
1209    }
1210    if (lFracPart == 2) {
1211       lFracPart = -1;
1212       lBestLag += 1;
1213    }
1214 
1215    *pDstFracPitch = lFracPart;
1216 
1217    return lBestLag;
1218 }
1219 
CNGGetSize(Ipp32s * pDstSize)1220 void CNGGetSize(Ipp32s *pDstSize)
1221 {
1222    *pDstSize = sizeof(CNGmemory);
1223    return;
1224 }
1225 
CNGInit(Ipp8s * cngMem)1226 void CNGInit(Ipp8s *cngMem)
1227 {
1228    CNGmemory *cngState = (CNGmemory *)cngMem;
1229    ippsZero_16s((Ipp16s*)cngState,sizeof(CNGmemory)>>1) ;
1230 
1231    ippsZero_32f(cngState->SumAutoCorrs,SUMAUTOCORRS_SIZE);
1232    ippsZero_32f(cngState->AutoCorrs,AUTOCORRS_SIZE);
1233    ippsZero_32f(cngState->Energies,GAINS_NUM);
1234 
1235    cngState->fCurrGain = 0.;
1236    cngState->lAutoCorrsCounter = 0;
1237    cngState->lFltChangeFlag = 0;
1238 }
1239 
gaussGen(Ipp16s * sCNGSeed)1240 static Ipp32f gaussGen(Ipp16s *sCNGSeed)
1241 {
1242     Ipp32s i, lTmp;
1243 
1244     lTmp = 0;
1245     for(i=0; i<12; i++) {
1246         lTmp += Rand_16s(sCNGSeed);
1247     }
1248     lTmp >>= 7;
1249     return((Ipp32f)lTmp * 0.001953125f);
1250 }
1251 
ComfortNoiseExcitation_G729(Ipp32f fCurrGain,Ipp32f * exc,Ipp16s * sCNGSeed,Ipp32s flag_cod,Ipp32f * ExcitationError,Ipp8s * phdMem,Ipp8s * pExtBuff)1252 void ComfortNoiseExcitation_G729(Ipp32f fCurrGain, Ipp32f *exc, Ipp16s *sCNGSeed, Ipp32s flag_cod, Ipp32f *ExcitationError, Ipp8s *phdMem, Ipp8s *pExtBuff)
1253 {
1254    Ipp32f *pGaussianExc;
1255    Ipp32s   *pos;
1256    Ipp32f *sign;
1257    Ipp32f *CurrentExcitation;
1258    Ipp32f fgp, fEner, fFact, fInterExc, k, discriminant, x1, x2, absMinRoot;
1259    Ipp32s   i, n, pitchDelay, lFrac;
1260    Ipp16s sGp, sTmp1, sTmp2;
1261    Ipp32s *delayLine;
1262    //Ipp64f ener_tmp;
1263 
1264    pGaussianExc = (Ipp32f *)pExtBuff;
1265    pos = (Ipp32s *)(pExtBuff + SUBFR_LEN*sizeof(Ipp32f));
1266    sign = (Ipp32f *)((Ipp8s *)pos + 4*sizeof(Ipp32s));
1267    delayLine = (Ipp32s *)((Ipp8s *)sign + 4*sizeof(Ipp32f));
1268 
1269    /* Loop on subframes */
1270    CurrentExcitation = exc;
1271    for (n = 0;  n < NUN_SUBFRAMES; n++) {
1272       /* Fenerate random adaptive codebook and fixed codebook parameters */
1273       sTmp1   = Rand_16s(sCNGSeed);
1274       lFrac    = (Ipp32s)(sTmp1 & (Ipp16s)0x0003) - 1;
1275       if(lFrac == 2) lFrac = 0;
1276       sTmp1 >>= 2;
1277       pitchDelay      = (Ipp32s)(sTmp1 & (Ipp16s)0x003F) + 40;
1278       sTmp1 >>= 6;
1279       sTmp2   = (Ipp16s)(sTmp1 & (Ipp16s)0x0007);
1280       pos[0]  = 5 * (Ipp32s)sTmp2;
1281       sTmp1 >>= 3;
1282       sTmp2   = (Ipp16s)(sTmp1 & (Ipp16s)0x0001);
1283       sign[0] = 2.f * (Ipp32f)sTmp2 - 1.f;
1284       sTmp1 >>= 1;
1285       sTmp2   = (Ipp16s)(sTmp1 & (Ipp16s)0x0007);
1286       pos[1]  = 5 * (Ipp32s)sTmp2 + 1;
1287       sTmp1 >>= 3;
1288       sTmp2   = (Ipp16s)(sTmp1 & (Ipp16s)0x0001);
1289       sign[1] = 2.f * (Ipp32f)sTmp2 - 1.f;
1290       sTmp1   = Rand_16s(sCNGSeed);
1291       sTmp2   = (Ipp16s)(sTmp1 & (Ipp16s)0x0007);
1292       pos[2]  = 5 * (Ipp32s)sTmp2 + 1;
1293       sTmp1 >>= 3;
1294       sTmp2   = (Ipp16s)(sTmp1 & (Ipp16s)0x0001);
1295       sign[2] = 2.f * (Ipp32f)sTmp2 - 1.f;
1296       sTmp1 >>= 1;
1297       sTmp2   = (Ipp16s)(sTmp1 & (Ipp16s)0x000F);
1298       pos[3]  = (Ipp32s)(sTmp2 & (Ipp16s)0x0001) + 3; /* j+3*/
1299       sTmp2 >>= 1;
1300       sTmp2  &= (Ipp16s)0x0007;
1301       pos[3] += 5 * (Ipp32s)sTmp2;
1302       sTmp1 >>= 4;
1303       sTmp2   = (Ipp16s)(sTmp1 & (Ipp16s)0x0001);
1304       sign[3] = 2.f * (Ipp32f)sTmp2 - 1.f;
1305       sGp      = (Ipp16s)(Rand_16s(sCNGSeed) & (Ipp16s)0x1FFF); /* < 0.5  */
1306       fgp      = (Ipp32f)sGp / 16384.f;
1307 
1308       /* Generate gaussian excitation */
1309       /*ippsRandomNoiseExcitation_G729B_16s32f(sCNGSeed, excg, SUBFR_LEN);
1310       ippsDotProd_32f64f(excg, excg, SUBFR_LEN,&ener_tmp);*/
1311       fEner = 0.f;
1312       for(i=0; i<SUBFR_LEN; i++) {
1313          pGaussianExc[i] = gaussGen(sCNGSeed);
1314          fEner += pGaussianExc[i] * pGaussianExc[i];
1315       }
1316 
1317       /*  Compute fFact = 0.5 x fCurrGain * sqrt(40 / fEner) */
1318       fFact = NORM_GAUSS * fCurrGain;
1319       fFact /= (Ipp32f)sqrt(fEner);
1320       /* Multiply excg by fFact */
1321       for(i=0; i<SUBFR_LEN; i++) {
1322          pGaussianExc[i] *= fFact;
1323       }
1324       //ippsMulC_32f_I(fFact, excg, SUBFR_LEN);
1325 
1326       /* generate random  adaptive excitation */
1327       delayLine[0] = pitchDelay;
1328       delayLine[1] = lFrac;
1329       ippsDecodeAdaptiveVector_G729_32f_I(delayLine, CurrentExcitation);
1330 
1331       /* CurrentExcitation is an adaptive + gaussian excitation */
1332       fEner = 0.f;
1333       for(i=0; i<SUBFR_LEN; i++) {
1334          CurrentExcitation[i] *= fgp;
1335          CurrentExcitation[i] += pGaussianExc[i];
1336          fEner += CurrentExcitation[i] * CurrentExcitation[i];
1337       }
1338       /* Compute fixed code gain */
1339       /* Solve EQ(X) = 4 X**2 + 2 b X + c, where b = fInterExc*/
1340       fInterExc = 0.f;
1341       for(i=0; i<4; i++) {
1342          fInterExc += CurrentExcitation[pos[i]] * sign[i];
1343       }
1344 
1345       /* Compute k = fCurrGain x fCurrGain x SUBFR_LEN */
1346       k = fCurrGain * fCurrGain * SUBFR_LEN;
1347 
1348       /* Compute discriminant = b^2 - 4*c, where c=fEner-k*/
1349       discriminant = fInterExc * fInterExc - 4.f * (fEner - k);
1350 
1351       if(discriminant < 0.f) {
1352          /* adaptive excitation = 0 */
1353          ippsCopy_32f(pGaussianExc, CurrentExcitation, SUBFR_LEN);
1354          fInterExc = 0.f;
1355          for(i=0; i<4; i++) {
1356             fInterExc += CurrentExcitation[pos[i]] * sign[i];
1357          }
1358          /* Compute discriminant = b^2 - 4*c, where c = - k x (1- alpha^2)*/
1359          discriminant = fInterExc * fInterExc + K_MUL_COEFF * k;
1360          fgp = 0.f;
1361       }
1362 
1363       discriminant = (Ipp32f)sqrt(discriminant);
1364       /* First root*/
1365       x1 = (discriminant - fInterExc) * 0.25f;
1366       /* Second root*/
1367       x2 = - (discriminant + fInterExc) * 0.25f;
1368       absMinRoot = ((Ipp32f)fabs(x1) < (Ipp32f)fabs(x2)) ? x1 : x2;
1369       if(absMinRoot >= 0.f) {
1370          CLIP_TO_UPLEVEL(absMinRoot,CNG_MAX_GAIN);
1371       } else {
1372          CLIP_TO_LOWLEVEL(absMinRoot,(-CNG_MAX_GAIN));
1373       }
1374 
1375       /* Update cur_exc with ACELP excitation */
1376       for(i=0; i<4; i++) {
1377          CurrentExcitation[pos[i]] += absMinRoot * sign[i];
1378       }
1379 
1380       if(flag_cod != DECODER) UpdateExcErr_G729(fgp, pitchDelay,ExcitationError);
1381       else {
1382          if(absMinRoot >= 0.f) PhaseDispersionUpdate_G729D(fgp,absMinRoot,phdMem);
1383          else PhaseDispersionUpdate_G729D(fgp,-absMinRoot,phdMem);
1384       }
1385       CurrentExcitation += SUBFR_LEN;
1386    } /* end of loop on subframes */
1387 
1388    return;
1389 }
1390 
1391 
1392 
1393 static __ALIGN32 CONST Ipp32f fFact[GAINS_NUM+1] =
1394         {(Ipp32f)0.003125, (Ipp32f)0.00078125, (Ipp32f)0.000390625};
1395 
quantEnergy(Ipp32f fEner,Ipp32f * pDstQEnergy)1396 static Ipp32s quantEnergy(Ipp32f fEner, Ipp32f *pDstQEnergy)
1397 {
1398     Ipp32f fEnergydB;
1399     Ipp32s index;
1400 
1401     if(fEner <= MIN_ENER) {  /* MIN_ENER <=> -8dB */
1402         *pDstQEnergy = (Ipp32f)-12.;
1403         return(0);
1404     }
1405 
1406     fEnergydB = (Ipp32f)10. * (Ipp32f)log10(fEner);
1407 
1408     if(fEnergydB <= (Ipp32f)-8.) {
1409         *pDstQEnergy = (Ipp32f)-12.;
1410         return(0);
1411     }
1412 
1413     if(fEnergydB >= (Ipp32f)65.) {
1414         *pDstQEnergy = (Ipp32f)66.;
1415         return(31);
1416     }
1417 
1418     if(fEnergydB <= (Ipp32f)14.) {
1419         index = (Ipp32s)((fEnergydB + (Ipp32f)10.) * 0.25);
1420         if (index < 1) index = 1;
1421         *pDstQEnergy = (Ipp32f)4. * (Ipp32f)index - (Ipp32f)8.;
1422         return(index);
1423     }
1424 
1425     index = (Ipp32s)((fEnergydB - (Ipp32f)3.) * 0.5);
1426     if (index < 6) index = 6;
1427     *pDstQEnergy = (Ipp32f)2. * (Ipp32f)index + (Ipp32f)4.;
1428     return(index);
1429 }
1430 
QuantSIDGain_G729B(Ipp32f * fEner,Ipp32s lNumSavedEnergies,Ipp32f * enerq,Ipp32s * idx)1431 void QuantSIDGain_G729B(Ipp32f *fEner, Ipp32s lNumSavedEnergies, Ipp32f *enerq, Ipp32s *idx)
1432 {
1433     Ipp32s i;
1434     Ipp32f averageEnergy;
1435 
1436     /* Quantize energy saved for frame erasure case*/
1437     if(lNumSavedEnergies == 0) {
1438         averageEnergy = (*fEner) * fFact[0];
1439     } else {
1440         /* Compute weighted average of energies*/
1441         averageEnergy = (Ipp32f)0.;
1442         for(i=0; i<lNumSavedEnergies; i++) {
1443             averageEnergy += fEner[i];
1444         }
1445         averageEnergy *= fFact[lNumSavedEnergies];
1446     }
1447 
1448     *idx = quantEnergy(averageEnergy, enerq);
1449 
1450     return;
1451 }
1452 
1453 static __ALIGN32 CONST Ipp32f coef_G729[2][2] = {
1454 {(Ipp32f)31.134575,
1455 (Ipp32f) 1.612322},
1456 
1457 {(Ipp32f) 0.481389,
1458 (Ipp32f) 0.053056}
1459 };
1460 
1461 static __ALIGN32 CONST Ipp32f thr1_G729[SIZECODEBOOK1-NUM_CAND1] = {
1462 (Ipp32f)0.659681,
1463 (Ipp32f)0.755274,
1464 (Ipp32f)1.207205,
1465 (Ipp32f)1.987740
1466 };
1467 
1468 static __ALIGN32 CONST Ipp32f thr2_G729[SIZECODEBOOK2-NUM_CAND2] = {
1469 (Ipp32f)0.429912,
1470 (Ipp32f)0.494045,
1471 (Ipp32f)0.618737,
1472 (Ipp32f)0.650676,
1473 (Ipp32f)0.717949,
1474 (Ipp32f)0.770050,
1475 (Ipp32f)0.850628,
1476 (Ipp32f)0.932089
1477 };
1478 
1479 static __ALIGN32 CONST Ipp32s map1_G729[SIZECODEBOOK1] = {
1480  5, 1, 4, 7, 3, 0, 6, 2};
1481 
1482 static __ALIGN32 CONST Ipp32s map2_G729[SIZECODEBOOK2] = {
1483  4, 6, 0, 2,12,14, 8,10,15,11, 9,13, 7, 3, 1, 5};
1484 
1485 static __ALIGN32 CONST Ipp32s imap1_G729[SIZECODEBOOK1] = {
1486  5, 1, 7, 4, 2, 0, 6, 3};
1487 static __ALIGN32 CONST Ipp32s imap2_G729[SIZECODEBOOK2] = {
1488  2,14, 3,13, 0,15, 1,12, 6,10, 7, 9, 4,11, 5, 8};
1489 
1490 static __ALIGN32 CONST Ipp32f gbk1_G729[SIZECODEBOOK1][2] = {
1491 {0.000010f, 0.185084f},
1492 {0.094719f, 0.296035f},
1493 {0.111779f, 0.613122f},
1494 {0.003516f, 0.659780f},
1495 {0.117258f, 1.134277f},
1496 {0.197901f, 1.214512f},
1497 {0.021772f, 1.801288f},
1498 {0.163457f, 3.315700f}};
1499 
1500 static __ALIGN32 CONST Ipp32f gbk2_G729[SIZECODEBOOK2][2] = {
1501 {0.050466f, 0.244769f},
1502 {0.121711f, 0.000010f},
1503 {0.313871f, 0.072357f},
1504 {0.375977f, 0.292399f},
1505 {0.493870f, 0.593410f},
1506 {0.556641f, 0.064087f},
1507 {0.645363f, 0.362118f},
1508 {0.706138f, 0.146110f},
1509 {0.809357f, 0.397579f},
1510 {0.866379f, 0.199087f},
1511 {0.923602f, 0.599938f},
1512 {0.925376f, 1.742757f},
1513 {0.942028f, 0.029027f},
1514 {0.983459f, 0.414166f},
1515 {1.055892f, 0.227186f},
1516 {1.158039f, 0.724592f}};
1517 
1518 static __ALIGN32 CONST Ipp32f coef_G729D[2][2] = {
1519 { 36.632507f, 2.514171f},
1520 {  0.399259f, 0.073709f}
1521 };
1522 
1523 static __ALIGN32 CONST Ipp32f thr1_G729D[SIZECODEBOOK1_ANNEXD-NUM_CAND1_ANNEXD] = {
1524   1.210869f,
1525   2.401702f
1526 };
1527 
1528 static __ALIGN32 CONST Ipp32f thr2_G729D[SIZECODEBOOK2_ANNEXD-NUM_CAND2_ANNEXD] = {
1529   0.525915f,
1530   0.767320f
1531 };
1532 
1533 static __ALIGN32 CONST Ipp32s map1_G729D[SIZECODEBOOK1_ANNEXD] = { 0, 4, 6, 5, 2, 1, 7, 3 };
1534 
1535 static __ALIGN32 CONST Ipp32s map2_G729D[SIZECODEBOOK2_ANNEXD] = { 0, 4, 3, 7, 5, 1, 6, 2 };
1536 
1537 static __ALIGN32 CONST Ipp32s imap1_G729D[SIZECODEBOOK1_ANNEXD] = { 0, 5, 4, 7, 1, 3, 2, 6 };
1538 
1539 
1540 
1541 static __ALIGN32 CONST Ipp32s imap2_G729D[SIZECODEBOOK2_ANNEXD] = { 0, 5, 7, 2, 1, 4, 6, 3 };
1542 
1543 
1544 static __ALIGN32 CONST Ipp32f gbk1_G729D[SIZECODEBOOK1_ANNEXD][2] = {
1545 { 0.357003f, 0.00000f},
1546 { 0.178752f, 0.065771f},
1547 { 0.575276f, 0.166704f},
1548 { 0.370335f, 0.371903f},
1549 { 0.220734f, 0.411803f},
1550 { 0.193548f, 0.566385f},
1551 { 0.238962f, 0.785625f},
1552 { 0.304379f, 1.360714f}
1553 };
1554 static __ALIGN32 CONST Ipp32f gbk2_G729D[SIZECODEBOOK2_ANNEXD][2] = {
1555 { 0.00000f, 0.254841f},
1556 { 0.243384f, 0.00000f},
1557 { 0.273293f, 0.447009f},
1558 { 0.480707f, 0.477384f},
1559 { 0.628117f, 0.694884f},
1560 { 0.660905f, 1.684719f},
1561 { 0.729735f, 0.655223f},
1562 { 1.002375f, 0.959743f}
1563 };
1564 
1565 static __ALIGN32 CONST Ipp32f PredCoeff[4] = {
1566 (Ipp32f)0.68,
1567 (Ipp32f)0.58,
1568 (Ipp32f)0.34,
1569 (Ipp32f)0.19
1570 };
1571 
GainCodebookPreselect_G729D(Ipp32f * pBestGains,Ipp32s * pCand,Ipp32f fGainCode)1572 static void   GainCodebookPreselect_G729D(Ipp32f *pBestGains, Ipp32s *pCand, Ipp32f fGainCode)
1573 {
1574     Ipp32f   x,y ;
1575 
1576     x = (pBestGains[1]-(coef_G729D[0][0]*pBestGains[0]+coef_G729D[1][1])*fGainCode) * INV_COEF_ANNEXD ;
1577     y = (coef_G729D[1][0]*(-coef_G729D[0][1]+pBestGains[0]*coef_G729D[0][0])*fGainCode
1578         -coef_G729D[0][0]*pBestGains[1]) * INV_COEF_ANNEXD ;
1579 
1580     if(fGainCode>(Ipp32f)0.0){
1581         /* pre select first index */
1582         pCand[0] = 0 ;
1583         do{
1584             if(y>thr1_G729D[pCand[0]]*fGainCode) (pCand[0])++ ;
1585             else               break ;
1586         } while((pCand[0])<(SIZECODEBOOK1_ANNEXD-NUM_CAND1_ANNEXD)) ;
1587         /* pre select second index */
1588         pCand[1] = 0 ;
1589         do{
1590             if(x>thr2_G729D[pCand[1]]*fGainCode) (pCand[1])++ ;
1591             else               break ;
1592         } while((pCand[1])<(SIZECODEBOOK2_ANNEXD-NUM_CAND2_ANNEXD)) ;
1593     }
1594     else{
1595         /* pre select first index */
1596         pCand[0] = 0 ;
1597         do{
1598             if(y<thr1_G729D[pCand[0]]*fGainCode) (pCand[0])++ ;
1599             else               break ;
1600         } while((pCand[0])<(SIZECODEBOOK1_ANNEXD-NUM_CAND1_ANNEXD)) ;
1601         /* pre select second index */
1602         pCand[1] = 0 ;
1603         do{
1604             if(x<thr2_G729D[pCand[1]]*fGainCode) (pCand[1])++ ;
1605             else               break ;
1606         } while((pCand[1])<(SIZECODEBOOK2_ANNEXD-NUM_CAND2_ANNEXD)) ;
1607     }
1608 
1609     return ;
1610 }
1611 
GainCodebookPreselect_G729(Ipp32f * pBestGains,Ipp32s * pCand,Ipp32f fGainCode)1612 static void   GainCodebookPreselect_G729(Ipp32f *pBestGains, Ipp32s *pCand, Ipp32f fGainCode)
1613 {
1614     Ipp32f   x,y ;
1615 
1616     x = (pBestGains[1]-(coef_G729[0][0]*pBestGains[0]+coef_G729[1][1])*fGainCode) * INV_COEF_BASE ;
1617     y = (coef_G729[1][0]*(-coef_G729[0][1]+pBestGains[0]*coef_G729[0][0])*fGainCode
1618         -coef_G729[0][0]*pBestGains[1]) * INV_COEF_BASE ;
1619 
1620     if(fGainCode>(Ipp32f)0.0){
1621         /* pre select first index */
1622         pCand[0] = 0 ;
1623         do{
1624             if(y>thr1_G729[pCand[0]]*fGainCode) (pCand[0])++ ;
1625             else               break ;
1626         } while((pCand[0])<(SIZECODEBOOK1-NUM_CAND1)) ;
1627         /* pre select second index */
1628         pCand[1] = 0 ;
1629         do{
1630             if(x>thr2_G729[pCand[1]]*fGainCode) (pCand[1])++ ;
1631             else               break ;
1632         } while((pCand[1])<(SIZECODEBOOK2-NUM_CAND2)) ;
1633     }
1634     else{
1635         /* pre select first index */
1636         pCand[0] = 0 ;
1637         do{
1638             if(y<thr1_G729[pCand[0]]*fGainCode) (pCand[0])++ ;
1639             else               break ;
1640         } while((pCand[0])<(SIZECODEBOOK1-NUM_CAND1)) ;
1641         /* pre select second index */
1642         pCand[1] = 0 ;
1643         do{
1644             if(x<thr2_G729[pCand[1]]*fGainCode) (pCand[1])++ ;
1645             else               break ;
1646         } while((pCand[1])<(SIZECODEBOOK2-NUM_CAND2)) ;
1647     }
1648 
1649     return ;
1650 }
1651 
GainUpdate_G729_32f(Ipp32f * pastQntEnergies,Ipp32f fGainCode)1652 static void GainUpdate_G729_32f(Ipp32f *pastQntEnergies, Ipp32f fGainCode)
1653 {
1654     Ipp32s j;
1655 
1656     /* update table of past quantized energies */
1657     for (j = 3; j > 0; j--)
1658         pastQntEnergies[j] = pastQntEnergies[j-1];
1659     pastQntEnergies[0] = (Ipp32f)20.0*(Ipp32f)log10((Ipp64f)fGainCode);
1660 
1661     return;
1662 }
1663 
GainPredict_G729_32f(Ipp32f * pastQntEnr,Ipp32f * FixedCodebookExc,Ipp32s len,Ipp32f * fGainCode)1664 static void GainPredict_G729_32f(Ipp32f *pastQntEnr, Ipp32f *FixedCodebookExc, Ipp32s len,Ipp32f *fGainCode)
1665 {
1666     Ipp32f fEnergy, predCodeboookGain;
1667     Ipp32s i;
1668     Ipp64f dTmp;
1669 
1670     predCodeboookGain = MEAN_ENER ;
1671 
1672     /* innovation energy */
1673     ippsDotProd_32f64f(FixedCodebookExc, FixedCodebookExc, len, &dTmp);
1674     fEnergy = (Ipp32f)dTmp+0.01f;
1675 
1676     fEnergy = (Ipp32f)10.0 * (Ipp32f)log10(fEnergy /(Ipp32f)len);
1677 
1678     predCodeboookGain -= fEnergy;
1679 
1680     /* predicted energy */
1681     for (i=0; i<4; i++) predCodeboookGain += PredCoeff[i]*pastQntEnr[i];
1682 
1683     /* predicted codebook gain */
1684     *fGainCode = predCodeboookGain;
1685     *fGainCode = (Ipp32f)pow((Ipp64f)10.0,(Ipp64f)(*fGainCode/20.0));   /* predicted gain */
1686 
1687     return;
1688 }
1689 
GainQuant_G729(Ipp32f * FixedCodebookExc,Ipp32f * pGainCoeff,Ipp32s lSbfrLen,Ipp32f * pitchGain,Ipp32f * codeGain,Ipp32s tamingflag,Ipp32f * PastQuantEnergy,G729Codec_Type codecType,Ipp8s * pExtBuff)1690 Ipp32s GainQuant_G729(Ipp32f *FixedCodebookExc, Ipp32f *pGainCoeff, Ipp32s lSbfrLen, Ipp32f *pitchGain, Ipp32f *codeGain,
1691                      Ipp32s tamingflag, Ipp32f *PastQuantEnergy, G729Codec_Type codecType,Ipp8s *pExtBuff)
1692 {
1693     Ipp32s *pCand,*index;
1694     Ipp32f fGainCode ;
1695     Ipp32f *pBestGain,fTmp;
1696     Ipp64f dGainCode;
1697     Ipp32s lQIndex;
1698 
1699     pBestGain = (Ipp32f *)pExtBuff;
1700     pCand = (Ipp32s *)(pExtBuff + 2*sizeof(Ipp32f));
1701     index = (Ipp32s *)((Ipp8s *)pCand + 2*sizeof(Ipp32s));
1702 
1703     GainPredict_G729_32f( PastQuantEnergy, FixedCodebookExc, lSbfrLen, &fGainCode);
1704 
1705     /*-- pre-selection --*/
1706     fTmp = (Ipp32f)-1./((Ipp32f)4.*pGainCoeff[0]*pGainCoeff[2]-pGainCoeff[4]*pGainCoeff[4]) ;
1707     pBestGain[0] = ((Ipp32f)2.*pGainCoeff[2]*pGainCoeff[1]-pGainCoeff[3]*pGainCoeff[4])*fTmp ;
1708     pBestGain[1] = ((Ipp32f)2.*pGainCoeff[0]*pGainCoeff[3]-pGainCoeff[1]*pGainCoeff[4])*fTmp ;
1709 
1710     if (tamingflag == 1){
1711        CLIP_TO_UPLEVEL(pBestGain[0],MAX_GAIN_TIMING2);
1712     }
1713     /* Presearch for gain codebook */
1714     if(codecType==G729D_CODEC) {
1715       GainCodebookPreselect_G729D(pBestGain,pCand,fGainCode) ;
1716 
1717       ippsGainCodebookSearch_G729D_32f(pGainCoeff, fGainCode, pCand, index, tamingflag);
1718 
1719       *pitchGain  = gbk1_G729D[index[0]][0]+gbk2_G729D[index[1]][0] ;
1720       dGainCode = (Ipp64f)(gbk1_G729D[index[0]][1]+gbk2_G729D[index[1]][1]);
1721 
1722       *codeGain =  (Ipp32f)(dGainCode) * fGainCode;
1723 
1724       if(dGainCode < 0.2) dGainCode = 0.2;
1725 
1726       lQIndex = map1_G729D[index[0]]*SIZECODEBOOK2_ANNEXD+map2_G729D[index[1]];
1727     } else {
1728       GainCodebookPreselect_G729(pBestGain,pCand,fGainCode) ;
1729 
1730       ippsGainCodebookSearch_G729_32f(pGainCoeff, fGainCode, pCand, index, tamingflag);
1731 
1732       *pitchGain  = gbk1_G729[index[0]][0]+gbk2_G729[index[1]][0] ;
1733       dGainCode = (Ipp64f)(gbk1_G729[index[0]][1]+gbk2_G729[index[1]][1]);
1734       *codeGain =  (Ipp32f)(dGainCode) * fGainCode;
1735 
1736       lQIndex = map1_G729[index[0]]*SIZECODEBOOK2+map2_G729[index[1]];
1737     }
1738     /* Update table of past quantized energies */
1739     GainUpdate_G729_32f( PastQuantEnergy, (Ipp32f)dGainCode);
1740 
1741     return lQIndex;
1742 }
1743 
DecodeGain_G729(Ipp32s index,Ipp32f * FixedCodebookExc,Ipp32s lSbfrLen,Ipp32f * pitchGain,Ipp32f * codeGain,Ipp32s rate,Ipp32f * PastQuantEnergy)1744 void DecodeGain_G729(Ipp32s index, Ipp32f *FixedCodebookExc, Ipp32s lSbfrLen, Ipp32f *pitchGain, Ipp32f *codeGain, Ipp32s rate, Ipp32f *PastQuantEnergy)
1745 {
1746 
1747 
1748     Ipp32s idxs[2];
1749     Ipp32f fGainCode;
1750     Ipp64f dGainCode;
1751 
1752     GainPredict_G729_32f( PastQuantEnergy, FixedCodebookExc, lSbfrLen, &fGainCode);
1753 
1754     /* Decode pitch and codebook gain. */
1755 
1756     if(rate==G729D_MODE) {
1757        idxs[0] = imap1_G729D[index>>NCODE2_B_ANNEXD] ;
1758        idxs[1] = imap2_G729D[index & (SIZECODEBOOK2_ANNEXD-1)] ;
1759 
1760        *pitchGain = gbk1_G729D[idxs[0]][0]+gbk2_G729D[idxs[1]][0];
1761        dGainCode = (Ipp64f)gbk1_G729D[idxs[0]][1]+gbk2_G729D[idxs[1]][1];
1762 
1763        *codeGain =  (Ipp32f)(dGainCode) * fGainCode;
1764 
1765        if(dGainCode < 0.2) dGainCode = 0.2;
1766     } else {
1767        idxs[0] = imap1_G729[index>>NCODE2_BITS] ;
1768        idxs[1] = imap2_G729[index & (SIZECODEBOOK2-1)] ;
1769 
1770        *pitchGain = gbk1_G729[idxs[0]][0]+gbk2_G729[idxs[1]][0];
1771        dGainCode = (Ipp64f)gbk1_G729[idxs[0]][1]+gbk2_G729[idxs[1]][1];
1772 
1773        *codeGain =  (Ipp32f) (dGainCode * fGainCode);
1774     }
1775 
1776     /* Update table of past quantized energies */
1777     GainUpdate_G729_32f( PastQuantEnergy, (Ipp32f)dGainCode);
1778 
1779     return;
1780 }
1781 
PSTGetSize(Ipp32s * pDstSize)1782 void PSTGetSize(Ipp32s *pDstSize)
1783 {
1784    *pDstSize = sizeof(PSTmemory);
1785    return;
1786 }
1787 
PSTInit(Ipp8s * pstMem)1788 void PSTInit(Ipp8s *pstMem)
1789 {
1790    PSTmemory *pstState = (PSTmemory *)pstMem;
1791 
1792    ippsZero_32f(pstState->ResidualMemory,RESISDUAL_MEMORY);
1793    ippsZero_32f(pstState->STPMemory,BWD_LPC_ORDER);
1794    ippsZero_32f(pstState->STPNumCoeff,SHORTTERM_POSTFLT_LEN_E);
1795    ippsZero_32f(pstState->ZeroMemory,BWD_LPC_ORDER);
1796 
1797    pstState->gainPrec = 1.;
1798 }
1799 
1800 static __ALIGN32 CONST Ipp32f STPTbl[SIZE_SHORT_INT_FLT_MEMORY] = {
1801 (Ipp32f) -0.005772, (Ipp32f)  0.087669, (Ipp32f)  0.965882, (Ipp32f) -0.048753,
1802 (Ipp32f) -0.014793, (Ipp32f)  0.214886, (Ipp32f)  0.868791, (Ipp32f) -0.065537,
1803 (Ipp32f) -0.028507, (Ipp32f)  0.374334, (Ipp32f)  0.723418, (Ipp32f) -0.060834,
1804 (Ipp32f) -0.045567, (Ipp32f)  0.550847, (Ipp32f)  0.550847, (Ipp32f) -0.045567,
1805 (Ipp32f) -0.060834, (Ipp32f)  0.723418, (Ipp32f)  0.374334, (Ipp32f) -0.028507,
1806 (Ipp32f) -0.065537, (Ipp32f)  0.868791, (Ipp32f)  0.214886, (Ipp32f) -0.014793,
1807 (Ipp32f) -0.048753, (Ipp32f)  0.965882, (Ipp32f)  0.087669, (Ipp32f) -0.005772};
1808 
1809 static __ALIGN32 CONST Ipp32f LTPTbl[SIZE_LONG_INT_FLT_MEMORY] = {
1810 (Ipp32f) -0.001246, (Ipp32f)  0.002200, (Ipp32f) -0.004791, (Ipp32f)  0.009621,
1811 (Ipp32f) -0.017685, (Ipp32f)  0.031212, (Ipp32f) -0.057225, (Ipp32f)  0.135470,
1812 (Ipp32f)  0.973955, (Ipp32f) -0.103495, (Ipp32f)  0.048663, (Ipp32f) -0.027090,
1813 (Ipp32f)  0.015280, (Ipp32f) -0.008160, (Ipp32f)  0.003961, (Ipp32f) -0.001827,
1814 (Ipp32f) -0.002388, (Ipp32f)  0.004479, (Ipp32f) -0.009715, (Ipp32f)  0.019261,
1815 (Ipp32f) -0.035118, (Ipp32f)  0.061945, (Ipp32f) -0.115187, (Ipp32f)  0.294161,
1816 (Ipp32f)  0.898322, (Ipp32f) -0.170283, (Ipp32f)  0.083211, (Ipp32f) -0.046645,
1817 (Ipp32f)  0.026210, (Ipp32f) -0.013854, (Ipp32f)  0.006641, (Ipp32f) -0.003099,
1818 (Ipp32f) -0.003277, (Ipp32f)  0.006456, (Ipp32f) -0.013906, (Ipp32f)  0.027229,
1819 (Ipp32f) -0.049283, (Ipp32f)  0.086990, (Ipp32f) -0.164590, (Ipp32f)  0.464041,
1820 (Ipp32f)  0.780309, (Ipp32f) -0.199879, (Ipp32f)  0.100795, (Ipp32f) -0.056792,
1821 (Ipp32f)  0.031761, (Ipp32f) -0.016606, (Ipp32f)  0.007866, (Ipp32f) -0.003740,
1822 (Ipp32f) -0.003770, (Ipp32f)  0.007714, (Ipp32f) -0.016462, (Ipp32f)  0.031849,
1823 (Ipp32f) -0.057272, (Ipp32f)  0.101294, (Ipp32f) -0.195755, (Ipp32f)  0.630993,
1824 (Ipp32f)  0.630993, (Ipp32f) -0.195755, (Ipp32f)  0.101294, (Ipp32f) -0.057272,
1825 (Ipp32f)  0.031849, (Ipp32f) -0.016462, (Ipp32f)  0.007714, (Ipp32f) -0.003770,
1826 (Ipp32f) -0.003740, (Ipp32f)  0.007866, (Ipp32f) -0.016606, (Ipp32f)  0.031761,
1827 (Ipp32f) -0.056792, (Ipp32f)  0.100795, (Ipp32f) -0.199879, (Ipp32f)  0.780309,
1828 (Ipp32f)  0.464041, (Ipp32f) -0.164590, (Ipp32f)  0.086990, (Ipp32f) -0.049283,
1829 (Ipp32f)  0.027229, (Ipp32f) -0.013906, (Ipp32f)  0.006456, (Ipp32f) -0.003277,
1830 (Ipp32f) -0.003099, (Ipp32f)  0.006641, (Ipp32f) -0.013854, (Ipp32f)  0.026210,
1831 (Ipp32f) -0.046645, (Ipp32f)  0.083211, (Ipp32f) -0.170283, (Ipp32f)  0.898322,
1832 (Ipp32f)  0.294161, (Ipp32f) -0.115187, (Ipp32f)  0.061945, (Ipp32f) -0.035118,
1833 (Ipp32f)  0.019261, (Ipp32f) -0.009715, (Ipp32f)  0.004479, (Ipp32f) -0.002388,
1834 (Ipp32f) -0.001827, (Ipp32f)  0.003961, (Ipp32f) -0.008160, (Ipp32f)  0.015280,
1835 (Ipp32f) -0.027090, (Ipp32f)  0.048663, (Ipp32f) -0.103495, (Ipp32f)  0.973955,
1836 (Ipp32f)  0.135470, (Ipp32f) -0.057225, (Ipp32f)  0.031212, (Ipp32f) -0.017685,
1837 (Ipp32f)  0.009621, (Ipp32f) -0.004791, (Ipp32f)  0.002200, (Ipp32f) -0.001246
1838 };
1839 
1840 static void HarmonicPostFilter_G729_32f(Ipp32s valPitchDelay, Ipp32f *pSrc, Ipp32f *pDst,
1841                            Ipp32s *isVoiced, Ipp32f valHarmonicCoeff, Ipp32f *mem);
1842 static void SearchDelay(Ipp32s valPitchDelay, Ipp32f *pSrcSignal, Ipp32s *LTPDelay, Ipp32s *lPhase,
1843                        Ipp32f *LTPGainNumerator, Ipp32f *LTPGainDemerator, Ipp32f *pSignal, Ipp32s *lOffset, Ipp32f *mem);
1844 static void HarmonicFilter_G729_32f(Ipp32f *pSrcSignal, Ipp32f *pSrcFltSignal, Ipp32f *pDstSignal, Ipp32f valFltGain);
1845 static void TiltCompensation_G729_32f(Ipp32f *pSrcSignal, Ipp32f *pDstSignal, Ipp32f val);
1846 static void Calc1stParcor(Ipp32f *pSrcImpulseResponse, Ipp32f *pDstPartialCorrCoeff, Ipp32s len);
1847 static void GainControl_G729(Ipp32f *pSrcSignal, Ipp32f *pDstSignal, Ipp32f *pSrcDstGain, Ipp32f *mem);
1848 
Post_G729E(G729FPDecoder_Obj * decoderObj,Ipp32s pitchDelay,Ipp32f * pSignal,Ipp32f * pLPC,Ipp32f * pDstFltSignal,Ipp32s * pVoicing,Ipp32s len,Ipp32s lenLPC,Ipp32s Vad)1849 void Post_G729E(G729FPDecoder_Obj *decoderObj, Ipp32s pitchDelay, Ipp32f *pSignal, Ipp32f *pLPC, Ipp32f *pDstFltSignal, Ipp32s *pVoicing,
1850                Ipp32s len, Ipp32s lenLPC, Ipp32s Vad)
1851 {
1852     LOCAL_ALIGN_ARRAY(32, Ipp32f, STPDenCoeff, BWD_LPC_ORDERP1,decoderObj);
1853     LOCAL_ALIGN_ARRAY(32, Ipp32f, LTPSignal, SUBFR_LENP1,decoderObj);
1854     LOCAL_ALIGN_ARRAY(32, Ipp32f, mem,SIZE_SEARCH_DEL_MEMORY+2*(FRAC_DELAY_RES-1),decoderObj);
1855     Ipp32f *pLTPSignal;
1856     Ipp32f f1stParcor,fG0, fTmp;
1857     Ipp32f *pResidual;
1858     Ipp32f *pSTPMemory;
1859     Ipp32s i;
1860     PSTmemory *pstState = (PSTmemory *)decoderObj->pstMem;
1861 
1862     pResidual = pstState->ResidualMemory + RESISDUAL_MEMORY;
1863     pSTPMemory = pstState->STPMemory + BWD_LPC_ORDER - 1;
1864 
1865     /* Compute weighted LPC coefficients */
1866     WeightLPCCoeff_G729(pLPC, decoderObj->g1PST, lenLPC, STPDenCoeff);
1867     WeightLPCCoeff_G729(pLPC, decoderObj->g2PST, lenLPC, pstState->STPNumCoeff);
1868     ippsZero_32f(&pstState->STPNumCoeff[lenLPC+1], (BWD_LPC_ORDER-lenLPC));
1869     /* Compute A(gamma2) residual */
1870     ippsConvBiased_32f(pstState->STPNumCoeff,lenLPC+1,pSignal,SUBFR_LEN+lenLPC,pResidual,SUBFR_LEN,lenLPC);
1871 
1872     /* Harmonic filtering */
1873     pLTPSignal = LTPSignal + 1;
1874 
1875     if (Vad > 1)
1876       HarmonicPostFilter_G729_32f(pitchDelay, pResidual, pLTPSignal, pVoicing, decoderObj->gHarmPST,mem);
1877     else {
1878       *pVoicing = 0;
1879       ippsCopy_32f(pResidual, pLTPSignal, SUBFR_LEN);
1880     }
1881 
1882     /* Save last output of 1/A(gamma1) (from preceding subframe) */
1883     LTPSignal[0] = *pSTPMemory;
1884 
1885     /* Controls Ipp16s term pst filter gain and compute f1stParcor   */
1886     /* compute i.r. of composed filter STPNumCoeff / STPDenCoeff */
1887     ippsSynthesisFilter_G729_32f(STPDenCoeff, lenLPC, pstState->STPNumCoeff, mem, len, pstState->ZeroMemory);
1888 
1889     /* compute 1st parcor */
1890     Calc1stParcor(mem, &f1stParcor, len);
1891 
1892     /* compute fG0 */
1893     fG0 = 0.f;
1894     for(i=0; i<len; i++) {
1895         fG0 += (Ipp32f)fabs(mem[i]);
1896     }
1897 
1898     /* Scale signal input of 1/A(gamma1) */
1899     if(fG0 > (Ipp32f)1.) {
1900       fTmp = (Ipp32f)1./fG0;
1901       ippsMulC_32f(pLTPSignal, fTmp, pLTPSignal, SUBFR_LEN);
1902     }
1903 
1904     /* 1/A(gamma1) filtering, STPMemory is updated */
1905     ippsSynthesisFilter_G729_32f(STPDenCoeff, lenLPC, pLTPSignal, pLTPSignal, SUBFR_LEN, &pstState->STPMemory[BWD_LPC_ORDER-lenLPC]);
1906     ippsCopy_32f(&pLTPSignal[SUBFR_LEN-BWD_LPC_ORDER], pstState->STPMemory, BWD_LPC_ORDER);
1907 
1908     /* Tilt filtering with : (1 + mu z-1) * (1/1-|mu|)*/
1909     TiltCompensation_G729_32f(LTPSignal, pDstFltSignal, f1stParcor);
1910 
1911     /* Gain control */
1912     GainControl_G729(pSignal, pDstFltSignal, &pstState->gainPrec,mem);
1913 
1914     /**** Update for next subframe */
1915     ippsMove_32f(&pstState->ResidualMemory[SUBFR_LEN], &pstState->ResidualMemory[0], RESISDUAL_MEMORY);
1916 
1917     LOCAL_ALIGN_ARRAY_FREE(32, Ipp32f, mem,SIZE_SEARCH_DEL_MEMORY+2*(FRAC_DELAY_RES-1),decoderObj);
1918     LOCAL_ALIGN_ARRAY_FREE(32, Ipp32f, LTPSignal, SUBFR_LENP1,decoderObj);  /* H0 output signal             */
1919     LOCAL_ALIGN_ARRAY_FREE(32, Ipp32f, STPDenCoeff, BWD_LPC_ORDERP1,decoderObj);   /* s.t. denominator coeff.      */
1920 
1921     return;
1922 }
1923 
HarmonicPostFilter_G729_32f(Ipp32s valPitchDelay,Ipp32f * pSrc,Ipp32f * pDst,Ipp32s * isVoiced,Ipp32f valHarmonicCoeff,Ipp32f * mem)1924 static void HarmonicPostFilter_G729_32f(Ipp32s valPitchDelay, Ipp32f *pSrc, Ipp32f *pDst,
1925                            Ipp32s *isVoiced, Ipp32f valHarmonicCoeff, Ipp32f *mem)
1926 {
1927     Ipp32s LTPDelay, lPhase;
1928     Ipp32f LTPGainNumerator, LTPGainDenominator;
1929     Ipp32f LTPGainNumerator2, LTPGainDenominator2;
1930     Ipp32f harmFltCoeff;
1931     Ipp32f *pDelayedSignal;
1932     Ipp32s lOffset;
1933     Ipp32f *pSignal = &mem[0];
1934     Ipp32f *searcgDelMem = &mem[SIZE_SEARCH_DEL_MEMORY];
1935 
1936     /* Sub optimal delay search */
1937     SearchDelay(valPitchDelay, pSrc, &LTPDelay, &lPhase, &LTPGainNumerator, &LTPGainDenominator,
1938                             pSignal, &lOffset,searcgDelMem);
1939     *isVoiced = LTPDelay;
1940 
1941     if(isVarZero(LTPGainNumerator))   {
1942         ippsCopy_32f(pSrc, pDst, SUBFR_LEN);
1943     } else {
1944         if(lPhase == 0) {
1945             pDelayedSignal = pSrc - LTPDelay;
1946         } else {
1947             Ipp64f z;
1948             /* Filtering with long filter*/
1949             ippsConvBiased_32f((Ipp32f*)&LTPTbl[(lPhase-1) * LONG_INT_FLT_LEN], LONG_INT_FLT_LEN,
1950                       &pSrc[LONG_INT_FLT_LEN_BY2-LTPDelay], SUBFR_LEN+LONG_INT_FLT_LEN,
1951                             pDst, SUBFR_LEN, LONG_INT_FLT_LEN);
1952 
1953             /* Compute fNumerator */
1954             ippsDotProd_32f64f(pDst, pSrc, SUBFR_LEN, &z);
1955             LTPGainNumerator2 = (Ipp32f)z;
1956             if(LTPGainNumerator2 < 0.0f) LTPGainNumerator2 = 0.0f;
1957 
1958             /* Compute den */
1959             ippsDotProd_32f(pDst, pDst, SUBFR_LEN, &LTPGainDenominator2);
1960 
1961             if(LTPGainNumerator2 * LTPGainNumerator2 * LTPGainDenominator> LTPGainNumerator * LTPGainNumerator * LTPGainDenominator2) {
1962                /* select long filter */
1963                 LTPGainNumerator = LTPGainNumerator2;
1964                 LTPGainDenominator = LTPGainDenominator2;
1965                 pDelayedSignal = pDst;
1966             } else {
1967                /* select Ipp16s filter */
1968                 pDelayedSignal = pSignal + ((lPhase-1) * SUBFR_LENP1 + lOffset);
1969             }
1970         }
1971 
1972         if(LTPGainNumerator >= LTPGainDenominator) {
1973             harmFltCoeff = 1.f/(1.f+ valHarmonicCoeff);
1974         } else {
1975             harmFltCoeff = LTPGainDenominator / (LTPGainDenominator + valHarmonicCoeff * LTPGainNumerator);
1976         }
1977 
1978         /** filtering by H0(z) = harmonic filter **/
1979         HarmonicFilter_G729_32f(pSrc, pDelayedSignal, pDst, harmFltCoeff);
1980     }
1981 
1982     return;
1983 }
1984 
SearchDelay(Ipp32s valPitchDelay,Ipp32f * pSrcSignal,Ipp32s * LTPDelay,Ipp32s * lPhase,Ipp32f * LTPGainNumerator,Ipp32f * LTPGainDemerator,Ipp32f * pSignal,Ipp32s * lOffset,Ipp32f * mem)1985 static void SearchDelay(Ipp32s valPitchDelay, Ipp32f *pSrcSignal, Ipp32s *LTPDelay, Ipp32s *lPhase,
1986     Ipp32f *LTPGainNumerator, Ipp32f *LTPGainDemerator, Ipp32f *pSignal, Ipp32s *lOffset, Ipp32f *mem)
1987 {
1988    Ipp32f *pDen0, *pDen1;
1989    Ipp32s iOfset, i, lLambda;
1990    Ipp32f fNumerator, fSqNumerator, fDenominator0, fDenominator1;
1991    Ipp32f fMaxDenominator, maxNumerator, squaredNumeratorMax;
1992    Ipp32s lMaxPhi;
1993    Ipp32f *pDelayedSignal;
1994     Ipp64f dEnergy, dDenominator, dTmp;
1995     Ipp32f fIntNumerator;
1996 
1997    pDen0 = &mem[0];
1998    pDen1 = &mem[FRAC_DELAY_RES-1];
1999 
2000    /* Compute current signal energy */
2001    ippsDotProd_32f64f(pSrcSignal, pSrcSignal, SUBFR_LEN, &dEnergy);
2002    if(dEnergy < 0.1) {
2003       *LTPGainNumerator = 0.f;
2004       *LTPGainDemerator = 1.f;
2005       *lPhase = 0;
2006       *LTPDelay = 0;
2007       return;
2008    }
2009 
2010     /* Selects best of 3 integer delays: Maximum of 3 numerators around valPitchDelay coder LTP delay*/
2011 
2012     ippsAutoCorrLagMax_32f(pSrcSignal, SUBFR_LEN, valPitchDelay - 1, valPitchDelay + 2, &fIntNumerator, &lLambda);
2013 
2014     if(fIntNumerator <= 0.) {
2015         *LTPGainNumerator = 0.f;
2016         *LTPGainDemerator = 1.f;
2017         *lPhase = 0;
2018         *LTPDelay   = 0;
2019         return;
2020     }
2021 
2022     /* Calculates denominator for lambda_max */
2023     ippsDotProd_32f64f(&pSrcSignal[-lLambda], &pSrcSignal[-lLambda], SUBFR_LEN, &dDenominator);
2024     if(dDenominator < 0.1) {
2025         *LTPGainNumerator = 0.f;
2026         *LTPGainDemerator = 1.f;
2027         *lPhase = 0;
2028         *LTPDelay   = 0;
2029         return;
2030     }
2031 
2032     /* Compute pSignal & denominators */
2033     pDelayedSignal = pSignal;
2034     fMaxDenominator = (Ipp32f)dDenominator;
2035 
2036     /* loop on lPhase to select the best lPhase around lLambda */
2037     for(i=0; i<FRAC_DELAY_RES-1; i++) {
2038 
2039         ippsConvBiased_32f((Ipp32f*)&STPTbl[i*SHORT_INT_FLT_LEN], SHORT_INT_FLT_LEN,
2040                       &pSrcSignal[SHORT_INT_FLT_LEN_BY2 - 1 - lLambda], SUBFR_LEN+1+SHORT_INT_FLT_LEN,
2041                             pDelayedSignal, SUBFR_LEN+1, SHORT_INT_FLT_LEN);
2042 
2043         /* recursive computation of fDenominator0 (lambda_max+1) and fDenominator1 (lambda_max) */
2044 
2045         /* common part to fDenominator0 and fDenominator1 */
2046         ippsDotProd_32f64f(&pDelayedSignal[1], &pDelayedSignal[1], SUBFR_LEN-1, &dTmp);
2047 
2048         /* Leftside denominator */
2049         fDenominator0  = (Ipp32f) (dTmp + pDelayedSignal[0] * pDelayedSignal[0]);
2050         pDen0[i] = fDenominator0;
2051 
2052         /* Rightside denominator */
2053         fDenominator1 = (Ipp32f) (dTmp + pDelayedSignal[SUBFR_LEN] * pDelayedSignal[SUBFR_LEN]);
2054         pDen1[i] = fDenominator1;
2055 
2056         if(fabs(pDelayedSignal[0])>fabs(pDelayedSignal[SUBFR_LEN])) {
2057            /* Choose left side*/
2058             if(fDenominator0 > fMaxDenominator) {
2059                 fMaxDenominator = fDenominator0;
2060             }
2061         } else {
2062            /* Choose right side*/
2063             if(fDenominator1 > fMaxDenominator) {
2064                 fMaxDenominator = fDenominator1;
2065             }
2066         }
2067         pDelayedSignal += SUBFR_LENP1;
2068     }
2069     if(fMaxDenominator < 0.1f ) {
2070         *LTPGainNumerator = 0.f;
2071         *LTPGainDemerator = 1.f;
2072         *lPhase    = 0;
2073         *LTPDelay   = 0;
2074         return;
2075     }
2076     /* Initialization */
2077     maxNumerator = (Ipp32f)fIntNumerator;
2078     fMaxDenominator      = (Ipp32f)dDenominator;
2079     squaredNumeratorMax    =  maxNumerator * maxNumerator;
2080     lMaxPhi      = 0;
2081     iOfset         = 1;
2082 
2083     pDelayedSignal     = pSignal;
2084 
2085     /* if fMaxDenominator = 0 or fNumerator!=0 & den=0: will be selected and declared unvoiced */
2086     /* Loop on lPhase */
2087     for(i=0; i<(FRAC_DELAY_RES-1); i++) {
2088 
2089         /* computes fNumerator for lambda_max+1 - i/FRAC_DELAY_RES */
2090         ippsDotProd_32f64f(pSrcSignal, pDelayedSignal, SUBFR_LEN, &dTmp);
2091 
2092         if(dTmp < 0.) fNumerator = (Ipp32f)0.;
2093         else fNumerator = (Ipp32f)dTmp;
2094         fSqNumerator = fNumerator * fNumerator;
2095 
2096         /* selection if fNumerator/sqrt(fDenominator0) max */
2097         if((fSqNumerator * fMaxDenominator) > (squaredNumeratorMax * pDen0[i])) {
2098             maxNumerator     = fNumerator;
2099             squaredNumeratorMax        = fSqNumerator;
2100             fMaxDenominator          = pDen0[i];
2101             iOfset             = 0;
2102             lMaxPhi          = i+1;
2103         }
2104 
2105         /* computes fNumerator for lambda_max - phi/FRAC_DELAY_RES */
2106 
2107         ippsDotProd_32f64f(pSrcSignal, &pDelayedSignal[1], SUBFR_LEN, &dTmp);
2108         if(dTmp < 0.) fNumerator = (Ipp32f)0.;
2109         else fNumerator = (Ipp32f)dTmp;
2110 
2111         fSqNumerator = fNumerator * fNumerator;
2112 
2113         /* selection if fNumerator/sqrt(fDenominator1) max */
2114         if((fSqNumerator * fMaxDenominator) > (squaredNumeratorMax * pDen1[i])) {
2115             maxNumerator     = fNumerator;
2116             squaredNumeratorMax        = fSqNumerator;
2117             fMaxDenominator          = pDen1[i];
2118             iOfset             = 1;
2119             lMaxPhi          = i+1;
2120         }
2121         pDelayedSignal += (SUBFR_LEN+1);
2122     }
2123 
2124     if(isVarZero(maxNumerator) || (fMaxDenominator <= 0.1f)) {
2125         *LTPGainNumerator = 0.f;
2126         *LTPGainDemerator = 1.f;
2127         *lPhase = 0;
2128         *LTPDelay = 0;
2129         return;
2130     }
2131 
2132     /* comparison numerator**2 with energy*denominator*Threshold */
2133     if(squaredNumeratorMax >= (fMaxDenominator * dEnergy * LTPTHRESHOLD)) {
2134         *LTPDelay   = lLambda + 1 - iOfset;
2135         *lOffset  = iOfset;
2136         *lPhase    = lMaxPhi;
2137         *LTPGainNumerator = maxNumerator;
2138         *LTPGainDemerator = fMaxDenominator;
2139     } else {
2140         *LTPGainNumerator = 0.f;
2141         *LTPGainDemerator = 1.f;
2142         *lPhase    = 0;
2143         *LTPDelay   = 0;
2144     }
2145     return;
2146 }
2147 
HarmonicFilter_G729_32f(Ipp32f * pSrcSignal,Ipp32f * pSrcFltSignal,Ipp32f * pDstSignal,Ipp32f valFltGain)2148 static void HarmonicFilter_G729_32f(Ipp32f *pSrcSignal, Ipp32f *pSrcFltSignal, Ipp32f *pDstSignal, Ipp32f valFltGain)
2149 {
2150     Ipp32f valFltGainNeg;
2151 
2152     valFltGainNeg = 1.f - valFltGain;
2153 
2154     ippsInterpolateC_G729_32f(pSrcSignal, valFltGain, pSrcFltSignal, valFltGainNeg, pDstSignal, SUBFR_LEN);
2155 
2156     return;
2157 }
2158 
Calc1stParcor(Ipp32f * pSrcImpulseResponse,Ipp32f * pDstPartialCorrCoeff,Ipp32s len)2159 static void Calc1stParcor(Ipp32f *pSrcImpulseResponse, Ipp32f *pDstPartialCorrCoeff, Ipp32s len)
2160 {
2161     Ipp32f firstCorr, secondCorr;
2162     Ipp64f dTmp;
2163 
2164     /* computation of the autocorrelation of the impulse response*/
2165     ippsDotProd_32f64f(pSrcImpulseResponse, pSrcImpulseResponse, len, &dTmp);
2166     firstCorr = (Ipp32f)dTmp;
2167 
2168     ippsDotProd_32f64f(pSrcImpulseResponse, &pSrcImpulseResponse[1], len-1, &dTmp);
2169     secondCorr = (Ipp32f)dTmp;
2170 
2171     if(isVarZero(firstCorr)) {
2172         *pDstPartialCorrCoeff = 0.f;
2173         return;
2174     }
2175 
2176     /* Compute 1st parcor */
2177     if(firstCorr < (Ipp32f)fabs(secondCorr) ) {
2178         *pDstPartialCorrCoeff = 0.0f;
2179         return;
2180     }
2181     *pDstPartialCorrCoeff = - secondCorr / firstCorr;
2182 
2183     return;
2184 }
2185 
TiltCompensation_G729_32f(Ipp32f * pSrcSignal,Ipp32f * pDstSignal,Ipp32f val)2186 static void TiltCompensation_G729_32f(Ipp32f *pSrcSignal, Ipp32f *pDstSignal, Ipp32f val)
2187 {
2188     Ipp32s n;
2189     Ipp32f fMu, fGamma, fTmp;
2190 
2191     if(val > 0.f) {
2192         fMu = val * GAMMA3_POSTFLT_P;
2193     }
2194     else {
2195         fMu = val * GAMMA3_POSTFLT_M;
2196     }
2197     fGamma = 1.f / (1.f - (Ipp32f)fabs(fMu));
2198 
2199     /* points on pSrcSignal(-1) */
2200     for(n=0; n<SUBFR_LEN; n++) {
2201         fTmp = fMu * pSrcSignal[n];
2202         fTmp += pSrcSignal[n+1];
2203         pDstSignal[n] = fGamma * fTmp;
2204     }
2205     return;
2206 }
2207 
GainControl_G729(Ipp32f * pSrcSignal,Ipp32f * pDstSignal,Ipp32f * pSrcDstGain,Ipp32f * mem)2208 void GainControl_G729(Ipp32f *pSrcSignal, Ipp32f *pDstSignal, Ipp32f *pSrcDstGain, Ipp32f *mem)
2209 {
2210     Ipp64f dInGain, dOutGain, fG0;
2211     Ipp32f *pTmpVector;
2212     Ipp64f *pTmpVectorD;
2213 
2214     pTmpVector = &mem[0];
2215     pTmpVectorD = (Ipp64f *)&mem[SUBFR_LEN];
2216 
2217     /* compute input gain */
2218     ippsAbs_32f(pSrcSignal,pTmpVector,SUBFR_LEN);
2219     ippsConvert_32f64f(pTmpVector,pTmpVectorD,SUBFR_LEN);
2220     ippsSum_64f(pTmpVectorD,SUBFR_LEN,&dInGain);
2221 
2222     if(isVarZero(dInGain)) {
2223         fG0 = 0.;
2224     }
2225     else {
2226         /* Compute output gain */
2227        ippsAbs_32f(pDstSignal,pTmpVector,SUBFR_LEN);
2228        ippsConvert_32f64f(pTmpVector,pTmpVectorD,SUBFR_LEN);
2229        ippsSum_64f(pTmpVectorD,SUBFR_LEN,&dOutGain);
2230         if(isVarZero(dOutGain)) {
2231             *pSrcDstGain = (Ipp32f)0.;
2232             return;
2233         }
2234 
2235         fG0 = (dInGain/ dOutGain);
2236         fG0 *= AGC_FACTORM1;
2237     }
2238 
2239     /* gain(n) = AGC_FACTOR gain(n-1) + (1-AGC_FACTOR)fG0 */
2240     /* pDstSignal(n) = gain(n) pDstSignal(n)                                   */
2241     ippsGainControl_G729_32f_I((Ipp32f)fG0, AGC_FACTOR, pDstSignal, pSrcDstGain);
2242     return;
2243 }
2244