在 DSP 上使用 lut 生成高 SNR 正弦波

信息处理 离散信号 声音的 音调产生
2022-02-24 06:38:04

我通过在 DSPic33f 上使用 lut 方法来生成窦。我的采样率为 48 kHz,所以我保存了第一个值的 12000 个(无符号整数,16 位)并使用三角公式计算正弦曲线的其他部分。我可以通过转动旋转编码器来改变这个正弦波的频率。每 2 毫秒,一个定时器中断读取旋转编码器的值,该值(以 Hz 为单位的频率)将成为读取我的 lut 的新索引。

一些代码供您理解:

ANGLE += FREQUENCY_VALUE;
if(ANGLE < SINE_TABLE_LEN)
{
    index  = ANGLE;
    sign = 1;
}
else if((ANGLE >= SINE_TABLE_LEN) && (ANGLE < SINE_TABLE_LEN2))
{
    index = SINE_TABLE_LEN2 - ANGLE;
    sign = 1;
}
else if((ANGLE >= SINE_TABLE_LEN2) && (ANGLE < SINE_TABLE_LEN3))
{
     index = ANGLE - SINE_TABLE_LEN2;
     sign = -1;
}
else if((ANGLE >= SINE_TABLE_LEN3) && (ANGLE < SINE_TABLE_LEN4))
{
     index = SINE_TABLE_LEN4 - ANGLE;
     sign = -1;
}
else
{
     ANGLE -= SINE_TABLE_LEN4;
     index = ANGLE;
     sign = 1;
}
audio_sample_l = sign * sine_lut[index-1];
audio_sample_r = audio_sample_l;

我将变量 ANGLE 初始化为 0,将 FREQUENCY_VALUE 初始化为 1。当绘制我的窦的 fft 时,我得到一些我无法解释的奇怪谐波噪声。当我将输出样本与我的 lut 中的样本进行比较时,它们是相同的(没有索引错误)。问题可能来自这样一个事实,即我不是从 lut 的开头而是从前一个样本开始以避免相位变化。也可能存在一些舍入误差。我的第三条线索是初始化值和索引计算(也在循环中测试)。你怎么看 ?

在此处输入图像描述

有人有一些想法来改变它吗?

2个回答

当 ANGLE 增加到 SINE_TABLE_LEN4 时跟踪您的逻辑——您会发现您正在访问缓冲区下方。在 C 中编码时,您应该真正采用从零开始的索引方案。

您正在生成一个阶梯式正弦波,这就是为什么您会得到如此多的谐波。由于您为 LUT 使用了 12000 个点,因此阶梯很小,因此谐波已经相当低 - 您的图片显示您生成的信号 (100Hz) 比最强谐波高 80dB。您尝试生成的任何未均匀划分为 48000 的频率都会在一定程度上导致谐波变差,因为在这些情况下您的 FREQUECY_VALUE 不会是整数,导致您查找的值略微偏离正确的值。

这几乎是您所使用的方法所期望的。请参阅此处的示例进行比较。 您可以按照该链接页面上的建议,从较小的 LUT 中获得相同的性能,或者从您的怪物 LUT 中获得更好的性能。

您真正需要生成的信号有多干净?