OpenAL 3D音效开发

发表于2016-05-24
评论0 2.7k浏览

介绍:
        这几年,随着声卡能力的提升与处理声音API的丰富,3D音效在游戏中扮演着愈演愈烈角色。在游戏中制造一个模拟真实的音响效果与精美的游戏画面同等重要。环境音与音乐可以让玩家感受游戏的另一种境界。不很多种声音API可以达到这种效果,比如微软的irectSound与DirectSound3D, Aureal的A3D与Creative Labs EAX.近不久,Loki Entertainment与 Creative Labs开发出了OpenAL.他们所做的是为了开发一些对声音处理的标准,并且是跨平台的。本教程就是介绍OpenAL,并初步涉及添加3D音效到你工程

        OpenAL是一个处理库,它包含了在游戏中播放声音与音乐的接口。它允许程序员加载任何声音,并可以控制某角色的位置,速度,方向与角度, 以便决定声音的传播。所有声音的位置都是相对于听者的,在游戏中就是角色的位置。角色越靠近声源,声音就越大。OpenAL可以用来录制音乐。也可以用流的方式在后台连续的播放音乐。OpenAL支持DirectSound3D与EAX.这些方法都包含在库中,不需要另外的编写代码就可以直接用。

        OpenAL较DirectSound与EAX的最大优点就是跨平台性。DirectSound3D只为windows设计,EAX是DirectSound3D的扩展。因此,如果想开发跨平台的应用程序,OpenAl是你不二选择。本教程主要在windows上展示OpenAL的主要用法。这儿的代码片断只是demo程序中的一些,你可以下载完整的例子。在例子中用OpenGL做为渲染库, 你可以比较两者之间的相同点。

 


开始:

        首先你要获取OpenAL的SDK。你可以在Creative Labs developer网站下载http://developer.creative.com. 安装好SDK后,你就可以开始用它的接口了。首先,你要在你游戏或应用程序开始的时候初始化OpenAL库。在我的应用程序中,我选择的是irectSound3D,你也可以选择EAX。初始化过程代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
ALCcontext *Context; 
ALCdevice *Device; 
Device = alcOpenDevice((ALubyte*)"DirectSound3D"); 
   
if (Device == NULL) 
    exit(-1); 
   
//Create context(s) 
Context=alcCreateContext(Device, NULL); 
//Set active context 
alcMakeContextCurrent(Context); 
// Clear Error Code 
alGetError();


加载声音:
    OpenAL初始化以后,你可以用声音填充Buffers。第一步是用alutLoadWAVFile接口加载声音。然后你得把填充了的Buffer与Source联系起来。然后就可以播放声音了。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
char* alBuffer;            //data for the buffer 
ALenum alFormatBuffer;     //for the buffer format 
ALsizei alFreqBuffer;      //for the frequency of the buffer 
long alBufferLen;          //the bit depth 
ALboolean alLoop;          //looped 
unsigned int alSource;     //buffer source 
unsigned int alSampleSet;  
//load the wave file 
alutLoadWAVFile("test.wav",&alFormatBuffer, (void**) &alBuffer, (unsigned int *) 
   
&alBufferLen, &alFreqBuffer, &loop); 
   
//create 1 source 
alGenSources(1, &alSource); 
   
//create 1 buffer 
alGenBuffers(1, &alSampleSet); 
   
//fills sample set with buffer data from alBuffer 
alBufferData(alSampleSet, alFormatBuffer, alBuffer, alBufferLen, alFreqBuffer); 
   
//assign the buffer to this source 
alSourcei(alSource, AL_BUFFER, alSampleSet); 
   
//release the data 
alutUnloadWAV(alFormatBuffer, alBuffer, alBufferLen, alFreqBuffer);

       在第一步中加载的声音文件是"test.wav"。声音数据读入并存入alBuffer。接着创建了一个source与buffer,然后把alBuffer中的数据与填入buffer中,最后source与buffer关联,wave数据释放。

 

设置Source属性:
   如果你安装了有声音的source,你将需要设置一些属性。你将需要alSource方法。这个方法有点类似OpenGL中的方法,它有几种不同的版本。比如:alSourcei,alSourcef, alSource3f, 等等。设置属性时什么样的属性将决定调用什么方法。设置属性的时候参数类型与方法是一一对应的,比如,如果需要一个浮点参数,此时需要alSourcef方法。第一个参数是你需要修改的source,第二个是要修改source的什么

属性。后面的参数就是具体的属性值。下面的方法是设置source的位置与速度。

1
2
3
4
5
//set source position 
alSource3f(alSource,AL_POSITION, xposition, yposition, zposition); 
   
//set source velocity 
alSource3f(alSource,AL_VELOCITY, xvelocity, yvelocity, zvelocity);


        这儿的alSource是我们要声音源,AL_POSITION与AL_VELOCITY代表我们想改变位置与速度。其余的是具体值。

  

听者:

  模拟现实中的声音接收者。 有了它,我们就可以模拟出更真实的音响效果。下面代码展示如何用Listener。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
float listenerx, listenery, listenerz; 
float vec[6]; 
   
listenerx=10.0f; 
listenery=0.0f; 
listenerz=5.0f; 
   
vec[0] = fvecx; //forward vector x value 
vec[1] = fvecy; //forward vector y value 
vec[2] = fvecz; //forward vector z value 
vec[3] = uvecx; //up vector x value 
vec[4] = uvecy; //up vector y value 
vec[5] = uvecz; //up vector z value 
//set current listener position 
alListener3f(AL_POSITION, listenerx, listenery, listenerz); 
   
//set current listener orientation 
alListenerfv(AL_ORIENTATION, vec);


播放声音:

  有了声音源,有了听者,那现在我们就可以播放我们的声音了。代码如下:

1
2
3
4
5
6
7
8
//tell the sound to loop continuously 
alSourcei(alSource,AL_LOOPING,AL_TRUE); 
   
//play the sound 
alSourcePlay(alSource); 
   
// To stop the sound 
alSourceStop(alSource);


清除工作:

  在你程序退出的时候, 你需要清除你的sources与buffers,并关闭OpenAL.方法很简单,下面有示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//delete our source 
alDeleteSources(1,&alSource); 
//delete our buffer 
alDeleteBuffers(1,&alSampleSet); 
//Get active context 
Context=alcGetCurrentContext(); 
//Get device for active context 
Device=alcGetContextsDevice(Context); 
//Disable context 
alcMakeContextCurrent(NULL); 
//Release context(s) 
alcDestroyContext(Context); 
//Close device 
alcCloseDevice(Device);

  这就是用OpenAL播放声音的基本方法。回忆一下步骤:首先初始化OpenAL,然后加载声音,接着设置source与listener的属性,最后就可能播放声音了。当然,OpenAL可以做的远远不只这些,这儿写的只是一些基本的知识。它很博大精深,大家慢慢研究吧。

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引

0个评论