OpenAL 失真的常见来源?
Common sources of OpenAL distortion?
我正在为我正在制作的游戏开发音频引擎。然而,当我播放我的声音片段时,它们大部分都很好,但出现了损坏和失真。我生成了一个正弦波,它应该给出一个纯音,但它仍然有这种失真——因此我认为它在 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 文件解析的 header 数据指定。因此,我不认为问题是使用了错误的格式或频率。
如果有人有任何使用 OpenAL 的经验,如果您看到问题或帮助调试的提示,我将不胜感激。谢谢!
您的音频数据格式错误。从documentation开始,16位数据为有符号整数数据,从-32768到+32767。
您仍然听到一些可识别为正弦波的声音,因为您的浮动的上半部分是正弦波。你可以听到,即使其他所有样本基本上都是随机的。
我正在为我正在制作的游戏开发音频引擎。然而,当我播放我的声音片段时,它们大部分都很好,但出现了损坏和失真。我生成了一个正弦波,它应该给出一个纯音,但它仍然有这种失真——因此我认为它在 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 文件解析的 header 数据指定。因此,我不认为问题是使用了错误的格式或频率。
如果有人有任何使用 OpenAL 的经验,如果您看到问题或帮助调试的提示,我将不胜感激。谢谢!
您的音频数据格式错误。从documentation开始,16位数据为有符号整数数据,从-32768到+32767。
您仍然听到一些可识别为正弦波的声音,因为您的浮动的上半部分是正弦波。你可以听到,即使其他所有样本基本上都是随机的。