comparison spandsp-0.0.3/spandsp-0.0.3/src/spandsp/g711.h @ 5:f762bf195c4b

import spandsp-0.0.3
author Peter Meerwald <pmeerw@cosy.sbg.ac.at>
date Fri, 25 Jun 2010 16:00:21 +0200
parents
children
comparison
equal deleted inserted replaced
4:26cd8f1ef0b1 5:f762bf195c4b
1 /*
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 * All rights reserved.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2, as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * $Id: g711.h,v 1.3 2006/10/24 13:45:28 steveu Exp $
26 */
27
28 /*! \file */
29
30 /*! \page g711_page A-law and mu-law handling
31 Lookup tables for A-law and u-law look attractive, until you consider the impact
32 on the CPU cache. If it causes a substantial area of your processor cache to get
33 hit too often, cache sloshing will severely slow things down. The main reason
34 these routines are slow in C, is the lack of direct access to the CPU's "find
35 the first 1" instruction. A little in-line assembler fixes that, and the
36 conversion routines can be faster than lookup tables, in most real world usage.
37 A "find the first 1" instruction is available on most modern CPUs, and is a
38 much underused feature.
39
40 If an assembly language method of bit searching is not available, these routines
41 revert to a method that can be a little slow, so the cache thrashing might not
42 seem so bad :(
43
44 Feel free to submit patches to add fast "find the first 1" support for your own
45 favourite processor.
46
47 Look up tables are used for transcoding between A-law and u-law, since it is
48 difficult to achieve the precise transcoding procedure laid down in the G.711
49 specification by other means.
50 */
51
52 #if !defined(_G711_H_)
53 #define _G711_H_
54
55 #ifdef __cplusplus
56 extern "C" {
57 #endif
58
59 /* N.B. It is tempting to use look-up tables for A-law and u-law conversion.
60 * However, you should consider the cache footprint.
61 *
62 * A 64K byte table for linear to x-law and a 512 byte table for x-law to
63 * linear sound like peanuts these days, and shouldn't an array lookup be
64 * real fast? No! When the cache sloshes as badly as this one will, a tight
65 * calculation may be better. The messiest part is normally finding the
66 * segment, but a little inline assembly can fix that on an i386, x86_64 and
67 * many other modern processors.
68 */
69
70 /*
71 * Mu-law is basically as follows:
72 *
73 * Biased Linear Input Code Compressed Code
74 * ------------------------ ---------------
75 * 00000001wxyza 000wxyz
76 * 0000001wxyzab 001wxyz
77 * 000001wxyzabc 010wxyz
78 * 00001wxyzabcd 011wxyz
79 * 0001wxyzabcde 100wxyz
80 * 001wxyzabcdef 101wxyz
81 * 01wxyzabcdefg 110wxyz
82 * 1wxyzabcdefgh 111wxyz
83 *
84 * Each biased linear code has a leading 1 which identifies the segment
85 * number. The value of the segment number is equal to 7 minus the number
86 * of leading 0's. The quantization interval is directly available as the
87 * four bits wxyz. * The trailing bits (a - h) are ignored.
88 *
89 * Ordinarily the complement of the resulting code word is used for
90 * transmission, and so the code word is complemented before it is returned.
91 *
92 * For further information see John C. Bellamy's Digital Telephony, 1982,
93 * John Wiley & Sons, pps 98-111 and 472-476.
94 */
95
96 //#define ULAW_ZEROTRAP /* turn on the trap as per the MIL-STD */
97 #define ULAW_BIAS 0x84 /* Bias for linear code. */
98
99 /*! \brief Encode a linear sample to u-law
100 \param linear The sample to encode.
101 \return The u-law value.
102 */
103 static __inline__ uint8_t linear_to_ulaw(int linear)
104 {
105 uint8_t u_val;
106 int mask;
107 int seg;
108
109 /* Get the sign and the magnitude of the value. */
110 if (linear < 0)
111 {
112 linear = ULAW_BIAS - linear;
113 mask = 0x7F;
114 }
115 else
116 {
117 linear = ULAW_BIAS + linear;
118 mask = 0xFF;
119 }
120
121 seg = top_bit(linear | 0xFF) - 7;
122
123 /*
124 * Combine the sign, segment, quantization bits,
125 * and complement the code word.
126 */
127 if (seg >= 8)
128 u_val = (uint8_t) (0x7F ^ mask);
129 else
130 u_val = (uint8_t) (((seg << 4) | ((linear >> (seg + 3)) & 0xF)) ^ mask);
131 #ifdef ULAW_ZEROTRAP
132 /* Optional ITU trap */
133 if (u_val == 0)
134 u_val = 0x02;
135 #endif
136 return u_val;
137 }
138 /*- End of function --------------------------------------------------------*/
139
140 /*! \brief Decode an u-law sample to a linear value.
141 \param ulaw The u-law sample to decode.
142 \return The linear value.
143 */
144 static __inline__ int16_t ulaw_to_linear(uint8_t ulaw)
145 {
146 int t;
147
148 /* Complement to obtain normal u-law value. */
149 ulaw = ~ulaw;
150 /*
151 * Extract and bias the quantization bits. Then
152 * shift up by the segment number and subtract out the bias.
153 */
154 t = (((ulaw & 0x0F) << 3) + ULAW_BIAS) << (((int) ulaw & 0x70) >> 4);
155 return (int16_t) ((ulaw & 0x80) ? (ULAW_BIAS - t) : (t - ULAW_BIAS));
156 }
157 /*- End of function --------------------------------------------------------*/
158
159 /*
160 * A-law is basically as follows:
161 *
162 * Linear Input Code Compressed Code
163 * ----------------- ---------------
164 * 0000000wxyza 000wxyz
165 * 0000001wxyza 001wxyz
166 * 000001wxyzab 010wxyz
167 * 00001wxyzabc 011wxyz
168 * 0001wxyzabcd 100wxyz
169 * 001wxyzabcde 101wxyz
170 * 01wxyzabcdef 110wxyz
171 * 1wxyzabcdefg 111wxyz
172 *
173 * For further information see John C. Bellamy's Digital Telephony, 1982,
174 * John Wiley & Sons, pps 98-111 and 472-476.
175 */
176
177 #define ALAW_AMI_MASK 0x55
178
179 /*! \brief Encode a linear sample to A-law
180 \param linear The sample to encode.
181 \return The A-law value.
182 */
183 static __inline__ uint8_t linear_to_alaw(int linear)
184 {
185 int mask;
186 int seg;
187
188 if (linear >= 0)
189 {
190 /* Sign (bit 7) bit = 1 */
191 mask = ALAW_AMI_MASK | 0x80;
192 }
193 else
194 {
195 /* Sign (bit 7) bit = 0 */
196 mask = ALAW_AMI_MASK;
197 linear = -linear - 8;
198 }
199
200 /* Convert the scaled magnitude to segment number. */
201 seg = top_bit(linear | 0xFF) - 7;
202 if (seg >= 8)
203 {
204 if (linear >= 0)
205 {
206 /* Out of range. Return maximum value. */
207 return (uint8_t) (0x7F ^ mask);
208 }
209 /* We must be just a tiny step below zero */
210 return (uint8_t) (0x00 ^ mask);
211 }
212 /* Combine the sign, segment, and quantization bits. */
213 return (uint8_t) (((seg << 4) | ((linear >> ((seg) ? (seg + 3) : 4)) & 0x0F)) ^ mask);
214 }
215 /*- End of function --------------------------------------------------------*/
216
217 /*! \brief Decode an A-law sample to a linear value.
218 \param alaw The A-law sample to decode.
219 \return The linear value.
220 */
221 static __inline__ int16_t alaw_to_linear(uint8_t alaw)
222 {
223 int i;
224 int seg;
225
226 alaw ^= ALAW_AMI_MASK;
227 i = ((alaw & 0x0F) << 4);
228 seg = (((int) alaw & 0x70) >> 4);
229 if (seg)
230 i = (i + 0x108) << (seg - 1);
231 else
232 i += 8;
233 return (int16_t) ((alaw & 0x80) ? i : -i);
234 }
235 /*- End of function --------------------------------------------------------*/
236
237 /*! \brief Transcode from A-law to u-law, using the procedure defined in G.711.
238 \param alaw The A-law sample to transcode.
239 \return The best matching u-law value.
240 */
241 uint8_t alaw_to_ulaw(uint8_t alaw);
242
243 /*! \brief Transcode from u-law to A-law, using the procedure defined in G.711.
244 \param alaw The u-law sample to transcode.
245 \return The best matching A-law value.
246 */
247 uint8_t ulaw_to_alaw(uint8_t ulaw);
248
249 #ifdef __cplusplus
250 }
251 #endif
252
253 #endif
254 /*- End of file ------------------------------------------------------------*/

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.