G711 语音压缩的 C#实现

 

using  System;

public   class  G711
{
    
static   readonly   byte [] ALawCompressTable  =   new   byte [] 
    { 
         
1 1 2 2 3 3 3 3 4 4 4 4 4 4 4 4 ,
         
5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 ,
         
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
         
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
         
7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 ,
         
7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7
         
7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 ,
         
7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7  
    };

    
static   readonly   short [] ALawDecompressTable  =   new   short [] 
    {
        
- 5504 - 5248 - 6016 - 5760 - 4480 - 4224 - 4992 - 4736
        
- 7552 - 7296 - 8064 - 7808 - 6528 - 6272 - 7040 - 6784
        
- 2752 - 2624 - 3008 - 2880 - 2240 - 2112 - 2496 - 2368
        
- 3776 - 3648 - 4032 - 3904 - 3264 - 3136 - 3520 - 3392
        
- 22016 , - 20992 , - 24064 , - 23040 , - 17920 , - 16896 , - 19968 , - 18944
        
- 30208 , - 29184 , - 32256 , - 31232 , - 26112 , - 25088 , - 28160 , - 27136
        
- 11008 , - 10496 , - 12032 , - 11520 , - 8960 - 8448 - 9984 - 9472
        
- 15104 , - 14592 , - 16128 , - 15616 , - 13056 , - 12544 , - 14080 , - 13568
        
- 344 ,   - 328 ,   - 376 ,   - 360 ,   - 280 ,   - 264 ,   - 312 ,   - 296
        
- 472 ,   - 456 ,   - 504 ,   - 488 ,   - 408 ,   - 392 ,   - 440 ,   - 424
        
- 88 ,    - 72 ,    - 120 ,   - 104 ,   - 24 ,    - 8 ,     - 56 ,    - 40
        
- 216 ,   - 200 ,   - 248 ,   - 232 ,   - 152 ,   - 136 ,   - 184 ,   - 168
        
- 1376 - 1312 - 1504 - 1440 - 1120 - 1056 - 1248 - 1184
        
- 1888 - 1824 - 2016 - 1952 - 1632 - 1568 - 1760 - 1696
        
- 688 ,   - 656 ,   - 752 ,   - 720 ,   - 560 ,   - 528 ,   - 624 ,   - 592
        
- 944 ,   - 912 ,   - 1008 - 976 ,   - 816 ,   - 784 ,   - 880 ,   - 848
        
5504 ,   5248 ,   6016 ,   5760 ,   4480 ,   4224 ,   4992 ,   4736
        
7552 ,   7296 ,   8064 ,   7808 ,   6528 ,   6272 ,   7040 ,   6784
        
2752 ,   2624 ,   3008 ,   2880 ,   2240 ,   2112 ,   2496 ,   2368
        
3776 ,   3648 ,   4032 ,   3904 ,   3264 ,   3136 ,   3520 ,   3392
        
22016 20992 24064 23040 17920 16896 19968 18944
        
30208 29184 32256 31232 26112 25088 28160 27136
        
11008 10496 12032 11520 8960 ,   8448 ,   9984 ,   9472
        
15104 14592 16128 15616 13056 12544 14080 13568
        
344 ,    328 ,    376 ,    360 ,    280 ,    264 ,    312 ,    296
        
472 ,    456 ,    504 ,    488 ,    408 ,    392 ,    440 ,    424
        
88 ,     72 ,    120 ,    104 ,     24 ,      8 ,     56 ,     40
        
216 ,    200 ,    248 ,    232 ,    152 ,    136 ,    184 ,    168
        
1376 ,   1312 ,   1504 ,   1440 ,   1120 ,   1056 ,   1248 ,   1184
        
1888 ,   1824 ,   2016 ,   1952 ,   1632 ,   1568 ,   1760 ,   1696
        
688 ,    656 ,    752 ,    720 ,    560 ,    528 ,    624 ,    592
        
944 ,    912 ,   1008 ,    976 ,    816 ,    784 ,    880 ,    848  
    };

    
static   readonly   byte [] MuLawCompressTable  =   new   byte [] 
    {
        
0 0 1 1 2 2 2 2 3 3 3 3 3 3 3 3
        
4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 ,
        
5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
        
5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5
        
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 ,
        
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 ,
        
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 ,
        
6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6
        
7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 ,
        
7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 ,
        
7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 ,
        
7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 ,
        
7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7
        
7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 ,
        
7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 ,
        
7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7  
    };

    
static   readonly   short [] MuLawDecompressTable  =   new   short []
    { 
        
- 32124 , - 31100 , - 30076 , - 29052 , - 28028 , - 27004 , - 25980 , - 24956
        
- 23932 , - 22908 , - 21884 , - 20860 , - 19836 , - 18812 , - 17788 , - 16764
        
- 15996 , - 15484 , - 14972 , - 14460 , - 13948 , - 13436 , - 12924 , - 12412
        
- 11900 , - 11388 , - 10876 , - 10364 - 9852 - 9340 - 8828 - 8316
        
- 7932 - 7676 - 7420 - 7164 - 6908 - 6652 - 6396 - 6140
        
- 5884 - 5628 - 5372 - 5116 - 4860 - 4604 - 4348 - 4092
        
- 3900 - 3772 - 3644 - 3516 - 3388 - 3260 - 3132 - 3004
        
- 2876 - 2748 - 2620 - 2492 - 2364 - 2236 - 2108 - 1980
        
- 1884 - 1820 - 1756 - 1692 - 1628 - 1564 - 1500 - 1436
        
- 1372 - 1308 - 1244 - 1180 - 1116 - 1052 ,   - 988 ,   - 924
        
- 876 ,   - 844 ,   - 812 ,   - 780 ,   - 748 ,   - 716 ,   - 684 ,   - 652
        
- 620 ,   - 588 ,   - 556 ,   - 524 ,   - 492 ,   - 460 ,   - 428 ,   - 396
        
- 372 ,   - 356 ,   - 340 ,   - 324 ,   - 308 ,   - 292 ,   - 276 ,   - 260
        
- 244 ,   - 228 ,   - 212 ,   - 196 ,   - 180 ,   - 164 ,   - 148 ,   - 132
        
- 120 ,   - 112 ,   - 104 ,    - 96 ,    - 88 ,    - 80 ,    - 72 ,    - 64
        
- 56 ,    - 48 ,    - 40 ,    - 32 ,    - 24 ,    - 16 ,     - 8 ,      0
        
32124 31100 30076 29052 28028 27004 25980 24956
        
23932 22908 21884 20860 19836 18812 17788 16764
        
15996 15484 14972 14460 13948 13436 12924 12412
        
11900 11388 10876 10364 ,   9852 ,   9340 ,   8828 ,   8316
        
7932 ,   7676 ,   7420 ,   7164 ,   6908 ,   6652 ,   6396 ,   6140
        
5884 ,   5628 ,   5372 ,   5116 ,   4860 ,   4604 ,   4348 ,   4092
        
3900 ,   3772 ,   3644 ,   3516 ,   3388 ,   3260 ,   3132 ,   3004
        
2876 ,   2748 ,   2620 ,   2492 ,   2364 ,   2236 ,   2108 ,   1980
        
1884 ,   1820 ,   1756 ,   1692 ,   1628 ,   1564 ,   1500 ,   1436
        
1372 ,   1308 ,   1244 ,   1180 ,   1116 ,   1052 ,    988 ,    924
        
876 ,    844 ,    812 ,    780 ,    748 ,    716 ,    684 ,    652
        
620 ,    588 ,    556 ,    524 ,    492 ,    460 ,    428 ,    396
        
372 ,    356 ,    340 ,    324 ,    308 ,    292 ,    276 ,    260
        
244 ,    228 ,    212 ,    196 ,    180 ,    164 ,    148 ,    132
        
120 ,    112 ,    104 ,     96 ,     88 ,     80 ,     72 ,     64
        
56 ,     48 ,     40 ,     32 ,     24 ,     16 ,      8 ,      0  
 };

    
static   byte  LinearToALawSample( short  sample)
    {
        
int  sign  =   0 ;
        
int  exponent  =   0 ;
        
int  mantissa  =   0 ;
        
byte  compressedByte  =   0 ;
        sign 
=  (( ~ sample)  >>   8 &   0x80 ;
        
if  (sign  ==   0 )
            sample 
=  ( short ) - sample;
        
if  (sample  >   32635 )
            sample 
=   32635 ;
        
if  (sample  >=   256 )
        {
            exponent 
=  ( int )ALawCompressTable[(sample  >>   8 &   0x7F ];
            mantissa 
=  (sample  >>  (exponent  +   3 ))  &   0x0F ;
            compressedByte 
=  ( byte )((exponent  <<   4 |  mantissa);
        }
        
else
            compressedByte 
=  ( byte )(sample  >>   4 );
        compressedByte 
^=  ( byte )(sign  ^   0x55 );
        
return  compressedByte;
    }

    
static   byte  LinearToMuLawSample( short  sample)
    {
        
int  cBias  =   0x84 ;
        
int  cClip  =   32635 ;
        
int  sign  =  (sample  >>   8 &   0x80 ;
        
if  (sign  !=   0 ) sample  =  ( short ) - sample;
        
if  (sample  >  cClip) sample  =  ( short )cClip;
        sample 
=  ( short )(sample  +  cBias);
        
int  exponent  =  ( int )MuLawCompressTable[(sample  >>   7 &   0xFF ];
        
int  mantissa  =  (sample  >>  (exponent  +   3 ))  &   0x0F ;
        
int  compressedByte  =   ~ (sign  |  (exponent  <<   4 |  mantissa);
        
return  ( byte )compressedByte;
    }

    
///   <summary> Encodes linear 16-bit linear PCM to 8-bit a-law. </summary>
    
///   <param name="buffer"> Data which to convert. Data must be in Little-Endian format. </param>
    
///   <param name="offset"> Offset in the buffer. </param>
    
///   <param name="count"> Number of bytes to encode. </param>
    
///   <returns> Returns encoded data. </returns>
    
///   <exception cref="ArgumentNullException"> Is raised when when  <b> buffer </b>  is null. </exception>
    
///   <exception cref="ArgumentException"> Is raised when any of the arguments has invalid value. </exception>
     public   static   byte [] Encode_aLaw( byte [] buffer,  int  offset,  int  count)
    {
        
if  (buffer  ==   null throw   new  ArgumentNullException( " buffer " );
        
if  (offset  <   0   ||  offset  >  buffer.Length)
            
throw   new  ArgumentException( " Argument offset is out of range. " );
        
if  (count  <   1   ||  (count  +  offset)  >  buffer.Length)
            
throw   new  ArgumentException( " Argument offset is out of range. " );
        
if  ((buffer.Length  %   2 !=   0 )
            
throw   new  ArgumentException( " Invalid buufer value, it doesn't contain 16-bit boundaries. " );
        
int  offsetInRetVal  =   0 ;
        
byte [] retVal  =   new   byte [count  /   2 ];
        
while  (offsetInRetVal  <  retVal.Length)
        {
            
//  Little-Endian - lower byte,higer byte.
             short  pcm  =  ( short )(buffer[offset  +   1 <<   8   |  buffer[offset]);
            offset 
+=   2 ;
            retVal[offsetInRetVal
++ =  LinearToALawSample(pcm);
        }
        
return  retVal;
    }

    
///   <summary> Decodes 8-bit a-law to 16-bit linear 16-bit PCM. </summary>
    
///   <param name="buffer"> Data to decode. Data must be in Little-Endian format. </param>
    
///   <param name="offset"> Offset in the buffer. </param>
    
///   <param name="count"> Number of bytes to decode. </param>
    
///   <returns> Return decoded data. </returns>
    
///   <exception cref="ArgumentNullException"> Is raised when when  <b> buffer </b>  is null. </exception>
    
///   <exception cref="ArgumentException"> Is raised when any of the arguments has invalid value. </exception>
     public   static   byte [] Decode_aLaw( byte [] buffer,  int  offset,  int  count)
    {
        
if  (buffer  ==   null )
            
throw   new  ArgumentNullException( " buffer " );
        
if  (offset  <   0   ||  offset  >  buffer.Length)
            
throw   new  ArgumentException( " Argument offset is out of range. " );
        
if  (count  <   1   ||  (count  +  offset)  >  buffer.Length)
            
throw   new  ArgumentException( " Argument offset is out of range. " );
        
int  offsetInRetVal  =   0 ;
        
byte [] retVal  =   new   byte [count  *   2 ];
        
for  ( int  i  =  offset; i  <  buffer.Length; i ++ )
        {
            
short  pcm  =  ALawDecompressTable[buffer[i]];
            retVal[offsetInRetVal
++ =  ( byte )(pcm  &   0xFF );
            retVal[offsetInRetVal
++ =  ( byte )(pcm  >>   8   &   0xFF );
        }
        
return  retVal;
    }

    
///   <summary> Encodes linear 16-bit linear PCM to 8-bit u-law. </summary>
    
///   <param name="buffer"> Data which to convert. Data must be in Little-Endian format. </param>
    
///   <param name="offset"> Offset in the buffer. </param>
    
///   <param name="count"> Number of bytes to encode. </param>
    
///   <returns> Returns encoded data. </returns>
     public   static   byte [] Encode_uLaw( byte [] buffer,  int  offset,  int  count)
    {
        
if  (buffer  ==   null )
            
throw   new  ArgumentNullException( " buffer " );
        
if  (offset  <   0   ||  offset  >  buffer.Length)
            
throw   new  ArgumentException( " Argument offset is out of range. " );
        
if  (count  <   1   ||  (count  +  offset)  >  buffer.Length)
            
throw   new  ArgumentException( " Argument offset is out of range. " );
        
if  ((buffer.Length  %   2 !=   0 )
            
throw   new  ArgumentException( " Invalid buufer value, it doesn't contain 16-bit boundaries. " );
        
int  offsetInRetVal  =   0 ;
        
byte [] retVal  =   new   byte [count  /   2 ];
        
while  (offsetInRetVal  <  retVal.Length)
        {
            
//  Little-Endian - lower byte,higer byte.
             short  pcm  =  ( short )(buffer[offset  +   1 <<   8   |  buffer[offset]);
            offset 
+=   2 ;
            retVal[offsetInRetVal
++ =  LinearToMuLawSample(pcm);
        }
        
return  retVal;
    }

    
///   <summary> Decodes 8-bit u-law to 16-bit linear 16-bit PCM. </summary>
    
///   <param name="buffer"> Data to decode. Data must be in Little-Endian format. </param>
    
///   <param name="offset"> Offset in the buffer. </param>
    
///   <param name="count"> Number of bytes to decode. </param>
    
///   <returns> Return decoded data. </returns>
    
///   <exception cref="ArgumentNullException"> Is raised when when  <b> buffer </b>  is null. </exception>
    
///   <exception cref="ArgumentException"> Is raised when any of the arguments has invalid value. </exception>
     public   static   byte [] Decode_uLaw( byte [] buffer,  int  offset,  int  count)
    {
        
if  (buffer  ==   null )
            
throw   new  ArgumentNullException( " buffer " );
        
if  (offset  <   0   ||  offset  >  buffer.Length)
            
throw   new  ArgumentException( " Argument offset is out of range. " );
        
if  (count  <   1   ||  (count  +  offset)  >  buffer.Length)
            
throw   new  ArgumentException( " Argument offset is out of range. " );
        
int  offsetInRetVal  =   0 ;
        
byte [] retVal  =   new   byte [count  *   2 ];
        
for  ( int  i  =  offset; i  <  buffer.Length; i ++ )
        {
            
short  pcm  =  MuLawDecompressTable[buffer[i]];
            retVal[offsetInRetVal
++ =  ( byte )(pcm  &   0xFF );
            retVal[offsetInRetVal
++ =  ( byte )(pcm  >>   8   &   0xFF );
        }
        
return  retVal;
    }

}

技术讨论的QQ群: 2514097 或 10987609

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值