Initial revision
[platform/upstream/gst-plugins-good.git] / gst / law / mulaw-conversion.c
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 #include <glib.h>
23
24 #define ZEROTRAP    /* turn on the trap as per the MIL-STD */
25 #define BIAS 0x84   /* define the add-in bias for 16 bit samples */
26 #define CLIP 32635
27
28 void
29 mulaw_encode(gint16* in, guint8* out, gint numsamples)
30 {
31     static gint16 exp_lut[256] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
32                                4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
33                                5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
34                                5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
35                                6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
36                                6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
37                                6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
38                                6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
39                                7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
40                                7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
41                                7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
42                                7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
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     gint16 sign, exponent, mantissa,i;
48     gint16 sample;
49     guint8 ulawbyte;
50
51     for(i=0;i<numsamples;i++) {
52       sample=in[i];
53       /** get the sample into sign-magnitude **/
54       sign = (sample >> 8) & 0x80;        /* set aside the sign */
55       if (sign != 0) sample = -sample;    /* get magnitude */
56       if (sample > CLIP) sample = CLIP;   /* clip the magnitude */
57       /** convert from 16 bit linear to ulaw **/
58       sample = sample + BIAS;
59       exponent = exp_lut[(sample>>7) & 0xFF];
60       mantissa = (sample >> (exponent+3)) & 0x0F;
61       ulawbyte = ~(sign | (exponent << 4) | mantissa);
62 #ifdef ZEROTRAP
63       if (ulawbyte == 0 ) ulawbyte = 0x02;  /* optional CCITT trap */
64 #endif
65       out[i]=ulawbyte;
66     }
67 }
68
69 /*
70  * This routine converts from ulaw to 16 bit linear
71  * 29 September 1989
72  *
73  * Craig Reese: IDA/Supercomputing Research Center
74  *
75  * References:
76  * 1) CCITT Recommendation G.711  (very difficult to follow)
77  * 2) MIL-STD-188-113,"Interoperability and Performance Standards
78  *     for Analog-to_Digital Conversion Techniques,"
79  *     17 February 1987
80  *
81  * Input: 8 bit ulaw sample
82  * Output: signed 16 bit linear sample
83  */
84
85 void
86 mulaw_decode(guint8* in,gint16* out,gint numsamples)
87 {
88     static gint16 exp_lut[8]={0,132,396,924,1980,4092,8316,16764};
89     gint16 sign, exponent, mantissa;
90     guint8 ulawbyte;
91     gint16 linear,i;
92     for(i=0;i<numsamples;i++) {
93       ulawbyte=in[i];
94       ulawbyte = ~ulawbyte;
95       sign = (ulawbyte & 0x80);
96       exponent = (ulawbyte >> 4) & 0x07;
97       mantissa = ulawbyte & 0x0F;
98       linear = exp_lut[exponent] + (mantissa << (exponent+3));
99       if (sign != 0) linear = -linear;
100       out[i]=linear;
101     }
102 }