Пример #1
0
            public Stream GetStream(string filename)
            {
                IdxEntry entry;

                if (!index.TryGetValue(filename, out entry))
                {
                    return(null);
                }

                s.Seek(entry.Offset, SeekOrigin.Begin);

                var waveHeaderMemoryStream = new MemoryStream();

                var channels = (entry.Flags & 1) > 0 ? 2 : 1;

                if ((entry.Flags & 2) > 0)
                {
                    // PCM
                    waveHeaderMemoryStream.Write(Encoding.ASCII.GetBytes("RIFF"));
                    waveHeaderMemoryStream.Write(BitConverter.GetBytes(entry.Length + 36));
                    waveHeaderMemoryStream.Write(Encoding.ASCII.GetBytes("WAVE"));
                    waveHeaderMemoryStream.Write(Encoding.ASCII.GetBytes("fmt "));
                    waveHeaderMemoryStream.Write(BitConverter.GetBytes(16));
                    waveHeaderMemoryStream.Write(BitConverter.GetBytes((short)1));
                    waveHeaderMemoryStream.Write(BitConverter.GetBytes((short)channels));
                    waveHeaderMemoryStream.Write(BitConverter.GetBytes(entry.SampleRate));
                    waveHeaderMemoryStream.Write(BitConverter.GetBytes(2 * channels * entry.SampleRate));
                    waveHeaderMemoryStream.Write(BitConverter.GetBytes((short)(2 * channels)));
                    waveHeaderMemoryStream.Write(BitConverter.GetBytes((short)16));
                    waveHeaderMemoryStream.Write(Encoding.ASCII.GetBytes("data"));
                    waveHeaderMemoryStream.Write(BitConverter.GetBytes(entry.Length));
                }

                if ((entry.Flags & 8) > 0)
                {
                    // IMA ADPCM
                    var samplesPerChunk = (2 * (entry.ChunkSize - 4)) + 1;
                    var bytesPerSec     = (int)Math.Floor(((double)(2 * entry.ChunkSize) / samplesPerChunk) * ((double)entry.SampleRate / 2));
                    var chunkSize       = entry.ChunkSize > entry.Length ? entry.Length : entry.ChunkSize;

                    waveHeaderMemoryStream.Write(Encoding.ASCII.GetBytes("RIFF"));
                    waveHeaderMemoryStream.Write(BitConverter.GetBytes(entry.Length + 52));
                    waveHeaderMemoryStream.Write(Encoding.ASCII.GetBytes("WAVE"));
                    waveHeaderMemoryStream.Write(Encoding.ASCII.GetBytes("fmt "));
                    waveHeaderMemoryStream.Write(BitConverter.GetBytes(20));
                    waveHeaderMemoryStream.Write(BitConverter.GetBytes((short)17));
                    waveHeaderMemoryStream.Write(BitConverter.GetBytes((short)channels));
                    waveHeaderMemoryStream.Write(BitConverter.GetBytes(entry.SampleRate));
                    waveHeaderMemoryStream.Write(BitConverter.GetBytes(bytesPerSec));
                    waveHeaderMemoryStream.Write(BitConverter.GetBytes((short)chunkSize));
                    waveHeaderMemoryStream.Write(BitConverter.GetBytes((short)4));
                    waveHeaderMemoryStream.Write(BitConverter.GetBytes((short)2));
                    waveHeaderMemoryStream.Write(BitConverter.GetBytes((short)samplesPerChunk));
                    waveHeaderMemoryStream.Write(Encoding.ASCII.GetBytes("fact"));
                    waveHeaderMemoryStream.Write(BitConverter.GetBytes(4));
                    waveHeaderMemoryStream.Write(BitConverter.GetBytes(4 * entry.Length));
                    waveHeaderMemoryStream.Write(Encoding.ASCII.GetBytes("data"));
                    waveHeaderMemoryStream.Write(BitConverter.GetBytes(entry.Length));
                }

                waveHeaderMemoryStream.Seek(0, SeekOrigin.Begin);

                // Construct a merged stream
                var mergedStream = new MergedStream(waveHeaderMemoryStream, s);

                mergedStream.SetLength(waveHeaderMemoryStream.Length + entry.Length);

                return(mergedStream);
            }