# Psegs inside other Patterns

I’ve read through this thread and it doesn’t quite seem to be what I’m asking for, so…

I’m trying to get the values that a Pwhite or a Pseq is pulling to change over time. In the following code, I would like the Pwhite to be pulling values similar to Pwhite(0.01, 0.15) and for this to gradually progress to be Pwhite(1, 2) at the end.

Similarly, I can get the code to work if the pause after the series of notes is a constant number. But I’d like the pause to get longer over time - but for some reason Pseg([5, 9], 100) doesn’t seem to work.

Here’s my code:

~aFx = Bus.audio(s, 2);

(
SynthDef(\a, {
var env, sig;
var freq = \freq.kr(60);
var numPartials = \numPartials.kr(12);
env = Env.perc(\atk.kr(0.01), \rel.kr(0.4)).ar(Done.freeSelf);
sig = WhiteNoise.ar(1) * Env.perc(0.01, 0.01).ar;
sig = DynKlank.ar([
[Array.fill(12, { |i| i + 1 })],
[Array.fill(12, { |i| 1/(i+1) * Rand(0.2, 1.5) })],
[Array.fill(12, { Rand(0.5, 1) })]
],
sig,
freq,
0,
\rel.kr(0.4) / 2
);

sig = RLPF.ar(sig, 6000);
sig = sig.sum * env * \amp.kr(0.2);

sig = Pan2.ar(sig, \pan.kr(0));
Out.ar(\out.kr(0), sig);

SynthDef(\aFx, {
var sig, wet;
sig = In.ar(\in.kr(0), 2);
wet = sig;
wet = wet + (CombC.ar(sig, 5, 3) * 0.4);
wet = wet + (CombC.ar(sig, 2, 0.5) * 0.3);
wet = wet + (CombC.ar(sig, 2, 0.5) * 0.2);
wet = wet + (CombC.ar(sig, 2, 0.5) * 0.1);
wet = wet + NHHall.ar(wet);
sig = XFade2.ar(sig, wet, \mix.kr(0.5).linlin(0, 1, -1, 1));
Out.ar(\out.kr(0), sig);
)

(
~numNotes = 15;
~length = 100;
t = Tuning.just;
x.free;

Routine {

s.sync;
x = Synth.tail(nil, \aFx, [in: ~aFx, mix: 0.2]);

Pdef(\a,
Pbind(
\instrument, \a,
\dur, Pseq([
Pwhite(
Pseg([0.01, 1], ~length, \sine),
Pseg([0.15, 2], ~length, \sine),
~numNotes - 1
),
5],
inf
),
\scale, Scale.majorPentatonic(t),
\degree, Pxrand((0..9), inf),
\root, Pstutter(~numNotes, Pseq([0, 3, 7, 10, 2, 5, 9], inf)),
\atk, 0.2,
\rel, Pseg([5, 15], ~length, \sine),
\octave, Pstutter(7, Pseq([3, 4, 5], inf)),
\amp, Pwhite(0.8, 1) * 0.2,
\pan, Pseg([0.75, -0.75, 0.75], [45, 45], \sine, inf),
\out, ~aFx
)
).play;

}.play;
)


As often occurs with Patterns, I’m unsure if this is a very basic problem, or something requiring deeper understanding - so very happy for any help!

Cheers,
Jordan

Hi.
I could not get your code to run but I could get this piece of the puzzle working:

(
~length = 0.5;
Pdef(0,
Pbind(
\dur, Pfunc({~length})
)
).play;
)


Bonus round:

(
~length = 1/Pstutter(Pwhite(5, 11), Pwhite(5, 11)).asStream;
Pdef(0,
Pbind(
\dur, Pfunc({~length.next})
)
).play;
)


Hey,

What do you mean you couldn’t get the code to work?

I also noticed there is a small mistake - the line \dur, 0.5
should be commented out, will fix in OP.

I am not quite sure what your code suggestion does and have a feeling I may have poorly communicated what I’m trying to do - I would like there to be a ‘cloud’ of notes with a pause after, and for the notes and pauses to get longer over time. Thanks again for having a look!

I am not sure, but I don’t think it’s possible to use environment variables like how you are doing it in your example.
How I’ve been taught to make them reach in to a Pdef is to put them in a Pfunc.
Also in the lower example I show how I’ve been taught to advance with .asStream on the sending side and .next on the receiving side.

I should let someone more experienced answer your question. I just chimed in because I knew how to do the thing I showed in my little things there.

This should do what you’re trying to do:

Pdef(\a,
Pbind(
\instrument, \a,
\dur, (Pwhite(
Pseg([0.01, 1], ~length, \sine),
Pseg([0.15, 2], ~length, \sine)
) * Pseq([Pn(1, ~numNotes - 1), 0], inf)) +
(Pseg([5, 9], ~length) * Pseq([Pn(0, ~numNotes - 1), 1], inf)),
\scale, Scale.majorPentatonic(t),
\degree, Pxrand((0..9), inf),
\root, Pstutter(~numNotes, Pseq([0, 3, 7, 10, 2, 5, 9], inf)),
\atk, 0.2,
\rel, Pseg([5, 15], ~length, \sine),
\octave, Pstutter(7, Pseq([3, 4, 5], inf)),
\amp, Pwhite(0.8, 1) * 0.2,
\pan, Pseg([0.75, -0.75, 0.75], [45, 45], \sine, inf),
\out, ~aFx
)
).play;


It’s kind of a hacky solution and is not very readable in my opinion, but it does the trick. Another perhaps more elegant approach might be to use recursive phrasing. That is a whole other can of worms in itself, but the tutorial in the help file is really great, and it does exactly what you are trying to do.

I think this should do it (not tested).

Unpacking “A pause that gets longer for every cycle”:

• “Gets longer” implies that there’s more than one pause. It also implies that the pause generator will have to maintain its state between Pseq cycles. A stream can do this but a pattern by itself can’t. (When Pseq embeds a pattern from its list, the subpattern always starts from the beginning and runs to the end – state is lost at that point.) So the Pseg for pause duration needs .asStream.

• One pause event per Pseq cycle: The Pseg stream will output multiple values, but you want to parcel them out one at a time. That’s a constraint pattern – Pfin.

                \dur, Pseq([
Pwhite(
Pseg([0.01, 1], ~length, \sine).asStream,
Pseg([0.15, 2], ~length, \sine).asStream,
~numNotes - 1
),
Pfin(1, Pseg([5, 9], ~length).asStream)
], inf),


Edit: First version missed .asStream` on the other 2 Pseg patterns. Fixed now. (Same logic: Pseg should keep its state between cycles; Pwhite’s length parameter is a built-in constraint, so you don’t need a separate Pfin there.)

hjh

@PitchTrebler I checked out recursive phrasing a while ago and put it in the basket of things that I wasn’t ready for - might be time for another look!

@jamshark70 this works perfectly, thanks!