OpenAL对象属性

在前面的章节中,介绍了OpenAL提供的几个最基本的对象:

  • 装数据的Buffer
  • 表示声源的Source
  • 表示听众的Listener

那么OpenAL是如何通过这几个对象来营造丰富的3D效果呢?这就要从OpenAL为这些对象设计的属性来说起了。

OpenAL函数风格

OpenAL实现一般是使用C来实现的,而其风格和OpenGL类似,为函数提供了诸如

alBufferf   // 参数是个float
alBuffer3f  // 参数是3个float
alBufferfv  // 参数是个float指针
alBufferi   // 参数是个int
alBuffer3i  // 参数是3个int
alBufferiv  // 参数是个int指针

这种alXxxx[f/3f/fv/i/3i/iv]的命名风格,初次接触可能不太容易理解,实际上就是一系列的Get和Set函数,比如:

void alBufferf(
  ALuint buffer,
  ALenum param,
  ALfloat value
);

如同:

buffer.param = (float) value

OC中的setter。这里buffer表示一个Buffer对象,param表示对应的属性,将其赋值为一个float类型的value。而:

void alBufferfv(
  ALuint buffer,
  ALenum param,
  ALfloat *values
);    

如同:

float value = buffer.parma     

OC中的getter。同样buffer表示一个Buffer对象,param表示对应的属性,将其取出赋给float类型的value

Buffer

OpenAL为Buffer设计的属性有:

属性类型意义
AL_FREQUENCYint采样率
AL_BITSint位深度
AL_CHANNELSint通道数
AL_SIZEint数据大小
AL_DATAint数据原始位置指针

创建和删除Buffer

创建Buffer的过程是通过调用接口由OpenAL来为我们创建:

 void alGenBuffers(
  ALsizei n,
  ALuint *buffers
);

这里通过n来表示创建几个Buffer,Buffer对应的引用通过buffers的数组返回。

void alDeleteBuffers(
  ALsizei n,
  ALuint *buffers
);

这个就是对应的删除方式,删除掉buffers数组中的Buffer对象。

当然,因为这两个方法都是void返回值的,所以需要去调用前面文章介绍“alGetError”来进行错误处理。

设置Buffer中的数据

Buffer创建好之后,本身是没有任何音频数据的,需要我们自己为其填充将要播放的数据:

void alBufferData(
  ALuint buffer,
  ALenum format,
  const ALvoid *data,
  ALsizei size,
  ALsizei freq
);

这里buffer表示要填充的Buffer对象,format是一个表示位深度的枚举,data为具体的PCM数据,size自然是PCM数据的长度,最后的freq是PCM数据的采样率。 format的枚举有 :

  • AL_FORMAT_MONO8 : 8位的MONO数据
  • AL_FORMAT_MONO16 : 16位MONO数据
  • AL_FORMAT_STEREO8 : 8为STEREO数据
  • AL_FORMAT_STEREO16 : 16位STEREO数据。

属性设置与查询

上面的填充数据一下子把最开始介绍的属性都设置了,如果发现此时给的值错了要怎么修改呢?或者怎么进行查询呢?因为上面我们介绍的属性都是int类型值,所以我们通过:

alBufferi
alBufferiv

来进行属性的访问。比如我们要查询采样率:

int freq = 0;
alBufferiv( buf, AL_ FREQUENCY, &freq);
printf("frequency is %d", freq);

Source

OpenAL为Source提供的属性有:

属性类型意义
AL_PITCHint音高倍数
AL_GAINfloat声音的增益
AL_MAX_DISTANCEfloat最远距离
AL_ROLLOFF_FACTORfloat衰减速率
AL_REFERENCE_DISTANCEfloat声音音量降低一半的距离
AL_MIN_GAINfloat最小增益
AL_MAX_GAINfloat最大增益
AL_CONE_OUTER_GAINfloat不在音源朝向的位置的增益
AL_CONE_INNER_ANGLEfloat音源朝向位置的增益
AL_CONE_OUTER_ANGLEfloat音源朝向的外角度,默认360°
AL_POSITION3f音源位置
AL_VELOCITY3f音源移动速度
AL_DIRECTION3f音源的方向向量
AL_SOURCE_RELATIVEint表示音源是否相对于听众位子
AL_SOURCE_TYPEint声源类型(AL_UNDETERMINED, AL_STATIC, or AL_STREAMING)
AL_LOOPINGint是否循环播放(AL_TRUE、AL_FALSE)
AL_BUFFERint绑定的Buffer的ID
AL_SOURCE_STATEint声源的状态,是否在播放(AL_STOPPED, AL_PLAYING)
AL_BUFFERS_QUEUEDint声源上绑定的Buffer的数目
AL_BUFFERS_PROCESSEDint声源上绑定的已经处理的Buffer数目
AL_SEC_OFFSETfloat当前播放位置,单位是s
AL_SAMPLE_OFFSETfloat当前播放位置,单位是采样率
AL_BYTE_OFFSETfloat当前播放位置,单位是byte

创建和销毁Source

同样Source也是由OpenAL来创建的:

void alGenSources (
    ALsizei n,
    ALuint *sources
);

一样的,n表示创建几个Source,结果存在sources数组中。对应的销毁方法:

