Use directsound 3D to implement 3D sound effects in the game

Source: Internet
Author: User

 Abstract:In 3D games, enhanced 3D sound effects can bring amazing audible effects to gamers. This article uses an example to demonstrate how to use Microsoft directsound 3D to implement 3D surround sound.

  Keywords:Directsound 3D Game 3D stereo

Before starting this article, I would like to say that directsound 3D is the essence of directsound. My personal feeling is that in the development of 3D games, 3D sound effects are generally completed using directsound 3D.

Directsound 3D was launched by Microsoft. It uses the sound size ratio adjustment and the Duble effect to simulate 3D sound effects with software, it created a standard method for locating sound files in 3D spaces. Any application can achieve the desired effect through it and a sound card that supports directsound 3D. Since this is jointly developed by many sound card manufacturers and Microsoft, most sound cards now support this technology. This article introduces the directsound 3D technology. You can use it in your program. I believe it will increase the color of your program.

Let's get started. Before we get started, I will first introduce several basic concepts related to directsound 3D. Then, we use an example to demonstrate how to use directsound 3D. The source code is attached to it and can be downloaded.

  3D space sound source listener

Directsound 3D implements 3D sound effects through software simulation, so we should first talk about the 3D simulation space of dsound. This space is similar to a real space. You can use the Cartesian coordinate system to describe the 3D space of dsound. There are three coordinate axes: X, Y, and Z.

In this simulated space, dsound provides a simulated sound source object and a listener object (listener). The relationship between the sound source and the listener can be described using three variables: location in 3D space, and the speed and direction of motion.

Location refers to the location where the source and listener are in three-dimensional space. As the two are in different positions, the listener will hear different sound effects.

The speed is the movement speed of the source and the listener in three-dimensional space. This feature also changes the coordinates of the two in space to produce different sound effects.

The relative movement of the source and listener also affects the effect of the listener's voice, because the sound is directional. This will be discussed below.

How can we generate 3D sound effects when we know 3D sound sources and listeners in 3D environments? Generally, when 3D sound effects are generated, there are mainly the following situations: 1. the sound source does not move, while the listener does not move in the Simulated 3D space. 2. The Listener does not move, let the sound source be moved in a simulated 3D space. 3 listeners and sounds are simultaneously moving. For example:


Figure 1 The sound source does not change, and the listener moves to produce 3D sound effects.

 


Figure 2 The Listener does not move, and the sound source is moved to produce 3D sound effects.

Directsound provides an interface for the listener and source object. We can set and change the location of the sound source or listener in the three methods mentioned above, so that the motion speed and direction can form a 3D sound effect,

In the 3D environment, we use the idirectsound3dbuffer8 interface to express the sound source. This interface is supported only when the dsbcaps_ctrl3d flag is set during creation, some functions provided by this interface are used to set and obtain the attributes of the sound source. In a virtual 3D environment, we can obtain the idirectsound3dlistener8 interface through the main buffer zone. Through this interface, we can control most parameters in the acoustic environment, such as the number of Doppler transformations, the ratio of volume attenuation.

The interface is very simple, but a lot of computing work is done internally by directsound.
 Maximum and minimum distance

The closer the listener is to the sound source, the larger the listener will hear. The half distance will decrease, and the volume will double. However, when you continue to approach the sound source, when the distance is shortened to a certain distance, the volume will not continue to increase. This is the minimum distance from the source.

The minimum distance of the sound source is the starting point where the sound volume begins to deteriorate significantly with the distance. For example, for an airplane, the minimum distance may be 100 m, but for a bee, the minimum distance is 2 cm. Based on the minimum distance, when the listener is m away from the plane, the sound volume is halved. for bees, when the sound volume exceeds 4cm, the sound volume is halved. The following figure shows the effect of the minimum and maximum distance on the volume of planes and bees.

The default minimum distance of directsound is ds3d_defaultmindistance, which is defined as 1 unit or 1 meter. We stipulate that the sound volume at one meter is full volume, half at two meters, and 1/4 at four meters, and so on. For most sounds, we need to set a relatively large minimum distance, so that when the sound moves, it will not fade so fast.

