5

所以,我正在构建一个线程化的 IMA ADPCM 解码器,将音频数据流式传输到 OpenAL (简短描述见下文),但我遇到了一些麻烦。

我的问题之一是有时我对 alBufferData 的调用:

alBufferData(*bufferID, format, pcmData, sizeInBytes, bitRate);

AL_INVALID_VALUE即使在检查它们看起来的参数时也会返回,例如,像这样:

bufferID='109770616', format='AL_FORMAT_STEREO16', dataPtr='109754188', sizeInBytes='8164'

任何线索,有人吗?发生这种情况时,实际播放的声音会有点口吃,并且错误通常会连续发生约 10 次(在相同的声音上)。当我重复启动相同的声音时,通常也会发生这种情况(例如,当用 LMG 短时间射击时……;))

流式解码器模块的快速简化之旅

如何播放声音:

  1. 触发声音播放。
  2. 一个 bufferSize 的音频被解码,其余的被排队等待进一步解码。
  3. 触发 OpenAL 开始播放声音。

解码/流式循环

  1. 对于排队等待解码的每个声音,解码 bufferSize 值的音频。
  2. 解码后的音频被添加到具有适当 bufferID 的 alBuffer(参见上面的调用)中。
4

2 回答 2

3

如果还不算太晚,我会告诉你我在使用 BufferData 时遇到的类似问题,这就是我修复它的方法。尽管请记住,我不知道您的线程程序的细节。

由于多种原因返回了无效值,我知道的原因是...... -
如果源已经分配了 bufferID,则将新缓冲区(到流式源)排队(因为如果您设置缓冲区 id,它将被设置为静态) . 如果是这样,请删除源属性中的 ID。
- 在播放中更改缓冲区格式。一旦源开始播放,您不能更改任何缓冲区设置(fmt,采样率),除了缓冲区数据本身,即使它在另一个排队的。

听起来您可能正在另一个线程中更改其中一个设置。

可能导致爆裂声的另一件事是重放声音。再次调用 play 只是停止源冷,然后倒回当前缓冲区并从头开始播放。演奏这样的枪声听起来不像你想要的那样(我假设是分层的)。2个选项,将剩余的枪声混合到缓冲区中然后重播,但这可能行不通。另一个简单的证明就是使用多个来源并轮流在每次开火时调用哪些来源。

祝你的项目好运。

于 2012-07-10T21:09:21.667 回答
1

由于我偶然发现了同样的错误并且这个问题是第一个出现在搜索引擎中的问题,我想快速发布我遇到的问题,希望它对其他人有用。我将 stb_vorbis (来自https://github.com/nothings/stb)与 OpenAL 一起使用,当我尝试将数据输入 OpenAL 时,我得到了相同的 AL_INVALID_VALUE 错误。事实证明,缓冲区必须是 4 的倍数(至少在 soft_al 实现和 AL_FORMAT_STEREO16 上(对于其他实现/格式可能不同)。

bufferSize = stb_vorbis_decode_filename("sound.ogg", &channels, &sampleFrequency, &pcmData);

// Adjust the bufferSize to a multiple of 4
bufferSize = bufferSize - bufferSize%4;

alBufferData(mySoundBuffer, AL_FORMAT_STEREO16, pcmData, bufferSize, sampleFrequency);

我通过反复试验得到了它,所以如果你遇到这个错误,你可能也想检查一下。

亲切的问候,莫里茨

于 2020-06-03T11:48:13.973 回答