Code: Select all
//init
if (sides < 2.f) sides = 2.f;
angle = tau / sides;
s0 = 1; s1 = 0;
//loop
p0 += wc * sides * 0.159154943f; //1/tau
while (p0 >= 1.f) p0 -= 1.f;
// 1: "complex" oscillator (go in circle) 2d rotation matrix
t = s0;
s0 = s0 * w0 + s1 * w1;
s1 = s1 * w0 - t * w1;
// 2: determine magnitude of polygon side at current rotation
float t0 = p0 * angle; // angle of phase through side
float t1 = .5f * (pi - angle); // other known angle in triangle
t = pi - t1 - t0; // angle opposite radius/side we are stepping from
t = sin(t1) / sin(t); // law of sines
oscillator = t * s0;
here's the referenced form locked to one cycle..
Code: Select all
float t0 = p * sides; t0 = fmod(t0, 1.f);
t = pi / t;
t = cos(t) / cos((t + t) * t0 - t);
p += wc; while (p >= 1.f) p -= 1.f;
*out1 = t * sin(p0 * tau);
not able to suss it myself, but made this fudgy thing which seems to drop aliasing bands alright for a 1 sample delay,
Code: Select all
float mess = wc * sides * 0.159154943f;
t0 = 0;
if (p0 + mess >= 1.f) {
t0 = 1.f - (1.f - p0) / mess;
t0 = (b0 - trivialosc - b1) * t0 * .5f;
}
else if (p0 < mess) {
t0 = 1.f - p0 / mess;
t0 = (b0 - trivialosc - b1) * t0 * .5f;
}
out = b0 + t0;
b1 = b0 - trivialosc; b0 = trivialosc;