It s a 3D World


It's a 3D World

Now that we have loaded and played a sound using DirectX Audio, let's see how easy it is to add a little code to move that sound in 3D.

To do this, we need to start working with AudioPaths. We create a 3D AudioPath that mixes all audio into a DirectSound 3D Buffer. We then use the IDirectSound3D interface on the buffer to move the sound as it plays.

Go back to the InitAudio() call, and change it to create a 3D AudioPath as the default path.

   // Initialize the performance with a default 3D AudioPath.
   pPerformance->InitAudio(NULL,NULL,NULL,
       DMUS_APATH_DYNAMIC_3D,   // Default AudioPath Type.
       2,                       // Only two pchannels needed for this wave.
       DMUS_AUDIOF_ALL,NULL);
 

This tells the performance to create a 3D AudioPath as its default path. Later, after the wave has been loaded and is ready to play, we access that path.

   // Before we play the wave, get the 3D AudioPath so we can set
   // the 3D position before and during playback.
   IDirectMusicAudioPath *p3DPath = NULL;
   pPerformance->GetDefaultAudioPath(&p3DPath);
 

The AudioPath GetObjectInPath() interface method grants direct access to any component within the span of the path. It is called GetObjectInPath(), and you will become quite familiar with it as you work with DirectMusic. In this case, use GetObjectInPath() to directly access the 3D Buffer interface.

     // Extract the 3D buffer interface from the 3D path.
     IDirectSound3DBuffer8 *p3DBuffer = NULL;
     p3DPath->GetObjectInPath(0,
         DMUS_PATH_BUFFER,0,GUID_NULL,0,
         IID_IDirectSound3DBuffer,
         (void **) &p3DBuffer);
     // Don't need this anymore.
     p3DPath->Release();
 

Now that we have the 3D interface, we can change the spatial position of any Segments played on this path. Before we play our sound, set its initial position in 3D space.

     // Initialize the 3D position so the sound does not jump
     // the first time we move it.
     p3DBuffer->SetPosition(-2,0.2,0.2,DS3D_IMMEDIATE);
 

Then, go ahead and play the wave.

     pPerformance->PlaySegmentEx(
         pSegment,  // Segment to play.
         NULL,NULL,0,0,NULL,NULL,NULL);
 

Now that the sound is playing, we can progressively move it through space.

     // Loop and slowly move the sound.
     float flXPos = (float) -1.99;
     for (; flXPos < 2.0; flXPos += (float) 0.01)
     {
         Sleep(20);    // Equivalent to updating at 50fps
         p3DBuffer->SetPosition(flXPos, flXPos, (float) 0.2, DS3D_IMMEDIATE);
     }
 

Ooh, isn't that cool?

We are finished now, so remember to release the buffer while shutting down.

     // Okay, done. Release the buffer interface.
     p3DBuffer->Release();
 

That concludes our whirlwind tour of basic DirectX Audio programming. Believe it or not, we covered most of what you need to know to get sound and music playing in your application. It can get so much more fun if you are willing to dig in deeper and really explore, and that is what we do in the upcoming chapters.



Using the CD

CD Content

This is a good time to introduce the Unit II material on the companion CD.

Take a look in the Unit II folder on the CD. It includes source directories for each project discussed in these chapters. Each directory is labeled with the chapter number and project name. So, for example, this chapter's programming projects are 8_Hello and 8_ Hello3D. The Bin directory contains the final executables of each project, the SourceMedia folder has the DirectMusic Producer source files to create the content, and the Media directory contains the final run-time media files for the sample projects.

You can either copy these files by hand or you can run the Setup program, also in the Unit II folder, to automatically install these files on your hard drive. It includes an uninstaller, so you can install, play with the materials, and when done wipe them out to make room for more on your hard drive.