blob: 3b07d8ba8ffd7b0ae03b3e9446f89a8963ea9888 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
2 * SpanDSP - a series of DSP components for telephony
3 *
4 * g711.h - In line A-law and u-law conversion routines
5 *
6 * Written by Steve Underwood <steveu@coppice.org>
7 *
8 * Copyright (C) 2001 Steve Underwood
9 *
10 * Despite my general liking of the GPL, I place this code in the
11 * public domain for the benefit of all mankind - even the slimy
12 * ones who might try to proprietize my work and use it to my
13 * detriment.
14 *
15 * $Id: g711.h,v 1.1 2006/06/07 15:46:39 steveu Exp $
16 *
17 * Modifications for WebRtc, 2011/04/28, by tlegrand:
18 * -Changed to use WebRtc types
19 * -Changed __inline__ to __inline
20 * -Two changes to make implementation bitexact with ITU-T reference implementation
21 */
22
niklase@google.com470e71d2011-07-07 08:21:25 +000023/*! \page g711_page A-law and mu-law handling
24Lookup tables for A-law and u-law look attractive, until you consider the impact
25on the CPU cache. If it causes a substantial area of your processor cache to get
26hit too often, cache sloshing will severely slow things down. The main reason
27these routines are slow in C, is the lack of direct access to the CPU's "find
28the first 1" instruction. A little in-line assembler fixes that, and the
29conversion routines can be faster than lookup tables, in most real world usage.
30A "find the first 1" instruction is available on most modern CPUs, and is a
pbos@webrtc.orgae4e2b32013-03-21 13:38:29 +000031much underused feature.
niklase@google.com470e71d2011-07-07 08:21:25 +000032
33If an assembly language method of bit searching is not available, these routines
34revert to a method that can be a little slow, so the cache thrashing might not
35seem so bad :(
36
37Feel free to submit patches to add fast "find the first 1" support for your own
38favourite processor.
39
40Look up tables are used for transcoding between A-law and u-law, since it is
41difficult to achieve the precise transcoding procedure laid down in the G.711
42specification by other means.
43*/
44
45#if !defined(_G711_H_)
46#define _G711_H_
47
48#ifdef __cplusplus
49extern "C" {
50#endif
51
andresp@webrtc.org262e6762014-09-04 13:28:48 +000052#include "webrtc/typedefs.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000053
54#if defined(__i386__)
55/*! \brief Find the bit position of the highest set bit in a word
56 \param bits The word to be searched
57 \return The bit number of the highest set bit, or -1 if the word is zero. */
pbos@webrtc.orgae4e2b32013-03-21 13:38:29 +000058static __inline__ int top_bit(unsigned int bits) {
59 int res;
niklase@google.com470e71d2011-07-07 08:21:25 +000060
pbos@webrtc.orgae4e2b32013-03-21 13:38:29 +000061 __asm__ __volatile__(" movl $-1,%%edx;\n"
62 " bsrl %%eax,%%edx;\n"
63 : "=d" (res)
64 : "a" (bits));
65 return res;
niklase@google.com470e71d2011-07-07 08:21:25 +000066}
niklase@google.com470e71d2011-07-07 08:21:25 +000067
68/*! \brief Find the bit position of the lowest set bit in a word
69 \param bits The word to be searched
70 \return The bit number of the lowest set bit, or -1 if the word is zero. */
pbos@webrtc.orgae4e2b32013-03-21 13:38:29 +000071static __inline__ int bottom_bit(unsigned int bits) {
72 int res;
niklase@google.com470e71d2011-07-07 08:21:25 +000073
pbos@webrtc.orgae4e2b32013-03-21 13:38:29 +000074 __asm__ __volatile__(" movl $-1,%%edx;\n"
75 " bsfl %%eax,%%edx;\n"
76 : "=d" (res)
77 : "a" (bits));
78 return res;
niklase@google.com470e71d2011-07-07 08:21:25 +000079}
niklase@google.com470e71d2011-07-07 08:21:25 +000080#elif defined(__x86_64__)
pbos@webrtc.orgae4e2b32013-03-21 13:38:29 +000081static __inline__ int top_bit(unsigned int bits) {
82 int res;
niklase@google.com470e71d2011-07-07 08:21:25 +000083
pbos@webrtc.orgae4e2b32013-03-21 13:38:29 +000084 __asm__ __volatile__(" movq $-1,%%rdx;\n"
85 " bsrq %%rax,%%rdx;\n"
86 : "=d" (res)
87 : "a" (bits));
88 return res;
niklase@google.com470e71d2011-07-07 08:21:25 +000089}
niklase@google.com470e71d2011-07-07 08:21:25 +000090
pbos@webrtc.orgae4e2b32013-03-21 13:38:29 +000091static __inline__ int bottom_bit(unsigned int bits) {
92 int res;
niklase@google.com470e71d2011-07-07 08:21:25 +000093
pbos@webrtc.orgae4e2b32013-03-21 13:38:29 +000094 __asm__ __volatile__(" movq $-1,%%rdx;\n"
95 " bsfq %%rax,%%rdx;\n"
96 : "=d" (res)
97 : "a" (bits));
98 return res;
niklase@google.com470e71d2011-07-07 08:21:25 +000099}
niklase@google.com470e71d2011-07-07 08:21:25 +0000100#else
pbos@webrtc.orgae4e2b32013-03-21 13:38:29 +0000101static __inline int top_bit(unsigned int bits) {
102 int i;
niklase@google.com470e71d2011-07-07 08:21:25 +0000103
pbos@webrtc.orgae4e2b32013-03-21 13:38:29 +0000104 if (bits == 0) {
105 return -1;
106 }
107 i = 0;
108 if (bits & 0xFFFF0000) {
109 bits &= 0xFFFF0000;
110 i += 16;
111 }
112 if (bits & 0xFF00FF00) {
113 bits &= 0xFF00FF00;
114 i += 8;
115 }
116 if (bits & 0xF0F0F0F0) {
117 bits &= 0xF0F0F0F0;
118 i += 4;
119 }
120 if (bits & 0xCCCCCCCC) {
121 bits &= 0xCCCCCCCC;
122 i += 2;
123 }
124 if (bits & 0xAAAAAAAA) {
125 bits &= 0xAAAAAAAA;
126 i += 1;
127 }
128 return i;
niklase@google.com470e71d2011-07-07 08:21:25 +0000129}
pbos@webrtc.orgae4e2b32013-03-21 13:38:29 +0000130
131static __inline int bottom_bit(unsigned int bits) {
132 int i;
133
134 if (bits == 0) {
135 return -1;
136 }
137 i = 32;
138 if (bits & 0x0000FFFF) {
139 bits &= 0x0000FFFF;
140 i -= 16;
141 }
142 if (bits & 0x00FF00FF) {
143 bits &= 0x00FF00FF;
144 i -= 8;
145 }
146 if (bits & 0x0F0F0F0F) {
147 bits &= 0x0F0F0F0F;
148 i -= 4;
149 }
150 if (bits & 0x33333333) {
151 bits &= 0x33333333;
152 i -= 2;
153 }
154 if (bits & 0x55555555) {
155 bits &= 0x55555555;
156 i -= 1;
157 }
158 return i;
159}
niklase@google.com470e71d2011-07-07 08:21:25 +0000160#endif
161
162/* N.B. It is tempting to use look-up tables for A-law and u-law conversion.
163 * However, you should consider the cache footprint.
164 *
165 * A 64K byte table for linear to x-law and a 512 byte table for x-law to
166 * linear sound like peanuts these days, and shouldn't an array lookup be
167 * real fast? No! When the cache sloshes as badly as this one will, a tight
168 * calculation may be better. The messiest part is normally finding the
169 * segment, but a little inline assembly can fix that on an i386, x86_64 and
170 * many other modern processors.
171 */
pbos@webrtc.orgae4e2b32013-03-21 13:38:29 +0000172
niklase@google.com470e71d2011-07-07 08:21:25 +0000173/*
174 * Mu-law is basically as follows:
175 *
176 * Biased Linear Input Code Compressed Code
177 * ------------------------ ---------------
178 * 00000001wxyza 000wxyz
179 * 0000001wxyzab 001wxyz
180 * 000001wxyzabc 010wxyz
181 * 00001wxyzabcd 011wxyz
182 * 0001wxyzabcde 100wxyz
183 * 001wxyzabcdef 101wxyz
184 * 01wxyzabcdefg 110wxyz
185 * 1wxyzabcdefgh 111wxyz
186 *
187 * Each biased linear code has a leading 1 which identifies the segment
188 * number. The value of the segment number is equal to 7 minus the number
189 * of leading 0's. The quantization interval is directly available as the
190 * four bits wxyz. * The trailing bits (a - h) are ignored.
191 *
192 * Ordinarily the complement of the resulting code word is used for
193 * transmission, and so the code word is complemented before it is returned.
194 *
195 * For further information see John C. Bellamy's Digital Telephony, 1982,
196 * John Wiley & Sons, pps 98-111 and 472-476.
197 */
198
199//#define ULAW_ZEROTRAP /* turn on the trap as per the MIL-STD */
pbos@webrtc.orgae4e2b32013-03-21 13:38:29 +0000200#define ULAW_BIAS 0x84 /* Bias for linear code. */
niklase@google.com470e71d2011-07-07 08:21:25 +0000201
202/*! \brief Encode a linear sample to u-law
203 \param linear The sample to encode.
204 \return The u-law value.
205*/
pbos@webrtc.orgae4e2b32013-03-21 13:38:29 +0000206static __inline uint8_t linear_to_ulaw(int linear) {
207 uint8_t u_val;
208 int mask;
209 int seg;
niklase@google.com470e71d2011-07-07 08:21:25 +0000210
pbos@webrtc.orgae4e2b32013-03-21 13:38:29 +0000211 /* Get the sign and the magnitude of the value. */
212 if (linear < 0) {
213 /* WebRtc, tlegrand: -1 added to get bitexact to reference implementation */
214 linear = ULAW_BIAS - linear - 1;
215 mask = 0x7F;
216 } else {
217 linear = ULAW_BIAS + linear;
218 mask = 0xFF;
219 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000220
pbos@webrtc.orgae4e2b32013-03-21 13:38:29 +0000221 seg = top_bit(linear | 0xFF) - 7;
niklase@google.com470e71d2011-07-07 08:21:25 +0000222
pbos@webrtc.orgae4e2b32013-03-21 13:38:29 +0000223 /*
224 * Combine the sign, segment, quantization bits,
225 * and complement the code word.
226 */
227 if (seg >= 8)
228 u_val = (uint8_t)(0x7F ^ mask);
229 else
230 u_val = (uint8_t)(((seg << 4) | ((linear >> (seg + 3)) & 0xF)) ^ mask);
niklase@google.com470e71d2011-07-07 08:21:25 +0000231#ifdef ULAW_ZEROTRAP
pbos@webrtc.orgae4e2b32013-03-21 13:38:29 +0000232 /* Optional ITU trap */
233 if (u_val == 0)
234 u_val = 0x02;
niklase@google.com470e71d2011-07-07 08:21:25 +0000235#endif
pbos@webrtc.orgae4e2b32013-03-21 13:38:29 +0000236 return u_val;
niklase@google.com470e71d2011-07-07 08:21:25 +0000237}
niklase@google.com470e71d2011-07-07 08:21:25 +0000238
239/*! \brief Decode an u-law sample to a linear value.
240 \param ulaw The u-law sample to decode.
241 \return The linear value.
242*/
pbos@webrtc.orgae4e2b32013-03-21 13:38:29 +0000243static __inline int16_t ulaw_to_linear(uint8_t ulaw) {
244 int t;
245
246 /* Complement to obtain normal u-law value. */
247 ulaw = ~ulaw;
248 /*
249 * Extract and bias the quantization bits. Then
250 * shift up by the segment number and subtract out the bias.
251 */
252 t = (((ulaw & 0x0F) << 3) + ULAW_BIAS) << (((int) ulaw & 0x70) >> 4);
253 return (int16_t)((ulaw & 0x80) ? (ULAW_BIAS - t) : (t - ULAW_BIAS));
niklase@google.com470e71d2011-07-07 08:21:25 +0000254}
niklase@google.com470e71d2011-07-07 08:21:25 +0000255
256/*
257 * A-law is basically as follows:
258 *
259 * Linear Input Code Compressed Code
260 * ----------------- ---------------
261 * 0000000wxyza 000wxyz
262 * 0000001wxyza 001wxyz
263 * 000001wxyzab 010wxyz
264 * 00001wxyzabc 011wxyz
265 * 0001wxyzabcd 100wxyz
266 * 001wxyzabcde 101wxyz
267 * 01wxyzabcdef 110wxyz
268 * 1wxyzabcdefg 111wxyz
269 *
270 * For further information see John C. Bellamy's Digital Telephony, 1982,
271 * John Wiley & Sons, pps 98-111 and 472-476.
272 */
273
pbos@webrtc.orgae4e2b32013-03-21 13:38:29 +0000274#define ALAW_AMI_MASK 0x55
niklase@google.com470e71d2011-07-07 08:21:25 +0000275
276/*! \brief Encode a linear sample to A-law
277 \param linear The sample to encode.
278 \return The A-law value.
279*/
pbos@webrtc.orgae4e2b32013-03-21 13:38:29 +0000280static __inline uint8_t linear_to_alaw(int linear) {
281 int mask;
282 int seg;
niklase@google.com470e71d2011-07-07 08:21:25 +0000283
pbos@webrtc.orgae4e2b32013-03-21 13:38:29 +0000284 if (linear >= 0) {
285 /* Sign (bit 7) bit = 1 */
286 mask = ALAW_AMI_MASK | 0x80;
287 } else {
288 /* Sign (bit 7) bit = 0 */
289 mask = ALAW_AMI_MASK;
290 /* WebRtc, tlegrand: Changed from -8 to -1 to get bitexact to reference
291 * implementation */
292 linear = -linear - 1;
293 }
294
295 /* Convert the scaled magnitude to segment number. */
296 seg = top_bit(linear | 0xFF) - 7;
297 if (seg >= 8) {
298 if (linear >= 0) {
299 /* Out of range. Return maximum value. */
300 return (uint8_t)(0x7F ^ mask);
niklase@google.com470e71d2011-07-07 08:21:25 +0000301 }
pbos@webrtc.orgae4e2b32013-03-21 13:38:29 +0000302 /* We must be just a tiny step below zero */
303 return (uint8_t)(0x00 ^ mask);
304 }
305 /* Combine the sign, segment, and quantization bits. */
306 return (uint8_t)(((seg << 4) | ((linear >> ((seg) ? (seg + 3) : 4)) & 0x0F)) ^
307 mask);
niklase@google.com470e71d2011-07-07 08:21:25 +0000308}
niklase@google.com470e71d2011-07-07 08:21:25 +0000309
310/*! \brief Decode an A-law sample to a linear value.
311 \param alaw The A-law sample to decode.
312 \return The linear value.
313*/
pbos@webrtc.orgae4e2b32013-03-21 13:38:29 +0000314static __inline int16_t alaw_to_linear(uint8_t alaw) {
315 int i;
316 int seg;
niklase@google.com470e71d2011-07-07 08:21:25 +0000317
pbos@webrtc.orgae4e2b32013-03-21 13:38:29 +0000318 alaw ^= ALAW_AMI_MASK;
319 i = ((alaw & 0x0F) << 4);
320 seg = (((int) alaw & 0x70) >> 4);
321 if (seg)
322 i = (i + 0x108) << (seg - 1);
323 else
324 i += 8;
325 return (int16_t)((alaw & 0x80) ? i : -i);
niklase@google.com470e71d2011-07-07 08:21:25 +0000326}
niklase@google.com470e71d2011-07-07 08:21:25 +0000327
328/*! \brief Transcode from A-law to u-law, using the procedure defined in G.711.
329 \param alaw The A-law sample to transcode.
330 \return The best matching u-law value.
331*/
pbos@webrtc.orgae4e2b32013-03-21 13:38:29 +0000332uint8_t alaw_to_ulaw(uint8_t alaw);
niklase@google.com470e71d2011-07-07 08:21:25 +0000333
334/*! \brief Transcode from u-law to A-law, using the procedure defined in G.711.
335 \param alaw The u-law sample to transcode.
336 \return The best matching A-law value.
337*/
pbos@webrtc.orgae4e2b32013-03-21 13:38:29 +0000338uint8_t ulaw_to_alaw(uint8_t ulaw);
niklase@google.com470e71d2011-07-07 08:21:25 +0000339
340#ifdef __cplusplus
341}
342#endif
343
344#endif