package zero1hd.wavedecoder; import java.io.DataInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.security.InvalidParameterException; public class WavDecoder { DataInputStream readStream; private int channels; private double sampleRate; private int dataSize; private int byteRate; public void setAudioFile(File file) throws InvalidParameterException { try { FileInputStream audioFile = new FileInputStream(file); readStream = new DataInputStream(audioFile); if (!readBytesToString(4).equals("RIFF")) { throw new InvalidParameterException("RIFF tag not found in header."); } dataSize = littleEndianIntBytes(); if (!readBytesToString(4).equals("WAVE")) { throw new InvalidParameterException("WAVE format tag not found."); } if (!readBytesToString(4).equals("fmt ")) { throw new InvalidParameterException("fmt header not found."); } if (readStream.readByte() != 16) { throw new InvalidParameterException("Data not pcm?"); } readStream.skipBytes(3); if (readStream.readByte() != 1) { throw new InvalidParameterException("Data not pcm?"); } readStream.skipBytes(1); channels = readStream.readByte(); readStream.skipBytes(1); sampleRate = littleEndianIntBytes(); byteRate = littleEndianIntBytes(); readStream.skipBytes(38); if (!readBytesToString(4).equals("data")) { throw new InvalidParameterException("initial data section tag not found"); } readStream.skipBytes(4); } catch (IOException e) { e.printStackTrace(); } } private String readBytesToString(int bytesToRead) throws IOException { byte byteString[] = new byte[bytesToRead]; readStream.read(byteString); return new String(byteString); } private int littleEndianIntBytes() throws IOException { int data = readStream.readInt(); return Integer.reverseBytes(data); } private short readLittleEndianShort() throws IOException { short data = readStream.readShort(); return Short.reverseBytes(data); } public int getChannels() { return channels; } public double getSampleRate() { return sampleRate; } public int getByteRate() { return byteRate; } public int getDataSize() { return dataSize; } public int readSamples(float[] samples) { int samplesRead = 0; for (int i = 0; i < samples.length; i++) { try { int currentSample = 0; for (int channel = 0; channel < channels; channel++) { currentSample += readLittleEndianShort(); } currentSample /= channels*Short.MAX_VALUE+1; samples[i] = currentSample; samplesRead++; } catch (IOException e) { break; } } return samplesRead; } }