gst_plugins_good/gst/law/mulaw-conversion.c
changeset 26 69c7080681bf
parent 24 bc39b352897e
child 28 4ed5253bb6ba
equal deleted inserted replaced
24:bc39b352897e 26:69c7080681bf
     1 /*
       
     2  * This routine converts from linear to ulaw
       
     3  * 29 September 1989
       
     4  *
       
     5  * Craig Reese: IDA/Supercomputing Research Center
       
     6  * Joe Campbell: Department of Defense
       
     7  *
       
     8  * References:
       
     9  * 1) CCITT Recommendation G.711  (very difficult to follow)
       
    10  * 2) "A New Digital Technique for Implementation of Any 
       
    11  *     Continuous PCM Companding Law," Villeret, Michel,
       
    12  *     et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
       
    13  *     1973, pg. 11.12-11.17
       
    14  * 3) MIL-STD-188-113,"Interoperability and Performance Standards
       
    15  *     for Analog-to_Digital Conversion Techniques,"
       
    16  *     17 February 1987
       
    17  *
       
    18  * Input: Signed 16 bit linear sample
       
    19  * Output: 8 bit ulaw sample
       
    20  */
       
    21 
       
    22 #ifdef HAVE_CONFIG_H
       
    23 #include "config.h"
       
    24 #endif
       
    25 
       
    26 #include <glib.h>
       
    27 
       
    28 #undef ZEROTRAP                 /* turn on the trap as per the MIL-STD */
       
    29 #define BIAS 0x84               /* define the add-in bias for 16 bit samples */
       
    30 #define CLIP 32635
       
    31 
       
    32 void
       
    33 mulaw_encode (gint16 * in, guint8 * out, gint numsamples)
       
    34 {
       
    35   static gint16 exp_lut[256] = { 0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
       
    36     4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
       
    37     5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
       
    38     5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
       
    39     6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
       
    40     6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
       
    41     6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
       
    42     6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
       
    43     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
       
    44     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
       
    45     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
       
    46     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
       
    47     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
       
    48     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
       
    49     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
       
    50     7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
       
    51   };
       
    52   gint16 sign, exponent, mantissa, i;
       
    53   gint16 sample;
       
    54   guint8 ulawbyte;
       
    55 
       
    56   for (i = 0; i < numsamples; i++) {
       
    57     sample = in[i];
       
    58       /** get the sample into sign-magnitude **/
       
    59     sign = (sample >> 8) & 0x80;        /* set aside the sign */
       
    60     if (sign != 0) {
       
    61       sample = -sample;         /* get magnitude */
       
    62     }
       
    63     /* sample can be zero because we can overflow in the inversion,
       
    64      * checking against the unsigned version solves this */
       
    65     if (((guint16) sample) > CLIP)
       
    66       sample = CLIP;            /* clip the magnitude */
       
    67 
       
    68       /** convert from 16 bit linear to ulaw **/
       
    69     sample = sample + BIAS;
       
    70     exponent = exp_lut[(sample >> 7) & 0xFF];
       
    71     mantissa = (sample >> (exponent + 3)) & 0x0F;
       
    72     ulawbyte = ~(sign | (exponent << 4) | mantissa);
       
    73 #ifdef ZEROTRAP
       
    74     if (ulawbyte == 0)
       
    75       ulawbyte = 0x02;          /* optional CCITT trap */
       
    76 #endif
       
    77     out[i] = ulawbyte;
       
    78   }
       
    79 }
       
    80 
       
    81 /*
       
    82  * This routine converts from ulaw to 16 bit linear
       
    83  * 29 September 1989
       
    84  *
       
    85  * Craig Reese: IDA/Supercomputing Research Center
       
    86  *
       
    87  * References:
       
    88  * 1) CCITT Recommendation G.711  (very difficult to follow)
       
    89  * 2) MIL-STD-188-113,"Interoperability and Performance Standards
       
    90  *     for Analog-to_Digital Conversion Techniques,"
       
    91  *     17 February 1987
       
    92  *
       
    93  * Input: 8 bit ulaw sample
       
    94  * Output: signed 16 bit linear sample
       
    95  */
       
    96 
       
    97 void
       
    98 mulaw_decode (guint8 * in, gint16 * out, gint numsamples)
       
    99 {
       
   100   static gint16 exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
       
   101   gint16 sign, exponent, mantissa;
       
   102   guint8 ulawbyte;
       
   103   gint16 linear, i;
       
   104 
       
   105   for (i = 0; i < numsamples; i++) {
       
   106     ulawbyte = in[i];
       
   107     ulawbyte = ~ulawbyte;
       
   108     sign = (ulawbyte & 0x80);
       
   109     exponent = (ulawbyte >> 4) & 0x07;
       
   110     mantissa = ulawbyte & 0x0F;
       
   111     linear = exp_lut[exponent] + (mantissa << (exponent + 3));
       
   112     if (sign != 0)
       
   113       linear = -linear;
       
   114     out[i] = linear;
       
   115   }
       
   116 }