throw new RiffFormatException("RIFF header not found");
}
if (!Arrays.equals(waveHeader, WaveFile.WAVE_HEADER)){
is.close();
throw new WaveFormatException("WAVE header missing");
}
// now, read in each chunk
FormatChunk formatChunk = null;
AudioDataChunk audioChunk = null;
byte[] chunkId = new byte[4];
byte[] chunkSize = new byte[4];
byte[] chunkData;
while (is.read(chunkId) == 4) {
is.read(chunkSize);
int size = (int)EndianConverter.littleEndianIntToJavaLong(chunkSize);
if (Arrays.equals(chunkId, FormatChunk.FORMAT_CHUNK_HEADER)) {
chunkData = new byte[size];
is.read(chunkData);
formatChunk = new FormatChunk();
try {
formatChunk.setChunkData(chunkData);
} catch (ChunkFormatException e) {
is.close();
throw new WaveFormatException("Bad Format Header");
}
} else if (Arrays.equals(chunkId,AudioDataChunk.AUDIO_DATA_CHUNK_HEADER)) {
chunkData = new byte[size];
// Reading the entire buffer may not work for large files, and reading one
// byte at a time is horribly slow. So, will read in 512 byte chunks
int readBufferSize = 512;
byte buffer[] = new byte[readBufferSize];
int bytesRead = is.read(buffer);
int fillCount = 0; // number of times buffer filled
while (bytesRead > 0) {
for(int index = 0; index < bytesRead; ++index) {
int fillPosition = (fillCount*readBufferSize)+index;
// for some reason, some files seem to have more bytes than they claim to...
// this will prevent IndexOutOfBounds exceptions
if (fillPosition < size) {
chunkData[(fillCount*readBufferSize)+index] = buffer[index];
}
}
bytesRead = is.read(buffer);
++fillCount;
}
audioChunk = new AudioDataChunk();
audioChunk.setChunkData(chunkData);
} else {
// read past the data, and ignore it
chunkData = new byte[size];
is.read(chunkData);
}
}
// close input stream
is.close();
// make sure the required chunks were found
if (formatChunk == null) {
throw new WaveFormatException("Format chunk not found");
}
if (audioChunk == null) {
throw new WaveFormatException("AudioData chunk not found");
}
WaveFile wave = new WaveFile();
wave.setAudioDataChunk(audioChunk);
wave.setFormatChunk(formatChunk);