Click here to Skip to main content
Email Password   helpLost your password?

Introduction

Managed DirectSound 9 is a part of Managed DirectX 9 library. In this tutorial I�m going to explain how to play sounds with Microsoft Managed DirectSound 9, how to apply effects, select the output audio device and a few more tricks. I hope you�ll discover that DirectSound is not as difficult as it seems.

Requirements

In order to develop and run applications using Managed DirectSound 9 (and all Managed DirectX 9), you have to install in your system the DirectX 9 standard redistributable package specifying in the command line the argument /InstallManagedDX (for example D:\Download\dxsetup /InstallManagedDX). You can also download from Microsoft�s website the package called the �DirectX 9.0c Redistributable for Software Developers - with updated DirectX for Managed Code and D3DX�, which includes and installs automatically the Managed DirectX libraries. Obviously, you have to add to your projects the references to Microsoft.DirectX and Microsoft.DirectX.DirectSound.

Here is an important note: in order to run the apps, the user is not forced to install the Managed DX9, but it is sufficient to copy in your apps� root folder the referenced assemblies. To do this, set the LocalCopy property of the assemblies to true or copy them manually. I suggest the first way because if you create the Installer for the app with Visual Studio, it will detect the references and copy the assemblies to the installation destination. In the second way you have to remember to add them manually. To simplify your life, add these using clauses to your source files:

using Microsoft.DirectX;
using Microsoft.DirectX.DirectSound;

First lines of code: play a Wave file

The first operation you have to do, is to create a DirectSound Device:

private Device dSound;

After this, set it up:

dSound = new Device();
dSound.SetCooperartiveLevel(handle, 
               CooperativeLevel.Priority);

Notes: handle is the handle to your main window (IntPtr), so write this.Handle. CooperativeLevel sets the hardware managing of the playback. There are three possibilities, but you should use Priority because it uses the hardware acceleration whenever possible. The Device constructor is overloaded: we�ll see other options later on.

The next step is to create a sound, using a Buffer, and its descriptor:

private SecondaryBuffer sound;
private BufferDescription d = new BufferDescription();
// Set descriptor�s flags

d.ControlPan = true;
d.ControlVolume = true;
d.ControlFrequency = true;
d.ControlEffects = true;

The flags are:

There are a few other flags, but we are not interested in them.

// Create the sound

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

filePath is the full path of the .wav file, d is the descriptor created above, and dSound is the Device that will play the sound. After this, the sound is ready to be played. As a first parameter you can also specify System.IO.Stream, for example if you are receiving the sound from the Internet (in this case you must manage the difference between data consuming and receiving rates: think about your media player when it stops the playback to retrieve more data from the server).

The operations you can perform with a SecondaryBuffer are:

Using speakers

Another amazing thing you can do, is to set the correct type of speakers attached to the output audio card. This option allows you to obtain better sound on each output system. The property you have to set is dSound.SpeakerConfig:

// Create new Speakers

Speakers s = new Speakers();

// Set properties

s.Mono = false; // Sets as a mono speaker

s.Headphone = false; // Sets as headphones

s.Stereo = false; // Sets as generic stereo speakers

s.Quad = false; // Sets as quad system (two front, two rear)

s.FiveDotOne = false; // Sets as a 5.1 surround system

s.SevenDotOne = true; // Sets as a 7.1 surround system

s.Surround = false; // Sets as a generic surround system


dSound.SpeakerConfig = s;

Note: if you set the Speakers creating a new Speakers object every time, you can avoid resetting the old properties. So just replace the old Speakers object.

Choosing between sound cards

In many systems there are more than one sound card. DirectSound 9 allows you to choose the correct one, arranging a way to select the default one, or to choose the card that the user wants. To enumerate and show the user the installed cards, do as follows (supposing that the list of sound cards is put into a ComboBox, named cmbAudioCards):

private DevicesCollection devList = new DevicesCollection();

cmbAudioCards.Items.Clear();
for(int i = 0; i < devList.Count; i++) {
   cmbAudioCards.Items.Add(devList[i].Description);
}

The first element is the default audio card that is always listed. The other items are the �physical� audio cards. For example you can see:

When the user selects a specific card, you can rebuild the Device as follows (in the ComboBox event handler):

dSound = new Device(devList[cmbAudioCards.SelectedIndex].DriverGuid);
dSound.SetCooperativeLevel(this.Handle, CooperativeLevel.Priority);
// You have to recreate the sound (the descriptor d can be reused)

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

