更新:我添加了更好的图像,以便您可以更好地看到问题。
每次信号通过“地”时,我的低通功能似乎都会引起奇怪的尖峰。我尝试过多种输入范围(-1 - 1)(-127 - 128)(0 - 255)。低通确实有效,但总是存在这些尖峰。
这也不是显示问题,因为我将数据写入文件并大胆打开它,它看起来是一样的。
这就是功能。 数据从 wav 文件加载并使用 SDL2 转换为 8 位单声道。 我希望它从 wav_buffer 获取数据,应用低通滤波器,然后将其复制到loud_buffer。我下面的图片显示了 wav_buffer 和 Loud_buffer 的显示。
// for reference
Uint8 *wav_buffer;
int wav_length;
Uint8 *loud_buffer;
const int filter_cutoff = 2000;
const int sRate = 44100;
void low_pass()
{
float prevOutput = 0;
float prevInput = 0;
float x = tanf(M_PI * filter_cutoff / sRate);
float output;
for (int p = 0; p < wav_length; p++)
{
output = x * wav_buffer[p] + x * prevInput - (x-1) * prevOutput;
output /= (x+1);
loud_buffer[p] = output;
prevOutput = output;
prevInput = wav_buffer[p];
}
}
这是wav_buffer中的数据。这里一切都好。
这是 low_pass 函数之后的loud_buffer。
找到解决方案了! 我现在感觉有点傻:|
使用 Sint8 而不是 Uint8 作为输入和输出来修复它。 这显然是特定于 SDL 数据类型的,因为如果没有这些类型,前面的函数就可以完美运行。
void low_pass()
{
long double x = tanf(M_PI * filter_cutoff / sRate);
long double output = 128;
Sint8 out; // Sint8 here was the solution :/
Sint8 input; // ^^^
for (int p = 0; p < wav_length; p++)
{
input = wav_buffer[p];
output = x * input + x * output - (x-1) * output;
output /= (x+1);
out = (Sint8)output;
loud_buffer[p] = out;
}
}