Application of DirectSound

Source: Internet
Author: User
Tags bit set

Assuming that only the PlaySound () API function is used to represent sound effects, it is not possible to show the sound mixing effect, as playsound will inevitably cause the existing sound to stop as it plays a sound. Therefore, using

PlaySound () It is unrealistic to build a game world that includes a rich music and sound effect.
DirectSound is able to solve the mixing problem perfectly, and it directly aims at hardware programming, minimizing the effect of game process logic on sound playback.
In this article, first talk about the use of DirectSound.

Initialization work is the first step, but also all the DirectX build initialization must do, generally divided into three steps: 1, set up a library connection support. 2. Add the required header files. 3, but also the most easy to forget a step, will

The Settings folder in which the DirectX SDK-related libraries are connected to the header file remains at the top.
The following are specific to DirectSound to tell the above three steps, 1. To join the library, there are two ways you can choose the Settings option in the Project menu bar and write in the section on the object and library module that connects this item.

Dsound.lib Dxguid.lib two strings; You can also put these two items in the workspace simply by adding a file to it. 2. Add <dsound.h> header files to the top of the code snippet, this is needless to go. 3. Suppose at this point that some

DirectSound the class name is not recognized, then check the settings in the setup options of the tool menu item to see if the DirectX SDK related content is placed first in Lib and include, because the first bit of the library in the compilation connection

is preferred as a connection.
You should also include the Winmm.lib and Mmsystem.h,mmreg.h header files, which are used when loading wave files.

Initialization work The second step, the establishment of DirectSound object
(1) Setting up DirectSound objects
(2) Set the sharing level
(3) Setting the format of the primary buffer
First to create a DirectSound object that represents the sound card, we first define the lpDirectSound PDS and then use the DirectSoundCreate (null, &PDS, NULL) method to build it, assuming you want to see if the object is successful.

, it is possible to define an HRESULT result variable, which accepts that the return of the DirectSoundCreate method is worth and infers whether it equals DS_OK, assuming that it is not equal to it, then the MessageBox () can be used to pop up the dialog box to tell the process

The sequencer failed to build. Note that the first parameter in directsoundcreate () is null, which means using the current preset sound card. You can also call Directsoundenumerate to get the available sound card.
Then to set the program coordination level, using the PDS call SetCooperativeLevel method to implement, note that this method has two parameters, the first parameter represents the main form of the application, and the second parameter sets the use of the resources of the excellent

First right.
Finally, to look at the concept of a buffer, the main buffer can be seen as a DirectSound is used to play the sound, producing a mixing effect of the area, it can be self-generated, but also can build themselves, but assume that they set up and set its playback mode

, the flag bit must be set to dsscl_priority when setting the coordination level. The secondary buffer stores the files that play the sound. After loading a sound file, just call the play () method and the sound will be actively fed into the main buffer and played

。 During initialization, you should focus on the DSBUFFERDESC structure, which is responsible for distinguishing between the primary and secondary buffers and the initialization of the buffer detail, and when using it, the first thing to empty is to use the memset () method to put all of its in-memory

The bit set to 0, the same time to set the size of the structure, and determine its flag bit, as well as set the buffer size and format, its detailed initialization process can see the article at the end of the sample.

After the initialization is complete, the sound files that need to be played should be loaded into the secondary buffers that have been initialized. Here we focus on how to read a sound file and get the information and playback data.
First of all, we need to know that wave is the use of chunks (chunk) to store files, including the FMT block in the record file format and the actual content of the file data block. Therefore, the following steps must be completed to read the file:
(1) Open file
(2) Confirm whether it is a riff file, the type is wave
(3) Find the FMT block and get the file format
(4) Find the data block and obtain the contents of the file
(5) Close the file
(6) Loading the sound into the secondary buffer
The detailed procedure is shown in the sample example.

Finally, of course, play and stop the use of, in detail, you can use the secondary buffer pointer to try.
/*--------------------------------------------------------------------------------*/

Here is a sample I wrote using DirectSound:
The following is the header file section
#ifndef Gamesound
#define Gamesound

#include "Dsound.h"
#include "Windows.h"
#include "mmsystem.h"
#include "Mmreg.h"


