Testing for multi-channel out of bounds (or: how to get the maximum value of a multi-channel UGen output?)

Hey ya’ll,
I’m making an out-of-bounds test on a UGen output that I want to monitor via SendReply.
Something like this:

{
	var minValue = -1.0;
	var maxValue = 1.0;
	var somesig = Saw.ar!2 * Line.ar(0.1, 3.0, 10); // eventually goes out of bounds
	var t_reset = Impulse.ar(0.05);
	var min = RunningMin.ar(somesig, t_reset);
	var max = RunningMax.ar(somesig, t_reset);
	var outofbounds = (min < minValue) + (max > maxValue);
	if(outofbounds.size > 1) { outofbounds = outofbounds.max };
	SendReply.ar(outofbounds, '/oob', [somesig]);
	Select.ar(somesig.abs > 1.0, [Limiter.ar(somesig), somesig]) * 0.001;
}.play;

OSCdef(\oob, {|msg| msg.postln }, '/oob');

The problem I’m running into is that this code sends two SendReply messages when the out-of-bounds condition is detected… my hunch is that this is happening because the outofbounds trigger is multi-channel expanding into two SendReply UGens.

What I’d like is to take the maximum of all channels coming out of the outofbounds test (i.e. if any channel is outofbounds, then the value of outofbounds will be 1)

My use of outofbounds.max unfortunately doesn’t seem to be doing the job :frowning:
Any thoughts? Thanks!

Is Collection>>inject what you want? (C.f. Magnitude>>max and Collection>>maxItem.)

I.e.

1.max(0) == 1;
1.max == 1;

[-1, 1, 0].maxItem == 1;
[-1, 1, 0].inject(-inf, { arg i, j; i.max(j) }) == 1;

{ SinOsc.ar(XLine.kr([100, 200], [400, 100], 2), 0) * 0.1 }.play;
{ SinOsc.ar(XLine.kr([100, 200], [400, 100], 2).inject(0, { arg i, j; i.max(j) }), 0) * 0.1 }.play;

1 Like

That did it, thanks! :slight_smile: