openal教程(三)
来源:互联网 发布:阿蒂仙 梵音藏心 知乎 编辑:程序博客网 时间:2024/05/12 23:12
原文:http://bbs.gameres.com/thread_12728.html
多源
你好,在这一章中,我们将在上一章的例程中加入一些元素,使他能同时
播放超过一种的音乐。
通常在一个优秀的游戏中有各种不同的音夹(clip),这是怎样实现的呢?
下面将介绍。
#include <conio.h>
#include <time.h>
#include <stdlib.h>
#include <al/al.h>
#include <al/alc.h>
#include <al/alu.h>
#include <al/alut.c>
// 我们需要的最大的数据缓冲.
#define NUM_BUFFERS 3
// 我们需要放三种声音.
#define NUM_SOURCES 3
// 缓冲和源标志.
#define BATTLE 0
#define GUN1 1
#define GUN2 2
// 存储声音数据.
ALuint Buffers[NUM_BUFFERS];
// 用于播放声音.
ALuint Sources[NUM_SOURCES];
// 源声音的位置.
ALfloat SourcesPos[NUM_SOURCES][3];
// 源声音的速度.
ALfloat SourcesVel[NUM_SOURCES][3];
// 听者的位置.
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 };
在这一章中,唯一的不同是多了3种将导入Openal系统的不同的声音效果 。
ALboolean LoadALData()
{
// 载入变量.
ALenum format;
ALsizei size;
ALvoid* data;
ALsizei freq;
ALboolean loop;
// 载入WAV数据.
alGenBuffers(NUM_BUFFERS, Buffers);
if (alGetError() != AL_NO_ERROR)
return AL_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)
return AL_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)
return AL_FALSE;
return AL_TRUE;
}
首先,我们导入文件数据到3个缓冲区,然后把3个缓冲区和3个源锁在
一起。唯一的不同是文件“battle.wav”在不停止时循环。
void SetListenervalues()
{
alListenerfv(AL_POSITION, ListenerPos);
alListenerfv(AL_VELOCITY, ListenerVel);
alListenerfv(AL_ORIENTATION, ListenerOri);
}
void KillALData()
{
alDeleteBuffers(NUM_BUFFERS, &Buffers[0]);
alDeleteSources(NUM_SOURCES, &Sources[0]);
alutExit();
}
在这段代码中,我们没有改变。
int main(int argc, char *argv[])
{
// Initialize OpenAL and clear the error bit.
alutInit(NULL, 0);
alGetError();
// Load the wav data.
if (LoadALData() == AL_FALSE)
return 0;
SetListenervalues();
// Setup an exit procedure.
atexit(KillALData);
// Begin the battle sample to play.
alSourcePlay(Sources[BATTLE]);
// Go through all the sources and check that they are playing.
// Skip the first source because it is looping anyway (will always be playing).
ALint play;
while (!kbhit())
{
for (int i = 1; i < NUM_SOURCES; i++)
{
alGetSourcei(Sources[i], AL_SOURCE_STATE, &play);
if (play != AL_PLAYING)
{
// Pick a random position around the listener to play the source.
double theta = (double) (rand() % 360) * 3.14 / 180.0;
SourcePos[i][0] = -float(cos(theta));
SourcePos[i][1] = -float(rand()%2);
SourcePos[i][2] = -float(sin(theta));
alSourcefv(Sources[i], AL_POSITION, SourcePos[i] );
alSourcePlay(Sourcev[i]);
}
}
}
return 0;
}
这段是这篇文章最有趣的地方。我们在这里将播放。如果他不播放,我们将
在3D空间中选一个点播放(点击)。
And bang! We are done. As most of you have probably seen,
you don't have to do anything special to play more than one source at a time.
OpenAL will handle all the mixing features to get the sounds right for their
respective distances and velocities. And when it comes right down to it,
isn't that the beauty of OpenAL?
You know that was a lot easier than I thought. I don't know why I waited so long
to write it. Anyway, if anyone reading wants to see something specific in future
tutorials (not necessarily pertaining to OpenAL, I have quite an extensive knowledge base)
drop me a line at lightonthewater@hotmail.com I plan to do tutorials on sharing
buffers and the Doppler effect in some later tutorial unless there is request for
something else. Have fun with the code!
- openal教程(三)
- openal教程(一)
- openal教程(一)
- openal教程(二)
- Openal 教程(四)
- openal教程
- openal全教程
- openal全教程
- openal
- OpenAL
- IOS音频3:之采用四种方式播放音频文件(三)AudioToolbox AVFoundation OpenAL AUDIO QUEUE
- Draw2D 教程(三)
- Draw2D 教程(三)
- Draw2D 教程(三)
- Ruby 教程(三)
- JPA 教程(三)
- JPA 教程(三)
- RxJava教程(三)
- Handler sendMessage 与 obtainMessage (sendToTarget)比较
- 小布老师所有视频 地址
- Linux多线程编程
- Linux下C语言实现LCD屏幕截图
- 43个免费的云计算技术服务
- openal教程(三)
- 经典SQL语句大全
- 2010-03-25 17:37 php 获取昨天 明天的日期
- 错误 3724,无法除去表"xxx",因为它正用于复制。
- HDU-1014魔鬼在细节中
- Android自动测试之Monkey工具
- Android自动测试之monkeyrunner工具
- VC:设置Tab 控件顺序(TabOrder)
- Java学习之路:不走弯路,就是捷径