DriverGuid is the Global Unique Identifier of the driver instance for the selected audio card. At the first start, or if the user doesn�t select a specific audio card, you can use the default constructor of Device, or select via-code the first element in devList, that is the default audio card.

Selecting different audio cards can effect the system performance: in the example above, the SoundBlaster Live! has in-hardware acceleration capabilities and supports upto 5.1 systems. Bluetooth audio is worst, and can cause a CPU load increment while applying effects or when managing 3D audio.

Applying effects to the audio playback

One of the most important features of DirectSound 9 is the possibility to apply real-time audio effects to the sounds in playback. You can also apply a virtually unlimited chain of effects (according to the system capabilities). All the effects are applied in-hardware whenever possible, otherwise emulated via-software (causing an important drop in the performance!). Remember to set the flag sound.ControlEffects to true!

In DirectSound 9 there are � needless to say :) � 9 effects: Chorus, Compressor, Distortion, Echo, Flanger, Gargle, Interactive3DLevel2Reverb, ParamEqualizer, WavesReverb. I want to say that there is not much documentation about these effects, especially because each of them has different settings. The first thing is to create an array of EffectDescription:

EffectDescription[] fx = new EffectDescription[1];

In this example we use only one effect, but if you want, you can use more effects by creating an array long enough, and inserting one effect per element. Suppose you want to apply the Echo effect:

fx[0].GuidEffectClass = DSoundHelper.StandardEchoGuid;
sound.SetEffects(fx);

Suppose now you want to apply the Parametric Equalizer effect:

fx[0].GuidEffectClass = DSoundHelper.StandardParamEqGuid;
sound.SetEffects(fx);

Note: you can apply effects only when the sound is not played. As I reported above, each effect has different options. I will explain here how to set up the Parametric Equalizer effect:

fx[0].GuidEffectClass = DSoundHelper.StandardParamEqGuid;
sound.SetEffects(fx);
ParamEqEffect eqEffect = (ParamEqEffect)sound.GetEffects(0);
EffectsParamEq eqParams = eqEffect.AllParameters;
// Specific properties!

eqParams.Bandwidth = 36; // Apply a gain on the highest frequency

eqParams.Gain = ParamEqEffect.GainMax;
eqEffect.AllParameters = eqParams;

Abstracting the procedure, you have to first create an array of effects with StandardEFFECTNAMEGuid, then set the parameters, using EFFECTNAMEEffect and EffectsEFFECTNAME objects, where EFFECTNAME is the name of the Effect. Always remember to perform the correct casts. To reset the effects on a sound, you have to overwrite it:

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

For further info about the effects, please go through the MSDN Library.

Conclusions

By now you should have developed a little familiarity with a DirectSound device, the Effects and other options. DirectSound fits to playbacks of short sounds, such as explosions, shots and so on. If you want to play a long Wave sound you should use the namespace Microsoft.DirectX.AudioVideoPlayback, that I will explain in future. In the next tutorial I will explain how to use 3D Sounds with DirectSound.

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralBadImageFormatException
Jan Wiaz
11:06 25 Nov '09  
I've download you demo, unzip the code, open my visual studio (2008 Team Edition) with the solution, clean and compile fine - and try to start the demo - but following error occurs:

System.BadImageFormatException: no guilty Win32-Application (HRESULT: 0x800 700C1)

Andy Idea whats wrong?

Installed Directx-SDK: Directx11

Regards
GeneralRe: BadImageFormatException
see_seA
14:32 6 Mar '10  
Make sure that you're building the program in x86 mode and not x64.
Generalis there any other method than this 4 listed?
hase-yachi
23:34 23 Sep '09  
Hello..need your help on playing audio file using vb.net. I did found 4 methods of playing audio file which are:
1. API (using winmm.dll)
2. My.computer.audio()
3. directsound (which is ur post)
4. using Windows Media Player

is there any other method other than these in vb.net?
GeneralNice Code !
monster_kill
19:39 18 Jul '09  
Nice work !

But ... can you give me an example how to make Equalizer Band ??


like Equalizer in Windows Media Player ?





Thanks for Help




Jacob Handaya
GeneralRe: Nice Code !
omlove
18:41 12 Nov '09  
Create an array of effectdescription of size 10

Algo

1: create an array of effectdescription of size 10

