只是使用的假设PlaySound()这个API函数来显示的声音效果,然后,然后,它不会出现在混合声音,因为PlaySound还有播放期间声音,这将不可避免地导致现有声音停止。

因此,使用

PlaySound()包括丰富音乐与音效的游戏世界是不现实的。

    而DirectSound就能够完美的解决混音问题,并且它直接针对硬件编程。最大程度上减小了游戏进程逻辑对于声音播放效果的影响。

    在这篇文章里,先谈谈DirectSound的使用。

初始化工作第一步,也是全部DirectX组建初始化的必做工作,总的来说分为三个步骤:1、设置好库连接的支持。2、加入须要的头文件。

3、也是大家最easy遗忘的一步,将

设置文件夹中与DirectX SDK相关的库与头文件的连接保持在最顶端。

    以下针对DirectSound来具体讲讲上面三个步骤,1.加入库连接,能够有两种方法,你能够在project菜单条中选择设置选项,并在连接这一项的对象与库模块这一栏目中写上

Dsound.lib Dxguid.lib两个字符串。你也能够仅仅在工作区用加入文件的方法把这两项放在里面。2.加入<dsound.h>头文件放在代码段的顶端。这个无须赘言。3.假设此时发现有些

Directsound的类名无法识别,那么请检查工具菜单项的设置选项中文件夹的设置,看是否在lib与include中都将DirectX SDK相关内容都放在第一位,由于在编译连接中第一位的库

是作为连接的首选的。

    另外还应加入Winmm.lib以及mmsystem.h,mmreg.h头文件,由于载入WAVE文件时会用到。

初始化工作第二步,DirectSound对象的建立

    (1)建立DirectSound对象

    (2)设定共享层级

    (3)设定主缓冲区的格式

    首先要建立一个代表声卡的DirectSound对象,我们先定义LPDIRECTSOUND pDS,然后用DirectSoundCreate(NULL, &pDS, NULL);方法来建立它,假设你想察看这个对象是否成功

的建立,能够定义一个HRESULT result变量。由它接受DirectSoundCreate方法的返回值得并推断是否等于DS_OK,假设不等于它,则能够用MessageBox()方式弹出对话框来告诉程

序员建立失败。注意DirectSoundCreate()中的第一个參数。是NULL。表示使用眼下预设的声卡。也能够调用DirectSoundEnumerate取得可用的声卡。

    然后要设定程序协调层级,使用pDS调用SetCooperativeLevel方法来实现,注意这种方法有两个參数,第一个參数代表应用程序的主窗体,而第二个參数则设定使用资源的优

先权。

    最后要看看缓冲区的概念。主缓冲区能够看作一个DirectSound是用来播放声音,产生混音效果的区域。它能够自己主动生成。也能够自己建立,但假设自己建立并设定其播放模式

,在设置协调层级时,标志位必须设定为DSSCL_PRIORITY.次缓冲区则存储播放声音的文件。在载入声音文件后,仅仅要调用Play()方法,声音就会自己主动的送入主缓冲区中并进行播放

。

在初始化过程中。应重点注意DSBUFFERDESC结构,它担负着区分主次缓冲区以及缓冲区明细初始化的重任,在使用它时,首先要清空,能够使用memset()方法来将其全部内存中

的位设为0。同一时候要设置结构的大小,并确定它的标志位,以及设置缓冲区大小与格式,其详细的初始化过程能够看文章结尾的样例。

在完毕了初始化工作后。应该先把须要播放的声音文件加载到已经完毕初始化的次缓冲区中。这里重点讲下怎样读入一个声音文件以及取得当中的信息与播放的资料。

首先我们要知道,WAVE是利用区块(chunk)方式存储文件的,包括纪录文件格式的fmt区块与文件实际内容的data区块。因此读取文件必需要完毕下面步骤:

    (1)打开文件

    (2)确认是否为RIFF文件。类型为WAVE

    (3)寻找fmt区块,取得文件格式

    (4)寻找data区块。取得文件内容

    (5)关闭文件

    (6)载入声音入次缓冲区

