001/**
002 * Portions Copyright 2001 Sun Microsystems, Inc.
003 * Portions Copyright 1999-2001 Language Technologies Institute, 
004 * Carnegie Mellon University.
005 * All Rights Reserved.  Use is subject to license terms.
006 * 
007 * See the file "license.terms" for information on usage and
008 * redistribution of this file, and for a DISCLAIMER OF ALL 
009 * WARRANTIES.
010 */
011package com.sun.speech.freetts.util;
012
013/**
014 * Provides a set of utilities for prrocessing wave/audio data.
015 */
016public class WaveUtils {
017
018    private static int[] exp_lut2 = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
019                                     4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
020                                     5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
021                                     5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
022                                     6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
023                                     6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
024                                     6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
025                                     6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
026                                     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
027                                     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
028                                     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
029                                     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
030                                     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
031                                     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
032                                     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
033                                     7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7};
034
035    private static final boolean ZEROTRAP = true;
036    private static final int CLIP = 32625;
037    private static final int BIAS = 0x84;
038        
039    private final static int[] expLut = { 0, 132, 396, 924, 1980, 4092, 
040                                          8316, 16764 };
041    
042    /**
043     * Converts a raw short to ulaw.
044     *
045     * @param sampleData signed 16-bit linear sample
046     *
047     * @return 8-bit ulaw sample, normalized
048     */
049    public static final byte shortToUlaw(short sampleData) {
050        int sign, exponent, mantissa;
051        int ulawByte;
052        int sample = (int) sampleData;
053                
054        sign = (sample >> 8) & 0x80; // set aside the sign
055        if (sign != 0) {             // get the magnitude
056            sample = -sample;
057        }
058        if (sample > CLIP) {         // clip the magnitude
059            sample = CLIP;
060        }
061        sample = sample + BIAS;
062        exponent = exp_lut2[ (sample >> 7) & 0xFF ];
063        mantissa = (sample >> (exponent + 3)) & 0x0F;
064        ulawByte = ~(sign | (exponent << 4) | mantissa);
065        
066        if (ZEROTRAP) {
067            if (ulawByte == 0) { // optional CCITT trap
068                ulawByte = 0x02;
069            }
070        }
071        
072        return (byte) ((ulawByte - 128) & 0xFF);
073    }
074
075
076    /**
077     * Converts from ulaw to 16 bit linear.
078     * <p>
079     * Craig Reese: IDA/Supercomputing Research Center
080     * <br>
081     * 29 September 1989
082     * <p>
083     * References:
084     * <br>
085     * 1) CCITT Recommendation G.711  (very difficult to follow)
086     * <br>
087     * 2) MIL-STD-188-113,"Interoperability and Performance Standards
088     *    for Analog-to_Digital Conversion Techniques," 17 February 1987
089     *
090     * @param uByte 8 bit ulaw sample
091     *
092     * @return signed 16 bit linear sample
093     */
094    public static final short ulawToShort(short uByte) {
095        int sign, exponent, mantissa;
096        int sample;
097        int ulawByte = uByte;
098                
099        ulawByte = ~(ulawByte);
100        sign = (ulawByte & 0x80);
101        exponent = (ulawByte >> 4) & 0x07;
102        mantissa = ulawByte & 0x0F;
103        sample = expLut[exponent] + ( mantissa << ( exponent + 3 ) );
104        if ( sign != 0 ) {
105            sample = -sample;
106        }
107        
108        return (short) sample;
109    }
110
111    /**
112     * Reconstructs a short from its hi and low bytes.
113     *
114     * @param hiByte the high byte
115     * @param loByte the low byte
116     * 
117     * @return the short value
118     */
119    public static final short bytesToShort(byte hiByte, byte loByte) {
120        int result = (0x000000FF & hiByte);
121        result = result << 8;
122        result |= (0x000000FF & loByte);
123        return (short) result;
124    }
125
126    /**
127     * Provides test program for method ulawToShort().
128     *
129     * @param args not used
130     */
131    public static void main(String[] args) {
132        for (int i = 0; i < 256; i++) {
133            System.out.println("" + i + "=" + ulawToShort((short) i));
134        }
135    }
136
137}