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