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 } |
|