Class Gamesound
{
Private
HWND Soundhwnd;

HRESULT result; Used to accept an established return value
lpDirectSound PDS; DirectSound object representing the sound card
Lpdirectsoundbuffer Pmainbuf; Declaring the primary buffer pointer
DSBufferDesc desc; Declarative descriptive narrative structure, used to initialize buffer areas
WaveFormatEx pwfmt; Declare sound structure to set the playback format

WaveFormatEx swfmt; declaring sound structures
Mmckinfo Ckriff; Information about the RIFF block
Mmckinfo Ckinfo; Sub-Chunk information
Mmresult Mmresult; The returned result
DWORD size; The actual data size
Hmmio Hbackground; Open multimedia files
Public
Gamesound ();
void Gamesoundinit (HWND); Establishment of Gamesound object
void Gamesoundbufferconstruct (); Creation of buffers
void Gamesoundfmtset (int, int, int); To set the playback format via the primary buffer pointer
void Gamesoundreadwavfile (char*, hmmio&);//The sound file is read into and the details are present in the HMMIO structure
void Gamesoundreadinbuffer (Lpdirectsoundbuffer&, char*);//Read the sound file into the secondary buffer


Lpdirectsoundbuffer Pstartmusic; Declaring a child buffer pointer (start music pointer)
Lpdirectsoundbuffer Ptalkmusic; Declaring a child buffer pointer (chat music pointer)
Lpdirectsoundbuffer Pwalkmusic; Declaring a child buffer pointer (walking music pointer)
Lpdirectsoundbuffer Pwarmusic; Declaring a child buffer pointer (battle music pointer)
Lpdirectsoundbuffer Pyudimusic; Declaring a child buffer pointer (attacking sound pointer)
Lpdirectsoundbuffer Pwinmusic; Declaring a child buffer pointer (Victory music pointer)
Lpdirectsoundbuffer Plosemusic; Declaring a child buffer pointer (failed sound pointer)

Lpdirectsoundbuffer Pattacksound; Declaring a child buffer pointer (attacking sound pointer)
Lpdirectsoundbuffer Paiattacksound; Declaring a child buffer pointer (attacking sound pointer)

void Gamesoundallstop (); For background music, when the background music is changed, all previous music stops to play new music
void Gamemusicplay (lpdirectsoundbuffer&); Used to play looping music
void Gamesoundplay (lpdirectsoundbuffer&); Used to play a one-time sound
};

#endif

The following is the source file section
#include "GameSound.h"

Gamesound::gamesound ()
{
}

void Gamesound::gamesoundinit (HWND hwnd)
{
this->pds;
This->soundhwnd = hwnd;
This->result = DirectSoundCreate (null, &PDS, NULL);
if (this->result! = DS_OK)
MessageBox (hwnd, "Build DirectSound object failed!") ", NULL,MB_OK);

This->result = This->pds->setcooperativelevel (hwnd, dsscl_priority);
if (this->result! = DS_OK)
MessageBox (hwnd, "Set Program coordination level failed!") ", NULL,MB_OK);

This->gamesoundbufferconstruct ();
}

void Gamesound::gamesoundbufferconstruct ()
{

memset (&this->desc, 0, sizeof (DESC)); Clear structure Contents
desc.dwsize = sizeof (DESC); Formulation descriptive narrative structure size
Desc.dwflags = Dsbcaps_primarybuffer; //???
desc.dwbufferbytes = 0;
Desc.lpwfxformat = NULL;
result = Pds->createsoundbuffer (&desc, &this->pmainbuf, NULL);
if (this->result! = DS_OK)
MessageBox (This->soundhwnd, "failed to establish primary buffer zone!") ", NULL,MB_OK);

 this->gamesoundreadinbuffer (This->ptalkmusic, "sound//talk2.wav");
 this->gamesoundreadinbuffer (This->pstartmusic, "sound//startwav.wav");
 this->gamesoundreadinbuffer (This->pwarmusic, "sound//zhandou.wav");
 this->gamesoundreadinbuffer (This->pwalkmusic, "sound//mainwav.wav");
 this->gamesoundreadinbuffer (This->pattacksound, "sound//fire.wav");
 this->gamesoundreadinbuffer (This->paiattacksound, "sound//fire2.wav");
 this->gamesoundreadinbuffer (This->pyudimusic, "sound//yudi.wav");
 this->gamesoundreadinbuffer (This->pwinmusic, "sound//win.wav");
 this->gamesoundreadinbuffer (This->plosemusic, "sound//lose.wav");
 
}

void Gamesound::gamesoundfmtset (int channels, int samplespersec, int wbitpersample)
{
    memset (&this->pwfmt, 0, sizeof (PWFMT));
    this->pwfmt.wformattag = WAVE_FORMAT_PCM;
    this->pwfmt.nchannels = channels;
    this->pwfmt.nsamplespersec = samplespersec;
    this->pwfmt.wbitspersample = wbitpersample;
    this->pwfmt.nblockalign = THIS->PWFMT.WBITSPERSAMPLE/8 * this->pwfmt.nchannels;
    this->pwfmt.navgbytespersec = this->pwfmt.nsamplespersec * this->pwfmt.nblockalign;
    This->result = This->pmainbuf->setformat (&THIS->PWFMT);
    if (this->result! = DS_OK)
 messagebox (This->soundhwnd, "Setting playback format failed! ", NULL,MB_OK);  
}

