博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

G.711 u律;A律 压缩算法

Posted on 2020-04-13 11:30  DarkenBlue  阅读(1203)  评论(0编辑  收藏  举报
  1. /********************************************************************** 
  2.  * g711.c 
  3.  * u-law, A-law and linear PCM conversions. 
  4.  **********************************************************************/  
  5.   
  6. #define SIGN_BIT    (0x80)      /* Sign bit for a A-law byte. */  
  7. #define QUANT_MASK  (0xf)       /* Quantization field mask.   */  
  8. #define NSEGS       (8)         /* Number of A-law segments.  */  
  9. #define SEG_SHIFT   (4)         /* Left shift for segment number. */  
  10. #define SEG_MASK    (0x70)      /* Segment field mask. */  
  11.   
  12. static short seg_end[8] = {0xFF, 0x1FF, 0x3FF, 0x7FF,  
  13.                            0xFFF, 0x1FFF, 0x3FFF, 0x7FFF};  
  14.   
  15. /* copy from CCITT G.711 specifications */  
  16. unsigned char _u2a[128] = { /* u- to A-law conversions */  
  17.     1,  1,  2,  2,  3,  3,  4,  4,  
  18.     5,  5,  6,  6,  7,  7,  8,  8,  
  19.     9,  10, 11, 12, 13, 14, 15, 16,  
  20.     17, 18, 19, 20, 21, 22, 23, 24,  
  21.     25, 27, 29, 31, 33, 34, 35, 36,  
  22.     37, 38, 39, 40, 41, 42, 43, 44,  
  23.     46, 48, 49, 50, 51, 52, 53, 54,  
  24.     55, 56, 57, 58, 59, 60, 61, 62,  
  25.     64, 65, 66, 67, 68, 69, 70, 71,  
  26.     72, 73, 74, 75, 76, 77, 78, 79,  
  27.     81, 82, 83, 84, 85, 86, 87, 88,  
  28.     89, 90, 91, 92, 93, 94, 95, 96,  
  29.     97, 98, 99, 100,101,102,103,104,  
  30.     105,106,107,108,109,110,111,112,  
  31.     113,114,115,116,117,118,119,120,  
  32.     121,122,123,124,125,126,127,128  
  33. };  
  34.   
  35. unsigned char _a2u[128] = { /* A- to u-law conversions */  
  36.     1,  3,  5,  7,  9,  11, 13, 15,  
  37.     16, 17, 18, 19, 20, 21, 22, 23,  
  38.     24, 25, 26, 27, 28, 29, 30, 31,  
  39.     32, 32, 33, 33, 34, 34, 35, 35,  
  40.     36, 37, 38, 39, 40, 41, 42, 43,  
  41.     44, 45, 46, 47, 48, 48, 49, 49,  
  42.     50, 51, 52, 53, 54, 55, 56, 57,  
  43.     58, 59, 60, 61, 62, 63, 64, 64,  
  44.     65, 66, 67, 68, 69, 70, 71, 72,  
  45.     73, 74, 75, 76, 77, 78, 79, 79,  
  46.     80, 81, 82, 83, 84, 85, 86, 87,  
  47.     88, 89, 90, 91, 92, 93, 94, 95,  
  48.     96, 97, 98, 99, 100,101,102,103,  
  49.     104,105,106,107,108,109,110,111,  
  50.     112,113,114,115,116,117,118,119,  
  51.     120,121,122,123,124,125,126,127  
  52. };  
  53.   
  54. static int search(int val,short *table,int size)  
  55. {  
  56.     int     i;  
  57.     for (i = 0; i < size; i++) {  
  58.         if (val <= *table++)  
  59.             return (i);  
  60.     }  
  61.     return (size);  
  62. }  
  63.   
  64. /********************************************************************* 
  65.  * linear2alaw() - Convert a 16-bit linear PCM value to 8-bit A-law 
  66.  *   
  67.  * linear2alaw() accepts an 16-bit integer and encodes it as A-law data. 
  68.  * 
  69.  *  Linear Input Code       Compressed Code 
  70.  *  -----------------       ------------------ 
  71.  *  0000000wxyza            000wxyz 
  72.  *  0000001wxyza            001wxyz 
  73.  *  000001wxyzab            010wxyz 
  74.  *  00001wxyzabc            011wxyz 
  75.  *  0001wxyzabcd            100wxyz 
  76.  *  001wxyzabcde            101wxyz 
  77.  *  01wxyzabcdef            110wxyz 
  78.  *  1wxyzabcdefg            111wxyz 
  79.  * 
  80.  * For further information see John C. Bellamy's Digital Telephony, 1982, 
  81.  * John Wiley & Sons, pps 98-111 and 472-476. 
  82.  *********************************************************************/  
  83. unsigned char linear2alaw(int pcm_val)  /* 2's complement (16-bit range) */  
  84. {  
  85.     int             mask;  
  86.     int             seg;  
  87.     unsigned char   aval;  
  88.   
  89.     if (pcm_val >= 0) {  
  90.         mask = 0xD5;        /* sign (7th) bit = 1 */  
  91.     } else {  
  92.         mask = 0x55;        /* sign bit = 0 */  
  93.         pcm_val = -pcm_val - 8;  
  94.     }  
  95.   
  96.     /* Convert the scaled magnitude to segment number. */  
  97.     seg = search(pcm_val, seg_end, 8);  
  98.   
  99.     /* Combine the sign, segment, and quantization bits. */  
  100.   
  101.     if (seg >= 8)        /* out of range, return maximum value. */  
  102.         return (0x7F ^ mask);  
  103.     else {  
  104.         aval = seg << SEG_SHIFT;  
  105.         if (seg < 2)  
  106.             aval |= (pcm_val >> 4) & QUANT_MASK;  
  107.         else  
  108.             aval |= (pcm_val >> (seg + 3)) & QUANT_MASK;  
  109.         return (aval ^ mask);  
  110.     }  
  111. }  
  112.   
  113. /********************************************************************* 
  114.  *    alaw2linear() - Convert an A-law value to 16-bit linear PCM 
  115.  *********************************************************************/  
  116. int alaw2linear(unsigned char a_val)  
  117. {  
  118.     int     t;  
  119.     int     seg;  
  120.   
  121.     a_val ^= 0x55;  
  122.   
  123.     t = (a_val & QUANT_MASK) << 4;  
  124.     seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;  
  125.     switch (seg) {  
  126.     case 0:  
  127.         t += 8;  
  128.         break;  
  129.     case 1:  
  130.         t += 0x108;  
  131.         break;  
  132.     default:  
  133.         t += 0x108;  
  134.         t <<= seg - 1;  
  135.     }  
  136.     return ((a_val & SIGN_BIT) ? t : -t);  
  137. }  
  138.   
  139. #define BIAS        (0x84)      /* Bias for linear code. */  
  140.   
  141. /********************************************************************* 
  142.  * linear2ulaw() - Convert a linear PCM value to u-law 
  143.  * 
  144.  * In order to simplify the encoding process, the original linear magnitude 
  145.  * is biased by adding 33 which shifts the encoding range from (0 - 8158) to 
  146.  * (33 - 8191). The result can be seen in the following encoding table: 
  147.  * 
  148.  *  Biased Linear Input Code    Compressed Code 
  149.  *  ------------------------    --------------- 
  150.  *  00000001wxyza               000wxyz 
  151.  *  0000001wxyzab               001wxyz 
  152.  *  000001wxyzabc               010wxyz 
  153.  *  00001wxyzabcd               011wxyz 
  154.  *  0001wxyzabcde               100wxyz 
  155.  *  001wxyzabcdef               101wxyz 
  156.  *  01wxyzabcdefg               110wxyz 
  157.  *  1wxyzabcdefgh               111wxyz 
  158.  * 
  159.  * Each biased linear code has a leading 1 which identifies the segment 
  160.  * number. The value of the segment number is equal to 7 minus the number 
  161.  * of leading 0's. The quantization interval is directly available as the 
  162.  * four bits wxyz.  * The trailing bits (a - h) are ignored. 
  163.  * 
  164.  * Ordinarily the complement of the resulting code word is used for 
  165.  * transmission, and so the code word is complemented before it is returned. 
  166.  * 
  167.  * For further information see John C. Bellamy's Digital Telephony, 1982, 
  168.  * John Wiley & Sons, pps 98-111 and 472-476. 
  169.  *********************************************************************/  
  170. unsigned char linear2ulaw(int pcm_val)  /* 2's complement (16-bit range) */  
  171. {  
  172.     int     mask;  
  173.     int     seg;  
  174.     unsigned char   uval;  
  175.   
  176.     /* Get the sign and the magnitude of the value. */  
  177.     if (pcm_val < 0) {  
  178.         pcm_val = BIAS - pcm_val;  
  179.         mask = 0x7F;  
  180.     } else {  
  181.         pcm_val += BIAS;  
  182.         mask = 0xFF;  
  183.     }  
  184.   
  185.     /* Convert the scaled magnitude to segment number. */  
  186.     seg = search(pcm_val, seg_end, 8);  
  187.   
  188.     /* 
  189.      * Combine the sign, segment, quantization bits; 
  190.      * and complement the code word. 
  191.      */  
  192.     if (seg >= 8)        /* out of range, return maximum value. */  
  193.         return (0x7F ^ mask);  
  194.     else {  
  195.         uval = (seg << 4) | ((pcm_val >> (seg + 3)) & 0xF);  
  196.         return (uval ^ mask);  
  197.     }  
  198.   
  199. }  
  200.   
  201. /********************************************************************* 
  202.  * ulaw2linear() - Convert a u-law value to 16-bit linear PCM 
  203.  * 
  204.  * First, a biased linear code is derived from the code word. An unbiased 
  205.  * output can then be obtained by subtracting 33 from the biased code. 
  206.  * 
  207.  * Note that this function expects to be passed the complement of the 
  208.  * original code word. This is in keeping with ISDN conventions. 
  209.  *********************************************************************/  
  210. int ulaw2linear( unsigned char  u_val)  
  211. {  
  212.     int     t;  
  213.   
  214.     /* Complement to obtain normal u-law value. */  
  215.     u_val = ~u_val;  
  216.   
  217.     /* 
  218.      * Extract and bias the quantization bits. Then 
  219.      * shift up by the segment number and subtract out the bias. 
  220.      */  
  221.     t = ((u_val & QUANT_MASK) << 3) + BIAS;  
  222.     t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;  
  223.   
  224.     return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));  
  225. }  
  226.   
  227. /* A-law to u-law conversion */  
  228. unsigned char alaw2ulaw(unsigned char   aval)  
  229. {  
  230.     aval &= 0xff;  
  231.     return ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) :  
  232.         (0x7F ^ _a2u[aval ^ 0x55]));  
  233. }  
  234.   
  235. /* u-law to A-law conversion */  
  236. unsigned char ulaw2alaw(unsigned char   uval)  
  237. {  
  238.     uval &= 0xff;  
  239.     return ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)):  
  240.            (0x55 ^ (_u2a[0x7F ^ uval] - 1)));  
  241. }