void alDeleteSources(
  ALsizei n,
  ALuint *sources
);

销毁source数组中存放的n个Source对象。

因为他们都是void函数,所以判断成功也是需要用alGetError来进行判断。

属性获取和设置

Source提供了完整的:

alSourcef 
alSource3f 
alSourcefv 
alSourcei 
alSource3i
alSourceiv
alGetSourcef 
alGetSource3f 
alGetSourcefv 
alGetSourcei 
alGetSource3i 
alGetSourceiv    

方法,可以对上面的属性进行操作和设置,比如要设置Source在Listenner的正前方。

alSourcei(source, AL_SOURCE_RELATIVE, 1)
alSourcei(source, AL_SOURCE_TYPE, ALSTATIC)
alSource3f(source, AL_POSITION, 1, 0, 1)

先设置Source为相对Listener的,然后再设置其位置并且为静止不动的。

播放控制

既然是声源,资源播放控制是通过他来实现的,播放这个声源、暂停播放这个声源。

 void alSourcePlay( ALuint source);
 void alSourcePause( ALuint source);
 void alSourceStop( ALuint source);
 void alSourceRewind( ALuint source);

四个函数分别表示:“播放” 、“暂停”、“停止”、“重置”功能。这里注意了,“停止”后再播放,就会从开始的数据部分进行播放了,而“重置”也是先停止并设置为初始状态。

绑定Buffer

Buffre的数据要如何送入到Source中呢?Source通过一个对来来管理所有的Buffer,这些Buffer将按照FIFO的顺序依次进行播放。

void alSourceQueueBuffers(
  ALuint source,
     ALsizei n,
  ALuint* buffers
);

这里讲buffers数组中的n个Buffer Enqueue到source的BufferQueue中。其相反动作自然是DeQueue

void alSourceUnqueueBuffers(
  ALuint source,
     ALsizei n,
  ALuint* buffers
);    

将buffer数组中的n个Buffer对象从source的BufferQueue中Dequeued掉。

Listener

听众可以认为是扬声器,所以就只有一个表现,因此就不用去创建和销毁了。 Listener提供的属性有:

属性类型意义
AL_GAINfloat增益
AL_POSITION3f位置
AL_VELOCITY3f速度向量
AL_ORIENTATIONfloat array前后朝向

属性获取和设置

Listener比较简单,只要设置其在空间中的位置和移动就可以了,所以其提供的所有函数都是用来设置和读取属性的:

alListenerf 
alListener3f 
alListenerfv 
alListeneri 
alListener3i 
alListeneriv 
alGetListenerf 
alGetListener3f 
alGetListenerfv 
alGetListeneri 
alGetListener3i 
alGetListeneriv

比如要设置其在原点朝向x轴方向:

ALfloat listenerOri[] = { 1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f };
alListener3f(AL_POSITION, 0, 0, 0);
alListener3f(AL_VELOCITY, 0, 0, 0);
alListenerfv(AL_ORIENTATION, listenerOri);

这里首先设置位置为原点,速度为0禁止不动,然后用两个(x,y,z) /(x/y/z)来表示朝向,前者表示"at"后者表示"up"。

总结

OpenAL中通过设置Source和Listenner的相对位置,并往Source中输入音频数据,通过控制Source的播放与否就可以在Listener侧听到3D空间中的传来的声音了。当然OpenAL不仅仅只有这些接口,还有对State、Device等的设置,这里不一一列举,可以参考官方手册。

参考

  1. OpenAL_Programmers_Guide
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ALUT(OpenAL Utility Toolkit)是一个用于OpenAL的工具包,它提供了一些方便的函数来简化OpenAL的使用。下面是使用ALUT库的步骤: 1. 下载OpenAL-Soft库,可以从官网下载:https://www.openal.org/downloads/ 。 2. 下载ALUT库,可以从官网下载:https://github.com/vancegroup/freealut/releases 。 3. 解压OpenAL-Soft和ALUT库。 4. 进入OpenAL-Soft源码目录,建立build目录(如果没有),进入build目录,执行cmake ..,生成vs2019工程文件OpenAl.sln。 5. 用vs2019打开OpenAl.sln工程文件,编译64位目标文件。 6. 在你的代码中包含AL/alut.h头文件。 7. 在你的代码中使用ALUT库提供的函数,例如alutInit()、alutCreateBufferFromFile()、alutCreateSource()等。 8. 在你的代码中使用OpenAL库提供的函数,例如alGenSources()、alSourcei()、alSourcePlay()等。 下面是一个使用ALUT库的例子: ```c #include <AL/alut.h> #include <AL/al.h> int main(int argc, char **argv) { // 初始化ALUT库 alutInit(&argc, argv); // 创建一个缓冲区并从文件中读取数据 ALuint buffer = alutCreateBufferFromFile("sound.wav"); // 创建一个源并将缓冲区分配给它 ALuint source; alGenSources(1, &source); alSourcei(source, AL_BUFFER, buffer); // 播放声音 alSourcePlay(source); // 等待声音播放完毕 ALint state; do { alGetSourcei(source, AL_SOURCE_STATE, &state); } while (state == AL_PLAYING); // 清理资源 alDeleteSources(1, &source); alDeleteBuffers(1, &buffer); alutExit(); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值