Linear interpolation of a sine wavetable

1. Jul 18, 2009

bitrex

Hi everyone. I'm doing a microcontroller project where I'm using a 256 element array of 1 byte values to output a sine wave at varying frequencies. I'm using the top 8 bytes of a 16 bit "angle increment" value that's incremented by varying amounts as an index to the array of values, to control the frequency of the output.

At low frequencies, however, there are too few data points to make a smooth output. I'd like to do linear interpolation of the sine wave data points to get a smoother output. The formula for the value of a function F(X) at a point between two known values F(X1) and F(X2) is:

$$F(x) = F(x_1) + (x - x_1) * \frac{F(x_2) - F(x_1)}{x_2 - x_1}$$

The first element of this equation, $$F(x_1)$$, is easy, it's just the value stored in the array at the top 8 bits of the current 16 bit angle increment. The second element is just the bottom 8 bits of the current angle increment. The third element, however, is more computationally intensive. However, since the third part of the function is just the first derivative of the sine function at the current point, and the derivative of the sine function is cosine, I was thinking I could just grab a value from the sine table that's pi/2 radians ahead of the current value and use that. Does that seem like it would work?

2. Jul 20, 2009

Pommie

Assuming you want to keep everything in integers and you keep your angle as a 16 bit integer - I.E. 0-65535. To get the linear interpreted value you would do,

Lookup Angle/256 in table - val1
Lookup next value -val2
Calculate val1+((val2-val1)*(Angle and 255))/256)

This is in fact your function above but done using integer maths.

Alternatively, if you only require a little more resolution, make your 256 byte table represent a quadrant. This would give your angle a range from 0-1023.

Mike.