我最近一直致力于将我的游戏移植到跨平台,并决定使用 OpenAL 作为我的跨平台音频引擎。
我有 16 个“通道”(OpenAL 源),可以同时播放最多 16 个声音。为了播放声音,我切换哪个缓冲区链接到给定的源,并设置增益、源位置等,以便在给定的“通道”(源)中播放声音。
问题是,我注意到我的“增益”设置似乎没有立即生效。例如,如果在给定源中以 0.5 增益播放响亮的“闪电”声音,那么当我稍后以 0.15 增益播放按钮单击声音时,此单击开始时声音太大。然后,每次播放时,音量都会减小,直到第 3 次或第 4 次点击时,听起来像是在正确的 0.15 增益左右。
第一次按钮点击声几乎听不见,而且音量似乎在逐渐增大,直到达到 0.15 增益。
简而言之,“源”似乎会记住以前的增益设置,即使我在同一源中播放新声音之前重置这些设置!这是一个错误吗?或者我对 OpenAL 有什么不明白的地方?如何让它“立即”更改为新的增益/位置设置?
播放声音的相关代码:
[Channel 是 0 到 15 之间的值,soundID 是 gBuffer 数组中的有效索引,stereoPosition 是 -255 到 255 之间的整数,volume 是 0 到 255 之间的值。这是来自一个函数,该函数是我的游戏的包装器用于使用 0-255 之间的值,因此它将这些值转换为正确的 OpenAL 值。]
// Stop any sound currently playing in this channel ("source")
alSourceStop( gSource[channel] );
// What sound effect ("buffer") is currently linked with this channel? (Even if not currently playing)
alGetSourcei( gSource[channel], AL_BUFFER, &curBuffer );
// attach a different buffer (sound effect) to the source (channel) only if it's different than the previously-attached one.
// (Avoid error code by changing it only if it's different)
if (curBuffer != gBuffer[soundID])
alSourcei( gSource[channel], AL_BUFFER, gBuffer[soundID] );
// Loop the sound?
alSourcei( gSource[channel], AL_LOOPING, (loopType == kLoopForever) );
// For OpenAL, we do this BEFORE starting the sound effect, to avoid sudden changes a split second after it starts!
volume = (volume / 2) + 1; // Convert from 0-255 to 0-128
{
float sourcePos[3] = {(float)stereoPosition / 50, 0.0, 2.0};
// Set Source Position
alSourcefv( gSource[channelNum], AL_POSITION, sourcePos ); // fv = float vector
// Set source volume
alSourcef( gSource[channelNum], AL_GAIN, (float)newVolume / 255 );
}
// Start playing the sound!
alSourcePlay( gSource[channel] );
如果需要的话,我也可以发布设置代码,但没什么特别的。只是打电话
alSourcef( gSource[n], AL_REFERENCE_DISTANCE, 5.0f );
对于每个来源。