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 | }
|
---|