Hi Mario.
We had a discussion about this on the chuck-dev a couple of years ago, when I created the Wavetable Chugin. I've copied below a very interesting comment from Perry Cook. To my surprise, on modern architectures, RT trig isn't really any more expensive than table lookup. I tested the Wavetable chugin vs SinOsc and found no significant difference in performance.
I still think a wavetable UGen would be a good addition to ChucK (maybe adapted from my Chugin) but it seems that, unless someone were able to create some additional optimizations, it wouldn't be any more efficient than the existing SinOsc.
Joel
-------------------
Forwarded message from Perry Cook below:
Hey all,
Chiming in on the various Sine-related topics here. SinOsc was designed like most of ChucK, to do things from the definition, without particular regard for efficiencies. In fact, a native Math.sin(BLAH) call isn’t that hideous. It used to be in the olden days, and we avoided it like the plague. The Motorola DSP 56000 had a built in quarter-wave of sine in ROM. (It also had an 8-bit muLaw decoding table built in as well). Many papers (Snell, Others) were written about the optimal length, bit-depth, etc of a sine table given different types of interpolation. Yamaha chips stored sine quads in both linear (for addition) and log (for multiplication) ROM, or hard-coded into gates for the absolute minimum expense.
Wavetables:
Indeed, SndBuf is ChucK’s built-in wavetable (in .loop mode). And, it could be a little cheaper, and it has built-in linear interpolation. If you want less distortion, just make your table longer. The “table” here is a .wav file you create and load. All you need add is an accessing function to set rate as a function of frequency.
And you could also add FM, PM, and other .sync-like functions as well. By this time, it might be worth comparing to SinOsc efficiency for FM and other audio- rate modulation tho. I just did a quick check and find SndBuf to be about equal to SinOsc (the number I can run before audio starts breaking up, just over 400).
See code below.
Note also that there are some other wavetable-like UGens already in the GenX family in ChucK. I don’t know about the relative efficiency of those, and I do know that that you need to drive (some of) them with a Phasor. So again, it might not end up being significantly cheaper.
On unit-circle sine generation: Spencer has already given us a great ChuGen called MagicSine, that does the rotation-based sine generation using only a couple of multiplies and adds. It’s most efficient if you’re not changing frequency rapidly.
Julius and I also did a “waveguide resonator” oscillator (similar to Magic Sine), but it also had built in exponential envelope (phasor that spins outward or inward), and allowed for modulation of the parameters for FM-like wave distortion. Not particularly efficient if you just want a sine wave. I have a ChuGen for that too, but never released it.
So the topic "many ways to skin a sine" is still active today!!
My comparison codes (in terminal, miniAudicle may vary, also Audio BUFSIZE might help):
/* SinOscCompare.ck ***************************************/
SinOsc s[1000];
Gain outMix => dac;
for (int i; i < 4000; i++) {
if (i%100 == 0) <<< "Sines", i+1 >>>; // this could be costing us some
s[i] => outMix;
Math.random2f(100,3000) => s[i].freq; // as would this
1.0/(i+1.0) => outMix.gain; // and this
10*ms => now; // but if those dominated, we’d probably hear 100 Hz distortion
}
/* SndBufCompare.ck ***************************************/
SndBuf s[1000];
Gain outMix => dac;
for (int i; i < 4000; i++) {
if (i%100 == 0) <<< "SndBufs", i+1 >>>; // this could be costing us some
"special:dope" => s[i].read; // maybe this too, but cacheing should help
1 => s[i].loop;
s[i] => outMix;
Math.random2f(0.2,5.0) => s[i].rate; // as would this
1.0/(i+1.0) => outMix.gain; // and this
10*ms => now; // but if those dominated, we’d probably hear 100 Hz distortion
}
_______________________________________________
chuck-dev mailing list
Sent from
Mailspring, the best free email app for work
Hi,
As already pointed out by someone else here, I noticed we've got the SinOsc UGen that doesn't use a wavetable but instead uses the sin function. I don't know what the reason behind this decision, but I was wondering whether it would be possible to also have a variant that uses wavetable as well. I presume that would help a bit in terms of performances, and I think it would be useful in scenarios where ChucK runs on platforms like Raspberry Pi.
cheers,
_______________________________________________
chuck-users mailing list
_______________________________________________
chuck-users mailing list
chuck-users@lists.cs.princeton.edu
https://lists.cs.princeton.edu/mailman/listinfo/chuck-users