Efficient sine oscillator

DSP, Plugin and Host development discussion.
RELATED
PRODUCTS

Post

(for topic completists.. dattorro's paper from ccrma in the 90's
https://ccrma.stanford.edu/~dattorro/Ef ... nPart3.pdf
you come and go, you come and go. amitabha neither a follower nor a leader be tagore "where roads are made i lose my way" where there is certainty, consideration is absent.

Post

Thanks for the link, I've read other parts of Dattorro's 3 papers, they are all very useful, but I missed the sin oscillator part. I love this quote (which applies to the method mystran and I have both posted about):

"The coupled form is a state-space digital filter structure
and is one of the foremost contributions of the branch of
linear systems theory known as state-variable analysis.

The coupled form has many attributes, including low trun-
cation noise and low coefficient sensitivity, respectively
due to signal and coefficient quantization within a finite-
precision machine"

It is odd that for a sin oscillator it was considered ok to use state space analysis, but when doing a digital svf it was not, since they are basically the same thing. I think it was that a division was considered too computationally expensive a while ago, even when efficient approximations are possible.

Here are all the parts:

Part 1: Reverberator and Other Filters https://ccrma.stanford.edu/~dattorro/Ef ... nPart1.pdf
Part 2: Delay-Line Modulation and Chorus https://ccrma.stanford.edu/~dattorro/Ef ... nPart2.pdf
Part 3: Oscillators: Sinusoidal and Pseudonoise Part 3 https://ccrma.stanford.edu/~dattorro/Ef ... nPart3.pdf
The Glue, The Drop - www.cytomic.com

Post

i don't get far beyond angular frequency so i'm in the dark about much of the exchange, but developing mass-springs gave me an appreciation of it and some fascination for it's origin (no one seems to know further than it's use at ccrma?). i have used it as a filter, i found oversampling was required for the audio range but the skirt (inferior rejection compared to other 6dB BP) seems very much more like some simple analog circuits.

i expect a wide appreciation of this gem will lead to further innovations and insight, or at least i'm being enthusiastic about something i've utilised :hihi:
you come and go, you come and go. amitabha neither a follower nor a leader be tagore "where roads are made i lose my way" where there is certainty, consideration is absent.

Post

Is this legit?

For frequency modulation, couldn't you create a complex fm bank of varying degrees of rotations to apply to a complex generator.

So you'd have a generator as such:

Code: Select all

// initialising
fs = samplePeriod
fq = frequency
complexGenerator = Complex(sin(2 * pi * fs / fq), cos(2 * pi * fs / fq))
complexOutput = Complex(0, 1)

// Applying frequency modulation
// frequencyModulationTable represents a class that manages frequency modulation generators for a set of FM frequencies
complexFmGenerator = complexGenerator * frequencyModulationTable.get(fq, currentFm.real)

// Calculating output
complexOutput = complexOutput * complexFmGenerator // this could also be complexGenerator when fm is not being used.
outputValue = complexOutput.real
Also I was thinking that it might be worth partitioning frequencies and rendering lower frequencies at lower samplerates, then upsampling. Thoughts?

Post

In fact complex lookup tables can easily be modulated as you are only calculating the rotation to produce the next sample of the sine wave.

Also on second thoughts you need not multiply the complexGenerator by a fm table but instead simply calculate the desired frequency (after modulation) and use lookup tables to find the complex value to multiply the complexOutput by, generating a lovely frequency modulated output. The fm value would naturally also need to be modulated (likely using the exact same table ;) ), but all in all each uses just 4 multiplies for each oscillator (that's under half the cost of calling sin, not accounting for page faults).

I've used this method for synchronising ifft synthesis and it syncs perfectly, .. for some reason I never thought about using it for sine oscillation :/

Edit: though on second thoughts I think that sine lookup still looks best, ... need to work out the maths on that, and I'd also imagine you may want to add an extra approximation step with complex fm (adding 4 more multiplies).

Post

AUTO-ADMIN: Non-MP3, WAV, OGG, SoundCloud, YouTube, Vimeo, Twitter and Facebook links in this post have been protected automatically. Once the member reaches 5 posts the links will function as normal.
andy-cytomic wrote:

Code: Select all (#)

init:
g = tan(pi*cutoff/samplerate);
g0 = 2/(1 + g*g);
g1 = g*g0;
loop:
const v1 = g0*ic1eq - g1*ic2eq;
const v2 = g1*ic1eq + g0*ic2eq;
ic1eq = v1 - ic1eq;
ic2eq = v2 - ic2eq;
Hi Andy
Thanks for sharing this code and for the helpful explanations in this thread. Is this code (rather than the modified coupled form) a better candidate for FM synthesis? I'm also wondering how this compares to just using a wavetable based oscillator when building an FM synth.
Thanks for your thoughts,
B

Post

It depends on the target architecture. The above code requires double precision, so implement it and time it against whichever method you are trying to beat! The version Mystran posted may be better, it will require more ops to compute coefficients but then may run ok with single precision, so with SSE you would get 4 oscillators instead of 2 with my version.
The Glue, The Drop - www.cytomic.com

Post Reply

Return to “DSP and Plugin Development”