详细过程见样例。

最后当然是播放与停止的使用了,详细能够自己去用次缓冲区指针试一下。

/*--------------------------------------------------------------------------------*/

//    以下是我写的一个使用DirectSound的样例:

////////////////////////////下面为头文件部分

#ifndef GAMESOUND

#define GAMESOUND

#include "dsound.h"

#include "windows.h"

#include "mmsystem.h"

#include "mmreg.h"

class GameSound

{

private:

    HWND soundhwnd;

HRESULT result;      //用来接受建立后的返回值

    LPDIRECTSOUND pDS;   //代表声卡的DirectSound对象

    LPDIRECTSOUNDBUFFER pMainBuf;  //声明主缓冲区指针

    DSBUFFERDESC desc;             //声明描写叙述结构。用来初始化缓冲区域

    WAVEFORMATEX pwfmt;            //声明声音结构,用来设定播放格式

 

    WAVEFORMATEX swfmt;    //声明声音结构

    MMCKINFO     ckRiff;   //RIFF区块的信息

    MMCKINFO     ckInfo;   //子区块的信息

    MMRESULT     mmresult; //返回的结果

    DWORD        size;     //实际资料的大小

    HMMIO        hbackground;    //打开的多媒体文件

public:

    GameSound();

    void GameSoundInit(HWND);             //GameSound对象的建立

    void GameSoundbufferConstruct();      //缓冲区的创建

    void GameSoundfmtSet(int ,int ,int);  //通过主缓冲区指针来设置播放格式

    void GameSoundReadWAVfile(char*, HMMIO&);//将声音文件读入并将明细存在HMMIO结构中

    void GameSoundReadinbuffer(LPDIRECTSOUNDBUFFER&, char*);//将声音文件读入次缓冲区中

LPDIRECTSOUNDBUFFER pStartmusic;  //声明子缓冲区指针(開始音乐指针)

    LPDIRECTSOUNDBUFFER pTalkmusic;  //声明子缓冲区指针(谈天音乐指针)

    LPDIRECTSOUNDBUFFER pWalkmusic;  //声明子缓冲区指针(行走音乐指针)

    LPDIRECTSOUNDBUFFER pWarmusic;  //声明子缓冲区指针(战斗音乐指针)

    LPDIRECTSOUNDBUFFER pyudimusic;  //声明子缓冲区指针(攻击声音指针)

    LPDIRECTSOUNDBUFFER pwinmusic;  //声明子缓冲区指针(胜利音乐指针)

    LPDIRECTSOUNDBUFFER plosemusic;  //声明子缓冲区指针(失败声音指针)

LPDIRECTSOUNDBUFFER pAttacksound;  //声明子缓冲区指针(攻击声音指针)

    LPDIRECTSOUNDBUFFER pAIAttacksound;  //声明子缓冲区指针(攻击声音指针)

void GameSoundAllstop();  //for背景音乐。让背景音乐更换时,先前的全部音乐都停止,从而播放新的音乐

    void GameMusicplay(LPDIRECTSOUNDBUFFER&);     //用来播放循环音乐

    void GameSoundplay(LPDIRECTSOUNDBUFFER&);     //用来播放一次性音效

};

#endif

////////////////////////////下面为源文件部分

#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, "建立 DirectSound 对象失败!", NULL,MB_OK);

this->result = this->pDS->SetCooperativeLevel(hwnd, DSSCL_PRIORITY);

 if(this->result != DS_OK)

  MessageBox(hwnd, "设定程序协调层级失败!", NULL,MB_OK);

this->GameSoundbufferConstruct(); 

}

void GameSound::GameSoundbufferConstruct()

{

memset(&this->desc, 0, sizeof(desc));   //清空结构内容

 desc.dwSize = sizeof(desc);             //配制描写叙述结构大小

 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, "建立主缓冲区域失败!", 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, "设定播放格式失败!

", NULL,MB_OK); 

}

