/*************************************************************************/ /* */ /* Centre for Speech Technology Research */ /* University of Edinburgh, UK */ /* Copyright (c) 1996 */ /* All Rights Reserved. */ /* */ /* Permission is hereby granted, free of charge, to use and distribute */ /* this software and its documentation without restriction, including */ /* without limitation the rights to use, copy, modify, merge, publish, */ /* distribute, sublicense, and/or sell copies of this work, and to */ /* permit persons to whom this work is furnished to do so, subject to */ /* the following conditions: */ /* 1. The code must retain the above copyright notice, this list of */ /* conditions and the following disclaimer. */ /* 2. Any modifications must be clearly marked as such. */ /* 3. Original authors' names are not deleted. */ /* 4. The authors' names are not used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */ /* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */ /* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */ /* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */ /* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */ /* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */ /* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */ /* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */ /* THIS SOFTWARE. */ /* */ /*************************************************************************/ /* Author : Alan Black and Paul Taylor */ /* Date : June 1996 */ /*-----------------------------------------------------------------------*/ /* Various low-level waveform conversion routines and file format */ /* independent i/o functions */ /* */ /* Acknowledgements */ /* ulaw conversion code provided by */ /* Craig Reese: IDA/Supercomputing Research Center */ /* IEEE extended conversion */ /* Apple Computer, Inc. */ /* */ /*=======================================================================*/ #include #include #include "EST_unix.h" #include #include #include "EST_wave_utils.h" #include "EST_wave_aux.h" #include "EST_error.h" static short st_ulaw_to_short(unsigned char ulawbyte); static unsigned char st_short_to_ulaw(short sample); /* * This table is * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische * Universitaet Berlin. See the accompanying file "COPYRIGHT" for * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. * take from speak_freely-7.2/gsm/src/toast_alaw.c */ static unsigned short a2s[] = { 5120,60160, 320,65200,20480,44032, 1280,64192, 2560,62848, 64,65456,10240,54784, 640,64864, 7168,58112, 448,65072,28672,35840, 1792,63680, 3584,61824, 192,65328,14336,50688, 896,64608, 4096,61184, 256,65264,16384,48128, 1024,64448, 2048,63360, 0,65520, 8192,56832, 512,64992, 6144,59136, 384,65136,24576,39936, 1536,63936, 3072,62336, 128,65392,12288,52736, 768,64736, 5632,59648, 352,65168,22528,41984, 1408,64064, 2816,62592, 96,65424,11264,53760, 704,64800, 7680,57600, 480,65040,30720,33792, 1920,63552, 3840,61568, 224,65296,15360,49664, 960,64544, 4608,60672, 288,65232,18432,46080, 1152,64320, 2304,63104, 32,65488, 9216,55808, 576,64928, 6656,58624, 416,65104,26624,37888, 1664,63808, 3328,62080, 160,65360,13312,51712, 832,64672, 5376,59904, 336,65184,21504,43008, 1344,64128, 2688,62720, 80,65440,10752,54272, 672,64832, 7424,57856, 464,65056,29696,34816, 1856,63616, 3712,61696, 208,65312,14848,50176, 928,64576, 4352,60928, 272,65248,17408,47104, 1088,64384, 2176,63232, 16,65504, 8704,56320, 544,64960, 6400,58880, 400,65120,25600,38912, 1600,63872, 3200,62208, 144,65376,12800,52224, 800,64704, 5888,59392, 368,65152,23552,40960, 1472,64000, 2944,62464, 112,65408,11776,53248, 736,64768, 7936,57344, 496,65024,31744,32768, 1984,63488, 3968,61440, 240,65280,15872,49152, 992,64512, 4864,60416, 304,65216,19456,45056, 1216,64256, 2432,62976, 48,65472, 9728,55296, 608,64896, 6912,58368, 432,65088,27648,36864, 1728,63744, 3456,61952, 176,65344,13824,51200, 864,64640 }; #define st_alaw_to_short(a) (a2s[(unsigned char)a]) void ulaw_to_short(const unsigned char *ulaw,short *data,int length) { /* Convert ulaw to shorts */ int i; for (i=0; i> 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 */ static short st_ulaw_to_short( unsigned char ulawbyte ) { static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 }; int sign, exponent, mantissa; short 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; } /* * C O N V E R T T O I E E E E X T E N D E D */ /* Copyright (C) 1988-1991 Apple Computer, Inc. * All rights reserved. * * Machine-independent I/O routines for IEEE floating-point numbers. * * NaN's and infinities are converted to HUGE_VAL or HUGE, which * happens to be infinity on IEEE machines. Unfortunately, it is * impossible to preserve NaN's in a machine-independent way. * Infinities are, however, preserved on IEEE machines. * * These routines have been tested on the following machines: * Apple Macintosh, MPW 3.1 C compiler * Apple Macintosh, THINK C compiler * Silicon Graphics IRIS, MIPS compiler * Cray X/MP and Y/MP * Digital Equipment VAX * * * Implemented by Malcolm Slaney and Ken Turkowski. * * Malcolm Slaney contributions during 1988-1990 include big- and little- * endian file I/O, conversion to and from Motorola's extended 80-bit * floating-point format, and conversions to and from IEEE single- * precision floating-point format. * * In 1991, Ken Turkowski implemented the conversions to and from * IEEE double-precision format, added more precision to the extended * conversions, and accommodated conversions involving +/- infinity, * NaN's, and denormalized numbers. */ #ifndef HUGE_VAL # define HUGE_VAL HUGE #endif /*HUGE_VAL*/ # define FloatToUnsigned(f) ((unsigned long)(((long)(f - 2147483648.0)) + 2147483647L) + 1) void ConvertToIeeeExtended(double num,unsigned char *bytes) { int sign; int expon; double fMant, fsMant; unsigned long hiMant, loMant; if (num < 0) { sign = 0x8000; num *= -1; } else { sign = 0; } if (num == 0) { expon = 0; hiMant = 0; loMant = 0; } else { fMant = frexp(num, &expon); if ((expon > 16384) || !(fMant < 1)) { /* Infinity or NaN */ expon = sign|0x7FFF; hiMant = 0; loMant = 0; /* infinity */ } else { /* Finite */ expon += 16382; if (expon < 0) { /* denormalized */ fMant = ldexp(fMant, expon); expon = 0; } expon |= sign; fMant = ldexp(fMant, 32); fsMant = floor(fMant); hiMant = FloatToUnsigned(fsMant); fMant = ldexp(fMant - fsMant, 32); fsMant = floor(fMant); loMant = FloatToUnsigned(fsMant); } } bytes[0] = expon >> 8; bytes[1] = expon; bytes[2] = hiMant >> 24; bytes[3] = hiMant >> 16; bytes[4] = hiMant >> 8; bytes[5] = hiMant; bytes[6] = loMant >> 24; bytes[7] = loMant >> 16; bytes[8] = loMant >> 8; bytes[9] = loMant; } /* * C O N V E R T F R O M I E E E E X T E N D E D */ /* * Copyright (C) 1988-1991 Apple Computer, Inc. * All rights reserved. * * Machine-independent I/O routines for IEEE floating-point numbers. * * NaN's and infinities are converted to HUGE_VAL or HUGE, which * happens to be infinity on IEEE machines. Unfortunately, it is * impossible to preserve NaN's in a machine-independent way. * Infinities are, however, preserved on IEEE machines. * * These routines have been tested on the following machines: * Apple Macintosh, MPW 3.1 C compiler * Apple Macintosh, THINK C compiler * Silicon Graphics IRIS, MIPS compiler * Cray X/MP and Y/MP * Digital Equipment VAX * * * Implemented by Malcolm Slaney and Ken Turkowski. * * Malcolm Slaney contributions during 1988-1990 include big- and little- * endian file I/O, conversion to and from Motorola's extended 80-bit * floating-point format, and conversions to and from IEEE single- * precision floating-point format. * * In 1991, Ken Turkowski implemented the conversions to and from * IEEE double-precision format, added more precision to the extended * conversions, and accommodated conversions involving +/- infinity, * NaN's, and denormalized numbers. */ #ifndef HUGE_VAL # define HUGE_VAL HUGE #endif /*HUGE_VAL*/ # define UnsignedToFloat(u) (((double)((long)(u - 2147483647L - 1))) + 2147483648.0) /**************************************************************** * Extended precision IEEE floating-point conversion routine. ****************************************************************/ double ConvertFromIeeeExtended(unsigned char *bytes) { double f; int expon; unsigned long hiMant, loMant; expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF); hiMant = ((unsigned long)(bytes[2] & 0xFF) << 24) | ((unsigned long)(bytes[3] & 0xFF) << 16) | ((unsigned long)(bytes[4] & 0xFF) << 8) | ((unsigned long)(bytes[5] & 0xFF)); loMant = ((unsigned long)(bytes[6] & 0xFF) << 24) | ((unsigned long)(bytes[7] & 0xFF) << 16) | ((unsigned long)(bytes[8] & 0xFF) << 8) | ((unsigned long)(bytes[9] & 0xFF)); if (expon == 0 && hiMant == 0 && loMant == 0) { f = 0; } else { if (expon == 0x7FFF) { /* Infinity or NaN */ f = HUGE_VAL; } else { expon -= 16383; f = ldexp((double)(hiMant), expon-=31); f += ldexp((double)(loMant), expon-=32); } } if (bytes[0] & 0x80) return -f; else return f; }