openal教程.docx

上传人:b****6 文档编号:6231236 上传时间:2023-01-04 格式:DOCX 页数:26 大小:26.31KB
下载 相关 举报
openal教程.docx_第1页
第1页 / 共26页
openal教程.docx_第2页
第2页 / 共26页
openal教程.docx_第3页
第3页 / 共26页
openal教程.docx_第4页
第4页 / 共26页
openal教程.docx_第5页
第5页 / 共26页
点击查看更多>>
下载资源
资源描述

openal教程.docx

《openal教程.docx》由会员分享,可在线阅读,更多相关《openal教程.docx(26页珍藏版)》请在冰豆网上搜索。

openal教程.docx

openal教程

openal教程

(一)

简介

  欢迎来到OPENAL的世界!

OPENAL一直在不断的创新,几乎没有一个API能达到

她的全部潜能。

一个很大的原因是因为hardware加速建立在特殊的版卡上。

然而,

CreativeLabs是APENAL的主要支持者,同时也是最大声卡厂商之一。

OPENAL的另

一个主要支持者LOKI。

  OPENAL不是商业产品,那样做限制了她的发展。

我只知道在PC游戏中用OPENAL。

OPENAL有许多的潜能,有许多的声音库工作在最底层的hardware上。

但OPENAL的

设计者经过无数的测试使她成为一个高级的API。

她的风格是自由的,不同的编码

风格和hardware部件将充分运用她的功能。

有OPENGL编程精练的人将很快掌握OPEN

AL。

OPENAL有建立3D环境音效的能力。

  OPENAL是verycool,她是一个非常清晰的API并且能融入你的代码。

你将做出

很COOL的音效,下面让我们进入COOLCOOL的OPENAL世界。

  #include

  #include

  #include

  #include

  #include

  #include

  你会发现再OPENAL头和OPENGL头的定义上有许多的相似之处。

除了“al.h","al

u.h","alut.h"与”gl.h","glu.h","glut.h"相似,还增加了一个"alc.h".ALC(

AUDIOLIBRARYCONTEXT)处理声音通过不同的平台,她也处理你在几个窗口下共

享设备的环境。

  //存储声音数据

ALuintBuffer;

//用于播放声音

ALuintSource;

  这是程序处理结构的初始化。

在OPENAL中三种不同的结构,所有关于声音播放和

声音数据存储在一个内存中,源(source)是指向放声音的空间。

明白源是非常

的重要。

源只播放内存中的背景声音数据。

源也给出了特殊的属性如位置和速度。

  第三个对象是听者,用户就是那唯一的听者。

听者属性属于源属性,决定如何

听声音。

例如,不同位置将决定声音的速度。

  //源声音的位置

ALfloatSourcePos[]={0.0,0.0,0.0};

//源声音的速度

ALfloatSourceVel[]={0.0,0.0,0.0};

//听者的位置

ALfloatListenerPos[]={0.0,0.0,0.0};

//听者的速度

ALfloatListenerVel[]={0.0,0.0,0.0};

//听者的方向(first3elementsare"at",second3are"up")

ALfloatListenerOri[]={0.0,0.0,-1.0,  0.0,1.0,0.0};

  在上面的代码中,我们定义了源和听者对象的位置和速度。

这些数组是基于笛

卡儿坐标的矢量。

你能很容易用结构或类做相同的事情。

  ALbooleanLoadALData()

{

    //载入变量.

    ALenumformat;

    ALsizeisize;

    ALvoid*data;

    ALsizeifreq;

    ALbooleanloop;

  在这里我们建立一个函数用于从一个文件中载入声音数据。

变量用于存储适合

我们的ALUT信息。

  //载入WAV数据

    alGenBuffers(1,&Buffer);

    if(alGetError()!

=AL_NO_ERROR)

        returnAL_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)

        returnAL_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)

        returnAL_TRUE;

    returnAL_FALSE;

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

  voidSetListenervalues()

{

    alListenerfv(AL_POSITION,    ListenerPos);

    alListenerfv(AL_VELOCITY,    ListenerVel);

    alListenerfv(AL_ORIENTATION,ListenerOri);

}

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

  voidKillALData()

