Click here to Skip to main content
15,879,053 members
Articles / Multimedia / DirectX
Article

The Ultimate Managed DirectSound 9 Tutorial Part 2: managing 3D Sounds

Rate me:
Please Sign up or sign in to vote.
4.71/5 (10 votes)
2 Aug 2005CPOL5 min read 104K   1.3K   54   19
How to playback sounds with 3D audio management.

Image 1

Introduction

The most exciting feature in DirectSound 9 is the possibility to move in the 3D space, the sounds and the points of listening. Audio is so important in applications such as videogames, that 3D audio is a godsend, especially because implementing 3D audio system with DirectSound 9 is very simple.

Requirements

To understand this tutorial, it is important to have familiarity with simple audio playback with Managed DirectSound 9 and with all the general concepts about Managed DirectX, so please read the previous tutorial about sound playback. In DirectSound 9 a sound source can be used in 3D only if it is mono. This is important because even a stereo file has ‘3D sound information’. If you try to use a non-mono file, DirectSound will raise an exception.

Using 3D audio sources and listeners

The technique is so simple that I will use only a paragraph to explain it. The first step is to create a Device and a sound, adding some new objects for this particular purpose:

C#
private Device dSound;
private SecondaryBuffer sound;

// New objects for 3D
private Buffer3D sound3D;
private Listener3D listener;

The Buffer3D is the new buffer object that manages the 3D virtualization of the sound. This object can be moved in the space and its properties will be considered later. Listener3D is a point of listening and represents, obviously, a ‘human’ listener. This object can be moved in the space and has some cool options. Now you can proceed and create the objects:

C#
dSound = new Device(); // Using default audio card
dSound.SetCooperativeLevel(this.Handle, 
                       CooperativeLevel.Priority);

BufferDescription d = new BufferDescription();
d.ControlVolume = true;
d.ControlPan = true;
d.ControlFrequency = true;
d.ControlEffects = true;
d.Control3D = true; // Important to enable 3D audio!
// See note below!
d.Guid3DAlgorithm = 
               DSoundHelper.Guid3DAlgorithmHrtfFull; 

sound = new SecondaryBuffer(filePath, d, dSound);

It is better to select, when possible, the most powerful audio card, so use the overloaded constructor of Device, as shown in the previous tutorial. A note about d.Guid3DAlgorithm: this property specifies the algorithm the system will use to manage the 3D audio. There are various possibilities:

  • Guid3DAlgorithmDefault (audio card’s default, very easy)
  • Guid3DAlgorithmHrtfFull (max quality, even if a software emulation is needed)
  • Guid3DAlgorithmHrtfLight (less quality but less used resources)
  • Guid3DAlgorithmNoVirtualization (only left/right effects, perfect in bad systems or even with stereo-only outputs or if you don’t move the sounds vertically)

The next step is to create the 3D buffer:

C#
sound3D = new Buffer3D(sound);
sound3D.Mode = Mode3D.HeadRelative;

The property sound3D.Mode specifies how the system will manage the 3D sound. There are three options:

  • HeadRelative (sound and listener positions will be considered)
  • Normal (listener will be virtually forced in 0, 0, 0 position)
  • Disable (disables 3D sound, useful to disable it temporarily)

Now it’s time to set up the listener:

C#
Buffer b;
// Another primary buffer is needed
BufferDescription dp = new BufferDescription(); 
dp.PrimaryBuffer = true;
dp.Control3D = true;
b = new Buffer(dp, dSound);

// Create the Listener3D
listener = new Listener3D(b);

// Setup initial position and options 
// for listener and sound3D

// Set the listener in the ‘zero’ 
// position of the space (origin)
listener.Position = new Vector3(0, 0, 0); 
sound3D.Position = new Vector3(0, 0, 0);

// Make the listener ‘looking forward’ (see MSDN)
Listener3DOrientation o = new Listener3DOrientation();
o.Front = new Vector3(0, 0, 1);
o.Top = new Vector3(0, 1, 0);
listener.Orientation = o;

