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."