24 using System.Collections.Generic;
27 namespace SiliconStudio.
Paradox.Audio.Wave
32 internal class SoundStream :
Stream
35 private long startPositionOfData;
42 public SoundStream(
Stream stream)
44 if (stream == null)
throw new ArgumentNullException(
"stream");
53 private unsafe
void Initialize(
Stream stream)
55 var parser =
new RiffParser(stream);
57 FileFormatName =
"Unknown";
60 if (!parser.MoveNext() || parser.Current == null)
62 ThrowInvalidFileFormat();
67 FileFormatName = parser.Current.Type;
68 if (FileFormatName !=
"WAVE")
69 throw new InvalidOperationException(
"Unsupported " + FileFormatName +
" file format. Only WAVE.");
75 var chunks = parser.GetAllChunks();
78 var fmtChunk =
Chunk(chunks,
"fmt ");
79 if (fmtChunk.Size <
sizeof(WaveFormat.__PcmNative))
80 ThrowInvalidFileFormat();
84 Format = WaveFormat.MarshalFrom(fmtChunk.GetData());
86 catch (InvalidOperationException ex)
88 ThrowInvalidFileFormat(ex);
91 switch (Format.Encoding)
93 case WaveFormatEncoding.Pcm:
94 case WaveFormatEncoding.IeeeFloat:
95 case WaveFormatEncoding.Extensible:
96 case WaveFormatEncoding.Adpcm:
99 ThrowInvalidFileFormat();
104 var dataChunk =
Chunk(chunks,
"data");
105 startPositionOfData = dataChunk.DataPosition;
106 length = dataChunk.Size;
108 input.Position = startPositionOfData;
111 protected void ThrowInvalidFileFormat(
Exception nestedException = null)
113 throw new InvalidOperationException(
"Invalid " + FileFormatName +
" file format", nestedException);
119 public WaveFormat Format {
get;
protected set; }
126 public override bool CanRead
136 public override bool CanSeek
146 public override bool CanWrite
148 get {
return false; }
169 public override long Position
173 return input.Position - startPositionOfData;
177 Seek(value, SeekOrigin.Begin);
181 protected override void Dispose(
bool disposing)
188 base.Dispose(disposing);
193 RiffChunk chunk = null;
194 foreach (var riffChunk
in chunks)
196 if (riffChunk.Type ==
id)
202 if (chunk == null || chunk.Type !=
id)
203 throw new InvalidOperationException(
"Invalid " + FileFormatName +
" file format");
207 private string FileFormatName {
get; set; }
215 public override void Flush()
217 throw new NotSupportedException();
239 public override long Seek(
long offset, SeekOrigin origin)
241 var newPosition = input.Position;
244 case SeekOrigin.Begin:
245 newPosition = startPositionOfData + offset;
247 case SeekOrigin.Current:
248 newPosition = input.Position + offset;
251 newPosition = startPositionOfData + length + offset;
255 if (newPosition < startPositionOfData || newPosition > (startPositionOfData + length))
256 throw new InvalidOperationException(
"Cannot seek outside the range of this stream");
258 return input.Seek(offset, origin);
276 public override void SetLength(
long value)
278 throw new NotSupportedException();
313 public override int Read(byte[] buffer,
int offset,
int count)
315 if ((input.Position + count) > (startPositionOfData + length))
316 throw new InvalidOperationException(
"Cannot read more than the length of the stream");
317 return input.Read(buffer, offset,
count);
334 public override long Length
336 get {
return length; }
368 public override void Write(byte[] buffer,
int offset,
int count)
370 throw new NotSupportedException();