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);

}).add;

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);
}).add;
)

(
~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,

thanks for your help.

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!