LFO code - how does it work

Software questions and issues with the FV-1

Moderator: frank

Post Reply
pudlll
Posts: 3
Joined: Wed Dec 17, 2014 7:32 am

LFO code - how does it work

Post by pudlll »

Hi
I might have stupid question, sorry for that. I stuck on 'batling lfos' code, could somebody explain to me how this generator works? I cannot understand middle part of this code.

Code: Select all

sof	0,0.01
wrax	freq,0

rdax	c,1
mulx	freq
rdax	s,1
wrax	s,-1
mulx	freq
rdax	c,1
wrax	c,1.99

mulx	amp		;scale output

wrax	dacl,1
wrax	dacr,0		;write both outputs
Digital Larry
Posts: 338
Joined: Mon Nov 12, 2012 1:12 pm
Contact:

Post by Digital Larry »

It's not a stupid question at all. In fact, I have a hard time understanding it. If you enjoy math, try reading this... I believe the theory is the same.

http://www.claysturner.com/dsp/digital_resonators.pdf
pudlll
Posts: 3
Joined: Wed Dec 17, 2014 7:32 am

Post by pudlll »

I found some very small explanation here:

Code: Select all

equ   s   reg10
equ   c   reg11
equ   freq   reg12
;
skp   run,start
clr            ; Clear ACC
wrax   s,0         ; Write 0 to sin reg
sof   0,0.5         ; 0.5 -> ACC
wrax   c,0         ; Write 0.5 to cos reg
;
start:
;
clr
rdax   pot0, 0.05      ; Read pot 0, scale to adjust max speed
wrax   freq, 0         ; Save the freq coefficient
;
; Do the SIN calculation
rdax   c, 1.0      ; COS -> ACC
mulx   freq      ; COS*fcoeff
rdax   s, 1.0      ; +SIN
wrax   s,0      ; Write it back
;
; Do the COS calculation, -SIN in ACC
rdax   s, -1.0
mulx   freq
rdax   c, 1.0
wrax   c, 0  
That gives at least info that s is sinus, c cos, I wasn't aware at the beginning what those registers represents.
Thanks for the link, although it doesnt look very 'friendly' :) I will try to understand it, wish me luck.
Last edited by pudlll on Fri Feb 27, 2015 7:25 am, edited 2 times in total.
Digital Larry
Posts: 338
Joined: Mon Nov 12, 2012 1:12 pm
Contact:

Post by Digital Larry »

I think the key is in this statement, although mapping that to the Spin implementation might require some interpretation:
Vieta’s formula allow’s one to recursively
find subsequent values of cos() and sin()
just by using the last two values and a
multiplicative factor. E.g.,

Next = 2cos( p)⋅Current − Last
frank
Posts: 1244
Joined: Wed Oct 19, 2005 12:26 pm
Contact:

Post by frank »

It is not Vieta’s formula, it is doing:

sin = sin + freq*cos
cos = cos - freq*sin

'freq' is the frequency coefficient.

The multiply by 1.99 at the end is not part of the resonator equation, it is just scaling up the result before it hits the amp multiplication.
Frank Thomson
Experimental Noize
pudlll
Posts: 3
Joined: Wed Dec 17, 2014 7:32 am

Post by pudlll »

Yeah, this is so called Magic Cyrcle Generator, right? Now I get it, I mean after putting this equations to excell I see exactly how it works, mathematical ground of it is still a bit abstract for me. Interesting is that those equation need to be calculated exactly in this order for proper work. I mean if we assume that we have some s(n) and c(n), we do equations at the same time, so like this:

s(n+1) = s(n) + freq*c(n)
c(n+1) = c(n) - freq*s(n)

it won't work correctly, values will grow to infinity. They need to be done like that:

s(n+1) = s(n) + freq*c(n)
c(n+1) = c(n) - freq*s(n+1)

Whoever figured it out at first place was a very clever person :)
frank
Posts: 1244
Joined: Wed Oct 19, 2005 12:26 pm
Contact:

Post by frank »

I once found an explanation of how it was derived many years ago but can no longer find it. If I recall correctly it was based on the trig identities:
sin(a + b) = sin(a)cos(b) + cos(a)sin(b)
cos(a + b) = cos(a)cos(b) – sin(a)sin(b)

It assumed cos(b) is about 1 (meaning b is very close to 0) then we can simplify to:

sin(a + b) = sin(a) + cos(a)sin(b)
cos(a + b) = cos(a) – sin(a)sin(b)

There was more in the explanation and will look to see if I can find it.

[added later]
Since b is very small we can say sin(b) = b (small angle approximation method) so we replace sin(b) with b giving:

sin(a + b) = sin(a) + cos(a)*b
cos(a + b) = cos(a) – sin(a)*b

So for small increments like in an LFO this works well. 'b' is the frequency control coefficient and gives nice waves without look up tables or using something like Taylor series.
Frank Thomson
Experimental Noize
amz-fx
Posts: 38
Joined: Wed Sep 06, 2006 7:06 am
Location: Louisiana, USA
Contact:

Post by amz-fx »

sin(a + b) = sin(a) + cos(a)*b
This works very well, except the output of the calculation exceeds +/- 1.0 so it has to be scaled down once the calculation is made.

A value of 0.577 for b is close to 45 degrees phase shift for the sine wave once it is scaled to the range. A 0.258 value of b is 22.5 degrees once scaled.

You just multiply the result of the calculation by a constant (usually in the range of 0.89 to 0.97) to scale down the result. Since it is slightly different for every value of b, it's best to work it out with a spreadsheet... or you can just use 0.8944 as the scaling constant and that will be good for shifts from 0 to 45 degrees though the lower degree shifts will not be full scale. Or, just clip the LFO value at +/- 1.0 and get slightly flat tops to the waves, which probably would not be noticeable since the amount that it goes over 1.0 is small.

The best part about it is that it can be done with the limited instruction set of the FV-1, and it is simple to implement.

Best regards, Jack
frank
Posts: 1244
Joined: Wed Oct 19, 2005 12:26 pm
Contact:

Post by frank »

Values like 0.577 and 0.258 are very large and really too big to use in this equation. Keep in mind that one of the assumptions is that sin(b)=b so we are talking only a very small increment each sample period.

At a 32.768KHz sample rate an LFO at 20Hz only increments by 0.2197 degrees each sample period which is 0.003835 radians and sin(0.003835) is 0.003835

For 45 degrees, that is 0.7854 radians and sin(0.7854) is 0.7071 so more than a 10% difference between b and sin(b).
Frank Thomson
Experimental Noize
amz-fx
Posts: 38
Joined: Wed Sep 06, 2006 7:06 am
Location: Louisiana, USA
Contact:

Post by amz-fx »

I read that in your previous post and started with a low value but it did not do the job.

I put the numbers in a spreadsheet and calculated the values then plotted the results. I'll take a look at your examples and see how they fit - maybe I missed a calculation or something.

Thanks, Jack
Post Reply