Skip to content
Snippets Groups Projects
ulaw.c 2.64 KiB
Newer Older
  • Learn to ignore specific revisions
  • Mark Spencer's avatar
    Mark Spencer committed
    /*
     * Asterisk -- A telephony toolkit for Linux.
     *
     * u-Law to Signed linear conversion
     * 
     * Copyright (C) 1999, Mark Spencer
     *
     * Mark Spencer <markster@linux-support.net>
     *
     * This program is free software, distributed under the terms of
     * the GNU General Public License
     */
    
    #include <asterisk/ulaw.h>
    
    #define ZEROTRAP    /* turn on the trap as per the MIL-STD */
    #define BIAS 0x84   /* define the add-in bias for 16 bit samples */
    #define CLIP 32635
    
    
    Mark Spencer's avatar
    Mark Spencer committed
    unsigned char __ast_lin2mu[16384];
    short __ast_mulaw[256];
    
    Mark Spencer's avatar
    Mark Spencer committed
    
    static unsigned char
    linear2ulaw(short sample)
    {
      static int 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};
      int sign, exponent, mantissa;
      unsigned char ulawbyte;
    
      /* Get the sample into sign-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. */
      sample = sample + BIAS;
      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 */
    #endif
    
      return(ulawbyte);
    }
    
    void ast_ulaw_init(void)
    {
    	int i;
    	/* 
    	 *  Set up mu-law conversion table
    	 */
    	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;
    
    Mark Spencer's avatar
    Mark Spencer committed
    	        __ast_mulaw[i] = y;
    
    Mark Spencer's avatar
    Mark Spencer committed
    	   }
    	  /* set up the reverse (mu-law) conversion table */
    
    Mark Spencer's avatar
    Mark Spencer committed
    	for(i = -32768; i < 32768; i++)
    
    Mark Spencer's avatar
    Mark Spencer committed
    	   {
    
    Mark Spencer's avatar
    Mark Spencer committed
    		__ast_lin2mu[((unsigned short)i) >> 2] = linear2ulaw(i);