Java File Read via ByteBuffer readFileHeader(FileInputStream fpi)

Here you can find the source of readFileHeader(FileInputStream fpi)

Description

read File Header

License

Open Source License

Declaration

public static int readFileHeader(FileInputStream fpi) 

Method Source Code

//package com.java2s;

import java.io.DataInputStream;
import java.io.EOFException;

import java.io.FileInputStream;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

import java.nio.channels.FileChannel;

public class Main {
    public static ByteOrder byteOrder = ByteOrder.LITTLE_ENDIAN;
    public static int srcChannels, dstChannels, srcBPS;
    public static int srcSamplingRate, dstSamplingRate, dstBPS;
    public static long length = 0;

    public static int readFileHeader(FileInputStream fpi) {
        DataInputStream inStrm = new DataInputStream(fpi);

        byte[] buf = new byte[4];
        try {//from  w  w w . j a  v a  2s  . c  o  m
            inStrm.readFully(buf, 0, 4);
            String fType = new String(buf, 0, 4);
            if ("RIFF".equals(fType)) {
                byteOrder = ByteOrder.LITTLE_ENDIAN;
                if (readWavHeader(inStrm, fpi.getChannel()))
                    return 1;
            } else if ("FORM".equals(fType)) {
                byteOrder = ByteOrder.BIG_ENDIAN;
                if (readAiffHeader(inStrm, fpi.getChannel()))
                    return 2;
            } else if ("fLaC".equals(fType)) {
                /*            fpi.getChannel().position(0);
                        FLACDecoder flacDec = new FLACDecoder(inStrm);
                        StreamInfo strmInfo = flacDec.readStreamInfo();
                        srcSamplingRate = strmInfo.getSampleRate();
                        srcBPS = strmInfo.getBitsPerSample()/8;
                        srcChannels = strmInfo.getChannels();
                        length = strmInfo.getTotalSamples() * srcBPS * srcChannels;
                        fpi.getChannel().position(0);
                        return 3;*/
            }
        } catch (IOException e1) {
            System.err.println("Error reading file header");
        }
        System.err.println(String.format("Error: Unsupported file type."));
        return 0;
    }

    private static boolean readWavHeader(DataInputStream inStrm, FileChannel fc) {
        byte[] buf = new byte[16];
        int size;
        ByteBuffer bb = ByteBuffer.wrap(buf).order(ByteOrder.LITTLE_ENDIAN);
        bb.clear();
        try {
            inStrm.readInt();

            inStrm.readFully(buf, 0, 8);
            if (!"WAVEfmt ".equals(new String(buf, 0, 8)))
                return false;

            inStrm.readFully(buf, 0, 4);
            size = bb.getInt();
            if (size > buf.length) {
                buf = new byte[size];
                bb = ByteBuffer.wrap(buf).order(ByteOrder.LITTLE_ENDIAN);
            }
            inStrm.readFully(buf, 0, size);
            bb.clear();

            if (bb.getShort() != 1) {
                System.err.println(String.format("Error: Only PCM is supported."));
                return false;
            }
            srcChannels = bb.getShort();
            srcSamplingRate = bb.getInt();
            srcBPS = bb.getInt();
            if ((int) srcBPS % srcSamplingRate * srcChannels != 0)
                return false;

            srcBPS /= srcSamplingRate * srcChannels;

            byte[] cbuf = new byte[4];
            for (;;) {
                inStrm.readFully(cbuf, 0, 4);
                try {
                    bb.clear();
                    inStrm.readFully(buf, 0, 4);
                    length = (long) bb.getInt();
                } catch (IOException ex) {
                    break;
                }
                if ("data".equals(new String(cbuf, 0, 4)))
                    break;
                fc.position(fc.position() + length);
            }
            if (fc.position() > fc.size()) {
                System.err.println(String.format("Couldn't find data chank"));
                return false;
            }

            if (srcBPS != 1 && srcBPS != 2 && srcBPS != 3 && srcBPS != 4) {
                System.err.println(String.format("Error : Only 8bit, 16bit, 24bit and 32bit PCM are supported."));
                return false;
            }

        } catch (IOException e1) {
            System.err.println("Error reading file header");
            return false;
        }
        return true;
    }

