@ -28,15 +28,25 @@
ASTERISK_FILE_VERSION ( __FILE__ , " $Revision$ " )
# include "asterisk/ulaw.h"
# include "asterisk/logger.h"
#if 0
/* ZEROTRAP is the military recommendation to improve the encryption
* of u - Law traffic . It is irrelevant with modern encryption systems
* like AES , and will simply degrade the signal quality .
* ZEROTRAP is not implemented in AST_LIN2MU and so the coding table
* tests will fail if you use it */
# define ZEROTRAP /*!< turn on the trap as per the MIL-STD */
# endif
# define BIAS 0x84 /*!< define the add-in bias for 16 bit samples */
# define CLIP 32635
# ifndef G711_NEW_ALGORITHM
unsigned char __ast_lin2mu [ 16384 ] ;
short __ast_mulaw [ 256 ] ;
static unsigned char linear2ulaw ( short sample )
{
static int exp_lut [ 256 ] = {
@ -71,6 +81,7 @@ static unsigned char linear2ulaw(short sample)
exponent = exp_lut [ ( sample > > 7 ) & 0xFF ] ;
mantissa = ( sample > > ( exponent + 3 ) ) & 0x0F ;
ulawbyte = ~ ( sign | ( exponent < < 4 ) | mantissa ) ;
# ifdef ZEROTRAP
if ( ulawbyte = = 0 )
ulawbyte = 0x02 ; /* optional CCITT trap */
@ -79,28 +90,158 @@ static unsigned char linear2ulaw(short sample)
return ulawbyte ;
}
# else
unsigned char __ast_lin2mu [ AST_ULAW_TAB_SIZE ] ;
short __ast_mulaw [ 256 ] ;
static unsigned char linear2ulaw ( short sample , int full_coding )
{
static const unsigned exp_lut [ 256 ] = {
0 , 0 , 1 , 1 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 ,
4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 , 4 ,
5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 ,
5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 , 5 ,
6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 ,
6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 ,
6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 ,
6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 , 6 ,
7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 ,
7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 ,
7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 ,
7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 ,
7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 ,
7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 ,
7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 ,
7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 , 7 } ;
unsigned sign , exponent , mantissa , mag ;
unsigned char ulawbyte ;
/* Get the sample into sign-magnitude. */
ast_ulaw_get_sign_mag ( sample , & sign , & mag ) ;
if ( mag > CLIP )
mag = CLIP ; /* clip the magnitude */
sign = ( sample > > 8 ) & 0x80 ; /* set aside the sign */
if ( sign ! = 0 )
sample = - sample ; /* get magnitude */
if ( sample > CLIP )
sample = CLIP ; /* clip the magnitude */
/* Convert from 16 bit linear to ulaw. */
mag + = BIAS ;
exponent = exp_lut [ ( mag > > 7 ) & 0xFF ] ;
mantissa = ( mag > > ( exponent + 3 ) ) & 0x0F ;
if ( full_coding ) {
/* full encoding, with sign and xform */
ulawbyte = ~ ( sign | ( exponent < < 4 ) | mantissa ) ;
# ifdef ZEROTRAP
if ( ulawbyte = = 0 )
ulawbyte = 0x02 ; /* optional CCITT trap */
# endif
} else {
/* half-cooked coding -- mantissa+exponent only (for lookup tab) */
ulawbyte = ( exponent < < 4 ) | mantissa ;
}
return ulawbyte ;
}
static inline short ulaw2linear ( unsigned char ulawbyte )
{
unsigned exponent , mantissa ;
short sample ;
static const short etab [ ] = { 0 , 132 , 396 , 924 , 1980 , 4092 , 8316 , 16764 } ;
ulawbyte = ~ ulawbyte ;
exponent = ( ulawbyte & 0x70 ) > > 4 ;
mantissa = ulawbyte & 0x0f ;
sample = mantissa < < ( exponent + 3 ) ;
sample + = etab [ exponent ] ;
if ( ulawbyte & 0x80 )
sample = - sample ;
return sample ;
}
# endif
/*!
* \ brief Set up mu - law conversion table
*/
void ast_ulaw_init ( void )
{
int i ;
for ( i = 0 ; i < 256 ; i + + ) {
short mu , e , f , y ;
static short etab [ ] = { 0 , 132 , 396 , 924 , 1980 , 4092 , 8316 , 16764 } ;
mu = 255 - i ;
e = ( mu & 0x70 ) / 16 ;
/*
* Set up mu - law conversion table
*/
# ifndef G711_NEW_ALGORITHM
for ( i = 0 ; i < 256 ; i + + ) {
short mu , e , f , y ;
static short etab [ ] = { 0 , 132 , 396 , 924 , 1980 , 4092 , 8316 , 16764 } ;
mu = 255 - i ;
e = ( mu & 0x70 ) / 16 ;
f = mu & 0x0f ;
y = f * ( 1 < < ( e + 3 ) ) ;
y + = etab [ e ] ;
if ( mu & 0x80 )
y = - y ;
if ( mu & 0x80 ) y = - y ;
__ast_mulaw [ i ] = y ;
}
/* set up the reverse (mu-law) conversion table */
for ( i = - 32768 ; i < 32768 ; i + + ) {
__ast_lin2mu [ ( ( unsigned short ) i ) > > 2 ] = linear2ulaw ( i ) ;
}
# else
for ( i = 0 ; i < 256 ; i + + ) {
__ast_mulaw [ i ] = ulaw2linear ( i ) ;
}
/* set up the reverse (mu-law) conversion table */
for ( i = 0 ; i < = 32768 ; i + = AST_ULAW_STEP ) {
AST_LIN2MU_LOOKUP ( i ) = linear2ulaw ( i , 0 /* half-cooked */ ) ;
}
# endif
# ifdef TEST_CODING_TABLES
for ( i = - 32768 ; i < 32768 ; + + i ) {
# ifndef G711_NEW_ALGORITHM
unsigned char e1 = linear2ulaw ( i ) ;
# else
unsigned char e1 = linear2ulaw ( i , 1 ) ;
# endif
short d1 = ulaw2linear ( e1 ) ;
unsigned char e2 = AST_LIN2MU ( i ) ;
short d2 = ulaw2linear ( e2 ) ;
short d3 = AST_MULAW ( e1 ) ;
if ( e1 ! = e2 | | d1 ! = d3 | | d2 ! = d3 ) {
ast_log ( LOG_WARNING , " u-Law coding tables test failed on %d: e1=%u, e2=%u, d1=%d, d2=%d \n " ,
i , ( unsigned ) e1 , ( unsigned ) e2 , ( int ) d1 , ( int ) d2 ) ;
}
}
ast_log ( LOG_NOTICE , " u-Law coding table test complete. \n " ) ;
# endif /* TEST_CODING_TABLES */
# ifdef TEST_TANDEM_TRANSCODING
/* tandem transcoding test */
for ( i = - 32768 ; i < 32768 ; + + i ) {
unsigned char e1 = AST_LIN2MU ( i ) ;
short d1 = AST_MULAW ( e1 ) ;
unsigned char e2 = AST_LIN2MU ( d1 ) ;
short d2 = AST_MULAW ( e2 ) ;
unsigned char e3 = AST_LIN2MU ( d2 ) ;
short d3 = AST_MULAW ( e3 ) ;
if ( i < 0 & & e1 = = 0x7f & & e2 = = 0xff & & e3 = = 0xff )
continue ; /* known and normal negative 0 case */
if ( e1 ! = e2 | | e2 ! = e3 | | d1 ! = d2 | | d2 ! = d3 ) {
ast_log ( LOG_WARNING , " u-Law tandem transcoding test failed on %d: e1=%u, e2=%u, d1=%d, d2=%d, d3=%d \n " ,
i , ( unsigned ) e1 , ( unsigned ) e2 , ( int ) d1 , ( int ) d2 , ( int ) d3 ) ;
}
}
ast_log ( LOG_NOTICE , " u-Law tandem transcoding test complete. \n " ) ;
# endif /* TEST_TANDEM_TRANSCODING */
}