Efficient sine oscillator

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

Hi,
I wonder how to implement efficient sine oscillator?
Thanks :)

Post

wrl from #lad@freenode shared me this link https://gist.github.com/wrl/9913185

Post

Modified coupled form:

x = x - e*y;
y = e*x + y;

----
e= 2*sin(omega/2.0); // omega = 2*pi*freq/sr;

init phase x,y = cos, sin
giq

Post

Would that coupled form be long-term accurate enough to run an old-style additive synthesis oscillator bank? Assuming that the application does not demand that any of the frequencies be changed after all the oscillators are started up?

For instance, if running a 64 sine, 64 cosine harmonic oscillator bank-- Ideally after a few minutes or preferably even indefinitely, all the higher harmonic sin oscillators would cross zero at the same time that the harmonic 1 sin oscillator crosses zero, and all the higher cos oscillators would cross zero at the same time that the harmonic 1 cos oscillator crosses zero.

Post

itoa wrote:Modified coupled form:

x = x - e*y;
y = e*x + y;

----
e= 2*sin(omega/2.0); // omega = 2*pi*freq/sr;

init phase x,y = cos, sin
This is very impressive, I need to setup some tests :)

Post

JCJR wrote: For instance, if running a 64 sine, 64 cosine harmonic oscillator bank-- Ideally after a few minutes or preferably even indefinitely, all the higher harmonic sin oscillators would cross zero at the same time that the harmonic 1 sin oscillator crosses zero, and all the higher cos oscillators would cross zero at the same time that the harmonic 1 cos oscillator crosses zero.
The moment you actually calculate the coefficient (the sine for it) you're already rounding it to some fixed precision, so you can't even accurately represent a perfectly harmonic oscillator bank with these (or pretty much any other recursive formula).

And worth noting: the modified couple form traces ellipsoids, not circles, so it's not really useful for quadrature pairs (unless you can live with an approximation). The deviation grows larger with increasing frequency. Also, if you initialize it with cos/sin pair (rather than just set x = 1), you'll end up with slightly different magnitudes of oscillation depending on frequency.

Post

mystran wrote: The moment you actually calculate the coefficient (the sine for it) you're already rounding it to some fixed precision, so you can't even accurately represent a perfectly harmonic oscillator bank with these (or pretty much any other recursive formula).

And worth noting: the modified couple form traces ellipsoids, not circles, so it's not really useful for quadrature pairs (unless you can live with an approximation). The deviation grows larger with increasing frequency. Also, if you initialize it with cos/sin pair (rather than just set x = 1), you'll end up with slightly different magnitudes of oscillation depending on frequency.
Thanks. Can't recall, need to look it up sometime, but read on musicdsp years ago, maybe from Nigel Redmon, of a form that works like a stripped down state variable filter in quadrature oscillation. Can't recall if the above coupled variant is the same as the "stripped down SVF" version, or something else.

One of these days I want to play with a harmonic oscillator bank, was just curious if there was a shortcut to table lookup. JOS says in one of his articles that before people started using phase vocoder-like techniques to avoid the oscillator bank, they used table lookup oscillator banks, and if anybody knows, it ought to be JOS. Was just curious if there is anything faster than table lookup that would stay in phase long-term.

Post

JCJR wrote:Would that coupled form be long-term accurate enough to run an old-style additive synthesis oscillator bank? Assuming that the application does not demand that any of the frequencies be changed after all the oscillators are started up?
That form is great for low frequencies (LFOs), but get progressively more asymmetrical as you move up—not good for an audio oscillator.

PS—And it craps out altogether...I think around one-third of the way to the Nyquist frequency, or thereabout. It's basically a Chamberlin state variable filter with the Q cranked.
My audio DSP blog: earlevel.com

Post

Thanks, Nigel!

Post

JCJR wrote:Thanks, Nigel!
You're welcome, and I'll add that a couple of things that make it really nice for an LFO is that the outputs (states) are in quadrature. Plus error cancel exactly, for both floating point and fixed point, so it can run forever with perfect stability—preset with 0 and the peak amplitude you want, and you have sine and cosine at that amplitude.

ref the latter half of this article:

http://www.earlevel.com/main/2003/03/02 ... le-filter/

(zat Jim? I think it is...Hi Jim!)
My audio DSP blog: earlevel.com

Post

Modified coupled form is the cheapest way... 3 variables per osc, easy coeff recalculation, it's a rocket especially on SIMD - e.g. you calculate blocks of 32/64 oscs without accessing memory!

Slight amp deviations with FM. I don't hear them :) Phase deviations are often desirable in musical context.

If you need more stable quadrature oscillator (for perfect sin/cos pairs) google for waveguide oscillator.
giq

Post

JCJR wrote:One of these days I want to play with a harmonic oscillator bank, was just curious if there was a shortcut to table lookup.
Once you have sin(ωt) and cos(ωt) for the fundamental frequency, You can generate all harmonics using trigonometric identities:

cos[(n+1)ωt] = cos(ωt)*cos((nωt) - sin(ωt)*sin(nωt)
sin[(n+1)ωt] = sin(ωt)*cos(nωt) + cos(ωt)*sin(nωt)

Pretty cheap and stable phase relationship guaranteed. :)

Post

JCJR wrote:
For instance, if running a 64 sine, 64 cosine harmonic oscillator bank-- Ideally after a few minutes or preferably even indefinitely, all the higher harmonic sin oscillators would cross zero at the same time that the harmonic 1 sin oscillator crosses zero, and all the higher cos oscillators would cross zero at the same time that the harmonic 1 cos oscillator crosses zero.
None of computed oscillators meet these criteria. But isn't the phase drift desired in most cases? Most of natural sounds are slightly inharmonic.
If you want to produce a perfect additive digital buzz, ifft is better.
giq

Post

Itoa, with your solution implementing FM requires an additional call to sin(). Do you have an other optimization? Thanks :)

Post

Unfortunately all recurrent models require coefs recalculation.. fortunately this needs only sin - not sin / cos pair.

Now it's time for some cheating :)
Depending on your needs: lets try to compute e only once for base tuning and then modulate it linearly (e+mod) or (e*(1+mod)) or use a rough cos(x) approximation (sin derivative).

For cheaper methods you may expect uneven partials detuning, slight amp variation. but.. our ears usually don't like mathematical correctness.
giq

Post Reply

Return to “DSP and Plugin Development”