FileDocCategorySizeDatePackage
UlawEncoderInputStream.javaAPI DocAndroid 1.5 API7147Wed May 06 22:41:56 BST 2009android.speech.srec

UlawEncoderInputStream

public final class UlawEncoderInputStream extends InputStream
InputStream which transforms 16 bit pcm data to ulaw data. Not yet ready to be supported, so
hide

Fields Summary
private static final String
TAG
private static final int
MAX_ULAW
private static final int
SCALE_BITS
private InputStream
mIn
private int
mMax
private final byte[]
mBuf
private int
mBufCount
private final byte[]
mOneByte
Constructors Summary
public UlawEncoderInputStream(InputStream in, int max)
Create an InputStream which takes 16 bit pcm data and produces ulaw data.

param
in InputStream containing 16 bit pcm data.
param
max pcm value corresponding to maximum ulaw value.

        mIn = in;
        mMax = max;
    
Methods Summary
public intavailable()

        return (mIn.available() + mBufCount) / 2;
    
public voidclose()

        if (mIn != null) {
            InputStream in = mIn;
            mIn = null;
            in.close();
        }
    
public static voidencode(byte[] pcmBuf, int pcmOffset, byte[] ulawBuf, int ulawOffset, int length, int max)


    
          
                    
        
        // from  'ulaw' in wikipedia
        // +8191 to +8159                          0x80
        // +8158 to +4063 in 16 intervals of 256   0x80 + interval number
        // +4062 to +2015 in 16 intervals of 128   0x90 + interval number
        // +2014 to  +991 in 16 intervals of  64   0xA0 + interval number
        //  +990 to  +479 in 16 intervals of  32   0xB0 + interval number
        //  +478 to  +223 in 16 intervals of  16   0xC0 + interval number
        //  +222 to   +95 in 16 intervals of   8   0xD0 + interval number
        //   +94 to   +31 in 16 intervals of   4   0xE0 + interval number
        //   +30 to    +1 in 15 intervals of   2   0xF0 + interval number
        //     0                                   0xFF
        
        //    -1                                   0x7F
        //   -31 to    -2 in 15 intervals of   2   0x70 + interval number
        //   -95 to   -32 in 16 intervals of   4   0x60 + interval number
        //  -223 to   -96 in 16 intervals of   8   0x50 + interval number
        //  -479 to  -224 in 16 intervals of  16   0x40 + interval number
        //  -991 to  -480 in 16 intervals of  32   0x30 + interval number
        // -2015 to  -992 in 16 intervals of  64   0x20 + interval number
        // -4063 to -2016 in 16 intervals of 128   0x10 + interval number
        // -8159 to -4064 in 16 intervals of 256   0x00 + interval number
        // -8192 to -8160                          0x00
        
        // set scale factors
        if (max <= 0) max = MAX_ULAW;
        
        int coef = MAX_ULAW * (1 << SCALE_BITS) / max;
        
        for (int i = 0; i < length; i++) {
            int pcm = (0xff & pcmBuf[pcmOffset++]) + (pcmBuf[pcmOffset++] << 8);
            pcm = (pcm * coef) >> SCALE_BITS;
            
            int ulaw;
            if (pcm >= 0) {
                ulaw = pcm <= 0 ? 0xff :
                        pcm <=   30 ? 0xf0 + ((  30 - pcm) >> 1) :
                        pcm <=   94 ? 0xe0 + ((  94 - pcm) >> 2) :
                        pcm <=  222 ? 0xd0 + (( 222 - pcm) >> 3) :
                        pcm <=  478 ? 0xc0 + (( 478 - pcm) >> 4) :
                        pcm <=  990 ? 0xb0 + (( 990 - pcm) >> 5) :
                        pcm <= 2014 ? 0xa0 + ((2014 - pcm) >> 6) :
                        pcm <= 4062 ? 0x90 + ((4062 - pcm) >> 7) :
                        pcm <= 8158 ? 0x80 + ((8158 - pcm) >> 8) :
                        0x80;
            } else {
                ulaw = -1 <= pcm ? 0x7f :
                          -31 <= pcm ? 0x70 + ((pcm -   -31) >> 1) :
                          -95 <= pcm ? 0x60 + ((pcm -   -95) >> 2) :
                         -223 <= pcm ? 0x50 + ((pcm -  -223) >> 3) :
                         -479 <= pcm ? 0x40 + ((pcm -  -479) >> 4) :
                         -991 <= pcm ? 0x30 + ((pcm -  -991) >> 5) :
                        -2015 <= pcm ? 0x20 + ((pcm - -2015) >> 6) :
                        -4063 <= pcm ? 0x10 + ((pcm - -4063) >> 7) :
                        -8159 <= pcm ? 0x00 + ((pcm - -8159) >> 8) :
                        0x00;
            }
            ulawBuf[ulawOffset++] = (byte)ulaw;
        }
    
public static intmaxAbsPcm(byte[] pcmBuf, int offset, int length)
Compute the maximum of the absolute value of the pcm samples. The return value can be used to set ulaw encoder scaling.

param
pcmBuf array containing 16 bit pcm data.
param
offset offset of start of 16 bit pcm data.
param
length number of pcm samples (not number of input bytes)
return
maximum abs of pcm data values

        int max = 0;
        for (int i = 0; i < length; i++) {
            int pcm = (0xff & pcmBuf[offset++]) + (pcmBuf[offset++] << 8);
            if (pcm < 0) pcm = -pcm;
            if (pcm > max) max = pcm;
        }
        return max;
    
public intread(byte[] buf, int offset, int length)

        if (mIn == null) throw new IllegalStateException("not open");

        // return at least one byte, but try to fill 'length'
        while (mBufCount < 2) {
            int n = mIn.read(mBuf, mBufCount, Math.min(length * 2, mBuf.length - mBufCount));
            if (n == -1) return -1;
            mBufCount += n;
        }
        
        // compand data
        int n = Math.min(mBufCount / 2, length);
        encode(mBuf, 0, buf, offset, n, mMax);
        
        // move data to bottom of mBuf
        mBufCount -= n * 2;
        for (int i = 0; i < mBufCount; i++) mBuf[i] = mBuf[i + n * 2];
        
        return n;
    
public intread(byte[] buf)

        return read(buf, 0, buf.length);
    
public intread()

        int n = read(mOneByte, 0, 1);
        if (n == -1) return -1;
        return 0xff & (int)mOneByte[0];