00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "asterisk.h"
00027
00028 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 89425 $")
00029
00030 #include "asterisk/ulaw.h"
00031
00032 #if 0
00033
00034
00035
00036
00037
00038 #define ZEROTRAP
00039 #endif
00040
00041 #define BIAS 0x84
00042 #define CLIP 32635
00043
00044 #ifndef G711_NEW_ALGORITHM
00045
00046 unsigned char __ast_lin2mu[16384];
00047 short __ast_mulaw[256];
00048
00049 static unsigned char linear2ulaw(short sample)
00050 {
00051 static int exp_lut[256] = {
00052 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
00053 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
00054 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
00055 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
00056 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00057 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00058 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00059 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00060 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00061 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00062 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00063 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00064 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00065 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00066 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00067 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 };
00068 int sign, exponent, mantissa;
00069 unsigned char ulawbyte;
00070
00071
00072 sign = (sample >> 8) & 0x80;
00073 if (sign != 0)
00074 sample = -sample;
00075 if (sample > CLIP)
00076 sample = CLIP;
00077
00078
00079 sample = sample + BIAS;
00080 exponent = exp_lut[(sample >> 7) & 0xFF];
00081 mantissa = (sample >> (exponent + 3)) & 0x0F;
00082 ulawbyte = ~(sign | (exponent << 4) | mantissa);
00083
00084 #ifdef ZEROTRAP
00085 if (ulawbyte == 0)
00086 ulawbyte = 0x02;
00087 #endif
00088
00089 return ulawbyte;
00090 }
00091
00092 #else
00093
00094 unsigned char __ast_lin2mu[AST_ULAW_TAB_SIZE];
00095 short __ast_mulaw[256];
00096
00097 static unsigned char linear2ulaw(short sample, int full_coding)
00098 {
00099 static const unsigned exp_lut[256] = {
00100 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
00101 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
00102 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
00103 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
00104 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00105 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00106 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00107 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00108 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00109 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00110 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00111 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00112 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00113 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00114 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00115 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 };
00116 unsigned sign, exponent, mantissa, mag;
00117 unsigned char ulawbyte;
00118
00119
00120 ast_ulaw_get_sign_mag(sample, &sign, &mag);
00121 if (mag > CLIP)
00122 mag = CLIP;
00123
00124 sign = (sample >> 8) & 0x80;
00125 if (sign != 0)
00126 sample = -sample;
00127 if (sample > CLIP)
00128 sample = CLIP;
00129
00130
00131 mag += BIAS;
00132 exponent = exp_lut[(mag >> 7) & 0xFF];
00133 mantissa = (mag >> (exponent + 3)) & 0x0F;
00134
00135 if (full_coding) {
00136
00137 ulawbyte = ~(sign | (exponent << 4) | mantissa);
00138 #ifdef ZEROTRAP
00139 if (ulawbyte == 0)
00140 ulawbyte = 0x02;
00141 #endif
00142 } else {
00143
00144 ulawbyte = (exponent << 4) | mantissa;
00145 }
00146
00147 return ulawbyte;
00148 }
00149
00150 static inline short ulaw2linear(unsigned char ulawbyte)
00151 {
00152 unsigned exponent, mantissa;
00153 short sample;
00154 static const short etab[]={0,132,396,924,1980,4092,8316,16764};
00155
00156 ulawbyte = ~ulawbyte;
00157 exponent = (ulawbyte & 0x70) >> 4;
00158 mantissa = ulawbyte & 0x0f;
00159 sample = mantissa << (exponent + 3);
00160 sample += etab[exponent];
00161 if (ulawbyte & 0x80)
00162 sample = -sample;
00163 return sample;
00164 }
00165 #endif
00166
00167
00168
00169
00170 void ast_ulaw_init(void)
00171 {
00172 int i;
00173
00174
00175
00176
00177 #ifndef G711_NEW_ALGORITHM
00178 for (i = 0;i < 256;i++) {
00179 short mu,e,f,y;
00180 static short etab[]={0,132,396,924,1980,4092,8316,16764};
00181
00182 mu = 255-i;
00183 e = (mu & 0x70)/16;
00184 f = mu & 0x0f;
00185 y = f * (1 << (e + 3));
00186 y += etab[e];
00187 if (mu & 0x80) y = -y;
00188 __ast_mulaw[i] = y;
00189 }
00190
00191 for (i = -32768; i < 32768; i++) {
00192 __ast_lin2mu[((unsigned short)i) >> 2] = linear2ulaw(i);
00193 }
00194 #else
00195
00196 for (i = 0; i < 256; i++) {
00197 __ast_mulaw[i] = ulaw2linear(i);
00198 }
00199
00200 for (i = 0; i <= 32768; i += AST_ULAW_STEP) {
00201 AST_LIN2MU_LOOKUP(i) = linear2ulaw(i, 0 );
00202 }
00203 #endif
00204
00205 #ifdef TEST_CODING_TABLES
00206 for (i = -32768; i < 32768; ++i) {
00207 #ifndef G711_NEW_ALGORITHM
00208 unsigned char e1 = linear2ulaw(i);
00209 #else
00210 unsigned char e1 = linear2ulaw(i, 1);
00211 #endif
00212 short d1 = ulaw2linear(e1);
00213 unsigned char e2 = AST_LIN2MU(i);
00214 short d2 = ulaw2linear(e2);
00215 short d3 = AST_MULAW(e1);
00216
00217 if (e1 != e2 || d1 != d3 || d2 != d3) {
00218 ast_log(LOG_WARNING, "u-Law coding tables test failed on %d: e1=%u, e2=%u, d1=%d, d2=%d\n",
00219 i, (unsigned)e1, (unsigned)e2, (int)d1, (int)d2);
00220 }
00221 }
00222 ast_log(LOG_NOTICE, "u-Law coding table test complete.\n");
00223 #endif
00224
00225 #ifdef TEST_TANDEM_TRANSCODING
00226
00227 for (i = -32768; i < 32768; ++i) {
00228 unsigned char e1 = AST_LIN2MU(i);
00229 short d1 = AST_MULAW(e1);
00230 unsigned char e2 = AST_LIN2MU(d1);
00231 short d2 = AST_MULAW(e2);
00232 unsigned char e3 = AST_LIN2MU(d2);
00233 short d3 = AST_MULAW(e3);
00234
00235 if (i < 0 && e1 == 0x7f && e2 == 0xff && e3 == 0xff)
00236 continue;
00237
00238 if (e1 != e2 || e2 != e3 || d1 != d2 || d2 != d3) {
00239 ast_log(LOG_WARNING, "u-Law tandem transcoding test failed on %d: e1=%u, e2=%u, d1=%d, d2=%d, d3=%d\n",
00240 i, (unsigned)e1, (unsigned)e2, (int)d1, (int)d2, (int)d3);
00241 }
00242 }
00243 ast_log(LOG_NOTICE, "u-Law tandem transcoding test complete.\n");
00244 #endif
00245 }
00246