using System; using System.IO; namespace Oni.Sound { internal class AifFile { #region Private data private const int fcc_FORM = 0x464f524d; private const int fcc_AIFC = 0x41494643; private const int fcc_COMM = 0x434f4d4d; private const int fcc_SSND = 0x53534e44; private int channelCount; private int numSampleFrames; private int sampleSize; private byte[] sampleRate; private int format; private byte[] soundData; #endregion public static AifFile FromFile(string filePath) { using (var reader = new BinaryReader(filePath, true)) { var header = new AifFile(); if (reader.ReadInt32() != fcc_FORM) throw new InvalidDataException("Not an AIF file"); int size = reader.ReadInt32(); if (reader.ReadInt32() != fcc_AIFC) throw new InvalidDataException("Not a compressed AIF file"); for (int chunkType, chunkSize, chunkStart; reader.Position < size; reader.Position = chunkStart + chunkSize) { chunkType = reader.ReadInt32(); chunkSize = reader.ReadInt32(); chunkStart = reader.Position; if (chunkType == fcc_COMM) header.ReadFormatChunk(reader, chunkSize); else if (chunkType == fcc_SSND) header.ReadDataChunk(reader, chunkSize); } return header; } } private void ReadFormatChunk(BinaryReader reader, int chunkSize) { channelCount = reader.ReadInt16(); numSampleFrames = reader.ReadInt32(); sampleSize = reader.ReadInt16(); sampleRate = reader.ReadBytes(10); format = reader.ReadInt32(); } private void ReadDataChunk(BinaryReader reader, int chunkSize) { reader.Position += 8; soundData = reader.ReadBytes(chunkSize - 8); } public int ChannelCount => channelCount; public int SampleFrames => numSampleFrames; public int SampleSize => sampleSize; public byte[] SampleRate => sampleRate; public int Format => format; public byte[] SoundData => soundData; } }