The maximum distance is the distance from the sound source volume that is no longer degraded. We call it the maximum distance from the sound source. The default maximum distance between directsound 3D buffer and ds3d_defaultmaxdistance is 1 billion. That is to say, when the sound is out of our Auditory range, the attenuation continues. Under the VxD driver, to avoid unnecessary computing, we need to set a reasonable maximum distance when creating the buffer.

The maximum distance is also used to prevent a sound from being heard. For example, if you set the minimum distance of a certain sound to 100 m, the sound may be lost at M, you can set the maximum distance to 800 m, so that you can ensure that the sound is 1/10 of the original sound no matter how far away.
Remember, the default unit is M.


Figure 3 maximum and minimum distance

  Processing mode

Sound buffers has three processing modes: Normal, head-relative, and disabled.

In normal mode, the location and direction of the sound source are absolute values in the real world. This mode is suitable for situations where the sound source is not moving relative to the listener.

In head reative mode, all 3D characteristics of the sound source are related to the current location, speed, and direction of the listener. When the listener moves or rotates, the 3D buffer will automatically reset the world space. This mode can be applied to implement a sound that keeps buzzing in the listener's head. The sound that keeps following the listener does not need to be implemented in 3D.

In disable mode, the 3 D Sound becomes invalid, and all sounds like the listener's head.

  Cone Effect of sound

The sound without direction has the same amplitude in all directions. The sound with direction has the largest amplitude in this direction. The cone Effect of sound is divided into internal cone effects, and the External Cone effect, the external angle of the cone should be greater than or equal to the internal angle of the cone.

Inside the cone, considering the basic volume in the buffer and the distance from the listener and the direction of the listener, the sound volume is the same as that without the cone effect.
Outside the cone, the normal volume is reduced, from 0 to a fraction of the negative.

Between the inside and the outside of the cone is a transitional zone, from the internal volume to the external volume, the volume gradually decreases. The following chart shows the cone effect of the sound.


Figure 4 Sound cone

Every 3D buffer has a sound cone, but by default, every 3D sound buffer is like a sound source without attenuation, because no sound volume is lowered inside and outside the cone, the angle inside and outside the cone is 360 degrees. Unless our application changes this setting, 3D sound has no sense of direction.

With 3D sound, you can add special effects to your program. For example, you can place the sound source in the middle of the room and direct the sound source to the door, then, the cone angle of the sound contains the width of the door, the exterior of the cone is wider, and the external volume of the cone is set to 0. In this way, the listener can only hear the sound near the door, and the sound is louder at the right of the door.

Some concepts related to directsound 3D are introduced here. Now we can start our 3D sound effect journey. I provide a demo. Next we will analyze how to program 3D sound effects. The demo interface is as follows:


Figure 5 demo page

The second method is used to implement 3D sound effects in this demo. That is, the listener does not move and the sound source motion method is used to generate 3D sound effects. Set the source to motion on a plane and set the Y axis to zero.

Like sound sources, listeners in the 3D world also have locations, speeds, and directions. For example


Figure 6 listener Coordinate System

The upward vector points to the top of the header. The forward vector points to the front of the face of the listener. The front vector is (0.0, 0.0, 1.0), and the top vector is (0.0, 1.0, 0.0 )., if needed, directsound can adjust the front vector because it is in the right direction of the top vector. Therefore, the buffer Motion Track set in our demo is in a plane. For example, the plane we choose is Y = 0. Therefore, it sounds like this demo, it's like the sound keeps turning around our head.
Next, let's take a step.

Step 2 declares some variables we will use.

Lpdirectsound8 g_pdsd = NULL; // directsound object pointer
Lpdirectsoundbuffer g_pdsbuffer = NULL; // auxiliary buffer pointer
Lpdirectsound3dbuffer g_pds3dbuffer = NULL; // 3D sound source object pointer
Lpdirectsound3dlistener g_pdslistener = NULL; // 3D listener object pointer
Ds3dbuffer g_dsbufferparams; // 3D buffer Properties
Ds3dlistener g_dslistenerparams; // listener Properties
Cwavefile * g_pwavefile = NULL; // a class object used to read and write wave files
Bool g_bplaying = false; // whether the video is being played

Step 2 initialize directsound, create the primary buffer, set the audio format of the primary buffer, and obtain the listener (listener) interface through the primary buffer. These tasks can be performed in the initialization of the dialog box.

