00001 /* 00002 * SpanDSP - a series of DSP components for telephony 00003 * 00004 * alaw_ulaw.h - In line A-law and u-law conversion routines 00005 * 00006 * Written by Steve Underwood <steveu@coppice.org> 00007 * 00008 * Copyright (C) 2001 Steve Underwood 00009 * 00010 * All rights reserved. 00011 * 00012 * This program is free software; you can redistribute it and/or modify 00013 * it under the terms of the GNU General Public License as published by 00014 * the Free Software Foundation; either version 2 of the License, or 00015 * (at your option) any later version. 00016 * 00017 * This program is distributed in the hope that it will be useful, 00018 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 * GNU General Public License for more details. 00021 * 00022 * You should have received a copy of the GNU General Public License 00023 * along with this program; if not, write to the Free Software 00024 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00025 * 00026 * $Id: alaw_ulaw.h,v 1.13 2006/01/18 13:21:37 steveu Exp $ 00027 */ 00028 00029 /*! \file */ 00030 00031 /*! \page alaw_ulaw_page A-law and mu-law handling 00032 Lookup tables for A-law and u-law look attractive, until you consider the impact 00033 on the CPU cache. If it causes a substantial area of your processor cache to get 00034 hit too often, cache sloshing will severely slow things down. The main reason 00035 these routines are slow in C, is the lack of direct access to the CPU's "find 00036 the first 1" instruction. A little in-line assembler fixes that, and the 00037 conversion routines can be faster than lookup tables, in most real world usage. 00038 A "find the first 1" instruction is available on most modern CPUs, and is a 00039 much underused feature. 00040 00041 If an assembly language method of bit searching is not available, these routines 00042 revert to a method that can be a little slow, so the cache thrashing might not 00043 seem so bad :( 00044 00045 Feel free to submit patches to add fast "find the first 1" support for your own 00046 favourite processor. 00047 */ 00048 00049 #if !defined(_ALAW_ULAW_H_) 00050 #define _ALAW_ULAW_H_ 00051 00052 #ifdef __cplusplus 00053 extern "C" { 00054 #endif 00055 00056 #if defined(__i386__) 00057 static __inline__ int top_bit(unsigned int bits) 00058 { 00059 int res; 00060 00061 __asm__ __volatile__(" movl $-1,%%edx;\n" 00062 " bsrl %%eax,%%edx;\n" 00063 : "=d" (res) 00064 : "a" (bits)); 00065 return res; 00066 } 00067 /*- End of function --------------------------------------------------------*/ 00068 00069 static __inline__ int bottom_bit(unsigned int bits) 00070 { 00071 int res; 00072 00073 __asm__ __volatile__(" movl $-1,%%edx;\n" 00074 " bsfl %%eax,%%edx;\n" 00075 : "=d" (res) 00076 : "a" (bits)); 00077 return res; 00078 } 00079 /*- End of function --------------------------------------------------------*/ 00080 #elif defined(__x86_64__) 00081 static __inline__ int top_bit(unsigned int bits) 00082 { 00083 int res; 00084 00085 __asm__ __volatile__(" movq $-1,%%rdx;\n" 00086 " bsrq %%rax,%%rdx;\n" 00087 : "=d" (res) 00088 : "a" (bits)); 00089 return res; 00090 } 00091 /*- End of function --------------------------------------------------------*/ 00092 00093 static __inline__ int bottom_bit(unsigned int bits) 00094 { 00095 int res; 00096 00097 __asm__ __volatile__(" movq $-1,%%rdx;\n" 00098 " bsfq %%eax,%%edx;\n" 00099 : "=d" (res) 00100 : "a" (bits)); 00101 return res; 00102 } 00103 /*- End of function --------------------------------------------------------*/ 00104 #else 00105 static __inline__ int top_bit(unsigned int bits) 00106 { 00107 int i; 00108 00109 if (bits == 0) 00110 return -1; 00111 i = 0; 00112 if (bits & 0xFFFF0000) 00113 { 00114 bits &= 0xFFFF0000; 00115 i += 16; 00116 } 00117 if (bits & 0xFF00FF00) 00118 { 00119 bits &= 0xFF00FF00; 00120 i += 8; 00121 } 00122 if (bits & 0xF0F0F0F0) 00123 { 00124 bits &= 0xF0F0F0F0; 00125 i += 4; 00126 } 00127 if (bits & 0xCCCCCCCC) 00128 { 00129 bits &= 0xCCCCCCCC; 00130 i += 2; 00131 } 00132 if (bits & 0xAAAAAAAA) 00133 { 00134 bits &= 0xAAAAAAAA; 00135 i += 1; 00136 } 00137 return i; 00138 } 00139 /*- End of function --------------------------------------------------------*/ 00140 00141 static __inline__ int bottom_bit(unsigned int bits) 00142 { 00143 int i; 00144 00145 if (bits == 0) 00146 return -1; 00147 i = 32; 00148 if (bits & 0x0000FFFF) 00149 { 00150 bits &= 0x0000FFFF; 00151 i -= 16; 00152 } 00153 if (bits & 0x00FF00FF) 00154 { 00155 bits &= 0x00FF00FF; 00156 i -= 8; 00157 } 00158 if (bits & 0x0F0F0F0F) 00159 { 00160 bits &= 0x0F0F0F0F; 00161 i -= 4; 00162 } 00163 if (bits & 0x33333333) 00164 { 00165 bits &= 0x33333333; 00166 i -= 2; 00167 } 00168 if (bits & 0x55555555) 00169 { 00170 bits &= 0x55555555; 00171 i -= 1; 00172 } 00173 return i; 00174 } 00175 /*- End of function --------------------------------------------------------*/ 00176 #endif 00177 00178 /* N.B. It is tempting to use look-up tables for A-law and u-law conversion. 00179 * However, you should consider the cache footprint. 00180 * 00181 * A 64K byte table for linear to x-law and a 512 byte sound like peanuts 00182 * these days, and shouldn't an array lookup be real fast? No! When the 00183 * cache sloshes as badly as this one will, a tight calculation is better. 00184 * The messiest part is normally finding the segment, but a little inline 00185 * assembly can fix that on an i386. 00186 */ 00187 00188 /* 00189 * Mu-law is basically as follows: 00190 * 00191 * Biased Linear Input Code Compressed Code 00192 * ------------------------ --------------- 00193 * 00000001wxyza 000wxyz 00194 * 0000001wxyzab 001wxyz 00195 * 000001wxyzabc 010wxyz 00196 * 00001wxyzabcd 011wxyz 00197 * 0001wxyzabcde 100wxyz 00198 * 001wxyzabcdef 101wxyz 00199 * 01wxyzabcdefg 110wxyz 00200 * 1wxyzabcdefgh 111wxyz 00201 * 00202 * Each biased linear code has a leading 1 which identifies the segment 00203 * number. The value of the segment number is equal to 7 minus the number 00204 * of leading 0's. The quantization interval is directly available as the 00205 * four bits wxyz. * The trailing bits (a - h) are ignored. 00206 * 00207 * Ordinarily the complement of the resulting code word is used for 00208 * transmission, and so the code word is complemented before it is returned. 00209 * 00210 * For further information see John C. Bellamy's Digital Telephony, 1982, 00211 * John Wiley & Sons, pps 98-111 and 472-476. 00212 */ 00213 00214 //#define ZEROTRAP /* turn on the trap as per the MIL-STD */ 00215 #define BIAS 0x84 /* Bias for linear code. */ 00216 00217 static __inline__ uint8_t linear_to_ulaw(int linear) 00218 { 00219 uint8_t u_val; 00220 int mask; 00221 int seg; 00222 00223 /* Get the sign and the magnitude of the value. */ 00224 if (linear < 0) 00225 { 00226 linear = BIAS - linear; 00227 mask = 0x7F; 00228 } 00229 else 00230 { 00231 linear = BIAS + linear; 00232 mask = 0xFF; 00233 } 00234 00235 seg = top_bit(linear | 0xFF) - 7; 00236 00237 /* 00238 * Combine the sign, segment, quantization bits, 00239 * and complement the code word. 00240 */ 00241 if (seg >= 8) 00242 u_val = 0x7F ^ mask; 00243 else 00244 u_val = ((seg << 4) | ((linear >> (seg + 3)) & 0xF)) ^ mask; 00245 #ifdef ZEROTRAP 00246 /* optional ITU trap */ 00247 if (u_val == 0) 00248 u_val = 0x02; 00249 #endif 00250 return u_val; 00251 } 00252 /*- End of function --------------------------------------------------------*/ 00253 00254 static __inline__ int16_t ulaw_to_linear(uint8_t ulaw) 00255 { 00256 int t; 00257 00258 /* Complement to obtain normal u-law value. */ 00259 ulaw = ~ulaw; 00260 /* 00261 * Extract and bias the quantization bits. Then 00262 * shift up by the segment number and subtract out the bias. 00263 */ 00264 t = (((ulaw & 0x0F) << 3) + BIAS) << (((int) ulaw & 0x70) >> 4); 00265 return ((ulaw & 0x80) ? (BIAS - t) : (t - BIAS)); 00266 } 00267 /*- End of function --------------------------------------------------------*/ 00268 00269 /* 00270 * A-law is basically as follows: 00271 * 00272 * Linear Input Code Compressed Code 00273 * ----------------- --------------- 00274 * 0000000wxyza 000wxyz 00275 * 0000001wxyza 001wxyz 00276 * 000001wxyzab 010wxyz 00277 * 00001wxyzabc 011wxyz 00278 * 0001wxyzabcd 100wxyz 00279 * 001wxyzabcde 101wxyz 00280 * 01wxyzabcdef 110wxyz 00281 * 1wxyzabcdefg 111wxyz 00282 * 00283 * For further information see John C. Bellamy's Digital Telephony, 1982, 00284 * John Wiley & Sons, pps 98-111 and 472-476. 00285 */ 00286 00287 #define AMI_MASK 0x55 00288 00289 static __inline__ uint8_t linear_to_alaw(int linear) 00290 { 00291 int mask; 00292 int seg; 00293 00294 if (linear >= 0) 00295 { 00296 /* Sign (7th) bit = 1 */ 00297 mask = AMI_MASK | 0x80; 00298 } 00299 else 00300 { 00301 /* Sign (7th) bit = 0 */ 00302 mask = AMI_MASK; 00303 linear = -linear - 8; 00304 } 00305 00306 /* Convert the scaled magnitude to segment number. */ 00307 seg = top_bit(linear | 0xFF) - 7; 00308 if (seg >= 8) 00309 { 00310 if (linear >= 0) 00311 { 00312 /* Out of range. Return maximum value. */ 00313 return (0x7F ^ mask); 00314 } 00315 /* We must be just a tiny step below zero */ 00316 return (0x00 ^ mask); 00317 } 00318 /* Combine the sign, segment, and quantization bits. */ 00319 return ((seg << 4) | ((linear >> ((seg) ? (seg + 3) : 4)) & 0x0F)) ^ mask; 00320 } 00321 /*- End of function --------------------------------------------------------*/ 00322 00323 static __inline__ int16_t alaw_to_linear(uint8_t alaw) 00324 { 00325 int i; 00326 int seg; 00327 00328 alaw ^= AMI_MASK; 00329 i = ((alaw & 0x0F) << 4); 00330 seg = (((int) alaw & 0x70) >> 4); 00331 if (seg) 00332 i = (i + 0x108) << (seg - 1); 00333 else 00334 i += 8; 00335 return (int16_t) ((alaw & 0x80) ? i : -i); 00336 } 00337 /*- End of function --------------------------------------------------------*/ 00338 00339 #ifdef __cplusplus 00340 } 00341 #endif 00342 00343 #endif 00344 /*- End of file ------------------------------------------------------------*/