    private static boolean readAiffHeader(DataInputStream inStrm, FileChannel fc) {
        byte[] buf = new byte[10];
        boolean isAIFC = false;
        try {
            inStrm.readInt();

            inStrm.readFully(buf, 0, 4);
            if ("AIFC".equals(new String(buf, 0, 4)))
                isAIFC = true;
            else if (!"AIFF".equals(new String(buf, 0, 4)))
                return false;

            String ckID;
            int ckSize;
            int offset;
            long dataPos = 0;
            int numSampleFrames = 0;
            long vTimestamp;
            boolean foundOne = false;
            double freq;
            while (true) {
                inStrm.readFully(buf, 0, 4);
                ckSize = inStrm.readInt();

                ckID = new String(buf, 0, 4);
                if ("COMM".equals(ckID)) {
                    srcChannels = inStrm.readShort();
                    numSampleFrames = inStrm.readInt();
                    srcBPS = inStrm.readShort();
                    inStrm.readFully(buf, 0, 10);
                    freq = extendedToDouble(buf);
                    srcSamplingRate = (int) freq;
                    if (isAIFC) {
                        ckID = new String(buf, 0, 4);
                        if (!"NONE".equals(ckID)) {
                            System.err.println("Compressed AIFF files are not supported");
                            return false;
                        }
                        if (ckSize - 22 > 0)
                            inStrm.skip(ckSize - 22);
                    }
                    if (foundOne)
                        break;
                    foundOne = true;
                } else if ("SSND".equals(ckID)) {
                    offset = inStrm.readInt();
                    inStrm.readInt();
                    dataPos = fc.position() + offset;
                    if (foundOne)
                        break;
                    foundOne = true;
                } else if ("FVER".equals(ckID)) {
                    vTimestamp = inStrm.readInt();
                    if (vTimestamp != 0xA2805140l) {
                        System.err.println("AIFF format version not recognized");
                        return false;
                    }
                }
            }
            if (srcBPS != 8 && srcBPS != 16 && srcBPS != 24 && srcBPS != 32) {
                System.err.println(String.format("Error : Only 8bit, 16bit, 24bit and 32bit PCM are supported."));
                return false;
            }
            srcBPS /= 8;
            length = numSampleFrames * srcChannels * srcBPS;
            if (length == 0) {
                System.err.println(String.format("Couldn't find data chank"));
                return false;
            }
            fc.position(dataPos);

        } catch (EOFException eof) {
            System.err.println(String.format("Couldn't find data chank"));
            return false;
        } catch (NumberFormatException e1) {
            System.err.println("Error reading file header");
            return false;
        } catch (IOException e1) {
            System.err.println("Error reading file header");
            return false;
        }
        return true;
    }

    public static double extendedToDouble(byte[] buf) throws NumberFormatException {
        ByteBuffer b = ByteBuffer.wrap(buf, 0, 10).order(ByteOrder.BIG_ENDIAN);
        int e = b.getShort();
        double sign = ((e & 0x80) != 0) ? -1 : 1;
        e &= 0x7fff;
        long m = b.getLong();

        double normal = (m & 0x8000000000000000L) != 0 ? 1 : 0;
        m &= 0x7fffffffffffffffL;

        if (m == 0)
            return 0;
        else {
            if (e == 0)
                e = -16382;
            else if ((e & 0x7fff) == 0x7fff)
                throw new NumberFormatException("NAN or Infinity");
            else
                e -= 16383;
        }
        // Shifting the divisor by 62 bits and then dividing the result by 2 deals
        // with the fact that java does not having unsign longs
        return sign * (normal + (double) m / (1L << 62) / 2) * Math.pow(2.0, (float) e);
    }
}

Related

  1. readFileAsStringArray(File file)
  2. readFileChannelFully(FileChannel fileChannel, byte buf[], int off, int len)
  3. readFileChannelFully(FileChannel fileChannel, byte buf[], int off, int len)
  4. readFileDataIntoBufferBE(FileChannel fc, final int size)
  5. readFileFragment(FileChannel fc, long pos, int size)
  6. readFileIntoString(File localFile)
  7. readFileIntoString(String path)
  8. readFileNIO(String path, StringBuilder builder)
  9. readFileToBuffer(java.io.File file)