Bandlimited VarSaw

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

3 Likes