FileDocCategorySizeDatePackage
ResampleInputStream.javaAPI DocAndroid 1.5 API4565Wed May 06 22:42:00 BST 2009android.media

ResampleInputStream

public final class ResampleInputStream extends InputStream
ResampleInputStream
hide

Fields Summary
private static final String
TAG
private InputStream
mInputStream
private final int
mRateIn
private final int
mRateOut
private byte[]
mBuf
private int
mBufCount
private static final int
mFirLength
private final byte[]
mOneByte
Constructors Summary
public ResampleInputStream(InputStream inputStream, int rateIn, int rateOut)
Create a new ResampleInputStream, which converts the sample rate

param
inputStream InputStream containing 16 bit PCM.
param
rateIn the input sample rate.
param
rateOut the output sample rate. This only handles rateIn == rateOut / 2 for the moment.

    
                                                
           
        // only support 2:1 at the moment
        if (rateIn != 2 * rateOut) throw new IllegalArgumentException("only support 2:1 at the moment");
        rateIn = 2;
        rateOut = 1;

        mInputStream = inputStream;
        mRateIn = rateIn;
        mRateOut = rateOut;
    
Methods Summary
public voidclose()

        try {
            if (mInputStream != null) mInputStream.close();
        } finally {
            mInputStream = null;
        }
    
protected voidfinalize()

        if (mInputStream != null) {
            close();
            throw new IllegalStateException("someone forgot to close ResampleInputStream");
        }
    
private static native voidfir21(byte[] in, int inOffset, byte[] out, int outOffset, int npoints)

public intread()

        int rtn = read(mOneByte, 0, 1);
        return rtn == 1 ? (0xff & mOneByte[0]) : -1;
    
public intread(byte[] b)

        return read(b, 0, b.length);
    
public intread(byte[] b, int offset, int length)

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

        // ensure that mBuf is big enough to cover requested 'length'
        int nIn = ((length / 2) * mRateIn / mRateOut + mFirLength) * 2;
        if (mBuf == null) {
            mBuf = new byte[nIn];
        } else if (nIn > mBuf.length) {
            byte[] bf = new byte[nIn];
            System.arraycopy(mBuf, 0, bf, 0, mBufCount);
            mBuf = bf;
        }
        
        // read until we have enough data for at least one output sample
        while (true) {
            int len = ((mBufCount / 2 - mFirLength) * mRateOut / mRateIn) * 2;
            if (len > 0) {
                length = len < length ? len : (length / 2) * 2;
                break;
            }
            // TODO: should mBuf.length below be nIn instead?
            int n = mInputStream.read(mBuf, mBufCount, mBuf.length - mBufCount);
            if (n == -1) return -1;
            mBufCount += n;
        }

        // resample input data
        fir21(mBuf, 0, b, offset, length / 2);
        
        // move any unused bytes to front of mBuf
        int nFwd = length * mRateIn / mRateOut;
        mBufCount -= nFwd;
        if (mBufCount > 0) System.arraycopy(mBuf, nFwd, mBuf, 0, mBufCount);
        
        return length;