<< >>
justin = { main feed , music , code , askjf , pubkey };
[ <<< last (older) article | view in index | next (newer) article >>> ]

October 1, 2008
stumbling in code

So while playing with some code to model a resonating spring (F=-k*pos), I discovered that the model I was using produced a very good sine wave approximation. This isn't normally something terribly interesting, as you can approximate sine/cosines very easily, but it was actually quite low complexity -- an iterative approximation with only 2 multiplies and 3 adds per sample. It can also generate the cos() (well, a 90 degree shifted signal) for each point for just one additional multiply.

The error is pretty low for the first few cycles, though after a bit it does drift in relation to the correct wave. I'm not going to spend too much more time on this, but if anybody wants to see if there's some way to correct it, go for it (it may just be rounding error, though, of course).

Here is the code:

// setup:
double cos_sc = PI/period_samples; // PI/n for a period of n
double pos=0; // actually sin(initial_state), 1 for cos(), 0 for sin()
double vel=1/cos_sc; // actually cos(initial_state)/cos_sc, 0 for cos(),1/cos_sc for sin()
double tmp = cos_sc*cos_sc;
double tmp2 = 1.0/(1.0+tmp);
double mul1 = (1.0-tmp)*tmp2;
double mul2 = tmp*2.0*tmp2;

// per-sample calculation
double output_value=pos;
// double cosine_output = vel*cos_sc;

// iterate to next sample
double newpos = pos*mul1 + vel*mul2;
vel -= (pos+newpos);
pos = newpos;

Ta-da! If anybody wants to go and do some fancy pants math to show why this works, too, I'd love to hear it... :)

Posted by Justin on Wed 01 Oct 2008 at 13:02 from 64.81.54.x
ahh, just found this: musicdsp.org/showArchiveComment.ph...

Less operations, pretty much same output..

Posted by Tim on Thu 09 Oct 2008 at 08:54 from 128.193.152.x
Har har...

as I read the first line and saw F=-k*pos I thought you were setting up a rant that was going to end in.."Fucking Piece of Shit"....

Posted by Nolan Eakins on Fri 10 Oct 2008 at 18:02 from 98.222.193.x
Just loop one cycle, perfect cos.