How To: Apply Basic 3D Positional Effects to a Cue

This example demonstrates how to apply 3D positioning effects to cues.

The XNA Framework audio system contains support for 3D audio positioning effects, using the AudioEmitter and AudioListener classes, and the Cue.Apply3D method. The effects simulate 3D positioning for sound by adjusting speaker mix for cues that use the 3D values.

Note that speaker mix is the only effect that will be automatically applied using this method; attenuation and Doppler-shift pitch modification effects must be applied via creation of runtime parameter controls (RPCs) in the Microsoft Cross-Platform Audio Creation Tool (XACT). See How To: Apply Attenuation and Doppler 3D Audio Effects and Apply3D for more information.

To apply basic 3D positional effects to a cue

  1. Create an XACT project and add it to a new XNA Game Studio project as described in How To: Add a Sound File to Your Game Using XACT. The project should contain at least one cue.
  2. In code, create an AudioEngine, WaveBank, and SoundBank at game start.
  3. Create an AudioEmitter, an AudioListener, and a Vector3 to store the 3D position of the sound entity.
  4. In the Game.Initialize method, load the AudioEngine, WaveBank, and SoundBank. Then, call SoundBank.GetCue to retrieve the Cue you want to play in 3D.
  5. Call Cue.Apply3D on the cue you retrieved in step 4.
  6. Call Cue.Play to begin playback of the cue. Note that you must have called Apply3D on the cue first; otherwise, the next call to Apply3D will throw an exception.
  7. During game update, call the Update method of the AudioEngine to allow the audio engine to process audio data.
  8. Set the Vector3 to the position you want the sound to come from. Set the AudioEmitter.Position property to this vector.
  9. Optionally, set the Vector3 to the position where you want the listener of the 3D sound to be. Set the AudioListener.Position property to this vector.
  10. Call Cue.Apply3D on the cue object you retrieved and played in step 4, passing in the AudioEmitter, an AudioListener.
Bb447687.note(en-US,XNAGameStudio.20).gifNote
Calling the Cue.Apply3D method automatically sets the speaker mix for any sound played by this cue to a value calculated by the difference in Position values between listener and emitter. In preparation for the mix, the sound is converted to monoaural. Any stereo information in the sound is discarded.

The following example uses a circular rotation around a stationary AudioListener to emphasize the 3D effect.

The Complete Sample

The code in this tutorial illustrates the technique described in the text. A complete code sample for this tutorial is available for you to download, including full source code and any additional supporting files required by the sample.

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace Basic3DAudio
{
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;

        // Audio objects
        AudioEngine engine;
        SoundBank soundBank;
        WaveBank waveBank;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
        }

        // 3D audio objects
        AudioEmitter emitter = new AudioEmitter();
        AudioListener listener = new AudioListener();
        Cue cue;

        protected override void Initialize()
        {
            base.Initialize();

            // Initialize audio objects
            engine = new AudioEngine("Content\\Audio\\3DAudio.xgs");
            soundBank = new SoundBank(engine, "Content\\Audio\\Sound Bank.xsb");
            waveBank = new WaveBank(engine, "Content\\Audio\\Wave Bank.xwb");

            // Get the cue and play it.
            // For 3D cues, you must call Apply3D before calling Play.
            cue = soundBank.GetCue("buzz");
            cue.Apply3D(listener, emitter);
            cue.Play();
        }

        protected override void LoadContent()
        {
        }

        protected override void UnloadContent()
        {
        }

        protected override void Update(GameTime gameTime)
        {
            // Allow the game to exit.
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // Move the object around in a circle.
            Vector3 objectPos = new Vector3(
                (float)Math.Cos(gameTime.TotalGameTime.Seconds) / 2,
                0,
                (float)Math.Sin(gameTime.TotalGameTime.Seconds));

            // Apply 3D settings to the cue.
            emitter.Position = objectPos;
            cue.Apply3D(listener, emitter);

            // Update the audio engine
            engine.Update();

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
            base.Draw(gameTime);
        }
    }
}

Community Additions

ADD
Show: