SawDPW super-efficient sawtooth oscillator with low aliasing
SawDPW.ar(freq, iphase, mul, add)
A sawtooth oscillator using the "Differentiated Parabolic Wave" technique, which suppresses aliasing at a wide range of frequencies, yet is about 3 times as CPU-efficient as SuperCollider's Saw ugen.
freq - frequency in Hertz
iphase - initial phase offset, a value ranging from -1 to 1.
It doesn't guarantee to be alias-free but sounds very good for most applications: e.g. at 44.1 kHz sample rate, aliasing can only be heard if the frequency goes over around 4 kHz. The technique is documented in Välimäki (2005) Signal Processing Letters 12(3) pages 214-217.
See also: PulseDPW
Server.default = s = Server.internal;
s.boot
s.scope
// Amplitude will be polled, move mouse to change frequency
{var x; x = SawDPW.ar(MouseX.kr(50, 2000, 1));Amplitude.ar(x, 0.2, 0.2).poll; x.madd(0.1).dup}.play
{var x; x = SawDPW.ar(K2A.ar(MouseX.kr(50, 2000, 1)));Amplitude.ar(x, 0.2, 0.2).poll; x.madd(0.1).dup}.play
// Listen to these to compare aliasing characteristics
{var x; x = SawDPW.ar(MouseX.kr(50, 10000, 1).poll); x.madd(0.1).dup}.play
{var x; x = Saw .ar(MouseX.kr(50, 10000, 1).poll); x.madd(0.1).dup}.play
{var x; x = LFSaw .ar(MouseX.kr(50, 10000, 1).poll); x.madd(0.1).dup}.play
{var x; x = [SawDPW, Saw].collect(_.ar(K2A.ar(MouseX.kr(10, 20000, 1).poll))); Amplitude.ar(x[0], 0.2, 0.2).poll; x.madd(0.1)}.play
// Efficiency comparisons:
~num = 100;
// scsynth on PPC Mac G4, idle around 2.1% CPU
// k-rate freq inputs
{Saw .ar({exprand(50, 1000)}.dup(~num)).mean.dup}.play // 30.7% CPU
{SawDPW.ar({exprand(50, 1000)}.dup(~num)).mean.dup}.play // 12.4% CPU
{LFSaw .ar({exprand(50, 1000)}.dup(~num)).mean.dup}.play // 7.0% CPU