DirectSound application

Source: Internet
Author: User

Assume that you only use the PlaySound () API function to express the sound effect, so the sound mixing effect cannot be displayed. Since PlaySound has a sound during playback, it will definitely cause the current sound to stop. Therefore

PlaySound () is unrealistic to build a game world that includes rich music and sound effects.
While DirectSound can perfectly solve the sound mixing problem, and it directly targets hardware programming, minimizing the impact of the game process logic on the sound playing effect.
In this article, let's talk about the use of DirectSound.

The first step of initialization is also required for all DirectX build initialization. In general, there are three steps: 1. Set the support for database connections. 2. Add the required header file. 3. This is also the easiest step for everyone to forget.

Set the connection between the libraries and header files related to the DirectX SDK in the folder to the top.
The following describes the above three steps for DirectSound: 1. there are two ways to add a warehouse receiving connection. You can select the setting option in the project menu bar and write it in the column connecting this item object to the library module.

Dsound. lib Dxguid. lib two strings; you can also put these two strings in the workspace by adding files. 2. Add the <dsound. h> Header file to the top of the code segment. 3. Assume that some

The Directsound class name cannot be identified. Check the folder settings in the setting options of the tool menu item to see if the DirectX SDK-related content is put first in both lib and include, because the first database in the compilation connection

Is the first choice for connection.
In addition, the Winmm. lib and mmsystem. h, mmreg. h header files should be added because they will be used when loading the WAVE file.

Step 2 of initialization: establish a DirectSound object
(1) create a DirectSound object
(2) set the sharing level
(3) set the format of the primary buffer
First, we need to create a DirectSound object that represents the sound card. First we need to define the LPDIRECTSOUND pDS, and then use the DirectSoundCreate (NULL, & tp, NULL); method to create it, suppose you want to check whether this object is successful

You can define an HRESULT result variable that accepts the return value of the DirectSoundCreate method and infer whether it is equal to DS_ OK. If it is not equal to it, you can use MessageBox () dialog box to tell the process

An error occurred while establishing the sequencer. Note that the first volume in DirectSoundCreate () is NULL, indicating that the preset sound card is used. You can also call DirectSoundEnumerate to obtain available sound cards.
Then you need to set the program coordination level and call the SetCooperativeLevel method to implement it by using the PPS. Note that this method has two workers. The first worker represents the main form of the application, the second shard number sets the resource usage optimization.

Permission first.
Finally, let's take a look at the concept of the buffer zone. The main buffer zone can be considered as a region where DirectSound is used to play the sound and produce the sound mixing effect. It can be automatically generated or created by itself, however, assume that you have created and set the playback mode.

When setting the coordination level, the flag must be set to DSSCL_PRIORITY. The second buffer is used to store the file for playing sound. After loading the sound file, you only need to call the Play () method, and the sound will be automatically sent to the main buffer and played.

. During the initialization process, pay attention to the DSBUFFERDESC structure, which is responsible for distinguishing the primary and secondary buffers and the initialization of the buffer details. When using this structure, you must first clear it and use memset () method to put all of its memory

To 0, set the size of the structure at the same time, determine its flag bit, and set the buffer size and format, the detailed initialization process can refer to the example at the end of the article.

After initialization, you should first load the audio files to be played into the buffer that has been initialized. Here we will focus on how to read a sound file and obtain information and playback materials.
First, we need to know that WAVE uses the chunk method to store files, including the fmt block in the file format and the data block in the actual content of the file. Therefore, the following steps must be completed to read the file:
(1) open a file
(2) Check whether it is a RIFF file of the WAVE type.
(3) Find the fmt block and obtain the file format
(4) search for data blocks and obtain file content
(5) close the file
(6) loading the audio buffer
For detailed procedures, see the example.

The last of course is the use of playing and stopping. You can use the buffer pointer for a try.
/*--------------------------------------------------------------------------------*/

// The following is an example using DirectSound:
/// // 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 the created return value
Lpdirectsound psp; // specifies the DirectSound object of the sound card.
LPDIRECTSOUNDBUFFER pMainBuf; // declare the master buffer pointer
DSBUFFERDESC desc; // declare the description structure to initialize the buffer area
WAVEFORMATEX pwfmt; // declare the sound structure to set the playback format
 
WAVEFORMATEX swfmt; // declare the sound structure
MMCKINFO ckRiff; // RIFF block information
MMCKINFO ckInfo; // subblock information
MMRESULT mmresult; // The Returned result.
DWORD size; // The actual data size.
HMMIO hbackground; // open multimedia file
Public:
GameSound ();
Void GameSoundInit (HWND); // Create a GameSound object
Void GameSoundbufferConstruct (); // create a buffer
Void GameSoundfmtSet (int, int, int); // you can use the primary buffer pointer to set the playback format.
Void GameSoundReadWAVfile (char *, HMMIO &); // read the audio file and store the details in the HMMIO structure.
Void GameSoundReadinbuffer (LPDIRECTSOUNDBUFFER &, char *); // read the audio file into the buffer

 
LPDIRECTSOUNDBUFFER pStartmusic; // declare the sub-buffer pointer (start music pointer)
LPDIRECTSOUNDBUFFER pTalkmusic; // declare the sub-buffer pointer (Tan Tian music pointer)
LPDIRECTSOUNDBUFFER pWalkmusic; // declare the sub-buffer pointer (walking music pointer)
LPDIRECTSOUNDBUFFER pWarmusic; // declare the sub-buffer pointer (combat music pointer)
LPDIRECTSOUNDBUFFER pyudimusic; // declare the sub-buffer pointer (attack sound pointer)
LPDIRECTSOUNDBUFFER pwinmusic; // declare the sub-buffer pointer (Shengli music pointer)
LPDIRECTSOUNDBUFFER plosemusic; // declare the sub-buffer pointer (failed sound pointer)

