The key parts of this presentation are between 20 and 25 minutes – in short, handling the phase increment of a sinusoidal oscillator by complex multiplication by a vector (faster than repeated sin
or cos
calls).
(
var point = Complex(0.9, 0);
// let's do a hundred steps per cycle
var phaseIncrement = 2pi / 100;
var vector = Complex(cos(phaseIncrement), sin(phaseIncrement));
var color = Color(0.5, 0.5, 1);
u = UserView(nil, Rect(800, 200, 400, 400)).front;
u.drawFunc = { |view|
var b = view.bounds.moveTo(0, 0);
var center = b.center;
Pen.color_(color)
.fillOval(Rect.aboutPoint(
Point(
(point.real + 1) * center.x,
(1 - point.imag) * center.y
),
10, 10
));
};
r = {
loop {
u.refresh;
point = point * vector; // no sin / cos here!
0.05.wait;
}
}.fork(AppClock);
u.onClose = { r.stop };
)
The algorithm would not be difficult to implement in C++. SC’s plug-in interface even includes complex-number operators already. And the cookiecutter template makes it straightforward to release for multiple platforms.
Edit: Of course, minutes after posting, then some details come to mind.
I’m not sure if a complex-multiply approach would be faster or slower than SinOsc’s lookup table approach. The presentation suggests that multiply-add is highly optimized in modern CPUs (+1 for complex multiply) and that removing a conditional to wrap the phase back around would also improve compiler optimization (+1), but the performance killer in the presentation’s native sine oscillator is the sin() function. SC uses a lookup instead. I can’t predict which would be faster or slower.
Modulating frequency would require updating the vector, requiring a cos and a sin. I didn’t watch through the whole thing to see how they handle that. Lookup would help but now that I think about it, continuously changing frequencies could be slower with complex multiply.
So maybe I was a bit hasty there. In any case, the real killer with DynKlang is that the multiply-adds are done in separate UGens – the function call overhead really adds up when you have a couple hundred partials. So a modulatable single-UGen Klang would help a lot.
hjh