[sdiy] Update - OT - Linear interpolation in C
Richie Burnett
rburnett at richieburnett.co.uk
Wed Feb 2 16:49:11 CET 2011
Hi Tom,
You can save a few instructions and registers by doing this...
; These variables come into assembly as:
; W4 - point1
; W5 - point2
; W6 - interpolation index
_Lerp:
; Do the interp
lac W4, A ; Load point1 value into Accum A
msc W4*W6, A ; Sub scaled point1 value as interp index increases
mac W5*W6, A ; Add scaled point2 value as interp index increases
; Get the result and return
sac.r A, W0 ; Truncate and round result, store to W0
The key things are loading the two sample values (I call them y0 and y1) that
you want to interpolate between, straight into MAC registers w4 and w5. That
saves two registers and two move instructions.
And you only need one interpolation index. (You don't need to generate the one
that's going in the opposite direction.) Initialise the accumulator with y0
then as the index increases you "crossfade" from y0 to y1 by progressively
subtracting a scaled amount of y0 and progressively adding a scaled amount of y1
to the accumulator.
You can also make use of the first MSC instruction to pre-fetch the y1 value
from memory ready for use in the MAC that follows. This is useful if y0 and y1
ultimately get pulled from an LUT in data-memory or via Program Space
Visibility.
If the interpolated lookup is part of a realtime audio synthesis loop then you
might also consider loosing the Return instruction. Calls and Returns waste 3
instruction cycles each because they trash the instruction execution pipeline.
Hve spent quite a lot of time optimising interpolated look-up on dsPIC so
hopefully this is helpful,
-Richie Burnett,
More information about the Synth-diy
mailing list