| 1 | using System; | 
 
 
 
 
 | 2 | using System.IO; | 
 
 
 
 
 | 3 |  | 
 
 
 
 
 | 4 | namespace Oni.Sound | 
 
 
 
 
 | 5 | { | 
 
 
 
 
 | 6 | internal class AifFile | 
 
 
 
 
 | 7 | { | 
 
 
 
 
 | 8 | #region Private data | 
 
 
 
 
 | 9 | private const int fcc_FORM = 0x464f524d; | 
 
 
 
 
 | 10 | private const int fcc_AIFC = 0x41494643; | 
 
 
 
 
 | 11 | private const int fcc_COMM = 0x434f4d4d; | 
 
 
 
 
 | 12 | private const int fcc_SSND = 0x53534e44; | 
 
 
 
 
 | 13 |  | 
 
 
 
 
 | 14 | private int channelCount; | 
 
 
 
 
 | 15 | private int numSampleFrames; | 
 
 
 
 
 | 16 | private int sampleSize; | 
 
 
 
 
 | 17 | private byte[] sampleRate; | 
 
 
 
 
 | 18 | private int format; | 
 
 
 
 
 | 19 | private byte[] soundData; | 
 
 
 
 
 | 20 | #endregion | 
 
 
 
 
 | 21 |  | 
 
 
 
 
 | 22 | public static AifFile FromFile(string filePath) | 
 
 
 
 
 | 23 | { | 
 
 
 
 
 | 24 | using (var reader = new BinaryReader(filePath, true)) | 
 
 
 
 
 | 25 | { | 
 
 
 
 
 | 26 | var header = new AifFile(); | 
 
 
 
 
 | 27 |  | 
 
 
 
 
 | 28 | if (reader.ReadInt32() != fcc_FORM) | 
 
 
 
 
 | 29 | throw new InvalidDataException("Not an AIF file"); | 
 
 
 
 
 | 30 |  | 
 
 
 
 
 | 31 | int size = reader.ReadInt32(); | 
 
 
 
 
 | 32 |  | 
 
 
 
 
 | 33 | if (reader.ReadInt32() != fcc_AIFC) | 
 
 
 
 
 | 34 | throw new InvalidDataException("Not a compressed AIF file"); | 
 
 
 
 
 | 35 |  | 
 
 
 
 
 | 36 | for (int chunkType, chunkSize, chunkStart; reader.Position < size; reader.Position = chunkStart + chunkSize) | 
 
 
 
 
 | 37 | { | 
 
 
 
 
 | 38 | chunkType = reader.ReadInt32(); | 
 
 
 
 
 | 39 | chunkSize = reader.ReadInt32(); | 
 
 
 
 
 | 40 | chunkStart = reader.Position; | 
 
 
 
 
 | 41 |  | 
 
 
 
 
 | 42 | if (chunkType == fcc_COMM) | 
 
 
 
 
 | 43 | header.ReadFormatChunk(reader, chunkSize); | 
 
 
 
 
 | 44 | else if (chunkType == fcc_SSND) | 
 
 
 
 
 | 45 | header.ReadDataChunk(reader, chunkSize); | 
 
 
 
 
 | 46 | } | 
 
 
 
 
 | 47 |  | 
 
 
 
 
 | 48 | return header; | 
 
 
 
 
 | 49 | } | 
 
 
 
 
 | 50 | } | 
 
 
 
 
 | 51 |  | 
 
 
 
 
 | 52 | private void ReadFormatChunk(BinaryReader reader, int chunkSize) | 
 
 
 
 
 | 53 | { | 
 
 
 
 
 | 54 | channelCount = reader.ReadInt16(); | 
 
 
 
 
 | 55 | numSampleFrames = reader.ReadInt32(); | 
 
 
 
 
 | 56 | sampleSize = reader.ReadInt16(); | 
 
 
 
 
 | 57 | sampleRate = reader.ReadBytes(10); | 
 
 
 
 
 | 58 | format = reader.ReadInt32(); | 
 
 
 
 
 | 59 | } | 
 
 
 
 
 | 60 |  | 
 
 
 
 
 | 61 | private void ReadDataChunk(BinaryReader reader, int chunkSize) | 
 
 
 
 
 | 62 | { | 
 
 
 
 
 | 63 | reader.Position += 8; | 
 
 
 
 
 | 64 | soundData = reader.ReadBytes(chunkSize - 8); | 
 
 
 
 
 | 65 | } | 
 
 
 
 
 | 66 |  | 
 
 
 
 
 | 67 | public int ChannelCount => channelCount; | 
 
 
 
 
 | 68 | public int SampleFrames => numSampleFrames; | 
 
 
 
 
 | 69 | public int SampleSize => sampleSize; | 
 
 
 
 
 | 70 | public byte[] SampleRate => sampleRate; | 
 
 
 
 
 | 71 | public int Format => format; | 
 
 
 
 
 | 72 | public byte[] SoundData => soundData; | 
 
 
 
 
 | 73 | } | 
 
 
 
 
 | 74 | } |