VAD.C
上传用户:meifeng08
上传日期:2013-06-18
资源大小:5304k
文件大小:5k
源码类别:

语音压缩

开发平台:

C/C++

  1. /*
  2. **
  3. ** File:        "vad.c"
  4. **
  5. ** Description:     Voice Activity Detection
  6. **
  7. ** Functions:       Init_Vad()
  8. **                  Vad()
  9. **
  10. **
  11. */
  12. /*
  13.     ITU-T G.723 Speech Coder   ANSI-C Source Code     Version 5.00
  14.     copyright (c) 1995, AudioCodes, DSP Group, France Telecom,
  15.     Universite de Sherbrooke.  All rights reserved.
  16. */
  17. #include <stdio.h>
  18. #include "typedef.h"
  19. #include "basop.h"
  20. #include "cst_lbc.h"
  21. #include "tab_lbc.h"
  22. #include "lsp.h"
  23. #include "vad.h"
  24. #include "coder.h"
  25. #include "lbccodec.h"
  26. VADSTATDEF  VadStat ;
  27. void    Init_Vad(void)
  28. {
  29.     int i ;
  30.     VadStat.Hcnt = 3 ;
  31.     VadStat.Vcnt = 0 ;
  32.     VadStat.Penr = 0x00000400L ;
  33.     VadStat.Nlev = 0x00000400L ;
  34.     VadStat.Aen = 0 ;
  35.     VadStat.Polp[0] = 1 ;
  36.     VadStat.Polp[1] = 1 ;
  37.     VadStat.Polp[2] = SubFrLen ;
  38.     VadStat.Polp[3] = SubFrLen ;
  39.     for(i=0; i < LpcOrder; i++) VadStat.NLpc[i] = 0;
  40. }
  41. Flag Comp_Vad( Word16 *Dpnt)
  42. {
  43.     int i,j ;
  44.     Word32  Acc0,Acc1 ;
  45.     Word16  Tm0, Tm1, Tm2 ;
  46.     Word16  Minp ;
  47.     Flag    VadState = 1 ;
  48.     static  Word16  ScfTab[11] = {
  49.          9170 ,
  50.          9170 ,
  51.          9170 ,
  52.          9170 ,
  53.         10289 ,
  54.         11544 ,
  55.         12953 ,
  56.         14533 ,
  57.         16306 ,
  58.         18296 ,
  59.         20529 ,
  60.     } ;
  61.     if ( !UseVx )
  62.         return VadState ;
  63.     /* Find Minimum pitch period */
  64.     Minp = PitchMax ;
  65.     for ( i = 0 ; i < 4 ; i ++ ) {
  66.         if ( Minp > VadStat.Polp[i] )
  67.             Minp = VadStat.Polp[i] ;
  68.     }
  69.     /* Check that all are multiplies of the minimum */
  70.     Tm2 = 0 ;
  71.     for ( i = 0 ; i < 4 ; i ++ ) {
  72.         Tm1 = Minp ;
  73.         for ( j = 0 ; j < 8 ; j ++ ) {
  74.             Tm0 = sub( Tm1, VadStat.Polp[i] ) ;
  75.             Tm0 = abs_s( Tm0 ) ;
  76.             if ( Tm0 <= 3 )
  77.                 Tm2 ++ ;
  78.             Tm1 = add( Tm1, Minp ) ;
  79.         }
  80.     }
  81.     /* Update adaptation enable counter if not periodic and not sine */
  82.     if ( (Tm2 == 4) || (CodStat.SinDet < 0) )
  83.         VadStat.Aen += 2 ;
  84.     else
  85.         VadStat.Aen -- ;
  86.     /* Clip it */
  87.     if ( VadStat.Aen > 6 )
  88.         VadStat.Aen = 6 ;
  89.     if ( VadStat.Aen < 0 )
  90.         VadStat.Aen = 0 ;
  91.     /* Inverse filter the data */
  92.     Acc1 = 0L ;
  93.     for ( i = SubFrLen ; i < Frame ; i ++ ) {
  94.         Acc0 = L_mult( Dpnt[i], 0x2000 ) ;
  95.         for ( j = 0 ; j < LpcOrder ; j ++ )
  96.             Acc0 = L_msu( Acc0, Dpnt[i-j-1], VadStat.NLpc[j] ) ;
  97.         Tm0 = round ( Acc0 ) ;
  98.         Acc1 = L_mac( Acc1, Tm0, Tm0 ) ;
  99.     }
  100.     /* Scale the rezidual energy */
  101.     Acc1 = L_mls( Acc1, (Word16) 2913 ) ;
  102.     /* Clip noise level in any case */
  103.     if ( VadStat.Nlev > VadStat.Penr ) {
  104.         Acc0 = L_sub( VadStat.Penr, L_shr( VadStat.Penr, 2 ) ) ;
  105.         VadStat.Nlev = L_add( Acc0, L_shr( VadStat.Nlev, 2 ) ) ;
  106.     }
  107.     /* Update the noise level, if adaptation is enabled */
  108.     if ( !VadStat.Aen ) {
  109.         VadStat.Nlev = L_add( VadStat.Nlev, L_shr( VadStat.Nlev, 5 ) ) ;
  110.     }
  111.     /* Decay Nlev by small amount */
  112.     else {
  113.         VadStat.Nlev = L_sub( VadStat.Nlev, L_shr( VadStat.Nlev,11 ) ) ;
  114.     }
  115.     /* Update previous energy */
  116.     VadStat.Penr = Acc1 ;
  117.     /* CLip Noise Level */
  118.     if ( VadStat.Nlev < 0x00000080L )
  119.         VadStat.Nlev = 0x00000080L ;
  120.     if ( VadStat.Nlev > 0x0001ffffL )
  121.         VadStat.Nlev = 0x0001ffffL ;
  122.     /* Compute the treshold */
  123.     Acc0 = L_shl( VadStat.Nlev, 13 ) ;
  124.     Tm0 = norm_l( Acc0 ) ;
  125.     Acc0 = L_shl( Acc0, Tm0 ) ;
  126.     Acc0 &= 0x3f000000L ;
  127.     Acc0 <<= 1 ;
  128.     Tm1 = extract_h( Acc0 ) ;
  129.     Acc0 = L_deposit_h( ScfTab[Tm0] ) ;
  130.     Acc0 = L_mac( Acc0, Tm1, ScfTab[Tm0-1] ) ;
  131.     Acc0 = L_msu( Acc0, Tm1, ScfTab[Tm0] ) ;
  132.     Tm1 = extract_h( Acc0 ) ;
  133.     Tm0 = extract_l( L_shr( VadStat.Nlev, 2 ) ) ;
  134.     Acc0 = L_mult( Tm0, Tm1 ) ;
  135.     Acc0 >>= 11 ;
  136.     /* Compare with the treshold */
  137.     if ( Acc0 > Acc1 )
  138.         VadState = 0 ;
  139.     /* Do the various counters */
  140.     if ( VadState ) {
  141.         VadStat.Vcnt ++ ;
  142.         VadStat.Hcnt ++ ;
  143.     }
  144.     else {
  145.         VadStat.Vcnt -- ;
  146.         if ( VadStat.Vcnt < 0 )
  147.             VadStat.Vcnt = 0 ;
  148.     }
  149.     if ( VadStat.Vcnt >= 2 ) {
  150.         VadStat.Hcnt = 6 ;
  151.         if ( VadStat.Vcnt >= 3 )
  152.             VadStat.Vcnt = 3 ;
  153.     }
  154.     if ( VadStat.Hcnt ) {
  155.         VadState = 1 ;
  156.         if ( VadStat.Vcnt == 0 )
  157.             VadStat.Hcnt -- ;
  158.     }
  159.     /* Update Periodicy detector */
  160.     VadStat.Polp[0] = VadStat.Polp[2] ;
  161.     VadStat.Polp[1] = VadStat.Polp[3] ;
  162.     return VadState ;
  163. }