只是使用的假设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. 使用WPF创建无边框窗体

    一.无边框窗口添加窗口阴影 实际上在WPF中添加无边框窗口的窗口阴影十分简单. 首先,设置WindowStyle="None"以及AllowsTransparency=" ...

  2. React Native是一套使用 React 构建 Native app 的编程框架

    React Native是一套使用 React 构建 Native app 的编程框架 React Native at first sight what is React Native? 跟据官方的描 ...

  3. 怎样设制 select 不可编辑 仅仅读

    1. <select style="width:195px" name="role"  id="role" onfocus=" ...

  4. 【转】C# string和StringBuilder的区别

    主要的区别在于 stringbuilder相对于string,效率要高些,string会在每次改变的时候进行内存重新组合,而stringbuilder则不会从新组合,另外stringbuilder有a ...

  5. .NET 4 并行(多核)编程系列之二 从Task开始

    原文:.NET 4 并行(多核)编程系列之二 从Task开始 .NET 4 并行(多核)编程系列之二 从Task开始 前言:我们一步步的从简单的开始讲述,还是沿用我一直的方式:慢慢演化,步步为营.   ...

  6. 如何使盘ISO图像文件

    原创作品.从 "深蓝blog" 博客,欢迎转载,请务必注明转载的来源,权法律责任. 深蓝的blog:http://blog.csdn.net/huangyanlong/articl ...

  7. php方法综述除去换行符(PHP_EOL使用变量)

    一个小包裹,事实上,不同的平台具有不同的实现.为什么要这样.它可以是一个世界是多样的. 最初unix与世界把它包/n取代,但windows为了体现自己的不同.要使用/r/n,更有意思的是,mac随着/ ...

  8. hadoop-HBase-observer的一个样例

    hbase(main):021:0> describe 'users' DESCRIPTION                                                   ...

  9. MVC的验证 jquery.validate.unobtrusive

    jQuery validate 根据 asp.net MVC的验证提取简单快捷的验证方式(jquery.validate.unobtrusive.js) 2013-07-22 19:07 4568人阅 ...

  10. python使用smtplib库和smtp.qq.com邮件服务器发送邮件(转)

    使用qq的邮件服务器需要注意的两个地方主要是: 1.协议问题 使用465端口 SSL 协议 2.口令问题 出现SMTPAuthenticationError 主要的原因就是口令和帐号信息不对,这里我们 ...