// Play the sound, if needed
sound.Play(0, BufferPlayFlags.Looping);

Vector3 is a struct that represents one point in a 3D space. It is located inside the Microsoft.DirectX namespace. Now you have to play the sound and move it, or move the listener. Let's see some tricks.

Listener3D has these important members:

  • Position: the position (Vector3) of the listener.
  • Velocity: (vx, vy, vz) the instantaneous speed (Vector3) of the listener. You should use this when the listener is moving and you want to apply a Doppler effect.
  • Orientation: it is the ‘forward’ orientation of the listener. You have to set the Front and the Top directions using Vector3 objects. In this tutorial I set the Front to the positive Z axis, and the Top to the positive Y axis.
  • DistanceFactor: it is the measurement unit for the distances. 1 equals to a meter, so 0.001 equals to a millimeter.
  • RolloffFactor: the sound attenuation in the space (0 to 10, 1 is the default for real world).
  • DopplerFactor: the factor for the automatic Doppler effect (0 to 10, 1 is the default for real world). If you don’t know what the Doppler effect is, I'll explain it with an example: think of a car that is approaching you. The noise that the car produces when it approaches you is different from the noise that is produces when it goes away. This effect occurs in each type of wave phenomena, such as sound and light spreading.

Buffer3D has these members:

  • Play, Stop and so on are inherited from the Buffer and are equal to the SecondaryBuffer’s ones.
  • Position: the sound source position (Vector3), same as Buffer3D.Position.
  • MinDistance, MaxDistance: the first one is the distance from where the sound starts to attenuate, the second one is the distance from where the sound stops to attenuate. In other words, until MinDistance the sound is at its max volume, between MinDistance and MaxDistance the sound gradually attenuates, over MaxDistance the sound remains at a low volume and attenuates no more. For these options Listener3D.DistanceFactor and Listener3D.RolloffFactor matter! Unfortunately, the best way to understand the real behaviour of these parameters is to try and test them.
  • Velocity: the speed of the sound source, if it is moving, the same as Listener3D.Velocity.
  • ConeOrientation: (Vector3) this option allows you to specify the cone inside which the sound will spread. The Vector3 is the end-point of an imaginary line starting from the sound position, defining the orientation of the cone.
  • ConeAngles: (Angles) the angle for the inside cone and outside cone: inside the first one the volume will have maximum value, inside the second one the volume will attenuate progressively (see MSDN).
  • ConeOutsideVolume: specifies the volume outside the external cone described above.

There are no more interesting features to describe. See the attached demo app, that shows a moving sound source and a fixed listener. You can move the source with your mouse or make it rotate around the listener. As usual, I suggest going through the MSDN documentation: after you understand the main techniques, extending them is very simple.

Performances notes

We can say DirectSound is very fast. This statement is valid in most cases, but we need to describe some situations. For example if the audio card doesn’t support 3D sounds, DirectSound will emulate them via software. If the system (or the same app) does not have to perform other tasks, the user won’t notice the difference. But if you are developing a videogame, 3D sounds will load the CPU, slowing down the system. So make your choices right. In the demo app you may notice a little roughness of the source’s movements, even though the CPU load remains under 10%.

Conclusions

Now you should be able to manage sounds inside a 3D space. Personally, I believe it is very simple. In the next tutorial I will explain how to record sounds with DirectSound’s CaptureDevice.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Italy Italy
Software Development Manager working on IaaS cloud computing. Cloud believer, (former) entrepreneur, F1 addict.

Follow me at dariosolera.it or on Twitter.

Comments and Discussions

 
Generalproblem moving listener Pin
namtiare5-Jul-07 23:48
namtiare5-Jul-07 23:48 
GeneralRe: problem moving listener Pin
macguyver1312-Jul-07 9:08
macguyver1312-Jul-07 9:08 
GeneralRe: problem moving listener Pin
Hypnotron23-Oct-07 11:56
Hypnotron23-Oct-07 11:56 
GeneralRe: problem moving listener Pin
Hypnotron23-Oct-07 14:18
Hypnotron23-Oct-07 14:18 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.