{

    alDeleteBuffers(1,&Buffer);

    alDeleteSources(1,&Source);

    alutExit();

}

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

intmain(intargc,char*argv[])

{

    //初始OPENAL并清错误字节

    alutInit(&argc,argv);

    alGetError();

  函数alutInit将安装ALC需要的东西。

ALUT通过ALC并设置她为当前建立OPENAL

环境描述。

在WINDOWS平台上初始DIRECTSOUND。

然后用‘GLGETERROR’检测错误。

  //载入WAV数据

    if(LoadALData()==AL_FALSE)

        return-1;

    SetListenervalues();

    //设置退出函数

    atexit(KillALData);

  我们将检测WAV文件是否正确载入。

如果没有退出程序。

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

  ALubytec='';

    while(c!

='q')

    {

        c=getche();

        switch(c)

        {

            //Pressing'p'willbeginplayingthesample.

            case'p':

alSourcePlay(Source);break;

            //Pressing's'willstopthesamplefromplaying.

            case's':

alSourceStop(Source);break;

            //Pressing'h'willpause(hold)thesample.

            case'h':

alSourcePause(Source);break;

        };

    }

    return0;

}

openal教程

(二)

循环和消退

希望你觉得上一章有用,这一章将更容易。

  #include

#include

#include

#include

#include

#include

#include

//存储声音数据.

ALuintBuffer;

//用于播放声音.

ALuintSource;

//  源声音的位置.

ALfloatSourcePos[]={0.0,0.0,0.0};

//源声音的速度.

ALfloatSourceVel[]={0.0,0.0,0.1};

//听者的位置.

ALfloatListenerPos[]={0.0,0.0,0.0};

//听者的速度

ALfloatListenerVel[]={0.0,0.0,0.0};

//听者的方向(first3elementsare"at",second3are"up")

ALfloatListenerOri[]={0.0,0.0,-1.0,  0.0,1.0,0.0};

这一章与上一章唯一的不同是源速度的改变,他的‘Z’现在是0.1.

ALbooleanLoadALData()

{

    //载入变量

    ALenumformat;

    ALsizeisize;

    ALvoid*data;

    ALsizeifreq;

    ALbooleanloop;

    //载入WAV数据.

    alGenBuffers(1,&Buffer);

    if(alGetError()!

=AL_NO_ERROR)

        returnAL_FALSE;

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

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

    alutUnloadWAV(format,data,size,freq);

    //捆绑源

    alGenSources(1,&Source);

    if(alGetError()!

=AL_NO_ERROR)

        returnAL_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,  AL_TRUE  );

    //做错误检测并返回

    if(alGetError()!

=AL_NO_ERROR)

        returnAL_FALSE;

    returnAL_TRUE;

}

在这一节中有两处改变,首先是导入“FOOTSTES。

WAV”,设置源‘AL_LOOPING’

为‘AL_TRUE’。

这意味着源播放直到停止时结束。

他将不断的循环播放。

voidSetListenervalues()

{

    alListenerfv(AL_POSITION,    ListenerPos);

    alListenerfv(AL_VELOCITY,    ListenerVel);

    alListenerfv(AL_ORIENTATION,ListenerOri);

}

voidKillALData()

{

    alDeleteBuffers(1,&Buffer);

    alDeleteSources(1,&Source);

    alutExit();

}

这里没有改变。

intmain(intargc,char*argv[])

{

    //  初始OPENAL并清错误字节

    alutInit(NULL,0);

    alGetError();

    //载入WAV数据.

    if(LoadALData()==AL_FALSE)

        return0;

    SetListenervalues();

    //  设置退出函数.

    atexit(KillALData);

    //开始源的播放.

    alSourcePlay(Source);

    //循环

    ALinttime=0;

    ALintelapse=0;

    while(!

kbhit())

    {

        elapse+=clock()-time;

        time+=elapse;

        if(elapse>50)

        {

            elapse=0;

            SourcePos[0]+=SourceVel[0];

            SourcePos[1]+=SourceVel[1];

            SourcePos[2]+=SourceVel[2];

            alSourcefv(Source,AL_POSITION,SourcePos);

        }

    }

    return0;

}

