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, <PDelay, &lPhase, <PGainNumerator, <PGainDenominator,
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*)<PTbl[(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, <PGainDenominator2);
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