if (magic != AiffFileFormat.AIFF_MAGIC) {
// not AIFF, throw exception
if (doReset) {
dis.reset();
}
throw new UnsupportedAudioFileException("not an AIFF file");
}
int length = dis.readInt();
int iffType = dis.readInt();
fileRead += 12;
int totallength;
if(length <= 0 ) {
length = AudioSystem.NOT_SPECIFIED;
totallength = AudioSystem.NOT_SPECIFIED;
} else {
totallength = length + 8;
}
// Is this an AIFC or just plain AIFF file.
boolean aifc = false;
// $$fb: fix for 4369044: javax.sound.sampled.AudioSystem.getAudioInputStream() works wrong with Cp037
if (iffType == AiffFileFormat.AIFC_MAGIC) {
aifc = true;
}
// Loop through the AIFF chunks until
// we get to the SSND chunk.
boolean ssndFound = false;
while (!ssndFound) {
// Read the chunk name
int chunkName = dis.readInt();
int chunkLen = dis.readInt();
fileRead += 8;
int chunkRead = 0;
// Switch on the chunk name.
switch (chunkName) {
case AiffFileFormat.FVER_MAGIC:
// Ignore format version for now.
break;
case AiffFileFormat.COMM_MAGIC:
// AIFF vs. AIFC
// $$fb: fix for 4399551: Repost of bug candidate: cannot replay aif file (Review ID: 108108)
if ((!aifc && chunkLen < 18) || (aifc && chunkLen < 22)) {
throw new UnsupportedAudioFileException("Invalid AIFF/COMM chunksize");
}
// Read header info.
int channels = dis.readShort();
dis.readInt();
int sampleSizeInBits = dis.readShort();
float sampleRate = (float) read_ieee_extended(dis);
chunkRead += (2 + 4 + 2 + 10);
// If this is not AIFC then we assume it's
// a linearly encoded file.
AudioFormat.Encoding encoding = AudioFormat.Encoding.PCM_SIGNED;
if (aifc) {
int enc = dis.readInt(); chunkRead += 4;
switch (enc) {
case AiffFileFormat.AIFC_PCM:
encoding = AudioFormat.Encoding.PCM_SIGNED;
break;
case AiffFileFormat.AIFC_ULAW:
encoding = AudioFormat.Encoding.ULAW;
sampleSizeInBits = 8; // Java Sound convention
break;
default:
throw new UnsupportedAudioFileException("Invalid AIFF encoding");
}
}
int frameSize = calculatePCMFrameSize(sampleSizeInBits, channels);
//$fb what's that ??
//if (sampleSizeInBits == 8) {
// encoding = AudioFormat.Encoding.PCM_SIGNED;
//}
format = new AudioFormat(encoding, sampleRate,
sampleSizeInBits, channels,
frameSize, sampleRate, true);
break;
case AiffFileFormat.SSND_MAGIC:
// Data chunk.
// we are getting *weird* numbers for chunkLen sometimes;
// this really should be the size of the data chunk....
int dataOffset = dis.readInt();
int blocksize = dis.readInt();
chunkRead += 8;
// okay, now we are done reading the header. we need to set the size
// of the data segment. we know that sometimes the value we get for
// the chunksize is absurd. this is the best i can think of:if the
// value seems okay, use it. otherwise, we get our value of
// length by assuming that everything left is the data segment;
// its length should be our original length (for all AIFF data chunks)
// minus what we've read so far.
// $$kk: we should be able to get length for the data chunk right after
// we find "SSND." however, some aiff files give *weird* numbers. what
// is going on??
if (chunkLen < length) {
dataLength = chunkLen - chunkRead;
} else {
// $$kk: 11.03.98: this seems dangerous!
dataLength = length - (fileRead + chunkRead);
}
ssndFound = true;
break;
} // switch
fileRead += chunkRead;
// skip the remainder of this chunk
if (!ssndFound) {
int toSkip = chunkLen - chunkRead;
if (toSkip > 0) {
fileRead += dis.skipBytes(toSkip);
}
}
} // while
if (format == null) {
throw new UnsupportedAudioFileException("missing COMM chunk");
}
AudioFileFormat.Type type = aifc?AudioFileFormat.Type.AIFC:AudioFileFormat.Type.AIFF;
return new AiffFileFormat(type, totallength, format, dataLength / format.getFrameSize());
}