| 1 |  | using System; | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 2 |  | using System.Collections.Generic; | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 3 |  | using System.IO; | 
 
 
 
 
 
 
 
 | 4 | + | //using System.Runtime.Remoting.Metadata.W3cXsd2001; | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 5 |  |  | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 6 |  | namespace Oni.Sound | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 7 |  | { | 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 | 10 |  | #region Private data | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 11 |  | private const int fcc_RIFF = 0x46464952; | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 12 |  | private const int fcc_WAVE = 0x45564157; | 
 
 
 
 
 
 
 
 
 
 
 | 13 | < | private const int fcc_fmt = 0x20746d66; | 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 | 13 | > | private const int fcc_fmt  = 0x20746d66; | 
 
 
 
 
 | 14 | > | private const int fcc_fact = 0x74636166; | 
 
 
 
 
 
 
 
 
 
 
 | 15 |  | private const int fcc_data = 0x61746164; | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 16 |  |  | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 17 |  | private WavFormat format; | 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 | 20 |  | private int averageBytesPerSecond; | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 21 |  | private int blockAlign; | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 22 |  | private int bitsPerSample; | 
 
 
 
 
 
 
 
 | 23 | + | private int sampleCount; | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 24 |  | private byte[] extraData; | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 25 |  | private byte[] soundData; | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 26 |  | #endregion | 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 | 37 |  | if (reader.ReadInt32() != fcc_WAVE) | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 38 |  | throw new InvalidDataException("Not a WAV file"); | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 39 |  |  | 
 
 
 
 
 
 
 
 
 
 
 | 40 | < | var header = new WavFile(); | 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 | 40 | > | var header = new WavFile() | 
 
 
 
 
 | 41 | > | { | 
 
 
 
 
 | 42 | > | sampleCount = 0 | 
 
 
 
 
 | 43 | > | }; | 
 
 
 
 
 
 
 
 
 
 
 | 44 |  |  | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 45 |  | for (int chunkType, chunkSize, chunkStart; reader.Position < size; reader.Position = chunkStart + chunkSize) | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 46 |  | { | 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 | 50 |  |  | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 51 |  | if (chunkType == fcc_fmt) | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 52 |  | header.ReadFormatChunk(reader, chunkSize); | 
 
 
 
 
 
 
 
 
 
 
 | 53 | < | else if (chunkType == fcc_data) | 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 | 53 | > | if (chunkType == fcc_fact) | 
 
 
 
 
 | 54 | > | header.ReadFactChunk(reader, chunkSize); | 
 
 
 
 
 | 55 | > | if (chunkType == fcc_data) | 
 
 
 
 
 
 
 
 
 
 
 | 56 |  | header.ReadDataChunk(reader, chunkSize); | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 57 |  | } | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 58 |  |  | 
 
 
 
 
 
 
 
 | 59 | + | header.ValidateSampleCount(); | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 60 |  | return header; | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 61 |  | } | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 62 |  | } | 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 | 76 |  | extraData = new byte[0]; | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 77 |  | } | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 78 |  |  | 
 
 
 
 
 
 
 
 | 79 | + | private void ReadFactChunk(BinaryReader reader, int chunkSize) | 
 
 
 
 
 
 
 
 | 80 | + | { | 
 
 
 
 
 
 
 
 | 81 | + | sampleCount = reader.ReadInt32(); | 
 
 
 
 
 
 
 
 | 82 | + | } | 
 
 
 
 
 
 
 
 | 83 | + |  | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 84 |  | private void ReadDataChunk(BinaryReader reader, int chunkSize) | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 85 |  | { | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 86 |  | soundData = reader.ReadBytes(chunkSize); | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 87 |  | } | 
 
 
 
 
 
 
 
 | 88 | + | private void ValidateSampleCount() // TODO: ACTUAL VALIDATION/CORRECTION | 
 
 
 
 
 
 
 
 | 89 | + | { | 
 
 
 
 
 
 
 
 | 90 | + | int sampleCountFromData = 0; | 
 
 
 
 
 
 
 
 | 91 | + | int wholeBlocks = soundData.Length / blockAlign; | 
 
 
 
 
 
 
 
 | 92 | + | if(sampleCount == 0) // not explicitly set (no fact chunk present) | 
 
 
 
 
 
 
 
 | 93 | + | { | 
 
 
 
 
 
 
 
 | 94 | + | Console.WriteLine("The imported WAV file has no FACT chunk."); | 
 
 
 
 
 
 
 
 | 95 | + | } | 
 
 
 
 
 
 
 
 | 96 | + | else // TODO: calculate sampleCountFromData, compare with sampleCount | 
 
 
 
 
 
 
 
 | 97 | + | { | 
 
 
 
 
 
 
 
 | 98 | + |  | 
 
 
 
 
 
 
 
 | 99 | + | } | 
 
 
 
 
 
 
 
 | 100 | + | } | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 101 |  |  | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 102 |  | public WavFormat Format => format; | 
 
 
 
 
 
 
 
 
 
 
 
 
 | 103 |  | public int ChannelCount => channelCount; |