About Integrator

Hi, this is more of a theoretical question.

What is “Integrator” usually used for?

Tell me if I’m wrong. As I see it, a Leaky Integrator is like a one pole lowpass filter and the actual formula should be

y[n] = α * x[n] + (1 - α) * y[n-1]

But in SC’s doc we get
out(0) = in(0) + (coef * out(-1))

By the way, this is the same as a [rpole~] object in Pd. I’m just a little confused.

Also, AI is telling me that naming it a leaky integrator depends on the usage/function. If we have sub-audible frequencies and using it to smooth a signal, instead of filtering audio at audible frequency. Is that right?

thanks folks

It’s like integration in calculus: a running sum. (Tbh, I’ve never used Integrator with coef < 1.0.)

See also LeakDC.

hjh

A nice application, I find, is the shift from PlayBuf to BufRd. In essence, phase is the integration of rate, and rate is the derivative of phase.

It’s not interchangeable: a jumping phase has no unique slope at the points of discontinuity – you could argue that, therefore, PlayBuf needs a startPos arg to achieve something similar.

// SC standard soundfile #1

(
p = Platform.resourceDir +/+ "sounds/a11wlk01-44_1.aiff";
b = Buffer.read(s, p);
)


// Exchange of BufRd and PlayBuf

// scratching between buffer indices 2000 and 4000

{ BufRd.ar(1, b, SinOsc.ar(3, 0, 1000, 3000)) }.plot(0.1);

// equivalent: PlayBuf, needs slope/rate (deviation of index change)
// rate in seconds, thus divide by sample rate

{ PlayBuf.ar(1, b, Slope.ar(SinOsc.ar(3, 0, 1000)) / SampleRate.ir, 1, 3000, 1) }.plot(0.1)


// vice versa: rate oscillation given

{ PlayBuf.ar(1, b, SinOsc.ar(10, 0, 0.2), 1, 1000, 1) }.plot(0.1)


// equivalent: Integrator sums up all samples, no need to regard sample rate

{ BufRd.ar(1, b, Integrator.ar(SinOsc.ar(10, 0, 0.2)) + 1000) }.plot(0.1);






1 Like

Integrator is also really useful for machine listening applications - e.g. use it to analyze your signals and generate triggers if a certain threshold is reached after some time (e.g. if there has been no low frequencies for e.g. 10s)

It is also possible to use it for waveshaping applications

(
Ndef(\x, {
	var sig = Integrator.ar(
		in: SinOsc.ar([pi, \baseSpread.kr(1.0)] * \baseMul.kr(20)),
		coef: VarSaw.ar(
			\modFreq.kr(10.0) * [1.0, \spread.kr(pi/2)],
			width: \width.kr(0.5),
		).abs,
	)/50;
	LeakDC.ar(sig.tanh);
}).play.gui;
Ndef(\x).scope;
)

Ndef(\x).clear;
1 Like

Thanks, what about this?

" AI is telling me that naming it a leaky integrator depends on the usage/function. If we have sub-audible frequencies and using it to smooth a signal, instead of filtering audio at audible frequency. Is that right?"

any word?

That is great fun, this little code snippet packs such a punch, I had never thought of using Integrator like that myself, thanks for sharing.

I guess… I don’t really feel qualified to say what is the correct name for it. I don’t think we’re going to change the name.

I’ve only ever used Integrator (and rpole~) as a signal-rate accumulator so the name doesn’t bother me.

In SC, if this or that filter with a specific name doesn’t serve a particular purpose, one can always revert to FOS and SOS for first- and second-order filters respectively. y[n] = α * x[n] + (1 - α) * y[n-1] would be FOS.ar(in, alpha, 0, 1 - alpha). I think JMc provided special-case filters like Integrator because back in the day, the CPU cost of multiplying by zero in FOS was worse than the maintenance weight of more filters. That’s really not much of a concern now.

hjh

The one-pole filter formula y[n] = α * x[n] + (1 - α) * y[n-1] acts like a “leaky integrator.”
It calculates a weighted average of the current input and the previous output sample.

This function accumulates input values over time, similar to integration, but with an important difference: it has a control parameter α (the filter coefficient) typically with a value less than 1 for a stable filter. If you multiply something by less then 1 it gets smaller.

For every sample, the current input signal is multiplied by α and added to the prior output value multiplied by (1 - α). Since (1 - α) is less than 1, the already accumulated values gradually decay over time. The current input is scaled by α to maintain the proper weighted average.

This makes it a “leaky” integrator - unlike a perfect integrator that accumulates values indefinitely, the leaky integrator loses “energy” over time. The filter coefficient α controls the leakiness (smaller α means less leakiness (slower decay), larger α means more leakiness (faster decay)).