直接数字合成中的线性插值

Bit*_*rex 5 c avr linear-interpolation

我正在研究C中的微控制器DDS项目,并且在确定如何计算线性插值以平滑输出值方面遇到了一些麻烦.现在的程序
使用24位累加器的前8位作为8位输出值数组的索引.我需要提出一个函数,它将占用累加器的中间和低位字节,并在数组中的"previous"和"next"值之间生成一个值.这对于快速硬件来说足够简单,但由于我使用的是微控制器,我真的需要避免做任何浮点运算或划分!

有了这些限制,我不确定如何从我的两个8位输入数字和累加器的低2个字节获得8位插值,这表示两个输入值之间的"距离".提前感谢任何建议!

澄清

DDS =直接数字合成

在DDS中,使用相位累加器从查找表生成波形.相位累加器通常包含整数分量和分数分量.整数组件用作查找表的索引.在简单的DDS实现中,忽略小数部分,但是对于更高质量的输出,小数分量用于在相邻查找表值之间进行内插(通常只是线性内插).对于上述问题,我们正在研究如何在给定分数f,其中的两个查找表值之间有效地执行此线性插值0 <= f < 1.

Pau*_*l R 7

假设您有一个波形值表(一个象限或四个象限,无关紧要),那么一个可能的优化是存储连续表值之间的增量值.即如果你有eg N = 256和波形表,LUT[N]那么你也有一个delta值表,LUT_delta[N].两个预先计算的表之间的关系是LUT_delta[i] = LUT[i+1] - LUT[i].因此,而不是找了两个连续的表值,LUT[i]并且LUT[i+1],这些相减得到增量,然后做插值,你只是仰望第一表值,LUT[i]和三角洲,LUT_delta[i]然后计算插值.这需要相同数量的表查找,但数学运算较少.如果您正在使用DSP,则应该能够使用单个乘法累加指令进行插值,否则它是通用CPU上的乘法+比例+加法.此外,如果您交换LUTLUT_delta值,您可以查看LUT[i]LUT_delta[i]使用单个读取,然后解压缩这两个值.

伪代码:

extract integer LUT index, i, from accumulator // just need a shift for this
extract fractional part of accumulator, f // mask or subtract to get f
get p = LUT[i] // lookup waveform value
get delta = LUT_delta[i] // lookup delta
calculate p_interp = p + p_delta * f // single multiply-accumulate instruction on most DSPs - need scaling on general purpose CPUs
Run Code Online (Sandbox Code Playgroud)