Mulling this over for a couple days: I wondered why we didn’t have a bandlimited VarSaw.
Then I realized: The current VarSaw isn’t implemented this way, but it’s really the integral of a non-bandlimited pulse wave (with variable pulse width) – if you remove DC so that the pulse wave is balanced around 0, then the integral should be stable, rising and falling in straight lines (with different up-vs-down times).
So, swap out the non-bandlimited pulse for a bandlimited Pulse
and control amplitudes, and… there it is.
(
a = {
var amp = 0.6;
var freq = MouseY.kr(200, 6000, 1);
var pulseWidth = SinOsc.kr(0.5).range(0.01, 0.99);
var pulse = Pulse.ar(freq, pulseWidth);
var varsaw = Integrator.ar(pulse);
// area under positive lobe of Pulse should be
// pulseWidth * (1 - pulseWidth).
// Integrator amp should be proportional to this.
// Maximum value is 0.5 * (1 - 0.5) == 0.25
var ampComp = 0.25 / (pulseWidth * (1 - pulseWidth));
// also the integral will be inversely proportional to frequency
var freqComp = freq / SampleRate.ir;
var sig = varsaw * ampComp * amp * freqComp;
// DC offset is quite nasty with this
// even LeakDC doesn't control it as well as I'd like
// Set the HPF frequency even higher for more stability
HPF.ar(HPF.ar(sig, 30), 30).dup
}.play;
)
hjh