2 use dsounhelper.parametricequalizer

here effect is an instance of effectdescription

so

effect[0] = dsounhelper.parameticequalizer;
do this 10 times


buffer.seteffect(effect);
QuestionVolume
towerturtle
12:07 19 Aug '08  
I created a trackbar and a method that occurs when the trackbar value is changed, and I want to know how to set the volume of the sound to the value of the trackbar.Confused Confused Confused Confused Confused Confused Confused Confused Confused Confused Confused Confused Confused Confused Confused Confused Confused
Generalvery good article
arbel kfir
3:16 11 Aug '08  
thanks dario

Kfir Arbel

GeneralSplit Audio Channel
ananduk76
17:07 7 Aug '08  
Hello

I need to split left and right audio channel and play it seperately in C#, Can you please let me know how to do that

Thanks
Vijay
QuestionWhy am I getting
Mike Staley
12:34 11 Apr '08  
Great article! It really makes sense but I can't seem to get around a problem. When the SecondaryBuffer object is created I get an indexoutofrangeexception. Can anyone tell me what I am doing wrong. Here is my version of the code developed from the examples above: D'Oh!

private Microsoft.DirectX.DirectSound.Device dSound;
private Microsoft.DirectX.DirectSound.SecondaryBuffer sound = null;

public double FinalAttemptForSoundDuration(System.Windows.Forms.Control cntl, System.Guid dogTag)
{
double result = 0;
try
{
dSound = new Microsoft.DirectX.DirectSound.Device();
string mediaPath = this.GetMediaFilePath(dogTag, false);

dSound.SetCooperativeLevel(cntl.Handle, CooperativeLevel.Priority);

BufferDescription desc = new BufferDescription();
// Set descriptor’s flags
desc.ControlPan = true;
desc.ControlVolume = true;
desc.ControlFrequency = true;
desc.ControlEffects = true;
desc.PrimaryBuffer = true;
sound = new Microsoft.DirectX.DirectSound.SecondaryBuffer(mediaPath, desc, dSound);
if (sound != null)
{
result = sound.Caps.BufferBytes / sound.Format.AverageBytesPerSecond;
}
}
catch (Exception ex)
{
// do error handling...
}
return result;
}
General24 Bit
Jammer
10:54 31 Mar '08  
Hi,

Fantasic article. I'm slowly digesting its contesnts and working through some of my own code using DirectX and C#.

One thing I can't seem to find any info on is how to go about configuring the secondary buffer in order to play 24bit files and files with higher sample rates. DO you know any good articles or sites to check out?

I can find loads of info for C++ but nothing for C# on this. The DirectX code samples only ever deal with 16bit audio as well so no luck there either.

If you have the time to help thanks very much!

Jammer

Going where everyone here has gone before! Smile
My Blog

Questionhow can i play mp3 file??
Ibrahim Dwaikat
10:24 7 Nov '07  
how can i play mp3 file??

Visit Me

www.engibrahim.tk

AnswerRe: how can i play mp3 file??
Ibrahim Dwaikat
12:44 14 Nov '07  
HELP ME PLEASE

Visit Me

www.engibrahim.tk

GeneralRe: how can i play mp3 file??
ronancarty
9:06 27 Jan '08  
As far as i know you gotta use

Microsoft.DirectX.AudioVideoPlayback;

check out a brilliant tutorial at

http://www.riemers.net/eng/Tutorials/DirectX/Csharp/Series2/tut17.php
Cool Cool Cool Cool
QuestionUse a 5.1 card to play 3 sounds from 3 sockets
ThePPK
2:05 28 Oct '07  
Is it possible to play 3 different sounds simultaneously on a sound card (Creative SB Live!) that has 3 physical output sockets (for 5.1 support) in the way when each sound comes from the specified socket?
As I understand from your article I can select 5.1 speaker configuration. But how in that case I could play 3 mono/stereo WAV so that first WAV go through "front" speakers of 5.1 system, second - through "back" speakers and etc.

Thank you very much!
Generalhow to record sound from mic by directx.directsound ?
legend_of_zanado
5:34 11 Jun '07  
how to record sound from mic by directx.directsound ?

i wanna see any example or blog ...
GeneralProblems with effects in C++
BlackBurn83
11:22 5 Jun '07  
I have some problems with the effects in C++, this is my code.