openal教程(三)

  多源

  

  你好,在这一章中,我们将在上一章的例程中加入一些元素,使他能同时

  播放超过一种的音乐。

  通常在一个优秀的游戏中有各种不同的音夹(clip),这是怎样实现的呢?

  下面将介绍。

  #include

#include

#include

#include

#include

#include

#include

//我们需要的最大的数据缓冲.

#defineNUM_BUFFERS3

//我们需要放三种声音.

#defineNUM_SOURCES3

//缓冲和源标志.

#defineBATTLE      0

#defineGUN1        1

#defineGUN2        2

//存储声音数据.

ALuintBuffers[NUM_BUFFERS];

//用于播放声音.

ALuintSources[NUM_SOURCES];

//源声音的位置.

ALfloatSourcesPos[NUM_SOURCES][3];

//源声音的速度.

ALfloatSourcesVel[NUM_SOURCES][3];

//听者的位置.

ALfloatListenerPos[]={0.0,0.0,0.0};

//听者的速度.

ALfloatListenerVel[]={0.0,0.0,0.0};

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

ALfloatListenerOri[]={0.0,0.0,-1.0,0.0,1.0,0.0};

在这一章中,唯一的不同是多了3种将导入Openal系统的不同的声音效果。

ALbooleanLoadALData()

{

    //载入变量.

    ALenumformat;

    ALsizeisize;

    ALvoid*data;

    ALsizeifreq;

    ALbooleanloop;

    //载入WAV数据.

    alGenBuffers(NUM_BUFFERS,Buffers);

    if(alGetError()!

=AL_NO_ERROR)

        returnAL_FALSE;

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

    alBufferData(Buffers[BATTLE],format,data,size,freq);

    alutUnloadWAV(format,data,size,freq);

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

    alBufferData(Buffers[GUN1],format,data,size,freq);

    alutUnloadWAV(format,data,size,freq);

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

    alBufferData(Buffers[GUN2],format,data,size,freq);

    alutUnloadWAV(format,data,size,freq);

    //捆绑源.

    alGenSources(NUM_SOURCES,Sources);

    if(alGetError()!

=AL_NO_ERROR)

        returnAL_FALSE;

    alSourcei(Sources[BATTLE],AL_BUFFER,  Buffers[BATTLE]  );

    alSourcef(Sources[BATTLE],AL_PITCH,    1.0              );

    alSourcef(Sources[BATTLE],AL_GAIN,    1.0              );

    alSourcefv(Sources[BATTLE],AL_POSITION,SourcePos[BATTLE]);

    alSourcefv(Sources[BATTLE],AL_VELOCITY,SourceVel[BATTLE]);

    alSourcei(Sources[BATTLE],AL_LOOPING,  AL_TRUE          );

    alSourcei(Sources[GUN1],AL_BUFFER,  Buffers[GUN1]  );

    alSourcef(Sources[GUN1],AL_PITCH,    1.0            );

    alSourcef(Sources[GUN1],AL_GAIN,    1.0            );

    alSourcefv(Sources[GUN1],AL_POSITION,SourcePos[GUN1]);

    alSourcefv(Sources[GUN1],AL_VELOCITY,SourceVel[GUN1]);

    alSourcei(Sources[GUN1],AL_LOOPING,  AL_FALSE      );

    alSourcei(Sources[GUN2],AL_BUFFER,  Buffers[GUN2]  );

    alSourcef(Sources[GUN2],AL_PITCH,    1.0            );

    alSourcef(Sources[GUN2],AL_GAIN,    1.0            );

    alSourcefv(Sources[GUN2],AL_POSITION,SourcePos[GUN2]);

    alSourcefv(Sources[GUN2],AL_VELOCITY,SourceVel[GUN2]);

    alSourcei(Sources[GUN2],AL_LOOPING,  AL_FALSE      );

    //做错误检测并返回

    if(alGetError()!

=AL_NO_ERROR)

        returnAL_FALSE;

    returnAL_TRUE;

}

首先,我们导入文件数据到3个缓冲区,然后把3个缓冲区和3个源锁在

一起。

唯一的不同是文件“battle.wav”在不停止时循环。

voidSetListenervalues()

{

    

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > IT计算机 > 计算机软件及应用

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1