package org.jaudiotagger.audio.aiff; import java.io.IOException; import java.io.RandomAccessFile; import org.jaudiotagger.audio.generic.Utils; public class CommonChunk extends Chunk { private AiffAudioHeader aiffHeader; /** * Constructor. * * @param hdr The header for this chunk * @param raf The file from which the AIFF data are being read * @param aHdr The AiffTag into which information is stored */ public CommonChunk ( ChunkHeader hdr, RandomAccessFile raf, AiffAudioHeader aHdr) { super (raf, hdr); aiffHeader = aHdr; } @Override public boolean readChunk() throws IOException { int numChannels = Utils.readUint16(raf); long numSampleFrames = Utils.readUint32(raf); int sampleSize = Utils.readUint16(raf); bytesLeft -= 8; String compressionType = null; String compressionName = null; double sampleRate = AiffUtil.read80BitDouble (raf); bytesLeft -= 10; if (aiffHeader.getFileType () == AiffAudioHeader.FileType.AIFCTYPE) { if (bytesLeft == 0) { // This is a rather special case, but testing did turn up // a file that misbehaved in this way. return false; } compressionType = AiffUtil.read4Chars (raf); // According to David Ackerman, the compression type can // change the endianness of the document. if (compressionType.equals ("sowt")) { aiffHeader.setEndian (AiffAudioHeader.Endian.LITTLE_ENDIAN); } bytesLeft -= 4; compressionName = AiffUtil.readPascalString (raf); bytesLeft -= compressionName.length () + 1; } aiffHeader.setBitsPerSample (sampleSize); aiffHeader.setSamplingRate ((int) sampleRate); aiffHeader.setChannelNumber (numChannels); aiffHeader.setLength ((int)( numSampleFrames / sampleRate)); aiffHeader.setPreciseLength((float) (numSampleFrames / sampleRate)); aiffHeader.setLossless(true); // for all known compression types // Proper handling of compression type should depend // on whether raw output is set if (compressionType != null) { if (compressionType.equals ("NONE")) { } else if (compressionType.equals ("raw ")) { compressionName = "PCM 8-bit offset-binary"; } else if (compressionType.equals ("twos")) { compressionName = "PCM 16-bit twos-complement big-endian"; } else if (compressionType.equals ("sowt")) { compressionName = "PCM 16-bit twos-complement little-endian"; } else if (compressionType.equals ("fl32")) { compressionName = "PCM 32-bit integer"; } else if (compressionType.equals ("fl64")) { compressionName = "PCM 64-bit floating point"; } else if (compressionType.equals ("in24")) { compressionName = "PCM 24-bit integer"; } else if (compressionType.equals ("in32")) { compressionName = "PCM 32-bit integer"; } else { aiffHeader.setLossless(false); // We don'timer know, so we have to assume lossy } aiffHeader.setAudioEncoding (compressionName); // The size of the data after compression isn'timer available // from the Common chunk, so we mark it as "unknown." // With a bit more sophistication, we could combine the // information from here and the Sound Data chunk to get // the effective byte rate, but we're about to release. String name = compressionName; if (name == null || name.length () == 0) { name = compressionType; } } return true; } }