分类:
2010-01-05 13:01:44
// 存贮声音数据.
ALuint Buffers[NUM_BUFFERS];
// 播放多个声音的源的矢量表
vector
首先,我写出了我们用于表明缓冲区数组的一些指令。我们将用几个WAV
文件,因此我们需要几个缓冲区。我们将用一个STL矢量代替用于存贮源
的一个数组。我们能做这些是因为他让我们能有一个源的动态数。我们能
一直添加源到场景,直到OPENAL脱离他们运行。
ALboolean InitOpenAL()
{
ALCdevice* pDevice;
ALCcontext* pContext;
ALCubyte* deviceSpecifier;
ALCubyte deviceName[] = "DirectSound3D";
// 得到设备句柄
pDevice = alcOpenDevice(deviceName);
// 得到设备说明.
deviceSpecifier = alcGetString(pDevice, ALC_DEVICE_SPECIFIER);
printf("Using device '%s'.\n", szDeviceSpecifier);
// 建立声音文本描述.
pContext = alcCreateContext(pDevice, NULL);
// 设置行为文本描述.
alcMakeContextCurrent(pContext);
// 检查错误.
if (alcGetError() != ALC_NO_ERROR)
return AL_FALSE;
return AL_TRUE;
}
这是来自上一章的代码。首先,我们得到 "DirectSound3D"设备的句柄,
然后获得用于程序的表明文本描述。
这个文本描述设置当前,函数将检查在我们返回成功前,是否出错。
void ExitOpenAL()
{
ALCcontext* pCurContext;
ALCdevice* pCurDevice;
// 得到当前文本描述
pCurContext = alcGetCurrentContext();
// 得到用于当前文本描述的设备?
pCurDevice = alcGetContextsDevice(pCurContext);
// 重置当前文本描述为NULL
alcMakeContextCurrent(NULL);
//释放文本描述和设备
alcDestroyContext(pCurContext);
alcCloseDevice(pCurDevice);
}
我们用和释放的文本描述和设备将收回。另外,在OPENAL暂停程序时,设置
当前文本描述为NULL。但是这些都不可预料。如果你用了多个文本描述,
你也许需要更好的方法来做这些事。我将介绍一些比较好的方法。
ALboolean LoadALData()
{
// 导入的变量
ALenum format;
ALsizei size;
ALvoid* da
ALsizei freq;
ALboolean loop;
// 装载WAV文件到缓冲区
alGenBuffers(NUM_BUFFERS, Buffers);
if(alGetError() != AL_NO_ERROR)
return AL_FALSE;
alutLoadWAVFile("wavdata/thunder.wav", &format, &da
alBufferData(Buffers[THUNDER], format, da
alutUnloadWAV(format, da
alutLoadWAVFile("wavdata/waterdrop.wav", &format, &da
alBufferData(Buffers[WATERDROP], format, da
alutUnloadWAV(format, da
alutLoadWAVFile("wavdata/stream.wav", &format, &da
alBufferData(Buffers[STREAM], format, da
alutUnloadWAV(format, da
alutLoadWAVFile("wavdata/rain.wav", &format, &da
alBufferData(Buffers[RAIN], format, da
alutUnloadWAV(format, da
alutLoadWAVFile("wavdata/ocean.wav", &format, &da
alBufferData(Buffers[OCEAN], format, da
alutUnloadWAV(format, da
alutLoadWAVFile("wavdata/chimes.wav", &format, &da
alBufferData(Buffers[CHIMES], format, da
alutUnloadWAV(format, da
// 错误检测
if (alGetError() != AL_NO_ERROR)
return AL_FALSE;
return AL_TRUE;
}
在这个函数中,我将移动产生源,这是因为我们将一个一个的初始化。
void AddSource(ALint type)
{
ALuint source;
alGenSources(1, &source);
if (alGetError() != AL_NO_ERROR)
{
printf("Error generating audio source.");
exit(-1);
}
alSourcei (source, AL_BUFFER, Buffers[type]);
alSourcef (source, AL_PITCH, 1.0 );
alSourcef (source, AL_GAIN, 1.0 );
alSourcefv(source, AL_POSITION, SourcePos );
alSourcefv(source, AL_VELOCITY, SourceVel );
alSourcei (source, AL_LOOPING, AL_TRUE );
alSourcePlay(source);
Sources.push_back(source);
}
这个函数将产生源,他将为我们载入的缓冲区中的一个产生一个源。用
‘TYPE’表示缓冲区,我们文章开始建立的指令将做这些事情。然后做
错误检测,确定源能播放。如果源不能将退出。
void KillALData()
{
for (vector
alDeleteSources(1, iter);
Sources.clear();
alDeleteBuffers(NUM_BUFFERS, Buffers);
ExitOpenAL();
}
这个函数将修改STL表。我们不得不删除每个源并且清除表上的内容。
ALubyte c = ' ';
while (c != 'q')
{
c = getche();
switch (c)
{
case 'w': AddSource(WATERDROP); break;
case 't': AddSource(THUNDER); break;
case 's': AddSource(STREAM); break;
case 'r': AddSource(RAIN); break;
case 'o': AddSource(OCEAN); break;
case 'c': AddSource(CHIMES); break;
};
}
这是程序的主函数,他等待键盘输入,建立源,播放声音。