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