/* * This file is part of jcabc2ps, * Copyright (C) 1996-1999 Michael Methfessel * See file jcabc2ps.c for details. */ /* The contents of this file (sox.h) permit the generation of .au * files on arbitrary machines. All this material was taken from * playabc, Copyright (C) 1994 Don Ward. */ /**************************************************************************/ /* * These are a few defines which allow Don Ward's playabc and tune programs * to use sound_tools routines from the publicly available sox libst.a library. * This means that playabc and tune can be run on platforms other than Suns. * This should work fine with sox versions 7 and later. * * Observers will note that this file contains elements which were inspired * by both the Sun multimedia headers and the sox headers. * Steve Allen (sla@lick.ucsc.edu) can be blamed for this. * */ #define audio_s2u st_linear_to_ulaw #define audio_s2d(pcms) (((unsigned short)(pcms)) == 0x8000 ? -1. : \ ((double)((short)(pcms))) / 32767.) #define audio_d2s(pcmd) ((pcmd) >= 1. ? 32767 : (pcmd) <= -1. ? -32767 :\ (short)((pcmd) * 32767.)) #define AUDIO_SUCCESS (0) #define AUDIO_UNIXERROR (-1) #define SUN_UNSPEC ((unsigned)(~0)) /* Unspecified data size */ #define SUN_MAGIC 0x2e736e64 /* Really '.snd' */ #define SUN_ULAW 1 /* u-law encoding */ #define SUN_HDRSIZE 24 /* Size of minimal header */ /* libst.c - portable sound tools library */ /* ** 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 */ #define BIAS 0x84 /* define the add-in bias for 16 bit samples */ #define CLIP 32635 unsigned char st_linear_to_ulaw( 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 st_ulaw_to_linear_slow( 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; } /* * Write out an unsigned long making sure that the byte order is big-endian * as is used by 680x0 and Sparc processors (which is where the use of * .snd and .au files originated--on Sun and NeXT systems). * This is to ensure that the byte order of the sound header is right. */ void be4(unsigned char * p, unsigned long ul) { *p++ = (ul >> 24) & 0xff; *p++ = (ul >> 16) & 0xff; *p++ = (ul >> 8) & 0xff; *p++ = (ul) & 0xff; } /* write a generic header for .au or .snd file as on Sun, NeXT systems */ int write_header (int fd ) { unsigned char hdrbuf[SUN_HDRSIZE]; be4(&hdrbuf[0], SUN_MAGIC); be4(&hdrbuf[4], SUN_HDRSIZE); be4(&hdrbuf[8], SUN_UNSPEC); be4(&hdrbuf[12], SUN_ULAW); be4(&hdrbuf[16], SAMPLES_PER_SEC); be4(&hdrbuf[20], 1); /* No. of channels */ /* and we leave the comment field as blank */ if(write(fd, hdrbuf, SUN_HDRSIZE) == SUN_HDRSIZE) return AUDIO_SUCCESS; else return AUDIO_UNIXERROR; }