DirectX:DirectSound:Tutorials:VBNET:DX9:Playing Sounds From ResX Files

From GPWiki
Jump to: navigation, search

DirectSound Tutorial

Playing a Sound from a ResX File

NOTE: This tutorial assumes you have read Machaira's tute on basic DirectSound use.

This example was written in VB.NET 2003, and demonstrates how you can write your own binary ResX files (in this case, a WAV file), and how to read data back out, and play the sound using the IO.MemoryStream class.

Writing ResX Files

Your first step of course has to be to create your own ResX resource file. This is a binary file format which gives you a lot more security than simply having you resources (sounds, images) just stored in directories in the open, for anyone to pinch! If you don't know the exact format of a ResX file (which you do, for yours), then it is very difficult to steal things from someone elses - but please note, not impossible.

Well, this is most simply explained by some code:

       Dim FS As New IO.FileStream(Application.StartupPath & "\file.wav", IO.FileMode.Open)
       Dim bytSound(FS.Length) As Byte
       FS.Read(bytSound, 0, FS.Length)
       FS.Close()
       Dim RRW As New System.Resources.ResXResourceWriter(Application.StartupPath & "\res.resx")
       RRW.AddResource("hello", bytSound)
       RRW.Generate()
       RRW.Close()

So the process is, read the WAV file into a byte array, and write the byte array to the ResX file.

Items are stored in a ResX file as a Name,Value pair. In this case, file.wav has been written to the ResX with the Name "hello". So later, we will read item "hello" back, and get the sound file back.

If you have 1000 files to write to a ResX, of course you would use the IO.Path, IO.Directory and IO.File Namespaces to automate the process, and use the actual filename as the Name for the item. You must ensure that every item has a unique Name.

The program that writes the ResX file should be a stand-alone application, not part of your game.

Reading from a ResX File

Well, to read back from the ResX file is also self-explanatory:

       Dim RRS As New System.Resources.ResXResourceSet(Application.StartupPath & "\res.resx")
       Dim yy As Object = RRS.GetObject("hello")
       Dim bytSound() As Byte = CType(yy, Byte())
       RRS.Close()

And there you have it, we have read in the item "hello" from the ResX file, and converted it back into a byte array again.

Playing the Sound from Memory

So now that we have the sound in a byte array in memory, how can we play it? Good question. The first bet is to use intellisense to check the overloads of the SecondaryBuffer class. We see that one of the calls to the constructor is:

SecondaryBuffer(source As System.IO.Stream, length As Integer, parent As Microsoft.DirectX.DirectSound.Device)

Perfect! But how can we have 'source' as an IO.Stream? The answer is to use a MemoryStream.

       Dim MS As New IO.MemoryStream(bytSound)
       Dim SB As New SecondaryBuffer(MS, bytSound.Length, dev)
       SB.Play(0, BufferPlayFlags.Default)

Done! Well, that was almost too easy... ;-)

- Sgt_Pinky

See Also