Fri Aug 17 00:17:20 2018

Asterisk developer's documentation


ulaw.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2005, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief u-Law to Signed linear conversion
00022  *
00023  * \author Mark Spencer <markster@digium.com> 
00024  */
00025 
00026 /*** MODULEINFO
00027    <support_level>core</support_level>
00028  ***/
00029 
00030 #include "asterisk.h"
00031 
00032 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 369001 $")
00033 
00034 #include "asterisk/ulaw.h"
00035 #include "asterisk/logger.h"
00036 
00037 #if 0
00038 /* ZEROTRAP is the military recommendation to improve the encryption
00039  * of u-Law traffic. It is irrelevant with modern encryption systems
00040  * like AES, and will simply degrade the signal quality.
00041  * ZEROTRAP is not implemented in AST_LIN2MU and so the coding table
00042  * tests will fail if you use it */
00043 #define ZEROTRAP    /*!< turn on the trap as per the MIL-STD */
00044 #endif
00045 
00046 #define BIAS 0x84   /*!< define the add-in bias for 16 bit samples */
00047 #define CLIP 32635
00048 
00049 #ifndef G711_NEW_ALGORITHM
00050 
00051 unsigned char __ast_lin2mu[16384];
00052 short __ast_mulaw[256];
00053 
00054 static unsigned char linear2ulaw(short sample)
00055 {
00056    static int exp_lut[256] = {
00057       0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
00058       4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
00059       5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
00060       5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
00061       6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00062       6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00063       6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00064       6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
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       7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00069       7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00070       7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00071       7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00072       7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 };
00073    int sign, exponent, mantissa;
00074    unsigned char ulawbyte;
00075    
00076    /* Get the sample into sign-magnitude. */
00077    sign = (sample >> 8) & 0x80;          /* set aside the sign */
00078    if (sign != 0)
00079       sample = -sample;              /* get magnitude */
00080    if (sample > CLIP)
00081       sample = CLIP;             /* clip the magnitude */
00082    
00083    /* Convert from 16 bit linear to ulaw. */
00084    sample = sample + BIAS;
00085    exponent = exp_lut[(sample >> 7) & 0xFF];
00086    mantissa = (sample >> (exponent + 3)) & 0x0F;
00087    ulawbyte = ~(sign | (exponent << 4) | mantissa);
00088    
00089 #ifdef ZEROTRAP
00090    if (ulawbyte == 0)
00091       ulawbyte = 0x02;   /* optional CCITT trap */
00092 #endif
00093    
00094    return ulawbyte;
00095 }
00096 
00097 #else
00098 
00099 unsigned char __ast_lin2mu[AST_ULAW_TAB_SIZE];
00100 short __ast_mulaw[256];
00101 
00102 static unsigned char linear2ulaw(short sample, int full_coding)
00103 {
00104    static const unsigned exp_lut[256] = {
00105       0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
00106       4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
00107       5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
00108       5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
00109       6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00110       6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00111       6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
00112       6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
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       7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00117       7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00118       7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00119       7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
00120       7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 };
00121    unsigned sign, exponent, mantissa, mag;
00122    unsigned char ulawbyte;
00123    
00124    /* Get the sample into sign-magnitude. */
00125    ast_ulaw_get_sign_mag(sample, &sign, &mag);
00126    if (mag > CLIP)
00127       mag = CLIP;                /* clip the magnitude */
00128    
00129    sign = (sample >> 8) & 0x80;          /* set aside the sign */
00130    if (sign != 0) 
00131       sample = -sample;              /* get magnitude */
00132    if (sample > CLIP)
00133       sample = CLIP;             /* clip the magnitude */
00134    
00135    /* Convert from 16 bit linear to ulaw. */
00136    mag += BIAS;
00137    exponent = exp_lut[(mag >> 7) & 0xFF];
00138    mantissa = (mag >> (exponent + 3)) & 0x0F;
00139    
00140    if (full_coding) {
00141       /* full encoding, with sign and xform */
00142       ulawbyte = ~(sign | (exponent << 4) | mantissa);
00143 #ifdef ZEROTRAP
00144       if (ulawbyte == 0)
00145          ulawbyte = 0x02;   /* optional CCITT trap */
00146 #endif
00147    } else {
00148       /* half-cooked coding -- mantissa+exponent only (for lookup tab) */
00149       ulawbyte = (exponent << 4) | mantissa;
00150    }
00151 
00152    return ulawbyte;
00153 }
00154    
00155 static inline short ulaw2linear(unsigned char ulawbyte)
00156 {
00157    unsigned exponent, mantissa;
00158    short sample;
00159    static const short etab[]={0,132,396,924,1980,4092,8316,16764};
00160    
00161    ulawbyte = ~ulawbyte;
00162    exponent = (ulawbyte & 0x70) >> 4;
00163    mantissa = ulawbyte & 0x0f;
00164    sample = mantissa << (exponent + 3);
00165    sample += etab[exponent];
00166    if (ulawbyte & 0x80)
00167       sample = -sample;
00168    return sample;
00169 }
00170 #endif
00171 
00172 /*!
00173  * \brief  Set up mu-law conversion table
00174  */
00175 void ast_ulaw_init(void)
00176 {
00177    int i;
00178    
00179    /*
00180     *  Set up mu-law conversion table
00181     */
00182 #ifndef G711_NEW_ALGORITHM
00183    for (i = 0;i < 256;i++) {
00184       short mu,e,f,y;
00185       static const short etab[]={0,132,396,924,1980,4092,8316,16764};
00186       
00187       mu = 255-i;
00188       e = (mu & 0x70)/16;
00189       f = mu & 0x0f;
00190       y = f * (1 << (e + 3));
00191       y += etab[e];
00192       if (mu & 0x80) y = -y;
00193       __ast_mulaw[i] = y;
00194    }
00195    /* set up the reverse (mu-law) conversion table */
00196    for (i = -32768; i < 32768; i++) {
00197       __ast_lin2mu[((unsigned short)i) >> 2] = linear2ulaw(i);
00198    }
00199 #else
00200    
00201    for (i = 0; i < 256; i++) {
00202       __ast_mulaw[i] = ulaw2linear(i);
00203    }
00204    /* set up the reverse (mu-law) conversion table */
00205    for (i = 0; i <= 32768; i += AST_ULAW_STEP) {
00206       AST_LIN2MU_LOOKUP(i) = linear2ulaw(i, 0 /* half-cooked */);
00207    }
00208 #endif
00209    
00210 #ifdef TEST_CODING_TABLES
00211    for (i = -32768; i < 32768; ++i) {
00212 #ifndef G711_NEW_ALGORITHM
00213       unsigned char e1 = linear2ulaw(i);
00214 #else
00215       unsigned char e1 = linear2ulaw(i, 1);
00216 #endif
00217       short d1 = ulaw2linear(e1);
00218       unsigned char e2 = AST_LIN2MU(i);
00219       short d2 = ulaw2linear(e2);
00220       short d3 = AST_MULAW(e1);
00221       
00222       if (e1 != e2 || d1 != d3 || d2 != d3) {
00223          ast_log(LOG_WARNING, "u-Law coding tables test failed on %d: e1=%u, e2=%u, d1=%d, d2=%d\n",
00224                i, (unsigned)e1, (unsigned)e2, (int)d1, (int)d2);
00225       }
00226    }
00227    ast_log(LOG_NOTICE, "u-Law coding table test complete.\n");
00228 #endif /* TEST_CODING_TABLES */
00229    
00230 #ifdef TEST_TANDEM_TRANSCODING
00231    /* tandem transcoding test */
00232    for (i = -32768; i < 32768; ++i) {
00233       unsigned char e1 = AST_LIN2MU(i);
00234       short d1 = AST_MULAW(e1);
00235       unsigned char e2 = AST_LIN2MU(d1);
00236       short d2 = AST_MULAW(e2);
00237       unsigned char e3 = AST_LIN2MU(d2);
00238       short d3 = AST_MULAW(e3);
00239       
00240       if (i < 0 && e1 == 0x7f && e2 == 0xff && e3 == 0xff)
00241          continue; /* known and normal negative 0 case */
00242       
00243       if (e1 != e2 || e2 != e3 || d1 != d2 || d2 != d3) {
00244          ast_log(LOG_WARNING, "u-Law tandem transcoding test failed on %d: e1=%u, e2=%u, d1=%d, d2=%d, d3=%d\n",
00245                i, (unsigned)e1, (unsigned)e2, (int)d1, (int)d2, (int)d3);
00246       }
00247    }
00248    ast_log(LOG_NOTICE, "u-Law tandem transcoding test complete.\n");
00249 #endif /* TEST_TANDEM_TRANSCODING */
00250 }
00251 

Generated on 17 Aug 2018 for Asterisk - The Open Source Telephony Project by  doxygen 1.6.1