OpenAL失真的常见来源?

时间:2017-11-26 02:41:04

标签: c++ audio game-engine openal ogg

我正在为我正在制作的游戏制作音频引擎。然而,当我播放我的声音片段时,它们的出现大部分都没问题,但是会受到损坏和扭曲。我生成了一个正弦波,它应该给出一个纯音,但它仍然有这种失真 - 因此我认为它在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 个答案:

答案 0 :(得分:4)

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

你仍然可以听到一些可识别为正弦波的东西,因为你的浮子的上半部分是正弦波。您可以听到,即使每个其他样本基本上是随机的。