【发布时间】:2011-10-21 02:28:56
【问题描述】:
我最近一直致力于将我的游戏移植到跨平台,并决定为我的跨平台音频引擎使用 OpenAL。
我有 16 个“通道”(OpenAL 源),可同时播放多达 16 个声音。要播放声音,我会切换与给定源链接的缓冲区,并设置增益、源位置等,以便在给定“通道”(源)中播放声音。
问题是,我注意到我的“增益”设置似乎没有立即生效。例如,如果在给定的源中以 0.5 增益播放响亮的“闪电”声音,那么当我稍后以 0.15 增益播放按钮单击声音时,此单击开始时声音太大。然后,每次播放时,音量都会降低,直到第 3 次或第 4 次单击时,它听起来像是在适当的 0.15 增益左右。
第一次按钮点击几乎听不见,音量似乎逐渐增大,直到达到 0.15 增益。
简而言之,“源”似乎会记住以前的增益设置,即使我在播放同一源中的新声音之前重置了这些设置!这是一个错误吗?或者我对 OpenAL 不了解的地方?如何让它“立即”更改为新的增益/位置设置?
播放声音的相关代码:
[Channel 是一个介于 0 和 15 之间的值,soundID 是 gBuffer 数组的有效索引,stereoPosition 是介于 -255 和 255 之间的整数,音量介于 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);
每个来源。
【问题讨论】:
-
我对此进行了更多测试,最好这样解释: 1) 在 OpenAL 源中以高增益播放声音,例如 1.0。 2) 声音播放完毕后,在任何源中以非常低的增益(例如 0.01)播放不同的声音。新声音不会以特定的 0.01 增益播放,而是从 1.0 增益开始并“向下滑动”到正确的增益设置。对于非常短的声音,例如按钮点击,这会导致接下来的几个点击声音以 1.0、0.7、0.4 和最后 0.01 的增益出现。 (这些值是对我耳朵听起来的估计值。)
-
这是在 MacOS X 10.6.8 上。我没有检查它是否发生在其他操作系统上。我可以轻松地修改 Apple 自己的 /Developer/ 中的 OpenAlExample 以重复相同的行为。
-
我也遇到过这种情况,想知道如何解决。
-
我最终联系了 Apple,他们告诉我这是一个已知但在 OS X 10.6 上的 OpenAL 实现中不会修复的问题。它已在 OS X 10.7 和 iPhone 中修复。
-
Glaiel - “解决方法”是在 OS X 10.6 或更早版本上使用 OpenAL 以外的其他东西,因为 Apple 不会在此操作系统上的实施中修复它。对于我的游戏,我根据平台切换到 irrKlang 或 SDL_Mixer。
标签: openal