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) 2005-2011 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 VAD functions.
26 //
27 */
28
29 #include "vadg729.h"
30 #include "aux_fnxs.h"
31
32 #define ZEROcrossBegin 120
33 #define VADinitFrame 32
34 #define ZEROcrossEnd 200
35
36 static __ALIGN32 CONST Ipp16s lbfCorr[VAD_LPC_DIM +1] = { 7869, 7011, 4838, 2299, 321,
37 -660, -782, -484, -164, 3, 39, 21, 4};
38 static __ALIGN32 CONST Ipp16s ifactor[33] = { IPP_MAX_16S, 16913, 17476, 18079,
39 18725, 19418, 20165, 20972, 21845, 22795, 23831, 24966,
40 26214, 27594,
41 29127, 30840, IPP_MAX_16S, 17476, 18725, 20165, 21845, 23831, 26214, 29127,
42 IPP_MAX_16S, 18725, 21845, 26214, IPP_MAX_16S, 21845, IPP_MAX_16S, IPP_MAX_16S, 0
43 };
44 static __ALIGN32 CONST Ipp16s ishift[33] = { 15, (7<<1), (7<<1), (7<<1), (7<<1), (7<<1), (7<<1), (7<<1),
45 (7<<1), (7<<1), (7<<1), (7<<1), (7<<1), (7<<1), (7<<1), (7<<1), (7<<1), 13, 13, 13, 13, 13, 13, 13, 13, 12, 12,
46 12, 12, 11, 11, 10, 15
47 };
48
ownSignChangeRate(Ipp16s * pSrc)49 static Ipp32s ownSignChangeRate(Ipp16s *pSrc /* [ZEROcrossEnd-ZEROcrossBegin+1] */) {
50 Ipp32s i;
51 Ipp32s sum=0;
52 for(i=1; i<=ZEROcrossEnd-ZEROcrossBegin; i++)
53 sum += (pSrc[i-1] * pSrc[i] < 0);
54 return sum;
55 }
56
57
58 /* ///////////////////////////////////////////////////////////////////////////////////////
59 // Name: ownMakeDecision
60 // Purpose:
61 // Parameters:
62 // lowBandE - energy
63 // highBandE - fullenergy
64 // spectrDist - distortion
65 // crossZeroRate - zero crossing
66 */
ownMakeDecision(Ipp16s lowBandE,Ipp16s highBandE,Ipp16s spectrDist,Ipp16s crossZeroRate)67 static Ipp16s ownMakeDecision(Ipp16s lowBandE,Ipp16s highBandE, Ipp16s spectrDist,Ipp16s crossZeroRate) {
68 Ipp32s L_tmp;
69 /* spectrDist vs crossZeroRate */
70 L_tmp = crossZeroRate * (-14680);
71 L_tmp += BWF_HARMONIC_E * (-28521);
72 L_tmp = L_tmp >> 7;
73 if(L_tmp > -spectrDist<<16 )
74 return 1;
75 L_tmp = crossZeroRate * 19065;
76 L_tmp += BWF_HARMONIC_E * (-19446);
77 L_tmp = L_tmp>>6;
78 if(L_tmp > -spectrDist<<16)
79 return 1;
80 /* highBandE vs crossZeroRate */
81 L_tmp = crossZeroRate * 20480;
82 L_tmp += BWF_HARMONIC_E * BWF_HARMONIC;
83 L_tmp = L_tmp>>1;
84 if(L_tmp < -highBandE<<16)
85 return 1;
86 L_tmp = crossZeroRate * (-BWF_HARMONIC);
87 L_tmp += BWF_HARMONIC_E * 19660;
88 L_tmp = L_tmp>>1;
89 if(L_tmp < -highBandE<<16)
90 return 1;
91 L_tmp = highBandE * IPP_MAX_16S;
92 if(L_tmp < -1024 * 30802)
93 return 1;
94 /* highBandE vs spectrDist */
95 L_tmp = spectrDist * (-28160);
96 L_tmp += 64 * 19988;
97 if(L_tmp < -highBandE<<9)
98 return 1;
99 L_tmp = spectrDist * IPP_MAX_16S;
100 if(L_tmp > 32 * 30199)
101 return 1;
102 /* lowBandE vs crossZeroRate */
103 L_tmp = crossZeroRate * (-20480);
104 L_tmp += BWF_HARMONIC_E * BWF2;
105 L_tmp = L_tmp >> 1;
106 if(L_tmp < -highBandE<<16)
107 return 1;
108 L_tmp = crossZeroRate * 23831;
109 L_tmp += (1<<12) * 31576;
110 L_tmp = L_tmp>>1;
111 if(L_tmp < -highBandE<<16)
112 return 1;
113 L_tmp = highBandE * IPP_MAX_16S;
114 if(L_tmp < -(1<<11) * 17367
115 ) return 1;
116 /* lowBandE vs spectrDist */
117 L_tmp = spectrDist * (-22400);
118 L_tmp += (1<<5) * 25395;
119 if(L_tmp < -lowBandE<<8)
120 return 1;
121 /* lowBandE vs highBandE */
122 L_tmp = highBandE * (-30427);
123 L_tmp += (1<<8) * (-29959);
124 if(L_tmp > -lowBandE<<15)
125 return 1;
126 L_tmp = highBandE * (-23406);
127 L_tmp += (1<<9) * 28087;
128 if(L_tmp < -lowBandE<<15)
129 return 1;
130 L_tmp = highBandE * 24576;
131 L_tmp += (1<<10) * COEFF1;
132 if(L_tmp < -lowBandE<<14)
133 return 1;
134 return 0;
135 }
136
VoiceActivityDetectInit_G729(Ipp8s * pVADmem)137 void VoiceActivityDetectInit_G729(Ipp8s* pVADmem) {
138 VADmemory_Obj* vadMem = (VADmemory_Obj*)pVADmem;
139 ippsZero_16s(vadMem->LSFMean, LPF_DIM);
140 ippsZero_16s(vadMem->minBuf, 16);
141 vadMem->SEMean = 0;
142 vadMem->SLEMean = 0;
143 vadMem->EMean = 0;
144 vadMem->SZCMean = 0;
145 vadMem->SILcounter = 0;
146 vadMem->updateCounter = 0;
147 vadMem->extCounter = 0;
148 vadMem->lessCounter = 0;
149 vadMem->frameCounter = 0;
150 vadMem->VADflag = 1;
151 vadMem->minVAD = IPP_MAX_16S;
152 vadMem->VADPrev = 1;
153 vadMem->VADPPrev = 1;
154 vadMem->minPrev = IPP_MAX_16S;
155 vadMem->minNext = IPP_MAX_16S;
156 vadMem->VADPrevEnergy = IPP_MAX_16S;
157 vadMem->VADflag2 = 0;
158 ippsZero_16s(vadMem->musicRC, 10);
159 vadMem->musicCounter=0;
160 vadMem->musicMCounter=0;
161 vadMem->conscCounter=0;
162 vadMem->MeanPgain =BWF_HARMONIC_E;
163 vadMem->count_pflag=0;
164 vadMem->Mcount_pflag=0;
165 vadMem->conscCounterFlagP=0;
166 vadMem->conscCounterFlagR=0;
167 vadMem->musicSEMean =0;
168 }
169
VoiceActivityDetectSize_G729(Ipp32s * pVADsize)170 void VoiceActivityDetectSize_G729(Ipp32s* pVADsize) {
171 //pVADsize[0] = (sizeof(VADmemory)+7)&(~7);
172 pVADsize[0] = (sizeof(VADmemory_Obj)+32);
173 }
174
175 static __ALIGN32 CONST Ipp16s vadTable[6][6]={
176 {24576, BWF_HARMONIC_E,26214, 6554,19661,PITCH_SHARP_MAX},
177 {31130, 1638,30147, 2621,21299,11469},
178 {31785, 983,30802, 1966,BWF2, 9830},
179 {32440, 328,31457, 1311,24576, BWF_HARMONIC_E},
180 {32604, 164,32440, 328,24576, BWF_HARMONIC_E},
181 {32604, 164,32702, 66,24576, BWF_HARMONIC_E},
182 };
183
VoiceActivityDetect_G729(Ipp16s * pSrc,Ipp16s * pLSF,Ipp32s * pAutoCorr,Ipp16s autoExp,Ipp16s pRc,Ipp16s * pVad,Ipp8s * pVADmem,Ipp16s * pTmp)184 void VoiceActivityDetect_G729(Ipp16s *pSrc,Ipp16s *pLSF,Ipp32s *pAutoCorr,
185 Ipp16s autoExp, Ipp16s pRc, Ipp16s *pVad, Ipp8s *pVADmem,Ipp16s *pTmp) {
186 Ipp32s L_tmp;
187 VADmemory_Obj *vadMem = (VADmemory_Obj*)pVADmem;
188 const Ipp16s *pVadTable;
189
190 Ipp16s frameCounter, VADPrev, VADPPrev, *LSFMean, *min_buf;
191 Ipp16s vadmin,SEMean,minPrev=IPP_MAX_16S,minNext,lessCounter,updateCounter;
192 Ipp16s SZCMean,SLEMean,EMean,prev_vadEner,SILcounter,v_flag,cnt_ext,cur_flag;
193 Ipp16s i, j, exp, fractal;
194 Ipp16s energy, energyLow, spectrDist, ZC, highBandE, lowBandE, crossZeroRate;
195 Ipp32s r0;
196
197 r0 = pAutoCorr[0];
198 for(i=0; i<= VAD_LPC_DIM ; i++)
199 pTmp[i]=(Ipp16s)(pAutoCorr[i]>>16);
200
201 VADPrev = vadMem->VADPrev;
202 VADPPrev = vadMem->VADPPrev;
203 LSFMean = vadMem->LSFMean;
204 min_buf = vadMem->minBuf;
205 vadmin = vadMem->minVAD;
206 SEMean = vadMem->SEMean;
207 minPrev = vadMem->minPrev;
208 minNext = vadMem->minNext;
209 lessCounter = vadMem->lessCounter;
210 updateCounter = vadMem->updateCounter;
211 SZCMean = vadMem->SZCMean;
212 SLEMean = vadMem->SLEMean;
213 EMean = vadMem->EMean;
214 prev_vadEner = vadMem->VADPrevEnergy;
215 SILcounter = vadMem->SILcounter;
216 v_flag = vadMem->VADflag2;
217 cnt_ext = vadMem->extCounter;
218 cur_flag = vadMem->VADflag;
219 frameCounter = vadMem->frameCounter;
220 if(frameCounter == IPP_MAX_16S) frameCounter = 256;
221 else frameCounter++;
222
223 /* get frame energy */
224 Log2_G729(r0, &exp, &fractal);
225 L_tmp = (autoExp+exp)*9864 + ((fractal*9864)>>15);
226 energy = (Ipp16s)(L_tmp>>4);
227 energy -= 6108;
228
229 /* get low band energy */
230 ippsDotProd_16s32s_Sfs(pTmp+1,lbfCorr+1,VAD_LPC_DIM ,&L_tmp,0);
231 L_tmp = 4 * L_tmp;
232 L_tmp = Add_32s(L_tmp, 2 * pTmp[0] * lbfCorr[0]);
233 Log2_G729(L_tmp, &exp, &fractal);
234 L_tmp = (autoExp+exp)*9864 + ((fractal*9864)>>15);
235 energyLow = (Ipp16s)(L_tmp>>4);
236 energyLow -= 6108;
237
238 /* calculate spectrDist */
239 for(i=0, L_tmp=0; i<LPF_DIM; i++) {
240 j = (Ipp16s)(pLSF[i] - LSFMean[i]);
241 L_tmp += j * j;
242 }
243 spectrDist = (Ipp16s)(L_tmp >> 15);
244
245 /* compute # zero crossing */
246 ZC=(Ipp16s)(ownSignChangeRate(pSrc+ZEROcrossBegin)*410);
247
248
249 if(frameCounter < 129) {
250 if(energy < vadmin) {
251 vadmin = energy;
252 minPrev = energy;
253 }
254
255 if(0 == (frameCounter & 7)) {
256 i = (Ipp16s)((frameCounter>>3) - 1);
257 min_buf[i] = vadmin;
258 vadmin = IPP_MAX_16S;
259 }
260 }
261
262 if(0 == (frameCounter & 7)) {
263 ippsMin_16s(min_buf,16,&minPrev);
264 }
265
266 if(frameCounter >= 129) {
267 if((frameCounter & 7) == 1) {
268 vadmin = minPrev;
269 minNext = IPP_MAX_16S;
270 }
271 if(energy < vadmin)
272 vadmin = energy;
273 if(energy < minNext)
274 minNext = energy;
275
276 if(!(frameCounter & 7)) {
277 for(i=0; i<15; i++)
278 min_buf[i] = min_buf[i+1];
279 min_buf[15] = minNext;
280 ippsMin_16s(min_buf,16,&minPrev);
281 }
282
283 }
284
285 if(frameCounter <= VADinitFrame) {
286 if(energy < 3072) {
287 pVad[0] = 0;
288 lessCounter++;
289 } else {
290 pVad[0] = 1;
291 EMean = (Ipp16s)(EMean + (energy>>5));
292 SZCMean = (Ipp16s)(SZCMean + (ZC>>5));
293 for(i=0; i<LPF_DIM; i++) {
294 LSFMean[i] = (Ipp16s)(LSFMean[i] + (pLSF[i] >> 5));
295 }
296 }
297 }
298
299 if(frameCounter >= VADinitFrame) {
300 if(VADinitFrame==frameCounter) {
301 L_tmp = EMean * ifactor[lessCounter];
302 EMean = (Ipp16s)(L_tmp>>ishift[lessCounter]);
303
304 L_tmp = SZCMean * ifactor[lessCounter];
305 SZCMean = (Ipp16s)(L_tmp >> ishift[lessCounter]);
306
307 for(i=0; i<LPF_DIM; i++) {
308 L_tmp = LSFMean[i] * ifactor[lessCounter];
309 LSFMean[i] = (Ipp16s)(L_tmp >> ishift[lessCounter]);
310 }
311 SEMean = (Ipp16s)(EMean - 2048);
312 SLEMean = (Ipp16s)(EMean - 2458);
313 }
314
315 highBandE = (Ipp16s)(SEMean - energy);
316 lowBandE = (Ipp16s)(SLEMean - energyLow);
317 crossZeroRate = (Ipp16s)(SZCMean - ZC);
318
319 if(energy < 3072)
320 pVad[0] = 0;
321 else
322 pVad[0] = ownMakeDecision(lowBandE, highBandE, spectrDist, crossZeroRate);
323
324 v_flag = 0;
325 if((VADPrev==1) && (pVad[0]==0) && (highBandE < -410) && (energy > 3072)) {
326 pVad[0] = 1;
327 v_flag = 1;
328 }
329
330 if(cur_flag == 1) {
331 if((VADPPrev == 1) && (VADPrev == 1) && (pVad[0] == 0) &&
332 Abs_16s((Ipp16s)(prev_vadEner - energy)) <= 614) {
333 cnt_ext++;
334 pVad[0] = 1;
335 v_flag = 1;
336 if(cnt_ext <= 4)
337 cur_flag = 1;
338 else {
339 cnt_ext = cur_flag = 0;
340 }
341 }
342 } else
343 cur_flag=1;
344
345 if(pVad[0] == 0)
346 SILcounter++;
347
348 if((pVad[0] == 1) && (SILcounter > 10)
349 && (energy - prev_vadEner <= 614)) {
350 pVad[0] = 0;
351 SILcounter=0;
352 }
353
354 if(pVad[0] == 1)
355 SILcounter=0;
356
357 if(((energy - 614) < SEMean) && (frameCounter > 128) && (!v_flag) && (pRc < 19661))
358 pVad[0] = 0;
359
360 if(((energy - 614) < SEMean) && (pRc < 24576) && (spectrDist < 83)) {
361 updateCounter++;
362 if(updateCounter < 20)
363 pVadTable = vadTable[0];
364 else
365 if(updateCounter < 30)
366 pVadTable = vadTable[1];
367 else
368 if(updateCounter < 40)
369 pVadTable = vadTable[2];
370 else
371 if(updateCounter < 50)
372 pVadTable = vadTable[3];
373 else
374 if(updateCounter < 60)
375 pVadTable = vadTable[4];
376 else
377 pVadTable = vadTable[5];
378 /* update means */
379 L_tmp = pVadTable[0] * SEMean + pVadTable[1] * energy;
380 SEMean = (Ipp16s)(L_tmp >> 15);
381
382 L_tmp = pVadTable[0] * SLEMean + pVadTable[1] * energyLow;
383 SLEMean = (Ipp16s)(L_tmp>>15);
384
385 L_tmp = pVadTable[2] * SZCMean + pVadTable[3] * ZC;
386 SZCMean = (Ipp16s)(L_tmp>>15);
387
388 for(i=0; i<LPF_DIM; i++) {
389 L_tmp = pVadTable[4] * LSFMean[i] + pVadTable[5] * pLSF[i];
390 LSFMean[i] = (Ipp16s)(L_tmp>>15);
391 }
392 }
393 if(frameCounter > 128 && ((SEMean < vadmin &&
394 spectrDist < 83) || (SEMean -vadmin) > 2048)) {
395 SEMean = vadmin;
396 updateCounter = 0;
397 }
398 }
399 vadMem->VADPrevEnergy = energy;
400 vadMem->minVAD = vadmin;
401 vadMem->SEMean = SEMean;
402 vadMem->minPrev = minPrev;
403 vadMem->minNext = minNext;
404 vadMem->lessCounter = lessCounter;
405 vadMem->updateCounter = updateCounter;
406 vadMem->SZCMean = SZCMean;
407 vadMem->SLEMean = SLEMean;
408 vadMem->EMean = EMean;
409 vadMem->SILcounter = SILcounter;
410 vadMem->VADflag2 = v_flag;
411 vadMem->extCounter = cnt_ext;
412 vadMem->VADflag = cur_flag;
413 vadMem->frameCounter = frameCounter;
414 }
415
416
417