Prepend data to stream in C# I'm working on an XNA project that loads several resources that are packed into a single file. XNA can take a WAV file stream and turn that into a SoundEffect (seen below in "case ".wav""). 

Since WAV files are large, I want to enable MP3 audio as one of the resources, so I found MP3Sharp, a cross-platform library that converts mp3 file data into PCM data.(just the wavform data, no headers.) Unfortunately, the method I have to use to integrate this in, "SoundEffect.FromStream(Stream stream)", is expecting both the WAV file headers and the PCM data (waveform) To do this, I am using several MemoryStreams and my instinct tells me that it is horribly inefficient.(noticeably too)  Below you will find the code, the important part being the "case ".mp3":" portion. How can I do this better? 

tl;dr: Prepend/combine streams in C#, how? (also note that nChannels and nSamplesPerSec need to be discovered from decoding the mp3 file)

I am worried that I am taking the wrong approach to reading from the stream and

byte[] data = reader.ReadBytes(reader.ReadInt32());
files[path] = data;
string extension = Path.GetExtension(path);
switch (extension)
{
    case ".png":
        string texturePath = Path.ChangeExtension(path, null);
        using (MemoryStream buffer = new MemoryStream(data))
        {
            textures[texturePath] = Texture2D.FromStream(Main.instance.GraphicsDevice, buffer);
        }
        break;
    case ".wav":
        string soundPath = Path.ChangeExtension(path, null);
        using (MemoryStream buffer = new MemoryStream(data))
        {
            sounds[soundPath] = SoundEffect.FromStream(buffer);
        }
        break;
    case ".mp3":
        // TODO, better way to do this?
        string mp3Path = Path.ChangeExtension(path, null);
        MemoryStream wavData = new MemoryStream();
        MemoryStream wavFile = new MemoryStream();
        ushort wFormatTag = 1;
        ushort nChannels;
        uint nSamplesPerSec;
        uint nAvgBytesPerSec;
        ushort nBlockAlign;
        ushort wBitsPerSample = 16;
        using (MemoryStream buffer = new MemoryStream(data))
        {
            using (MP3Sharp.MP3Stream s = new MP3Sharp.MP3Stream(buffer))
            {
                s.CopyTo(wavData);
                nChannels = (ushort)s.ChannelCount;
                nSamplesPerSec = (uint)s.Frequency;
            }
        }
        nBlockAlign = (ushort)(nChannels * (wBitsPerSample / 8));
        nAvgBytesPerSec = (uint)(nSamplesPerSec * nChannels * (wBitsPerSample / 8));
        using (BinaryWriter bw = new BinaryWriter(wavFile))
        {
            bw.Write("RIFF".ToCharArray());
            bw.Write((UInt32)(wavData.Length + 36));
            bw.Write("WAVE".ToCharArray());
            bw.Write("fmt ".ToCharArray());
            bw.Write(16);
            bw.Write(wFormatTag);
            bw.Write(nChannels);
            bw.Write(nSamplesPerSec);
            bw.Write(nAvgBytesPerSec);
            bw.Write(nBlockAlign);
            bw.Write(wBitsPerSample);
            bw.Write("data".ToCharArray());
            bw.Write((UInt32)(wavData.Length));
            bw.Write(wavData.ToArray());
        }
        using (MemoryStream buffer = new MemoryStream(wavFile.ToArray()))
        {
            sounds[mp3Path] = SoundEffect.FromStream(buffer);
        }
        break;
    }


The full method is available on GitHub.
I agree with Heslacher, should be fairly easy to do with NAudio.

var output = new MemoryStream();
using (var reader = new Mp3FileReader(mp3File))
using (var writer = new WaveFileWriter(output, reader.WaveFormat))
{
    //read from reader, write to writer, like you would do with regular streams
    //header is appended automatically to output stream in WaveFileWriter constructor
}


You should also consider encapsulating your resource loading logic to separate class (or classes: one class per resource type). Handling textures and sound in single method looks messy. Single resposibility.

EDIT: If you have to stick to the library of your choosing, then you should just use single output stream.

var output = new MemoryStream();
using (var input = new MP3Sharp.MP3Stream(yourMp3FileStream))
using (var writer = new BinaryWriter(output, Encoding.UTF8, true))
{
    var headerSize = 44; //or w/e it is for RIFF, I might have forgotten
    output.Position = headerSize;
    input.CopyTo(output);
    output.Position = 0;
    //wtite your header
    writer.Write("RIFF".ToCharArray());
    ...
}


Also notice, that you can stack usings on top of each other without adding extra braces.