OpenAL 失真的常见来源?

Posted

技术标签:

【中文标题】OpenAL 失真的常见来源?【英文标题】:Common sources of OpenAL distortion? 【发布时间】:2017-11-26 02:41:04 【问题描述】:

我正在为我正在制作的游戏开发音频引擎。然而,当我播放我的声音片段时,它们大部分都还可以,但会被破坏和扭曲。我生成了一个正弦波,它应该给出一个纯音,但它仍然有这种失真——因此我认为它在 OpenAL 端。

问题是,我并没有对 OpenAL 做任何花哨的事情。

首先,我生成 48000 个正弦波样本

  #include <math.h>
  #define PI 3.14159265

  float amplitude = .5f;
  float frequency = 440;
  float phase = 0.f;
  float time = 0.f;
  int sampleRate = 48000;
  float dt = 1.0f / sampleRate;

  float sineWave[48000];
  fox_for(sample, sampleRate)  // standard macro for for loop
    float val = amplitude * sin(2 * PI * frequency * time + phase);
    sineWave[sample] = val;
    time += dt;
  

一切都很好。 [-.5, .5] 中的一堆浮点数,呈正弦波模式。然后我执行标准的 OpenAL 步骤:生成源和缓冲区。将数据绑定到缓冲区,将缓冲区绑定到源,然后播放声音。

// Open device and context
if (ALCdevice *device = alcOpenDevice(NULL)) 
    if (ALCcontext *context = alcCreateContext(device, NULL)) 
      alcMakeContextCurrent(context);
     else 
      gameLog.writeStr("ALC context opening failed");
    
   else 
    gameLog.writeStr("ALC device opening failed");
  

  // Generate a source, set its properties to default explicitly
  ALuint source;
  alGenSources(1, &source);

  alSourcef(source, AL_PITCH, 1.0f);    
  alListener3f(AL_POSITION, 0.0f, 0.0f, 0.0f);
  alSource3f(source, AL_POSITION, 0.0f, 0.0f, 0.0f);
  alSourcef(source, AL_GAIN, 0.5f);
  alSource3f(source, AL_POSITION, 0.f, 0.f, 0.f);
  alSource3f(source, AL_VELOCITY, 0.f, 0.f, 0.f);

  // Fill buffers with sine wave data
  ALuint testBuf;
  alGenBuffers(1, &testBuf);
  alBufferData(testBuf, AL_FORMAT_MONO16, &sineWave[0], 48000 * sizeof(float), 48000);

  // Play sound
  alSourcei(source, AL_BUFFER, testBuf);
  alSourcePlay(source);

我得到一个明显是 440hz 的音符,但模糊且相当失真。我的第一个想法是格式 AL_FORMAT_MONO16 可能导致浮点数(64 位)被解释为 16 位数字序列。但如果是这样的话,我想声音会非常失真和无法识别。

在我的游戏中,使用 libvorbisfile 将数据作为原始字节读取,格式和频率由从 .ogg 文件解析的标头数据指定。因此,我认为问题不在于使用了错误的格式或频率。

如果有人对 OpenAL 有任何经验,如果您发现问题或帮助调试的提示,我将不胜感激。谢谢!

【问题讨论】:

【参考方案1】:

您的音频数据格式错误。从documentation开始,16位数据是有符号整数数据,从-32768到+32767。

您仍然听到一些可识别为正弦波的声音,因为您的浮点数的上半部分类似于正弦波。您可以听到这一点,即使其他所有样本本质上都是随机的。

【讨论】:

感谢您的回复!我已经将 .ogg 文件中的 pcm 数据加载为 16 位整数。我试图将我生成的正弦波更改为 16 位整数,但我仍然得到相同数量的失真。我检查了我正在生成的整数,它们都在 [-99, 99] 中,所以我认为现在没有任何剪裁。你还有其他建议吗?非常感谢您的宝贵时间! 糟糕!所以看起来我的声音太安静了,听不到我正在使用的振幅。一旦我把它调到适当的音量,一切听起来都很好。对于阅读本文的任何人,请确保测试声音在 +/- 1k 的范围内,并且采用 16 位整数的形式。非常感谢!

以上是关于OpenAL 失真的常见来源?的主要内容,如果未能解决你的问题,请参考以下文章

确定何时播放缓冲区而不在 OpenAL 中轮询源

OpenAL不播放声音

OpenAL 2d 平移 C++

Android OpenAL?

OpenAL 3d 定位和平移中心

openal:获取源的当前播放位置