public static bool LoadSound(Stream s, out Func <Stream> result, out short channels, out int sampleBits, out int sampleRate) { result = null; channels = -1; sampleBits = -1; sampleRate = -1; var type = s.ReadASCII(4); if (type != "RIFF") { return(false); } s.ReadInt32(); // File-size var format = s.ReadASCII(4); if (format != "WAVE") { return(false); } WaveType audioType = 0; var dataOffset = -1L; var dataSize = -1; short blockAlign = -1; int uncompressedSize = -1; while (s.Position < s.Length) { if ((s.Position & 1) == 1) { s.ReadByte(); // Alignment } if (s.Position == s.Length) { break; // Break if we aligned with end of stream } var blockType = s.ReadASCII(4); switch (blockType) { case "fmt ": var fmtChunkSize = s.ReadInt32(); var audioFormat = s.ReadInt16(); audioType = (WaveType)audioFormat; if (!Enum.IsDefined(typeof(WaveType), audioType)) { throw new NotSupportedException("Compression type {0} is not supported.".F(audioFormat)); } channels = s.ReadInt16(); sampleRate = s.ReadInt32(); s.ReadInt32(); // Byte Rate blockAlign = s.ReadInt16(); sampleBits = s.ReadInt16(); s.ReadBytes(fmtChunkSize - 16); break; case "fact": var chunkSize = s.ReadInt32(); uncompressedSize = s.ReadInt32(); s.ReadBytes(chunkSize - 4); break; case "data": dataSize = s.ReadInt32(); dataOffset = s.Position; s.Position += dataSize; break; case "LIST": case "cue ": var listCueChunkSize = s.ReadInt32(); s.ReadBytes(listCueChunkSize); break; default: s.Position = s.Length; // Skip to end of stream break; } } if (audioType == WaveType.ImaAdpcm) { sampleBits = 16; } var chan = channels; result = () => { var audioStream = SegmentStream.CreateWithoutOwningStream(s, dataOffset, dataSize); if (audioType == WaveType.ImaAdpcm) { return(new WavStream(audioStream, dataSize, blockAlign, chan, uncompressedSize)); } return(audioStream); // Data is already PCM format. }; return(true); }
public Stream GetContent(PackageEntry entry) { return(SegmentStream.CreateWithoutOwningStream(s, dataStart + entry.Offset, (int)entry.Length)); }
public Stream GetStream(string filename) { var entry = index[filename]; return(SegmentStream.CreateWithoutOwningStream(s, entry.Offset, (int)entry.Size)); }