[comp.sys.mac.misc] Converting ulaw

jms@tardis.Tymnet.COM (Joe Smith) (06/02/91)

In article <20014@sdcc6.ucsd.edu> smaschue@sdcc13.ucsd.edu (sean) writes:
>I am trying to write a gnu c program to convert sound files from that wacky
>SPARC format to mac format.  I followed the alogrithm that someone mentioned
>a few days ago (just add 127) and this does not seem to work.

To convert from signed 8-bit format (as used by the Amiga and Atari ST) to
unsigned 8-bit format (as used on the Mac), go through the file and
for every byte:
	a) add 128
	b) subtract 128
	c) XOR with 0x80
	d) any one of the above.

To convert from u-law format (such as used on Sun's SPARC) to Mac format,
first convert from u-law to linear and then do the above conversion.

The "u-law" encoding is similar to a sign-magnitude floating-point number
stored in one's-complement form.  This table shows what happens when the
data is converted from u-law to linear, and scaled so that the results are
between -127 and +127.  In general, the conversion is from 8-bit u-law to
16-bit linear shifted right by 8 bits.  This table uses floating-point output
to demonstrate that u-law has a much finer resolution than 8-bit linear code.

00 -125.48  25 -25.98  4A -4.86  6F  -0.52  94 54.48  B9 10.73  DE 1.67
01 -121.48  26 -24.98  4B -4.61  70  -0.47  95 52.48  BA 10.23  DF 1.55
02 -117.48  27 -23.98  4C -4.36  71  -0.44  96 50.48  BB  9.73  E0 1.45
03 -113.48  28 -22.98  4D -4.11  72  -0.41  97 48.48  BC  9.23  E1 1.39
04 -109.48  29 -21.98  4E -3.86  73  -0.38  98 46.48  BD  8.73  E2 1.33
05 -105.48  2A -20.98  4F -3.61  74  -0.34  99 44.48  BE  8.23  E3 1.27
06 -101.48  2B -19.98  50 -3.42  75  -0.31  9A 42.48  BF  7.73  E4 1.20
07 -97.48   2C -18.98  51 -3.30  76  -0.28  9B 40.48  C0  7.36  E5 1.14
08 -93.48   2D -17.98  52 -3.17  77  -0.25  9C 38.48  C1  7.11  E6 1.08
09 -89.48   2E -16.98  53 -3.05  78  -0.22  9D 36.48  C2  6.86  E7 1.02
0A -85.48   2F -15.98  54 -2.92  79  -0.19  9E 34.48  C3  6.61  E8 0.95
0B -81.48   30 -15.23  55 -2.80  7A  -0.16  9F 32.48  C4  6.36  E9 0.89
0C -77.48   31 -14.73  56 -2.67  7B  -0.12  A0 30.98  C5  6.11  EA 0.83
0D -73.48   32 -14.23  57 -2.55  7C  -0.09  A1 29.98  C6  5.86  EB 0.77
0E -69.48   33 -13.73  58 -2.42  7D  -0.06  A2 28.98  C7  5.61  EC 0.70
0F -65.48   34 -13.23  59 -2.30  7E  -0.03  A3 27.98  C8  5.36  ED 0.64
10 -62.48   35 -12.73  5A -2.17  7F   0.00  A4 26.98  C9  5.11  EE 0.58
11 -60.48   36 -12.23  5B -2.05  80 125.48  A5 25.98  CA  4.86  EF 0.52
12 -58.48   37 -11.73  5C -1.92  81 121.48  A6 24.98  CB  4.61  F0 0.47
13 -56.48   38 -11.23  5D -1.80  82 117.48  A7 23.98  CC  4.36  F1 0.44
14 -54.48   39 -10.73  5E -1.67  83 113.48  A8 22.98  CD  4.11  F2 0.41
15 -52.48   3A -10.23  5F -1.55  84 109.48  A9 21.98  CE  3.86  F3 0.38
16 -50.48   3B  -9.73  60 -1.45  85 105.48  AA 20.98  CF  3.61  F4 0.34
17 -48.48   3C  -9.23  61 -1.39  86 101.48  AB 19.98  D0  3.42  F5 0.31
18 -46.48   3D  -8.73  62 -1.33  87  97.48  AC 18.98  D1  3.30  F6 0.28
19 -44.48   3E  -8.23  63 -1.27  88  93.48  AD 17.98  D2  3.17  F7 0.25
1A -42.48   3F  -7.73  64 -1.20  89  89.48  AE 16.98  D3  3.05  F8 0.22
1B -40.48   40  -7.36  65 -1.14  8A  85.48  AF 15.98  D4  2.92  F9 0.19
1C -38.48   41  -7.11  66 -1.08  8B  81.48  B0 15.23  D5  2.80  FA 0.16
1D -36.48   42  -6.86  67 -1.02  8C  77.48  B1 14.73  D6  2.67  FB 0.12
1E -34.48   43  -6.61  68 -0.95  8D  73.48  B2 14.23  D7  2.55  FC 0.09
1F -32.48   44  -6.36  69 -0.89  8E  69.48  B3 13.73  D8  2.42  FD 0.06
20 -30.98   45  -6.11  6A -0.83  8F  65.48  B4 13.23  D9  2.30  FE 0.03
21 -29.98   46  -5.86  6B -0.77  90  62.48  B5 12.73  DA  2.17  FF 0.00
22 -28.98   47  -5.61  6C -0.70  91  60.48  B6 12.23  DB  2.05
23 -27.98   48  -5.36  6D -0.64  92  58.48  B7 11.73  DC  1.92
24 -26.98   49  -5.11  6E -0.58  93  56.48  B8 11.23  DD  1.80

Most of the following program was extracted from posting by Brian Foley.
   Brian Foley		email: bfoley@greatlakes.Central.Sun.COM
   Systems Engineer	snail-mail: 1000 Town Center
   Sun Microsystems		    Suite 1700
   GreatLakes Region		    Southfield, MI 48075     (313)352-7070

#include <stdio.h>
#include <math.h>
/* The following main() routine is by Joe Smith <jms@tardis.tymnet.com> */
main() {
  int i;  unsigned char data;
  for (i=0; i<256; i++) {		/* Create a ulaw to linear table. */
    data = i;				/* (scaled so output is +/- 128.) */
    printf("%02X %6.2f\n",i,(float)ulaw2linear(data)/256.0);
    }
  }

/**
 ** Signal conversion routines for use with the Sun4/60 audio chip
 **/

/*
 * 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);
    }

/*
 * 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);
    }




-- 
Joe Smith (408)922-6220 | SMTP: jms@tardis.tymnet.com or jms@gemini.tymnet.com
BT Tymnet Tech Services | UUCP: ...!{ames,pyramid}!oliveb!tymix!tardis!jms
PO Box 49019, MS-C51    | BIX: smithjoe | CA license plate: "POPJ P," (PDP-10)
San Jose, CA 95161-9019 | humorous dislaimer: "My Amiga 3000 speaks for me."