3 ms·
The symmetry of the waveform can be exploited for additional precision for a similar memory and computational footprint. Make the 256-entry LUT of half of a si
by willis936 5y ago
The symmetry of the waveform can be exploited for additional precision for a similar memory and computational footprint. Make the 256-entry LUT of half of a sine lobe rather than a full period then do some bookkeeping to track where in the period you are for reflections of LUT index and y value.
Example (1-indexed):
f = 1000;
tPer = 1 / f;
ts = 1 / 48000;
LUT = int16( 2^15 * sinpi( (1:256) / 256 / 2 ) );
t = 0;
while true
t = mod( t + ts, tPer);
i = uint16( floor( t * f * 1024 ) );
if i <= 256
y = LUT(i);
elseif i <= 512
y = LUT(257-mod(i,257));
elseif i <= 768
y = -LUT(mod(i,257));
else
y = -LUT(257-mod(i,257));
end
end
I left out interpolation to keep the concept highlighted.
Unsurprisingly: it's faster and more accurate to skip the LUT when using MATLAB. It's faster still to use vectors and batched function calls.
- jamesmunns 5y agoMentioned more details about this in a top level comment - but the total LUT is small (256 * 2 = 512 bytes), so I didn't 1/4 it because that would introduce more per-cycle cost (to do the rotation), to save a few hundred bytes. This was an okay tradeoff for me, but this might be a bigger deal for larger LUTs, or more precise values than 16-bit PCM samples. Additionally my error max was already enough, where adding 4x the LUT precision would be diminishing returns for my application.