LPDIRECTSOUNDBUFFER pAttacksound; // declare the sub-buffer pointer (attack sound pointer)
LPDIRECTSOUNDBUFFER extends attacksound; // declare the sub-buffer pointer (attack sound pointer)

Void GameSoundAllstop (); // for background music. When you change the background music, all the previous music stops to play new music.
Void GameMusicplay (LPDIRECTSOUNDBUFFER &); // used to play loop music
Void GameSoundplay (LPDIRECTSOUNDBUFFER &); // used to play one-time sound effects
};

# Endif

 

/// // The source file
# Include "GameSound. h"

GameSound: GameSound ()
{
}

Void GameSound: GameSoundInit (HWND hwnd)
{
This-> PPS;
This-> soundhwnd = hwnd;
This-> result = DirectSoundCreate (NULL, & PPS, NULL );
If (this-> result! = DS_ OK)
MessageBox (hwnd, "an error occurred while creating the DirectSound object! ", NULL, MB_ OK );

This-> result = this-> PPS-> SetCooperativeLevel (hwnd, DSSCL_PRIORITY );
If (this-> result! = DS_ OK)
MessageBox (hwnd, "failed to set the program coordination level! ", NULL, MB_ OK );

This-> GameSoundbufferConstruct ();
}

Void GameSound: GameSoundbufferConstruct ()
{

Memset (& this-> desc, 0, sizeof (desc); // clear the structure content
Desc. dwSize = sizeof (desc); // specify the description structure size.
Desc. dwFlags = DSBCAPS_PRIMARYBUFFER ;//???
Desc. dwBufferBytes = 0;
Desc. lpwfxFormat = NULL;
Result = PPS-> CreateSoundBuffer (& desc, & this-> pMainBuf, NULL );
If (this-> result! = DS_ OK)
MessageBox (this-> soundhwnd, "an error occurred while creating the primary buffer area! ", 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-> audio attacksound, "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, "an error occurred while setting the playback format! ", NULL, MB_ OK );
}

Void GameSound: GameSoundReadWAVfile (char * filename, HMMIO & hmmbackground)
{
Hmmbackground = mmioOpen (filename, NULL, MMIO_ALLOCBUF | MMIO_READ); // open the file
If (hmmbackground = NULL)
MessageBox (this-> soundhwnd, "the file does not exist! ", NULL, MB_ OK );

// Search type
CkRiff. fccType = mmioFOURCC ('W', 'A', 'V', 'E'); // sets the file type.
Mmresult = mmioDescend (hmmbackground, & ckRiff, NULL, MMIO_FINDRIFF );
If (mmresult! = MMSYSERR_NOERROR)
MessageBox (this-> soundhwnd, "File Format error! ", NULL, MB_ OK );

// Search area
CkInfo. ckid = mmioFOURCC ('F', 'M', 'T', ''); // you can specify the block type.
Mmresult = mmioDescend (hmmbackground, & ckInfo, & ckRiff, MMIO_FINDCHUNK );
If (mmresult! = MMSYSERR_NOERROR)
MessageBox (this-> soundhwnd, "File Format error! ", NULL, MB_ OK );
If (mmioRead (hmmbackground, (HPSTR) & swfmt, sizeof (swfmt) =-1)
MessageBox (this-> soundhwnd, "reading format failed! ", NULL, MB_ OK );

Mmresult = mmioAscend (hmmbackground, & ckInfo, 0); // jump out of the sub-block

// Search area
CkInfo. ckid = mmioFOURCC ('D', 'A', 'T', 'A ');
Mmresult = mmioDescend (hmmbackground, & ckInfo, & ckRiff, MMIO_FINDCHUNK );
If (mmresult! = MMSYSERR_NOERROR)
MessageBox (this-> soundhwnd, "File Format error! ", 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 the structure content
Desc. dwSize = sizeof (desc); // specify the description structure size.
Desc. dwFlags = DSBCAPS_STATIC | DSBCAPS_CTRLPAN |
DSBCAPS_CTRLVOLUME | DSBCAPS_GLOBALFOCUS ;//???
Desc. dwBufferBytes = this-> size;
Desc. lpwfxFormat = & this-> swfmt;
Result = PPS-> CreateSoundBuffer (& desc, & buffer, NULL );
If (this-> result! = DS_ OK)
MessageBox (this-> soundhwnd, "failed to set up the buffer area! ", NULL, MB_ OK );

 

Result = buffer-> Lock (0, this-> size, & pAudio, & bytesAudio, NULL, NULL );
If (this-> result! = DS_ OK)
MessageBox (this-> soundhwnd, "failed to lock the buffer! ", NULL, MB_ OK );

This-> mmresult = mmioRead (this-> hbackground, (HPSTR) pAudio, bytesAudio );

If (mmresult =-1)
MessageBox (this-> soundhwnd, "failed to read audio file data", NULL, MB_ OK );

This-> result = buffer-> Unlock (pAudio, bytesAudio, NULL, NULL );

If (this-> result! = DS_ OK)
MessageBox (this-> soundhwnd, "failed to unlock the buffer! ", 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-> initiate attacksound-> 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-> initiate attacksound-> SetCurrentPosition (0 );
}

Void GameSound: GameMusicplay (LPDIRECTSOUNDBUFFER & buffer)
{
This-> GameSoundAllstop ();

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

Void GameSound: GameSoundplay (LPDIRECTSOUNDBUFFER & buffer)
{
Buffer-> Play (0, 0, 0 );
}

DirectSound application

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.