public static void ReadAiffHeader(Stream stream, out WaveFormat format, out long dataChunkPosition, out int dataChunkLength, List<AiffFileReader.AiffChunk> chunks) { dataChunkPosition = -1L; format = null; BinaryReader binaryReader = new BinaryReader(stream); if (AiffFileReader.ReadChunkName(binaryReader) != "FORM") { throw new FormatException("Not an AIFF file - no FORM header."); } AiffFileReader.ConvertInt(binaryReader.ReadBytes(4)); string a = AiffFileReader.ReadChunkName(binaryReader); if (a != "AIFC" && a != "AIFF") { throw new FormatException("Not an AIFF file - no AIFF/AIFC header."); } dataChunkLength = 0; while (binaryReader.BaseStream.Position < binaryReader.BaseStream.Length) { AiffFileReader.AiffChunk aiffChunk = AiffFileReader.ReadChunkHeader(binaryReader); if (aiffChunk.ChunkName == "\0\0\0\0" || binaryReader.BaseStream.Position + (long)((ulong)aiffChunk.ChunkLength) > binaryReader.BaseStream.Length) { break; } if (aiffChunk.ChunkName == "COMM") { short channels = AiffFileReader.ConvertShort(binaryReader.ReadBytes(2)); AiffFileReader.ConvertInt(binaryReader.ReadBytes(4)); short bits = AiffFileReader.ConvertShort(binaryReader.ReadBytes(2)); double num = IEEE.ConvertFromIeeeExtended(binaryReader.ReadBytes(10)); format = new WaveFormat((int)num, (int)bits, (int)channels); if (aiffChunk.ChunkLength > 18u && a == "AIFC") { if (new string(binaryReader.ReadChars(4)).ToLower() != "none") { throw new FormatException("Compressed AIFC is not supported."); } binaryReader.ReadBytes((int)(aiffChunk.ChunkLength - 22u)); } else { binaryReader.ReadBytes((int)(aiffChunk.ChunkLength - 18u)); } } else if (aiffChunk.ChunkName == "SSND") { uint num2 = AiffFileReader.ConvertInt(binaryReader.ReadBytes(4)); AiffFileReader.ConvertInt(binaryReader.ReadBytes(4)); dataChunkPosition = (long)((ulong)(aiffChunk.ChunkStart + 16u + num2)); dataChunkLength = (int)(aiffChunk.ChunkLength - 8u); binaryReader.BaseStream.Position += (long)((ulong)(aiffChunk.ChunkLength - 8u)); } else { if (chunks != null) { chunks.Add(aiffChunk); } binaryReader.BaseStream.Position += (long)((ulong)aiffChunk.ChunkLength); } } if (format == null) { throw new FormatException("Invalid AIFF file - No COMM chunk found."); } if (dataChunkPosition == -1L) { throw new FormatException("Invalid AIFF file - No SSND chunk found."); } }
/// <summary> /// Ensures valid AIFF header and then finds data offset. /// </summary> /// <param name="stream">The stream, positioned at the start of audio data</param> /// <param name="format">The format found</param> /// <param name="dataChunkPosition">The position of the data chunk</param> /// <param name="dataChunkLength">The length of the data chunk</param> /// <param name="chunks">Additional chunks found</param> public static void ReadAiffHeader(System.IO.Stream stream, out WaveFormatProvider format, out long dataChunkPosition, out int dataChunkLength, List <AiffChunk> chunks) { dataChunkPosition = -1; format = null; BinaryReader br = new BinaryReader(stream); if (ReadChunkName(br) != "FORM") { throw new FormatException("Not an AIFF file - no FORM header."); } uint fileSize = ConvertInt(br.ReadBytes(4)); string formType = ReadChunkName(br); if (formType != "AIFC" && formType != "AIFF") { throw new FormatException("Not an AIFF file - no AIFF/AIFC header."); } dataChunkLength = 0; while (br.BaseStream.Position < br.BaseStream.Length) { AiffChunk nextChunk = ReadChunkHeader(br); if (nextChunk.ChunkName == "COMM") { short numChannels = ConvertShort(br.ReadBytes(2)); uint numSampleFrames = ConvertInt(br.ReadBytes(4)); short sampleSize = ConvertShort(br.ReadBytes(2)); double sampleRate = IEEE.ConvertFromIeeeExtended(br.ReadBytes(10)); format = new WaveFormatProvider((int)sampleRate, (int)sampleSize, (int)numChannels); if (nextChunk.ChunkLength > 18 && formType == "AIFC") { // In an AIFC file, the compression format is tacked on to the COMM chunk string compress = new string(br.ReadChars(4)).ToLower(); if (compress != "none") { throw new FormatException("Compressed AIFC is not supported."); } br.ReadBytes((int)nextChunk.ChunkLength - 22); } else { br.ReadBytes((int)nextChunk.ChunkLength - 18); } } else if (nextChunk.ChunkName == "SSND") { uint offset = ConvertInt(br.ReadBytes(4)); uint blockSize = ConvertInt(br.ReadBytes(4)); dataChunkPosition = nextChunk.ChunkStart + 16 + offset; dataChunkLength = (int)nextChunk.ChunkLength - 8; br.ReadBytes((int)nextChunk.ChunkLength - 8); } else { if (chunks != null) { chunks.Add(nextChunk); } br.ReadBytes((int)nextChunk.ChunkLength); } if (nextChunk.ChunkName == "\0\0\0\0") { break; } } if (format == null) { throw new FormatException("Invalid AIFF file - No COMM chunk found."); } if (dataChunkPosition == -1) { throw new FormatException("Invalid AIFF file - No SSND chunk found."); } }
public bool Read(string filePath) { if (File.Exists(filePath)) { string fileName = Path.GetFileNameWithoutExtension(filePath); PresetName = fileName; BinaryFile bFile = new BinaryFile(filePath, BinaryFile.ByteOrder.BigEndian); string firstChunkID = bFile.ReadString(4); // chunk ID = "FORM" int ckSize = bFile.ReadInt32(); string formType = bFile.ReadString(4); // read first data chunk string chunkID = bFile.ReadString(4); // if chunkID == "COMT" then CommentsChunk if (chunkID.Equals("COMT")) { long curposTmpComt = bFile.GetPosition(); bFile.Seek(curposTmpComt - 4); // CommentsChunk string chunkIDComt = bFile.ReadString(4); // chunk ID = "COMT" int chunkSizeComt = bFile.ReadInt32(); int numComments = bFile.ReadUInt16(); long curposTmpComt2 = bFile.GetPosition(); for (int i = 0; i < numComments; i++) { int commentTimestamp = (int)bFile.ReadUInt32(); string marker = bFile.ReadString(4); int count = (int)bFile.ReadByte(); comments.Add(bFile.ReadString(count)); } bFile.Seek(curposTmpComt2 + chunkSizeComt - 2); } string chunkID2 = bFile.ReadString(4); // if chunkID2 == "COMM" then CommonChunk if (chunkID2.Equals("COMM")) { long curposTmpComm = bFile.GetPosition(); bFile.Seek(curposTmpComm - 4); // CommonChunk string chunkIDComm = bFile.ReadString(4); // chunk ID = "COMM" int chunkSizeComm = bFile.ReadInt32(); channels = bFile.ReadInt16(); numSampleFrames = (int)bFile.ReadUInt32(); bitsPerSample = bFile.ReadInt16(); // read IEEE 80-bit extended double precision byte[] sampleRateBytes = bFile.ReadBytes(0, 10, BinaryFile.ByteOrder.LittleEndian); double sampleRateDouble = IEEE.ConvertFromIeeeExtended(sampleRateBytes); sampleRate = (int)sampleRateDouble; } string chunkID3 = bFile.ReadString(4); // if chunkID3 == "SSND" then SoundDataChunk if (chunkID3.Equals("SSND")) { long curposTmpSsnd = bFile.GetPosition(); bFile.Seek(curposTmpSsnd - 4); // SoundDataChunk string chunkIDSsnd = bFile.ReadString(4); // chunk ID = "SSND" int chunkSizeSsnd = bFile.ReadInt32(); int offset = (int)bFile.ReadUInt32(); int blocksize = (int)bFile.ReadUInt32(); byte[] data = bFile.ReadBytes(offset, chunkSizeSsnd - 8, BinaryFile.ByteOrder.LittleEndian); // swap waveform data WaveformData = SwapAiffEndian(data); } bFile.Close(); return(true); } else { return(false); } }