void GameSound::GameSoundReadWAVfile(char* filename, HMMIO &hmmbackground)

{

 hmmbackground = mmioOpen(filename, NULL, MMIO_ALLOCBUF | MMIO_READ);  //打开文件

 if(hmmbackground == NULL)

  MessageBox(this->soundhwnd, "文件不存在!", NULL,MB_OK);

//搜索类型

 ckRiff.fccType = mmioFOURCC('W', 'A', 'V', 'E');//设定文件类型

 mmresult = mmioDescend(hmmbackground, &ckRiff, NULL, MMIO_FINDRIFF);

 if(mmresult != MMSYSERR_NOERROR)

        MessageBox(this->soundhwnd, "文件格式错误!

", NULL,MB_OK);

//搜索区块

 ckInfo.ckid = mmioFOURCC('f', 'm', 't', ' ');//设定区块类型

 mmresult = mmioDescend(hmmbackground, &ckInfo, &ckRiff, MMIO_FINDCHUNK);

        if(mmresult != MMSYSERR_NOERROR)

  MessageBox(this->soundhwnd, "文件格式错误!", NULL,MB_OK);

 if(mmioRead(hmmbackground, (HPSTR)&swfmt, sizeof(swfmt)) == -1)

  MessageBox(this->soundhwnd, "读取格式失败!

", NULL,MB_OK);

mmresult = mmioAscend(hmmbackground, &ckInfo, 0);   //跳出子区块

//搜索区块

 ckInfo.ckid = mmioFOURCC('d', 'a', 't', 'a');

 mmresult = mmioDescend(hmmbackground, &ckInfo, &ckRiff, MMIO_FINDCHUNK);

 if(mmresult != MMSYSERR_NOERROR)

  MessageBox(this->soundhwnd, "文件格式错误!", 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));   //清空结构内容

 desc.dwSize = sizeof(desc);             //配制描写叙述结构大小

 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, "建立次缓冲区域失败!

", NULL,MB_OK);

result = buffer->Lock(0, this->size, &pAudio, &bytesAudio, NULL, NULL, NULL);

 if(this->result != DS_OK)

  MessageBox(this->soundhwnd, "锁定缓冲区失败!", NULL,MB_OK);

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

if(mmresult == -1)

  MessageBox(this->soundhwnd, "读取声音文件资料失败", NULL,MB_OK);

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

if(this->result != DS_OK)

  MessageBox(this->soundhwnd, "解除锁定缓冲区失败!", 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);

}

DirectSound应用的更多相关文章

  1. WIN32下使用DirectSound接口的简单音频播放器(支持wav和mp3)

    刚好最近接触了一些DirectSound,就写了一个小程序练练手,可以用来添加播放基本的wav和mp3音频文件的播放器.界面只是简单的GDI,dxsdk只使用了DirectSound8相关的接口. D ...

  2. 运用Microsoft.DirectX.DirectSound和Microsoft.DirectX实现简单的录音功能

    1.首先要使用Microsoft.DirectX.DirectSound和Microsoft.DirectX这两个dll进行录音,需要先安装microsoft directx 9.0cz这个组件, 百 ...

  3. Microsoft.DirectX.DirectSound.dll和Microsoft.DirectX.dll引用,导致项目无法调试问题

    最近在做录音功能,用到了Microsoft.DirectX.DirectSound.dll和Microsoft.DirectX.dll两个dll,但是引入后,无法调试项目 具体解决方法: 修改app. ...

  4. DirectSound的应用

    假设仅仅使用PlaySound()这个API函数来表现声音效果的话,那么就无法表现出声音的混音效果,由于PlaySound在播放还有一个声音时,必定会导致现有声音的停止.因此,使用 PlaySound ...

  5. DirectSound播放PCM(可播放实时采集的音频数据)

    前言 该篇整理的原始来源为http://blog.csdn.net/leixiaohua1020/article/details/40540147.非常感谢该博主的无私奉献,写了不少关于不同多媒体库的 ...

  6. 最简单的视音频播放示例8:DirectSound播放PCM

    本文记录DirectSound播放音频的技术.DirectSound是Windows下最常见的音频播放技术.目前大部分的音频播放应用都是通过DirectSound来播放的.本文记录一个使用Direct ...

  7. [转]directsound抓取麦克风PCM数据封装类

    网上有很多方法从麦克风读取PCM数据,不想一一举例.只是在这里发布一个我自己写的directsound的麦克风PCM数据采集类,通过它,可以很方便的利用directsound技术把麦克风的数据采集到, ...

  8. DirectSound学习(三)--类、方法、属性翻译

    DirectSound.Device :Contains methods and properties used to create buffer objects, manage devices, a ...

  9. DirectSound学习(二)--流式缓冲区

    使用流式缓冲方式播放波形音频文件比较复杂,主要原因是在只有一个缓冲区提供给用户的前提下,这个缓冲区在提供给声卡播放数据的同是还需要用户不断的定时向其中写入数据.要注意从缓冲区这时是一个环形缓冲区,声音 ...

  10. Microsoft.DirectX.DirectSound学习(一)

    背景:为什么用到这个类库呢?公司要一个要播放音频文件(.wav)的功能,本来想着很ez的事,网上提供的jq插件.本地也有很多播放器,怎么用都行.可当我实现的时候发现大部分网上插件在火狐上不支持.wav ...

随机推荐

  1. Gradle cookbook(转)

    build.gradle apply plugin:"java" [compileJava,compileTestJava,javadoc]*.options*.encoding ...

  2. nodejs添加路由route步骤详解

    首先,毋庸置疑, 新建一个基础express站点.建好之后, 有三个文件需要code(当然,三个步骤顺序随意). 下面以添加一个'/about'为例说明. 1. 在views文件夹里,新建一个jade ...

  3. android 他们定义对话框

    创建一个布局文件 my_dialog.xml <?xml version="1.0" encoding="utf-8"?> <Relative ...

  4. [Django] Base class in the model layer

    In the model layer, the Model class is the base class while the ModelBase class is metaclass.

  5. android性能测试内存泄漏

    1.什么是内存泄漏?     适用于该系统的内存使用内存泄漏,未回复(释放),该内存可以没有事业,也不能被其他人使用使用自己. 2.出有什么差别?    内存泄漏是分配出去的内存无法回收.    内存 ...

  6. 网站通常使用一些javascript包裹 简化电话

    //对于Web地址参数 //前面加"=="进行标识,否则直接返回 //解码时依据是否含有"=="标识来决定是否要解码 var base64EncodeChars ...

  7. 矢量编程——随着MNIST案例

    矢量编程使用的所有明确的矢量运算,而不是for周期. 上一节所用的是512*512*10的数据集非常小.我们取的patch非常小(8*8),学来的特征非常少(25).而我又凝视掉了梯度校验(偷懒),所 ...

  8. Idea开发环境

    Idea开发环境中搭建Maven 1.配置Maven的环境变量 a.首先我们去maven官网下载Maven程序,解压到安装目录,如图所示: b.配置M2_HOME的环境变量,然后将该变量添加到Path ...

  9. Linux tcpdump命令具体解释

    简单介绍 用简单的话来定义tcpdump,就是:dump the traffic on a network,依据使用者的定义对网络上的数据包进行截获的包分析工具. tcpdump能够将网络中传送的数据 ...

  10. spring整合redis客户端及缓存接口设计(转)

    一.写在前面 缓存作为系统性能优化的一大杀手锏,几乎在每个系统或多或少的用到缓存.有的使用本地内存作为缓存,有的使用本地硬盘作为缓存,有的使用缓存服务器.但是无论使用哪种缓存,接口中的方法都是差不多. ...