专题10游戏音乐与音效_第1页
专题10游戏音乐与音效_第2页
专题10游戏音乐与音效_第3页
专题10游戏音乐与音效_第4页
专题10游戏音乐与音效_第5页
已阅读5页,还剩27页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

专题10游戏音乐与音效,多媒体程序设计,主讲蔡宇辉,抛砖引玉,如果您在玩一种以跳舞为主的游戏时,您只能看到屏幕上那些上下左右箭头一直在往上跑,但是却不能听到任何的声音,这时,你只能看着那些箭头猛踩踏板,而不能跟着音乐的节拍起舞,那么游戏玩起来还会觉得有趣吗?一个好的游戏,除了有真实而具有震撼力的游戏画面之外,游戏的音乐与音效也是相当重要的部分。像仙剑奇侠传的中国古典音乐,暗黑破坏神的欧美风格的音乐,都给玩家留下了深刻的印象。另外,在很多3D射击游戏中,音效的处理也是相当重要的一个工作,程序员往往需要设计一个真实的3D音效,让玩家根据音效来判断所处的环境。,DirectSound简介声音的播放过程DirectSound的编程步骤3D音效的实现,DirectSound简介,DirectSound是DirectXAudio的一个较底层的部件,提供了丰富的接口函数,实现.wav格式的波形声音数据的播放控制。与一般的WindowsAPI提供的声音播放函数不同,DirectSound可实现多个声音的混合播放,便于在游戏的背景声音下实现各种角色发出声音。DirectSound可充分使用声卡的内存资源,同时也提供了3D声效算法,模拟出真实的3D立体声。,主缓冲区和次缓冲区,声卡或系统内存,声卡内存,声音的播放过程:若干声音文件数据,装入相应的次缓冲区中。次缓冲区位于声卡或系统内存中,需要事先进行申请。所申请的次缓冲区大小,一般为对应的声音文件大小。将次缓冲区的声音数据输出到混声器进行混频处理,输出数字化的声音数据到主缓冲区。主缓冲区中的声音数据,转换为模拟信号,送入扬声器中进行播放。,声音的播放过程,声音的播放过程,主缓冲区:可以看做是一个DirectSound,是用来播放声音、产生混音效果的区域,它有一个预设的播放格式(8bit、22kHz),而声音文件在播放时便按照这种格式输出。主缓冲区在建立DirectSound对象时自动生成,不过如果需要比默认值更好的播放品质,就必须建立主缓冲区并设定其播放的格式,并且在设定协调级别时,标志位必须设定为DSSCL_PRIORITY或DSSCL_EXCLUSIVE。次缓冲区:存储播放声音的文件,可以建立多个次缓冲区来存放多个要播放的声音文件。,DirectSound的编程步骤,创建DirectSound对象设置设备的协调级别建立主缓冲区建立次缓冲区装入声音数据到次缓冲区声音的播放与控制,创建DirectSound对象,创建一个代表声卡的IDirectSound8对象:,HRESULTDirectSoundCreate8(/声卡设备全局标志,一般为NULL,表示默认的声卡LPCGUIDlpcGuidDevice,/返回的IDirectSound8接口对象指针LPDIRECTSOUND8*ppDS8,LPUNKNOWNpUnkOuter/必须为NULL);,if(FAILED(DirectSoundCreate8(NULL,设置设备的协调级别,在建立了IDirectSound8对象之后,需要设置声卡设备的协调级别,告诉Windows使用硬件的权限,其他应用软件与游戏如何共享声卡设备。,HRESULTSetCooperativeLevel(HWNDhwnd,/窗口句柄DWORDdwLevel/协调级别);,if(FAILED(m_pDirectSound-SetCooperativeLevel(hwnd,dwCoopLevel)returnfalse;,dwLevel有如下几个取值:DSSCL_EXCLUSIVE:对于DirectX8.0以上版本,此标志与DSSCL_PRIORITY具有相同的作用。对于以前的版本,此标志设置声卡设备为当前程序独占。DSSCL_NORMAL:正常模式,其他程序可共享设备。此标志下,主缓冲区的播放格式不允许修改。DSSCL_PRIORITY:具有优先设置DirectSound设备的权限。如:可调用SetFormat函数设置主次缓冲区的播放格式。DSSCL_WRITEPRIMARY:可写主缓冲区,此时次缓冲区就不可进行播放处理,即不能将次缓冲区的数据送进混声器,再输出到主缓冲区上。,建立主缓冲区,DSBUFFERDESCbufferDesc;ZeroMemory(,如果需要设置主缓冲区的新播放格式,则可调用CreateSoundBuffer函数,从声卡内存中分配出主缓冲区:,CreateSoundBuffer函数原型:,HRESULTCreateSoundBuffer(LPCDSBUFFERDESCpcDSBufferDesc,/缓冲区的描述结构LPDIRECTSOUNDBUFFER*ppDSBuffer,/返回的缓冲区指针LPUNKNOWNpUnkOuter/必须为NULL);,typedefstructDSBUFFERDESCDWORDdwSize;/结构体的大小DWORDdwFlags;/缓冲区的用途标志DWORDdwBufferBytes;/缓冲区的大小DWORDdwReserved;/保留未用,必须为0LPWAVEFORMATEXlpwfxFormat;/声音的格式属性GUIDguid3DAlgorithm;/3D声效算法,一般不必理会DSBUFFERDESC;,DSBUFFERDESC结构体的定义:,WAVEFORMATEXwaveFormat;ZeroMemory(,创建了主缓冲区后,可以通过调用SetFormat函数来设定主缓冲区的播放格式,以改变声音播放的品质与效果。,建立次缓冲区,次缓冲区用来装入实际的声音数据,因此,必须根据实际的声音文件大小,创建一个相应大小的次缓冲区。.wav文件依据称为RIFF的资源互换文件格式来存放声音数据。文件头包括3个块,分别是RIFF块、fmt块和data块。每个块由块名称、块的大小以及块的数据构成。,fmt块,RIFF块,data块,为了读取.wav文件的声音格式数据,并将实际声音数据装入次缓冲区,定义如下的一个对应于.wav文件头的结构体sWaveHeader。,typedefstructsWaveHeader_tagcharRiffID4;/RIFF块longWaveformChunkSize;/4个字节charWaveID4;/.wav文件应为WAVE类型charFormatID4;/fmt块(末尾有一个空格)longFormatChunkSize;/16个字节shortFormatTag;/.wav文件应为WAVE_FORMAT_PCMshortChannels;/声道数longSampleRate;/采样频率longBytesPerSec;/每秒采样的字节数shortBlockAlign;/块对齐大小shortBitsPerSample;/bit位数(8bit或16bit)charDataID4;/data块longDataSize;/data块的大小(实际的声音数据)sWaveHeader;,读取.wav文件的声音格式数据:,/打开bird.wav文件FILE*fp;if(fp=fopen(bird.wav,rb)=NULL)returnfalse;/定义文件头结构体变量,存储声音属性信息sWaveHeader*pWaveHeader=newsWaveHeader();/读入文件头信息到结构体变量fread(pWaveHeader,sizeof(sWaveHeader),1,fp);/检查是否为.wav文件if(memcmp(pWaveHeader-RiffID,RIFF,4)|memcmp(pWaveHeader-WaveID,WAVE,4)|memcmp(pWaveHeader-FormatID,fmt,4)|memcmp(pWaveHeader-DataID,data,4)returnfalse;,取得文件的声音属性信息后,就可以进行次缓冲区的创建。方法大体上与主缓冲区的创建差不多,只是一些参数的设置需要做出修改。首先,次缓冲区需要根据.wav文件头的数据,填写一个WAVEFORMATEX结构体的信息,以反映声音数据的基本属性,如下所示:,WAVEFORMATEXwaveFormat;ZeroMemory(,接下来,填充缓冲区描述结构体信息,提供音量控制、声音数据大小和格式等说明,并将前面的waveFormat声音格式变量设置进去。,DSBUFFERDESCbufferDesc;ZeroMemory(,最后,调用IDirectSound8接口的CreateSoundBuffer函数,创建一个IDirectSoundBuffer对象,这个对象已被IDirectSoundBuffer8扩充,并提供了一些新的函数。一般需要转换为IDirectSoundBuffer8对象,再加以使用。为此,利用IDirectSoundBuffer接口的QueryInterface函数,查找返回IDirectSoundBuffer8接口对象,,IDirectSoundBuffer*pDirectSoundBuf=NULL;IDirectSoundBuffer8*m_pDirectSoundBuf8;if(FAILED(m_pDirectSound-CreateSoundBuffer(,装入声音数据到次缓冲区,取得次缓冲区后,就可以将.wav文件中的实际声音数据加载到次缓冲区进行播放。为此,先利用IDirectSoundBuffer8接口提供的Lock函数,锁定缓冲区,再进行写入操作。,HRESULTLock(DWORDdwOffset,/锁定的起始位置DWORDdwBytes,/锁定字节数LPVOID*ppvAudioPtr1,/返回的第一个位置指针LPDWORDpdwAudioBytes1,/锁定的第一个缓冲区块大小LPVOID*ppvAudioPtr2,/返回的第二个位置指针LPDWORDpdwAudioBytes2,/锁定的第二个缓冲区块大小DWORDdwFlags/锁定标志,默认为DSBLOCK_FROMWRITECURSOR);,声音数据全部写入次缓冲区后,需要调用IDirectSoundBuffer8接口的UnLock函数,对缓冲区进行解锁。,读数据到缓冲区:,/锁定缓冲区BYTE*pSoundPtr1=NULL;BYTE*pSoundPtr2=NULL;DWORDdwSoundSize1,dwSoundSize2;if(FAILED(m_pDirectSoundBuf8-Lock(0,pWaveHeader-DataSize,(void*),声音的播放与控制,当声音数据加载到次缓冲区后,就可以调用IDirectSoundBuffer8接口提供的Play函数,将声音播放出来。Play函数实际是将次缓冲区的声音数据送到混声器中,与其他正在播放的声音一起混合,最后输出到主缓冲区自动播放。,HRESULTPlay(DWORDdwReserved1,/保留未用,必须为0DWORDdwPriority,/优先权,一般为0DWORDdwFlags/播放方式);,一般设置前两个参数的值为0,最后一个参数取true或false来播放缓冲区的声音,true为循环播放。声音的播放位置,可以通过IDirectSoundBuffer8接口的SetCurrentPosition函数来设置:,HRESULTSetCurrentPosition(DWORDdwNewPosition/偏移位置(距缓冲区的开始处));,/设置声音的播放位置m_pDirectSoundBuf8-SetCurrentPosition(0);/播放一次if(FAILED(m_pDirectSoundBuf8-Play(0,0,bLoop?true:false)returnfalse;,停止播放:,if(FAILED(m_pDirectSoundBuf8-Stop()returnfalse;,音量控制:,if(FAILED(m_pDirectSoundBuf8-SetVolume(lVolume)returnfalse;,3D音效的实现,3D音效与2D音效最大的区别就在于3D音效加入了空间感,这在3D游戏中是很常见的。比如,如果敌人从玩家的左边靠近,则脚步声会从左边逐渐靠近玩家,声音也会越来越大。原理:根据发声者和倾听者的位置、声音速度和发音锥区域等信息,计算倾听者的音强,以决定播放的声音大小。本质上是根据3D的空间因素,确定倾听者听到声音的大小。实现过程:建立发声者建立倾听者播放与控制,建立发声者,发声者用一个IDirectSound3DBuffer8接口对象来表示。先创建一个添加了DSBCAPS_CTRL3D标志的次缓冲区,然后调用QueryInterface取得一个IDirectSound3DBuffer8接口对象,从而创建了一个3D音效缓冲区,之后就可以进一步设置发声者的声音锥区域和最大最小距离。,建立倾听者,倾听者对象用一个IDirectSound3DListener8接口对象来表示。这个对象需要使用设置了DSBCAPS_CTRL3D标志的主缓冲区,调用QueryInterface函数进行创建,之后就要设置倾听者的位置和方向。,播放与控制,IDirectSound3DBuffer8接口并没有提供播放声音的Play函数,因此,发声者的3D音效缓冲区只是用来

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论