<code>
   array<EffectDescription^, 1> ^objEffects;
   objEffects = gcnew array<EffectDescription^,1>(1);
   objEffects[0] = gcnew EffectDescription();
   objEffects[0]->GuidEffectClass = DSoundHelper::StandardEchoGuid;
   objBuffer->SetEffects( (array<EffectDescription, 1>^) objEffects);
</code>

It compiles well, but when I'm executing it, I get an error on the last rule, and it says that it cannot convert a value to array.
Anybody an idea, I'm spent already 2 days to solve this problem. Thanks in advance.
GeneralRe: Problems with effects in C++
BlackBurn83
21:42 5 Jun '07  
Finally solved, I threated the class as a reference class and it was a value class.
So this is the code that works fine for me.


<code>
array<EffectDescription, 1> ^objEffects;
   objEffects = gcnew array<EffectDescription,1>(1);
   objEffects[0].GuidEffectClass = DSoundHelper::StandardEchoGuid;
   objBuffer->SetEffects( (array<EffectDescription, 1>^) objEffects);
   objBuffer->Play(0,BufferPlayFlags::Default);
</code>

GeneralSlow with hanging
BlackBurn83
9:20 28 May '07  
I build also an application, but used C++.NET (managed) just for practice purposes.
I look at your application for the "playing" trackbar, but when I run my application now, I get hangs and it is really slow.

I guess it has something to do with the timer, cause the slowness will start from there, is there a way to run it an seperate thread or did I forget something?
GeneralRe: Slow with hanging
BlackBurn83
0:17 30 May '07  
I fixed it, the problem occurs with large WAV files, cause the bufferbytes can be above 50.000 and .NET doesn't like to split up the trackbar in to such amount of steps.
QuestionUsing Bluetooth as a sound card
JayJay1982
2:13 13 Mar '07  
In the Tutorial the option of choosing between different sound cards is mentioned.

I would like to choose the option Bluetooth as a soundcard. But I got a questions about that:

Does that work with any Bluetooth Chip? (I am using a Widcomm Chip) Or is it just working for the Microsoft Bluetooth stack?

Did anyone already test that???

Jan


Questionstreaming audio player
may886
2:43 9 Feb '07  
hi! can anyone help me with my really big problem...plszz...can anyone help me how to send audio over the network?not the typical file transfer though. the requirement is to stream audio in real time over the network using c#. i really have a hard time..please.. anyone with a kind heart please...Frown

mumwei Blush
AnswerRe: streaming audio player
Ibrahim Dwaikat
5:36 2 Nov '07  
Any one have the solution??

may886, did you solve the problem??

plz reply to me.. I need it ASAP

Visit Me

www.engibrahim.tk

QuestionProblem of "Field not found"
billylebarbare
4:57 8 Mar '06  
We have a code like yours but as soon as we tried to use flanger effects in it, we have the following error:
An unhandled exception of type 'System.MissingFieldException' occurred in WindowsApplication1.exe

Additional information: Field not found: Microsoft.DirectX.DirectSound.DSoundHelper.StandardEchoGuid.


Of course we have included the differents dll needed and check the version. Some people said this problem is caused because we use Windows 2000 and there are some conflicts with DirectX. Is that true? Do you know where the problem come form?

Sorry for our english, we are french and it is not our mother tongue.

AnswerRe: Problem of "Field not found"
Dario Solera
21:52 8 Mar '06  
billylebarbare wrote:
Sorry for our english, we are french and it is not our mother tongue.
No problem, I'm Italian. Laugh

I've never noticed that error before. MSDN Library didn't help, and the documentation of Managed DirectX is very poor.
I'm not a DX guru (I learned Managed DirectSound only to use it for a project), so I'm afraid I can't help you.

Anyway you should try to run the application on another machine, for example one with Windows XP. If the problem persists, you'll know that it's probably a programming bug, if not, it's that incompatibility you mentioned before.

___________________________________ Tozzi is right: Gaia is getting rid of us.
My Blog [ITA]

GeneralCalculation of playing time
Erlend
23:08 9 Nov '05  
I guess your calculation of the playing time is only correct if the frequency of the soundbuffer is not changed.

I guess this is closer to the reality :

float nrOfSeconds = soundBuffer.Caps.BufferBytes / (float)soundBuffer.Frequency;

Thanks for the article, good job !!Suspicious

Erlend Robaye

Belgium
Erland.Robaye@fluxys.net


Last Updated 28 Sep 2005 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010