Is it possible to sort the output values of Ugen arrays by output value?

We can let sclang sort an array:

(
a = (0..10).scramble; 
a.sort
)
(
a = (0..10).scramble;
a.sort.reverse
)

Could we do the same with the output value of Ugens?

(
{
	a = DC.ar((-1, -0.8 .. 1).scramble);
	a.poll(0)
}.play
)
(
{ 
	a = DC.ar((-1, -0.8 .. 1).scramble);
	a.sort.poll(0) // .sort is not accepted. 
}.play
)
(
{ 
	a = DC.ar((-1, -0.8 .. 1).scramble.sort);// .sort is accepted here, but that is not what I mean!
	a.poll(0)
}.play
)

This may be a ridiculous question, but if there’s an ingenious way, I’d love to hear it!

1 Like

You should be able to sort control rate signals by writing them into a buffer, then sorting that. I don’t think there is a good Ugen to do this sorting in the SCClass library, but there must be one out there somewhere. Perhaps Flucoma has one?

Sorting audio rate signals (at audio rate) is complex though (if you only want to sort by the first sample it is the same as control rate), because you needs to fake having a block size of one. I know mis_lib has some things to do this, I think it would be possible to make a sorter out of that… but it would not be easy, nor fast to run.

But this raises a question, what does it mean for one audio signal to be less than another? Sorting by high frequency content or amplitude would often make more sense, all of which are control rate signals.

1 Like

Thank you for your kind explanation! I had the need to sort the array of Ugen by there output values while answering a question in the following post:

The following line contains array of Ugens:

relTimes = num.collect { |i| Rand(1, 5.0 * (i + 1) / num) }

To get a sorted result, I could do something like this:

relTimes = (num..1).collect { |i| Rand(5.4 - (i / num), 4.6) * i / num + 0.5}.poll(0);

However, as you pointed out, it is difficult to find a real sort using the native sc libraries.

I think this way could be theoretically possible, but not within a SynthDef…

Using ArrayMax from the scplugins, I could see the maximum value and the index of the UGen in the array that outputs the maximum value. However, the index is not an integer but an OutputProxy. So it is not possible to sort an UGen array in a Synth. Using SendReply and OSCFunc (or OSCdef) seems to be the only way at the moment, but there is no benefit to doing so.

I think it would be very handy if there was a converter that would convert the current output value of a Ugen to a float or integer. Max has such functionality: snapshot~ and the right output of number~. Maybe in SC4?

(
{
	var array, findMaximum, sortedArray = [];
	array = (4..1).collect { |i| Rand(1, 5) };
	array.poll(0);
	findMaximum = { |array|
		var maxIndex = ArrayMax.kr(array)[1];
		maxIndex.class.postln;
		sortedArray.add(array[maxIndex]);
		//Array.removeAt(maxIndex);
	};
	array.size.do { findMaximum.(array) }
//sortedArray.poll(0)
}.play
)
OutputProxy
ERROR: Primitive '_BasicAt' failed.
Index not an Integer
RECEIVER:
Instance of Array {    (0x159ebbde8, gc=20, fmt=01, flg=00, set=02)
  indexed slots [4]
      0 : instance of Rand (0x159ade598, size=8, set=3)
      1 : instance of Rand (0x118751868, size=8, set=3)
      2 : instance of Rand (0x2834e3d18, size=8, set=3)
      3 : instance of Rand (0x159d54e28, size=8, set=3)
}

You need to use select to index into the array.

I believe snapshot is like sending the value to the language then back to the server.

1 Like

Not possible, there are only ugens on the server. Numbers are converted to ugens when the synthdef sends them to the server (simplification), these numbers are immutable and cannot change.

1 Like

Select is used to select a ugen (or a ugen with an adjacent ugen or ugens) from an ugen array. Currently I am trying to find a way to sort the ugen indices by their output values, for example: Rand. In this case I could not find a way to use Select to sort the array by the output value of the ugens.

Sorting the array of ugens is basically impossible as far as I know. Strangely enough, I think it would be good if the functionality I learned to be impossible was possible in SC. I do not know why my thoughts tend in this direction.

Ah, you are correct! I missed it…

Thanks for the clarification!