void Gamesound::gamesoundreadwavfile (char* filename, Hmmio &hmmbackground)
{
Hmmbackground = Mmioopen (filename, NULL, MMIO_ALLOCBUF |  Mmio_read); Open File
if (Hmmbackground = = NULL)
MessageBox (This->soundhwnd, "file does not exist!") ", NULL,MB_OK);

Search Type
Ckriff.fcctype = MMIOFOURCC (' W ', ' A ', ' V ', ' E ');//Set File type
Mmresult = Mmiodescend (Hmmbackground, &ckriff, NULL, Mmio_findriff);
if (mmresult! = mmsyserr_noerror)
MessageBox (This->soundhwnd, "file format is wrong! ", NULL,MB_OK);

Search for chunks
Ckinfo.ckid = MMIOFOURCC (' f ', ' m ', ' t ', ');//Set block type
Mmresult = Mmiodescend (Hmmbackground, &ckinfo, &ckriff, Mmio_findchunk);
if (mmresult! = mmsyserr_noerror)
MessageBox (This->soundhwnd, "file format is wrong! ", NULL,MB_OK);
if (Mmioread (Hmmbackground, (hpstr) &swfmt, sizeof (swfmt)) = =-1)
MessageBox (This->soundhwnd, "read format failed! ", NULL,MB_OK);

Mmresult = Mmioascend (hmmbackground, &ckinfo, 0); Jump out of sub-chunks

Search for chunks
Ckinfo.ckid = MMIOFOURCC (' d ', ' a ', ' t ', ' a ');
Mmresult = Mmiodescend (Hmmbackground, &ckinfo, &ckriff, Mmio_findchunk);
if (mmresult! = mmsyserr_noerror)
MessageBox (This->soundhwnd, "file format is wrong!", NULL,MB_OK);

size = Ckinfo.cksize;

}

void Gamesound::gamesoundreadinbuffer (lpdirectsoundbuffer& buffer, char* filename)
{
LPVOID Paudio;
DWORD Bytesaudio;


This->gamesoundreadwavfile (filename, this->hbackground);

memset (&this->desc, 0, sizeof (DESC)); Clear structure Contents
desc.dwsize = sizeof (DESC); Formulation descriptive narrative structure size
Desc.dwflags = Dsbcaps_static | Dsbcaps_ctrlpan |
Dsbcaps_ctrlvolume |   Dsbcaps_globalfocus; //???
Desc.dwbufferbytes = this->size;
Desc.lpwfxformat = &this->swfmt;
result = Pds->createsoundbuffer (&desc, &buffer, NULL);
if (this->result! = DS_OK)
MessageBox (This->soundhwnd, "failed to build the secondary buffer zone!") ", NULL,MB_OK);

result = Buffer->lock (0, This->size, &paudio, &bytesaudio, NULL, NULL, NULL);
if (this->result! = DS_OK)
MessageBox (This->soundhwnd, "Lock buffer failed!", NULL,MB_OK);

This->mmresult = Mmioread (This->hbackground, (HPSTR) Paudio, Bytesaudio);

if (Mmresult = =-1)
MessageBox (This->soundhwnd, "read sound file data failed", NULL,MB_OK);

This->result = Buffer->unlock (Paudio, bytesaudio, NULL, NULL);

if (this->result! = DS_OK)
MessageBox (This->soundhwnd, "Unlocked buffer failed!", NULL,MB_OK);

Mmioclose (this->hbackground, 0);
}

void Gamesound::gamesoundallstop ()
{
 this->pattacksound->stop ();
 this->pstartmusic->stop ();
 this->ptalkmusic->stop ();
 this->pwalkmusic->stop ();
 this->pwarmusic->stop ();
 this->pyudimusic->stop ();
 this->pwinmusic->stop ();
 this->plosemusic->stop ();
 this->paiattacksound->stop ();
 this->pattacksound->setcurrentposition (0);
 this->pstartmusic->setcurrentposition (0);
 this->ptalkmusic->setcurrentposition (0);
 this->pwalkmusic->setcurrentposition (0);
 this->pwarmusic->setcurrentposition (0);
 this->pyudimusic->setcurrentposition (0);
 this->pwinmusic->setcurrentposition (0);
 this->plosemusic->setcurrentposition (0);
 this->paiattacksound->setcurrentposition (0);
}

void Gamesound::gamemusicplay (lpdirectsoundbuffer& buffer)
{
This->gamesoundallstop ();

Buffer->play (0, 0, 1);
}

void Gamesound::gamesoundplay (lpdirectsoundbuffer& buffer)
{
Buffer->play (0, 0, 0);
}

Application of DirectSound

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.