DirectSound:
Basics
By: Jack Hoxley
Written: May 2000
Download:
DS_Simple.Zip
(12kb)
Luckily for you, DirectSound
at the basic level is extremely easy; so easy you could be mistaken for thinking
something was wrong. If it makes you feel better it does get harder...
If you are familiar with DirectDraw
you will know about surfaces - and how they hold graphical information. There
is a similiar structure used in DirectSound, but they are called buffers. A
buffer holds the sound data in memory so that you can access it, change it,
play it and do various other things.
All sounds are in .Wav format,
which tends to be the standard sound format for most things, Directsound can
only use .Wav format sounds. If you want to create your own sound format, or
want to use a compression method you will have to write some clever conversion
code.
The DirectSound program revolves
around the main DirectX object, which is used to create a Directsound object:
Set Ds =
Dx.DirectSoundCreate("")
'It is best to check for errors before continuing
If Err.Number <> 0 Then
MsgBox "Unable to Continue, Error creating Directsound object."
Exit Sub
End If
'This tells DX how much we want directsound. If
it
'is set to normal DX will allow other programs to use the soundcard
'If it is set to Exclusive ONLY we get to use the soundcard. Which
'is what you want when writing a game...
Ds.SetCooperativeLevel Form1.hWnd, DSSCL_NORMAL |
|
|
|
You may notice that the DirectSoundCreate
has a blank parameter (""); this is only done for simplicity and should
not be used in a proper program. This parameter allows you to specify which
sound driver that you want to use for your application, specifying ("")
allows DirectSound to choose the default driver. This is usually fine, but it
is best to allow the user to specify which sound driver he/she wants to use;
it is quite possible that an end user may have 5 or 6 drivers, and/or two sound
cards (although unlikely) - How do you know that the default driver is A: The
Best one B: Problem free C: Supports the features that you want. By allowing
the user to select which one they want you can save yourself a lot of hassle
when distributing the program.
Once the DirectSound engine has
been initialised successfully you can load sounds into the buffers. First, though,
you will need some sounds to play. This is the only part where DirectSound becomes
complicated (so far) as good sounds can make a program, and bad sounds can destroy
it. Proffesional game developers will have proper recording studios and expensive
equipment for recording their sounds - and you can tell; most people reading
this probably wont have a recording studio available to them. If you have a
decent soundcard and a reasonable microphone then you can probably get away
without the recording studio, but you'll have to be careful.
The other factor to the sound files is their size and quality. Wav files can
be extremely large - 100's of megabytes for 5 minutes or good quality audio.
Even if you are using a large-capacity medium, you probably won't want it to
have this size of sound file on it; on top of that, it will probably take a
while to load a 100Mb sound file into memory (there are ways around this - see
Streaming from a file). You now have several choices:
- Use Compression. This can
be quite complicated, and the sound will need as much memory as it did when
uncompressed.
- You can Stream from a file
- this involves running it from the hard drive, and not from memory
- You can lower the quality.
This is the best, simplest and safest option
Quality. There are 2 things that
you can bare in mind when selecting the quality:
- Bit depth - 8 or 16, 16 is
better quality but larger.
- Number of channels. 1 or
2 - mono or stereo. If you use mono you will not get any seperation between
the right and left speakers, using stereo will be better quality, but again,
the file siaze will increase.
Try and fit your sound files
into either of these catergories for a simple decision:
- If it is a beep/click/squeek
or other sort of small noise you can get away with using the lowest quality;
the average person will not know/hear the difference between an 8bit beep
and a 16bit beep. If the sound fits here, make it 1 channel, 8 bit
- If it is speech, or a sound
where quality is important - usually where you need to pick out individual
noises; make it high quality. 16 bit and 2 channels.
Then there is the second part
to think about, you need to specify these setting when CREATING the sound in
your sound program. It won't make any difference if the sound quality is saved
as 8bit/1channel and Directsound tries to play it at 16bit/2channel, nor will
it make any difference to the file size.
DsDesc.lFlags
= DSBCAPS_CTRLFREQUENCY Or DSBCAPS_CTRLPAN Or DSBCAPS_CTRLVOLUME Or DSBCAPS_STATIC
DsWave.nFormatTag = WAVE_FORMAT_PCM
'Sound Must be PCM otherwise we get errors
DsWave.nChannels = 2 '1=
Mono, 2 = Stereo
DsWave.lSamplesPerSec = 22050
DsWave.nBitsPerSample = 16
'16 =16bit, 8=8bit
DsWave.nBlockAlign = DsWave.nBitsPerSample / 8 *
DsWave.nChannels
DsWave.lAvgBytesPerSec = DsWave.lSamplesPerSec * DsWave.nBlockAlign
' This line creates a sound buffer based on the
information you have just
'put in the two structures
Set DsBuffer = Ds.CreateSoundBufferFromFile(App.Path
& "\Tester.Wav", DsDesc, DsWave) |
|
|
|
This is a similiar structure
to that used by DirectDraw when creating a surface - should you have knowledge
of that.
Finally, we can play and stop
our sound. This part requires no explanation - it's so easy:
Sub
PlaySound()
'Set the next lines flag to DSBPLAY_DEFAULT if you
'only want it to play once.
DsBuffer.Play DSBPLAY_LOOPING
'One thing to note, the program will continue operating
whilst the
'sound is still playing. This is called Asyncronous processing.
'If you are used to the API sound functions, you may know that
'by default you're program stops running whilst the sound plays
'Because it works like this you can play multiple sounds at once.
'But, if you want you're program to wait for the sound to finish you will
'have to write in a little loop that keeps going until
'the sound has reached the end.
End Sub
Sub StopSound()
'Stopping it effectively pauses it
DsBuffer.Stop
'Only when you set the current position to 0 will
'it go back to the beginning
DsBuffer.SetCurrentPosition 0
'You can use the SetCurrentPosition to jump around
'a sound file as you like; which can be useful
End Sub |
|
|
|
Finished!
You can download a complete working
example fromt he top of the page, or you can get it from the downloads
page
|