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: 105840 $")
00029
00030 #include "asterisk/alaw.h"
00031
00032 #ifndef G711_NEW_ALGORITHM
00033 #define AMI_MASK 0x55
00034
00035 static inline unsigned char linear2alaw(short int linear)
00036 {
00037 int mask;
00038 int seg;
00039 int pcm_val;
00040 static int seg_end[8] =
00041 {
00042 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF
00043 };
00044
00045 pcm_val = linear;
00046 if (pcm_val >= 0) {
00047
00048 mask = AMI_MASK | 0x80;
00049 } else {
00050
00051 mask = AMI_MASK;
00052 pcm_val = -pcm_val;
00053 }
00054
00055
00056 for (seg = 0; seg < 8; seg++) {
00057 if (pcm_val <= seg_end[seg]) {
00058 break;
00059 }
00060 }
00061
00062 return ((seg << 4) | ((pcm_val >> ((seg) ? (seg + 3) : 4)) & 0x0F)) ^ mask;
00063 }
00064 #else
00065 static unsigned char linear2alaw(short sample, int full_coding)
00066 {
00067 static const unsigned exp_lut[128] = {
00068 1,1,2,2,3,3,3,3,
00069 4,4,4,4,4,4,4,4,
00070 5,5,5,5,5,5,5,5,
00071 5,5,5,5,5,5,5,5,
00072 6,6,6,6,6,6,6,6,
00073 6,6,6,6,6,6,6,6,
00074 6,6,6,6,6,6,6,6,
00075 6,6,6,6,6,6,6,6,
00076 7,7,7,7,7,7,7,7,
00077 7,7,7,7,7,7,7,7,
00078 7,7,7,7,7,7,7,7,
00079 7,7,7,7,7,7,7,7,
00080 7,7,7,7,7,7,7,7,
00081 7,7,7,7,7,7,7,7,
00082 7,7,7,7,7,7,7,7,
00083 7,7,7,7,7,7,7,7 };
00084 unsigned sign, exponent, mantissa, mag;
00085 unsigned char alawbyte;
00086
00087 ast_alaw_get_sign_mag(sample, &sign, &mag);
00088 if (mag > 32767)
00089 mag = 32767;
00090
00091 exponent = exp_lut[(mag >> 8) & 0x7f];
00092 mantissa = (mag >> (exponent + 3)) & 0x0f;
00093 if (mag < 0x100)
00094 exponent = 0;
00095
00096 if (full_coding) {
00097
00098 alawbyte = (unsigned char)(sign | (exponent << 4) | mantissa);
00099 alawbyte ^= AST_ALAW_AMI_MASK;
00100 } else {
00101
00102 alawbyte = (exponent << 4) | mantissa;
00103 }
00104 return alawbyte;
00105 }
00106 #endif
00107
00108 #ifndef G711_NEW_ALGORITHM
00109 static inline short int alaw2linear (unsigned char alaw)
00110 {
00111 int i;
00112 int seg;
00113
00114 alaw ^= AMI_MASK;
00115 i = ((alaw & 0x0F) << 4) + 8 ;
00116 seg = (((int) alaw & 0x70) >> 4);
00117 if (seg) {
00118 i = (i + 0x100) << (seg - 1);
00119 }
00120 return (short int) ((alaw & 0x80) ? i : -i);
00121 }
00122 #else
00123 static inline short alaw2linear(unsigned char alawbyte)
00124 {
00125 unsigned exponent, mantissa;
00126 short sample;
00127
00128 alawbyte ^= AST_ALAW_AMI_MASK;
00129 exponent = (alawbyte & 0x70) >> 4;
00130 mantissa = alawbyte & 0x0f;
00131 sample = (mantissa << 4) + 8 ;
00132 if (exponent)
00133 sample = (sample + 0x100) << (exponent - 1);
00134 if (!(alawbyte & 0x80))
00135 sample = -sample;
00136 return sample;
00137 }
00138 #endif
00139
00140
00141
00142 #ifndef G711_NEW_ALGORITHM
00143 unsigned char __ast_lin2a[8192];
00144 #else
00145 unsigned char __ast_lin2a[AST_ALAW_TAB_SIZE];
00146 #endif
00147 short __ast_alaw[256];
00148
00149 void ast_alaw_init(void)
00150 {
00151 int i;
00152
00153
00154
00155 #ifndef G711_NEW_ALGORITHM
00156 for (i = 0; i < 256; i++) {
00157 __ast_alaw[i] = alaw2linear(i);
00158 }
00159
00160 for (i = -32768; i < 32768; i++) {
00161 __ast_lin2a[((unsigned short)i) >> 3] = linear2alaw(i);
00162 }
00163 #else
00164 for (i = 0; i < 256; i++) {
00165 __ast_alaw[i] = alaw2linear(i);
00166 }
00167
00168 for (i = 0; i <= 32768; i += AST_ALAW_STEP) {
00169 AST_LIN2A_LOOKUP(i) = linear2alaw(i, 0 );
00170 }
00171 #endif
00172
00173 #ifdef TEST_CODING_TABLES
00174 for (i = -32768; i < 32768; ++i) {
00175 #ifndef G711_NEW_ALGORITHM
00176 unsigned char e1 = linear2alaw(i);
00177 #else
00178 unsigned char e1 = linear2alaw(i, 1);
00179 #endif
00180 short d1 = alaw2linear(e1);
00181 unsigned char e2 = AST_LIN2A(i);
00182 short d2 = alaw2linear(e2);
00183 short d3 = AST_ALAW(e1);
00184
00185 if (e1 != e2 || d1 != d3 || d2 != d3) {
00186 ast_log(LOG_WARNING, "a-Law coding tables test failed on %d: e1=%u, e2=%u, d1=%d, d2=%d\n",
00187 i, (unsigned)e1, (unsigned)e2, (int)d1, (int)d2);
00188 }
00189 }
00190 ast_log(LOG_NOTICE, "a-Law coding tables test complete.\n");
00191 #endif
00192
00193 #ifdef TEST_TANDEM_TRANSCODING
00194
00195 for (i = -32768; i < 32768; ++i) {
00196 unsigned char e1 = AST_LIN2A(i);
00197 short d1 = AST_ALAW(e1);
00198 unsigned char e2 = AST_LIN2A(d1);
00199 short d2 = AST_ALAW(e2);
00200 unsigned char e3 = AST_LIN2A(d2);
00201 short d3 = AST_ALAW(e3);
00202
00203 if (e1 != e2 || e2 != e3 || d1 != d2 || d2 != d3) {
00204 ast_log(LOG_WARNING, "a-Law tandem transcoding test failed on %d: e1=%u, e2=%u, d1=%d, d2=%d, d3=%d\n",
00205 i, (unsigned)e1, (unsigned)e2, (int)d1, (int)d2, (int)d3);
00206 }
00207 }
00208 ast_log(LOG_NOTICE, "a-Law tandem transcoding test complete.\n");
00209 #endif
00210
00211 }
00212