# [sdiy] Approximating sine with plain integer math

MTG grant at musictechnologiesgroup.com
Thu Apr 7 03:15:17 CEST 2016

Does this group have a functional archive?  There was a bunch of talk
about using Phase Accumulators for LFOs. If memory serves it has a small
table and perhaps some interpolation. All integer and could be used on
an 8-bit micro.

GB

On 4/6/2016 4:45 PM, Jay Schwichtenberg wrote:
> I would agree that using a "lookup table" with linear interpolation would be
> better.
>
> You only need a table of 0-90 degrees if memory for the table is limited.
> Also you could pre-compute slopes and offsets for the linear interpolation
> equation.
>
> Jay S.
>
> -----Original Message-----
> From: Synth-diy [mailto:synth-diy-bounces at dropmix.xs4all.nl] On Behalf Of
> Richie Burnett
> Sent: Wednesday, April 06, 2016 4:28 PM
> To: John Ames; synthdiy diy
> Subject: Re: [sdiy] Approximating sine with plain integer math
>
> Neat.  It's got quite a high distortion for a sinewave as you said, and has
> only odd harmonics present.  The waveform you have actually generated is the
>
> integral of a triangle waveform.
>
> As a triangle is the integral of a squarewave and has a steeper spectral
> roll-off, your waveform is the integral of the triangle waveform, and has an
>
> even steeper spectral roll-off:
>
> Square has odd harmonics only and -6dB/oct rolloff
> Triangle has odd harmonics only and -12dB/oct rolloff
> "John Ames' sinewave approx" has odd harmonics only and -18dB/oct rolloff.
>
> You can play similar tricks with generating successive integrals of a
> sawtooth waveform, to get from sawtooth to parabola and then to something
> that looks sine-like and has a -18dB/oct rolloff, but has both odd and even
> harmonics present.  Technically inferior to your approximation because the
> THD is higher, but might sound nicer with even harmonics present!?!?
>
> Did you consider a lookup-table with linear interpolation? ...that would be
> my method of choice for sinewave generation if I wanted low distortion.  You
>
> can also get excellent results with low-order polynomial approximations with
>
> or without range-reduction techniques to exploit the inherent symmetries of
> the sine function.  These can all be implemented with fixed-point
> arithmetic.  No need to go to floating point.
>
> Good luck with your project!
>
> -Richie,
>
>
> -----Original Message-----
> From: John Ames
> Sent: Wednesday, April 06, 2016 11:55 PM
> To: synthdiy diy
> Subject: [sdiy] Approximating sine with plain integer math
>
> I'm working on a softsynth for a project, and one of my goals is to
> avoid floating-point math (no particular reason other than just to see
> if I can, but there's still architectures out there where it makes a
> significant difference, so what the hey.) Initially I had compromised
> on that when I needed a sine waveform for my oscillators, but today,
> while playing around with a way to make the sawtooth less of a plain
> linear ramp, I stumbled onto a way to generate what I think is quite a
> satisfactory sine waveform using only a few integer operations. Since
> I'm rather pleased with it and it might prove useful to somebody,
> here's the algorithm:
>
> 1. Generate a sawtooth in the range -max to +max (i.e. -32768 to 32767
> for a 16-bit integer.)
> 2. Square it.
> 3. Divide by +max (i.e. 32767.)
> 4. Multiply by the sign of the original value.
> 5. Subtract the original value.
> 6. Multiply by 4.
> 7. The result is inverted (or 180 degrees out-of-phase, if you want to
> look at it that way,) so re-invert it if this is a problem for you. Or
> just multiply by -4 in step 6.
>
> There's probably a few different ways to implement this depending on
> what kind of architecture you're doing it on, but here's a basic C
> implementation:
>
> #include <stdlib.h>
> #include <limits.h>
>
> /* sawToSine - takes a sawtooth sample as a signed integer and returns
> the equivalent sine sample. */
>
> int sawToSine(int saw)
> {
>      return ((((saw * saw) / INT_MAX) * (saw / abs(saw))) - saw) * -4;
> }
>
>>From a quick check with a graphing calculator (paste:
>
> \left(\left(\left(x^2\cdot
> \operatorname{sign}\left(x\right)\right)-x\right)\cdot -4\right)-\sin
> \left(x\cdot \pi \right)
>
> into https://www.desmos.com/calculator to see,) it looks like has a
> maximum distortion of ~5.5% compared to a true sine, and it's actually
> a little "fuller" and rounder, which I like. From a quick code test,
> it maintains almost full peak-to-peak range and never overflows.
>
> Whether this is any faster than using floating-point probably depends
> on how expensive integer multiplies and divides are on your target
> architecture, but I just thought it was interesting and wanted to
> share :)
> _______________________________________________
> Synth-diy mailing list
> Synth-diy at dropmix.xs4all.nl
> http://dropmix.xs4all.nl/mailman/listinfo/synth-diy
>
>
> -----
> No virus found in this message.
> Checked by AVG - www.avg.com
> Version: 2016.0.7497 / Virus Database: 4545/11975 - Release Date: 04/06/16
>
> _______________________________________________
> Synth-diy mailing list
> Synth-diy at dropmix.xs4all.nl
> http://dropmix.xs4all.nl/mailman/listinfo/synth-diy
>
> _______________________________________________
> Synth-diy mailing list
> Synth-diy at dropmix.xs4all.nl
> http://dropmix.xs4all.nl/mailman/listinfo/synth-diy
>
>