Newsgroups: comp.speech
Path: lyra.csx.cam.ac.uk!warwick!pipex!howland.reston.ans.net!europa.eng.gtefsd.com!MathWorks.Com!zombie.ncsc.mil!afterlife!jpcampb
From: jpcampb@afterlife.ncsc.mil (Joe Campbell)
Subject: Re: Source code for mu-law -> linear pcm.
Message-ID: <1994Apr9.205610.14093@afterlife.ncsc.mil>
Organization: The Great Beyond
References: <1994Apr6.080602.11306@cm.cf.ac.uk>
Date: Sat, 9 Apr 1994 20:56:10 GMT
Lines: 116

In article <1994Apr6.080602.11306@cm.cf.ac.uk>,
Paul Brown <P.A.Brown@cm.cf.ac.uk> wrote:
>I'm sorry to display my ignorance but could anybody direct me to source code (preferably in C or C++) that will enable me to convert audio data between linear PCM and (12-bit) mu-law encoding.

From the FAQ:

Q2.6: How do I convert to/from mu-law format?
... 
On SUN Sparc systems have a look in the directory /usr/demo/SOUND.  Included
are table lookup macros for ulaw conversions.  [Note however that not all
systems will have /usr/demo/SOUND installed as it is optional - see your
system admin if it is missing.]
 
OR, here is some sample conversion code in C.
 
# include <stdio.h>
 
unsigned char linear2ulaw(/* int */);
int ulaw2linear(/* unsigned char */);
 
/*
** This routine converts from linear to ulaw.
**
** Craig Reese: IDA/Supercomputing Research Center
** Joe Campbell: Department of Defense
** 29 September 1989
**
** 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 */
#undef ZEROTRAP
#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(ulawbyte);
}
 
/*
** This routine converts from ulaw to 16 bit linear.
**
** Craig Reese: IDA/Supercomputing Research Center
** 29 September 1989
**
** 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);
-- 
.............................................................................
; Dr. Campbell  N3JBC  jpcampb@afterlife.ncsc.mil  74040.305@compuserve.com ;
; Speaking for myself     Happiness = Reality - Expectations, Click & Clack ;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
