[转载]OpenAL Tutorial 1

来源:互联网 发布:郭沫若和鲁迅比 知乎 编辑:程序博客网 时间:2024/06/10 02:00

OpenAL Tutorial 1

OpenAL一直在不断的创新,几乎没有一个API能达到她的全部潜能。一个很大的原因是因为Hardware加速建立在特殊的板卡上。然而,Creative LabsOpenAL的主要支持者,同时也是最大声卡厂商之一。OpenAL的另一个主要支持者LOKI.

  OpenAL不是商业产品,那样做限制了她的发展。我只知道在PC游戏中用OpenALOpenAL有许多的潜能,有许多的声音库工作在最地层的Hardware上。但OpenAL的设计者经过无数的测试使她成为一个高级的API。她的风格是自由的,不同的编码风格和Hardware部件将充分运用她的功能。有OpenAL编程精练的人将很快掌握OpenALOpenAL有建立3D环境音效的能力。

  OpenALvery cool,她是一个非常清晰的API并且能熔入你的代码。你将做出很COOL的音效,下面让我们进入COOL COOLOPENAL世界。      

  #include <conio.h>

  #include <stdlib.h>

  #include <al/al.h>

  #include <al/alc.h>

  #include <al/alu.h>

  #include <al/alut.h>

  你会发现再OpenAL头和OpenGL头的定义上有许多的相似之处。除了”al.h", "alu.h", "alut.h"与”gl.h", "glu. h","glut.h"相似,还增加了一个"alc.h". ALCAUDIO LIBRARY CONTEXT)处理声音通过不同的平台,她也处理你在几个窗口下共享设备的环境。

  // 存储声音数据

  ALuint Buffer;

  // 用于播放声音

  ALuint Source;

这是程序处理结构的初始化。在OpenAL中三种不同的结构,所有关于声音播放和声音数据存储在一个内存中,源(source)是指向放声音的空间。明白源是非常的重要。源只播放内存中的背景声音数据。源也给出了特殊的属性,,位置和速度。第三个对象是听者,用户就是那唯一的听者。听者属性属于源属性,决定如何听声音。例如,不同位置将决定声音的速度。

// 源声音的位置

ALfloat SourcePos[] = { 0.0, 0.0, 0.0 };

  // 源声音的速度

  ALfloat SourceVel[] = { 0.0, 0.0, 0.0 };

  // 听者的位置

  ALfloat ListenerPos[] = { 0.0, 0.0, 0.0 };

  // 听者的速度

  ALfloat ListenerVel[] = { 0.0, 0.0, 0.0 };

  // 听者的方向 (first 3 elements are "at", second 3 are "up")

  ALfloat ListenerOri[] = { 0.0, 0.0, -1.0, 0.0, 1.0, 0.0 };

在上面的代码中,我们定义了源和听者对象的位置和速度。这些数组是基于笛卡儿坐标的矢量。很容易用结构或类做相同的事情。

ALboolean LoadALData()

{

         // 载入变量

         ALenum format;

         ALsizei size;

         ALvoid* data;

         ALsizei freq;

         ALboolean loop;

在这里我们建立一个函数用于从一个文件中载入声音数据。变量用于存储适合我们的ALUT信息。

         // 载入WAV数据

         alGenBuffers(1, &Buffer);

         If (alGetError() != AL_NO_ERROR)

                return AL_FALSE;

         alutLoadWAVFile("wavdata/FancyPants.wav", &format, &data, &size, &freq, &loop);

         alBufferData(Buffer, format, data, size, freq);

         alutUnloadWAV(format, data, size, freq);

函数alGenBufers用于建立对象内存并把他们存储在我们定义的变量中。然后判断数据是否存储。

ALUT库为我们打开文件,提供我们建立内存所需的信息,并且在我们归属所有数据到内存后,她将处理这些数据。

            // 捆绑源

         alGenSources(1, &Source);

         if (alGetError() != AL_NO_ERROR)

                return AL_FALSE;

         alSourcei (Source, AL_BUFFER, Buffer );

         alSourcef (Source, AL_PITCH, 1.0f );

         alSourcef (Source, AL_GAIN, 1.0f );

         alSourcefv(Source, AL_POSITION, SourcePos);

         alSourcefv(Source, AL_VELOCITY, SourceVel);

         alSourcei (Source, AL_LOOPING, loop );

我们用建立内存对象的方法建立了源对象。然后,我们定义源属性用于录放。最重要的属性是她用的内存。这告诉源用于录放。因此,我们只有捆绑她。同时,我们也告诉她我们定义的源位置和速度。

         // 做错误检测并返回

         if (alGetError() == AL_NO_ERROR)

                return AL_TRUE;

                return AL_FALSE;

}

在函数的结尾,我们将做更多的检测,以确定她的正确。

  void SetListenervalues()

  {

         alListenerfv(AL_POSITION, ListenerPos);

         alListenerfv(AL_VELOCITY, ListenerVel);

         alListenerfv(AL_ORIENTATION, ListenerOri);

  }

我们建立一个函数用于更新听者速度。

  void KillALData()

  {

         alDeleteBuffers(1, &Buffer);

         alDeleteSources(1, &Source);

         alutExit();

  }

这是一个关闭函数,用于释放内存和音频设备。

  int main(int argc, char *argv[])

  {

         // 初始OpenAL并清错误字节

         alutInit(&argc, argv);

         alGetError();

函数alutInit将安装ALC需要的东西。ALUT通过ALC并设置她为当前建立OpenAL环境描述。在WINDOWS平台上初始DIRECTSOUND。然后用‘ALGETERROR’检测错误。

         // 载入WAV数据

         if (LoadALData() == AL_FALSE)

         return -1;

         SetListenervalues();

         // 设置退出函数

         alexit(KillALData);

         我们将检测WAV文件是否正确载入。如果没有退出程序。

         正确后,更新听者参数,最后退出。

         ALubyte c = ' ';

         while (c != 'q')

         {

                   c = getche();

                switch (c)

                {

                       // Pressing 'p' will begin playing the sample.

                       case 'p': alSourcePlay(Source); break;

                       // Pressing 's' will stop the sample from playing.

                      case 's': alSourceStop(Source); break;

                       // Pressing 'h' will pause (hold) the sample.

                       case 'h': alSourcePause(Source); break;

                };

         }

         return 0;

       }

原创粉丝点击