XNA Content Pipeline Load .wav Files At Runtime

1.1k views Asked by At

I'm trying to load a song at runtime using XNA Game Studio. However, it isn't in a .xnb format unless it was in the Content Project folder when the program was first compiled. As I want to retrieve the file from anywhere on the computer and load it with the Content Pipeline, I don't know what to do except for having the user put their song into the Content Project folder before they start the program. However, I was wondering if there was a better, more user-friendly way to do this. Also, they won't be able to put anything in the Content Project folder at all when the app is released as only the .exe will be released, not the actual VS2012 solution. Is there a way to load files at runtime without them being in the Content Project folder?

Thanks in advance!

2

There are 2 answers

0
mcmonkey4eva On BEST ANSWER

XNA contains built in methods to handle this (No need for all the codework in Pat's answer!)

        System.IO.FileStream fs = new System.IO.FileStream(@"C:\Myfile.wav", System.IO.FileMode.Open);
        SoundEffect mysound = SoundEffect.FromStream(fs);
        fs.Dispose();

@"C:\Myfile.wav" can be a relative or absolute path.

1
Pat Lillis On

You could try streaming it into/from a byte array (as described at MSDN's Streaming Data from a WAV File).

Basically, use TitleContainer.OpenStream(@"soundfile.wav") in your LoadContent() function to create a System.IO.Stream object. Then to a BinaryReader with new BinaryReader(wavStream).

Read the header:

int chunkID = reader.ReadInt32();
int fileSize = reader.ReadInt32();
int riffType = reader.ReadInt32();
int fmtID = reader.ReadInt32();
int fmtSize = reader.ReadInt32();
int fmtCode = reader.ReadInt16();
int channels = reader.ReadInt16();
int sampleRate = reader.ReadInt32();
int fmtAvgBPS = reader.ReadInt32();
int fmtBlockAlign = reader.ReadInt16();
int bitDepth = reader.ReadInt16();

if (fmtSize == 18)
{
    // Read any extra values
    int fmtExtraSize = reader.ReadInt16();
    reader.ReadBytes(fmtExtraSize);
}

int dataID = reader.ReadInt32();
int dataSize = reader.ReadInt32();

Read the actual sound data:

byteArray = reader.ReadBytes(dataSize);

Then a whole bunch of complicated code to set up the DynamicSoundEffect object (detailed at the link above)

Then you can just use dynamicSound.Play() and dynamicSound.Stop() to play and stop your sound!

Disclaimer: I haven't tested this method of playing sounds, but it's from MSDN so it's probably accurate