// Initialize dsound
Hresult hr;
If (failed (hR = directsoundcreate8 (null, & g_pdsd, null )))
Return false;
If (failed (hR = g_pdsd-> setcooperativelevel (m_hwnd, dsscl_priority )))
Return false;
// Initialize the main buffer zone of directsound and set the format
Lpdirectsoundbuffer pdsbprimary = NULL;
Dsbufferdesc dsbdesc;
Zeromemory (& dsbdesc, sizeof (dsbufferdesc ));
Dsbdesc. dwsize = sizeof (dsbufferdesc );
Dsbdesc. dwflags = dsbcaps_ctrl3d | dsbcaps_primarybuffer; // do not forget to set the dsbcaps_ctrl3d flag when creating the primary buffer. Only when this flag is specified can you request a 3D buffer pointer from this auxiliary buffer.
If (failed (hR = g_pdsd-> createsoundbuffer (& dsbdesc, & pdsbprimary, null )))
Return false;
// Obtain the listener pointer in the 3D simulated world.
If (failed (hR = pdsbprimary-> QueryInterface (iid_idirectsound3dlistener, (void **) & g_pdslistener )))
Return false;

Waveformatex WFX;
Zeromemory (& WFX, sizeof (waveformatex ));
WFX. wformattag = (Word) wave_format_pcm;
WFX. nchannels = wavechannel;
WFX. nsamplespersec = wavesamplepersec;
WFX. wbitspersample = wavebitspersample;
WFX. nblockalign = (Word) (WFX. wbitspersample/8 * WFX. nchannels );
WFX. navgbytespersec = (DWORD) (WFX. nsamplespersec * WFX. nblockalign );
If (failed (hR = pdsbprimary-> setformat (& WFX) // set the audio format of the buffer.
Return false;

Step 2: Create a secondary buffer and obtain the 3dbuffer pointer through the secondary buffer.

Dsbufferdesc dsbd;
Zeromemory (& dsbd, sizeof (dsbufferdesc ));
Dsbd. dwsize = sizeof (dsbufferdesc );
Dsbd. dwflags = dsbcaps_ctrl3d | dsbcaps_globalfocus | dsbcaps_ctrlpositionnotify | dsbcaps_getcurrentposition2;
// Check the flag set when the buffer of the auxiliary buffer is created. The 3D flag is naturally needed. Also, you need to note that dsbcaps_ctrlpositionpolicy. If you use the stream buffer, you need to play the video while filling the data in the buffer. You need to set this flag so that the event will be triggered when directsound plays to the specified position.
// Dsbd. dwbufferbytes = max_audio_buf * bufferpolicysize; // If stream buffer is used, you can set the appropriate buffer size.
Dsbd. dwbufferbytes = g_pwavefile-> getsize (); // If static buffer is used, the buffer size is the file size.
Dsbd. guid3dalgorithm = guid3dalgorithm;
Dsbd. lpwfxformat = g_pwavefile-> m_pwfx;
If (failed (hR = g_pdsd-> createsoundbuffer (& dsbd, & g_pdsbuffer, null )))
Return;
// Obtain the pointer of the 3D buffer through the auxiliary buffer.
If (failed (hR = g_pdsbuffer-> QueryInterface (iid_idirectsound3dbuffer, (void **) & g_pds3dbuffer )))
Return;

G_dsbufferparams.dwsize = sizeof (ds3dbuffer );
G_pds3dbuffer-> getallparameters (& g_dsbufferparams );

// Set the 3dbuffer attribute.
G_dsbufferparams.dwmode = ds3dmode_headrelative;
G_pds3dbuffer-> setallparameters (& g_dsbufferparams, ds3d_immediate );

Step 1: Set the Doppler factor and the minimum maximum distance.

Float fdopplerfactor;
Float frolofffactor;
Float fmindistance;
Float fmaxdistance;

Csliderctrl * pdopplerslider = (csliderctrl *) getdlgitem (idc_doppler_slider );
Fdopplerfactor = pdopplerslider-> getpos ();

Csliderctrl * proloffslider = (csliderctrl *) getdlgitem (idc_roloff_slider );
Frolofffactor = proloffslider-> getpos ();

Csliderctrl * pmindistslider = (csliderctrl *) getdlgitem (idc_mindistance_slider );
Fmindistance = pmindistslider-> getpos ();
Csliderctrl * pmaxdistslider = (csliderctrl *) getdlgitem (idc_maxdistance_slider );
Fmaxdistance = pmaxdistslider-> getpos ();

G_dslistenerparams.fldopplerfactor = fdopplerfactor;
G_dslistenerparams.flrolofffactor = frolofffactor;

If (g_pdslistener)
{
G_pdslistener-> setallparameters (& g_dslistenerparams, ds3d_deferred );
G_pdslistener-> commitdeferredsetlistener ();
}

G_dsbufferparams.flmindistance = fmindistance;
G_dsbufferparams.flmaxdistance = fmaxdistance;

If (g_pds3dbuffer)
G_pds3dbuffer-> setallparameters (& g_dsbufferparams, ds3d_deferred );

Step 2: Call the play method of the secondary buffer to play the audio file.

DWORD res;
Lpvoid lplockbuf;
DWORD Len;
DWORD dwwrite;

G_pdsbuffer-> lock (0, 0, & lplockbuf, & Len, null, null, dsblock_entirebuffer );
G_pwavefile-> Read (byte *) lplockbuf, Len, & dwwrite );
G_pdsbuffer-> unlock (lplockbuf, Len, null, 0 );
G_pdsbuffer-> setcurrentposition (0 );
G_pdsbuffer-> play (0, 0, dsbplay_looping );

The last important part of step 6th is that we set a clock in the program. This clock event is used to trigger the motion of the directsound sound source as follows:

The sound source trajectory is based on the fxscale and fyscale we set, that is, we drag the vertical and horizontal slider, is an elliptical shape, of course, if fxscale = fyscale, it is a circular track. We can adjust it, And then constantly adjust the Motion Track of the buffer through the ontimer event.


Figure 7 trajectory of sound source Motion

Void cdsound3dplaydemodlg: ontimer (uint nidevent)
{
Float fxscale;
Float fyscale;

Fxscale = (csliderctrl *) getdlgitem (idc_horizontal_slider)-> getpos ()/100366f;

Fyscale = (csliderctrl *) getdlgitem (idc_vertical_slider)-> getpos ()/100366f;
Float T = timegettime ()/1000.0f;

// Move the sound object around the listener. The maximum radius of
// Orbitis 27.5 units.
D3dvector vposition;
Vposition. x = orbit_max_radius * fxscale * (float) sin (t );
Vposition. Y = 0.0f;
Vposition. z = orbit_max_radius * fyscale * (float) Cos (t );

D3dvector vvelocity;
Vvelocity. x = orbit_max_radius * fxscale * (float) sin (t + 0.05f );
Vvelocity. Y = 0.0f;
Vvelocity. z = orbit_max_radius * fyscale * (float) Cos (t + 0.05f );

Memcpy (& g_dsbufferparams.vposition, & vposition, sizeof (d3dvector ));
Memcpy (& g_dsbufferparams.vvelocity, & vvelocity, sizeof (d3dvector ));

Updategrid (vposition. X, vposition. z );

If (g_pds3dbuffer)
G_pds3dbuffer-> setallparameters (& g_dsbufferparams, ds3d_immediate );
// With the simulation of buffer motion, we need to constantly change the 3dbuffer parameter.
}

Now, the introduction here is basically clear. If you have any questions, please refer to the Demo code. For programmers, read the code, it is clearer than reading the article.

  Conclusion

This article uses an example to demonstrate how to use directsound to implement 3D stereo sound effects in Game Development. We provide a demo source code, which you can download. The demo in this article is in windowx XP, debug in 2000 + vc.7.0. For more information, see DirectX on msdn.

Two questions are prompted:

1. In my demo program, I provide two methods for playing audio files. One is relatively simple static buffer, which is suitable for small wave files, another method is to use streaming buffer to open a relatively small cache, and then play and fill the data in the buffer. This method is suitable for large wave files. Of course, the latter method is troublesome and requires a separate thread. I have made detailed comments in the program. If you are careful enough, you will surely find out.

2. Be sure to remember that 3D sound effects only support single-channel wave files. Do not try to implement three-dimensional stereo effects on a multi-channel wave file.

Last leave an email, aooang@hotmail.com have any questions contact me.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.