Path: super!cfreese From: cfreese@super.ORG (Craig F. Reese) Newsgroups: comp.dsp Subject: SPARCStation audio conversion (ulaw <-> linear) Message-ID: <14899@super.ORG> Date: 29 Sep 89 23:23:49 GMT Sender: news@super.ORG Reply-To: cfreese@super.UUCP (Craig F. Reese) Distribution: na Organization: Supercomputing Research Center, Bowie, Md. Lines: 120 TWIMC, Below are two routines I wrote for converting between ulaw and linear. I use them with the SparcStation and they seem to work fine. I am pretty sure (99.9%) that they implement the standard as specified in the references. Note that the standard deals with converting between 12 bit linear and 8 bit ulaw. These routines assume 16 bit linear. Thus, some bit shifting may be necessary. craig ------------------------------------------------------------------ /** ** Signal conversion routines for use with the Sun4/60 audio chip **/ /* * This routine converts from linear to ulaw * 29 September 1989 * * Craig Reese: IDA/Supercomputing Research Center * Joe Campbell: Department of Defense * * References: * 1) CCITT Recommendation G.711 (very difficult to follow) * 2) "A New Digital Technique for Implementation of Any * Continuous PCM Companding Law," Villeret, Michel, * et al. 1973 IEEE Int. Conf. on Communications, Vol 1, * 1973, pg. 11.12-11.17 * 3) MIL-STD-188-113,"Interoperability and Performance Standards * for Analog-to_Digital Conversion Techniques," * 17 February 1987 * * Input: Signed 16 bit linear sample * Output: 8 bit ulaw sample */ #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 unsigned char linear2ulaw(sample) int 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 the result **/ return(ulawbyte); } /* * This routine converts from ulaw to 16 bit linear * 29 September 1989 * * Craig Reese: IDA/Supercomputing Research Center * * References: * 1) CCITT Recommendation G.711 (very difficult to follow) * 2) MIL-STD-188-113,"Interoperability and Performance Standards * for Analog-to_Digital Conversion Techniques," * 17 February 1987 * * Input: 8 bit ulaw sample * Output: signed 16 bit linear sample */ int ulaw2linear(ulawbyte) unsigned char ulawbyte; { static int exp_lut[8]={0,132,396,924,1980,4092,8316,16764}; int sign, exponent, mantissa, sample; ulawbyte = ~ulawbyte; sign = (ulawbyte & 0x80); exponent = (ulawbyte >> 4) & 0x07; mantissa = ulawbyte & 0x0F; sample = exp_lut[exponent] + (mantissa << (exponent+3)); if (sign != 0) sample = -sample; return(sample); } ----------------- Craig F. Reese Email: cfreese@super.org Institute for Defense Analyses/ Supercomputing Research Center 17100 Science Dr. Bowie, MD 20715-4300