Pfunc case { Pseq((0..5),inf).asStream.next} HOW TO?

Hello everyone,

I’m trying to use a simple Pseq((0…5),inf).asStream.next ,because I would love to receive back the values 0,1,2,3,4,5 over and over inside a Pfunc with a case structure, but I receive only zeros.
How to keep the pseq counting correctly?

I found this solution, but … it’s ugly.
I would love to use the list patterns without limitations.

~o = 0;
(
 Pbindef(\ampAnalysis,
    \instrument, \DcOuts,
    \amp, Pseq(~amp,inf), //  my ~amp array
    \bus,
Pfunc {  |d|
	case
		{ d[\amp] > 0.9 }{ (0..5) }
		{ d[\amp] < 0.5 }{ ~o = ((~o + 1)%6); } // THIS IS MY UGLY SOLUTION
		{ d[\amp] > 0.5 &&   d[\amp] < 0.9 }{ Prand([0,1,2,3,4,5],inf).asStream.next; } // works
	}
  ).play;
)

or in this way …

~o = 0;
(
 Pbindef(\ampAnalysis,
    \instrument, \DcOuts,
    \amp, Pseq(~amp,inf), //  my ~amp array
    \bus,
Pfunc {  |d|
	case
		{ d[\amp] > 0.9 }{ (0..5) }

		{ d[\amp] < 0.5 }{  ~o = ((~o + 1)%6); // A kind of solution..
		Pseq([0,1,2,3,4,5]., inf,~o).asStream.next.postln;} 

    	{ d[\amp] > 0.5 &&   d[\amp] < 0.9 }{ Prand([0,1,2,3,4,5],inf).asStream.next; } // works
    	}
      ).play;
    )

Do you think it’s possible ?

Thank you very much for all the help!

If I get it correctly, you want to have a stream that counts only when you match your case ( amp < 0.5).
The problem with creating the Pseq, or calling .asStream, in the Pfunc is that you get a new stream every time, and that’s why you get only zeros. So, a quick fix would be putting the stream (and not the Pseq) in ~o:

~o = Pseq((0..5),inf).asStream;
(
 Pbindef(\ampAnalysis,
    \instrument, \DcOuts,
    \amp, Pwhite(0.0,1.0,inf), // for testing
    \bus, Pfunc {  |d|
        case
        { d[\amp] > 0.9 }{ (0..5) }
        { d[\amp] < 0.5 }{ ~o.next }
        { d[\amp] > 0.5 &&   d[\amp] < 0.9 }{ Prand([0,1,2,3,4,5],inf).asStream.next; }
	}
  ).trace.play;
)

A more “idiomatic” solution would be IMO an extra key with Pclutch:

(
 Pbindef(\ampAnalysis,
    \instrument, \DcOuts,
    \amp, Pwhite(0.0,1.0,inf), // for testing
    \counter, Pclutch(Pseq((0..5),inf),Pkey(\amp) < 0.5),
    \bus, Pfunc {  |d|
        case
        { d[\amp] > 0.9 }{ (0..5) }
        { d[\amp] < 0.5 }{ d[\counter] }
        { d[\amp] > 0.5 &&   d[\amp] < 0.9 }{ Prand([0,1,2,3,4,5],inf).asStream.next; }
	}
  ).trace.play;
)

Pclutch polls from Pseq only when the condition is true (amp < 0.5). The extra key (\counter) is not sent to your instrument (unless your instrument has a \counter argument, in which case you would just select a different name for the extra key).

We can even get crazy idiomatic (and with no extra key) with Pswitch1:

 Pbindef(\ampAnalysis,
    \instrument, \DcOuts,
    \amp, Pwhite(0.0,1.0,inf), // for testing
    \bus, Pswitch1 ([
        Pseq((0..5),inf), // amp < 0.5
        Prand([0,1,2,3,4,5],inf), // 0.5 <= amp < 0.9 
        (0..5) // 0.9 <= amp < inf
    ],
    // find first thr for which amp < thr
    Pfunc{|d| [0.5,0.9,inf].detectIndex{|thr|d.amp<thr}}
    )
  ).trace.play;
2 Likes

Or just

~o = (:0..5).repeat;
2 Likes

also

~o = (:..5).loop;

:slight_smile:

but ok, in a patch I’d also probably prefer Pseq

1 Like

Ah, one of those cheeky things:

Stream.findRespondingMethodFor(\loop) // -> Object:loop

repeat is defined in Stream itself.

Unlike repeat I see loop doesn’t take a customizable count

	loop { ^this.repeat(inf) }