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