# Pattern with computed envelop

Hi,

Based on the tuto Pattern Guide 06b: Time Based Patterns I wrote this little pattern with two keys controlled by an envelop:

(
p = Pseq([
Pbind(\instrument, \tic, // normal one
\seqlen, { rrand(2,10) }, // duration of the pattern
\pls, Env(#[0.8, 0.2, 0.6], #[2,2], \sin), // average duration between tics
\amp, 0.5,
\pan, Pgauss(0,0.3,inf),
\freq, Pif(Ptime(inf) <= 4, Env(#[220, 440, 220], #[2,2], \sin)), // frequency controled by envelop.
\dur, Pgauss(Pkey(\pls),Pfunc({|evt| evt[\pls]/8;}) ,inf) // time to next tic
),
Rest({1+1.rand})
], inf).play;
)


I compute a random length for the pattern (\seqlen) and I’d like to have the envelops aligned on this duration. So I adapted the Pif and the Env accordingly but both lead to errors

(
p = Pseq([
Pbind(\instrument, \tic, // normal one
\seqlen, { rrand(2,10) }, // duration of the pattern
\pls, Env(#[0.8, 0.2, 0.6], #[Pkey(\seqlen)/2,Pkey(\seqlen)/2], \sin), // average duration between tics
\amp, 0.5,
\pan, Pgauss(0,0.3,inf),
\freq, Pif(Ptime(inf) <= Pkey(\seqlen), Env(#[220, 440, 220], #[Pkey(\seqlen)/2,Pkey(\seqlen)/2], \sin)), // frequency controled by envelop.
\dur, Pgauss(Pkey(\pls),Pfunc({|evt| evt[\pls]/8;}) ,inf) // time to next tic
),
Rest({1+1.rand})
], inf).play;
)


Il also tried with a Pfunc with no better result.
How should I do ?

#[ ... ] is a literal array.

Pkey(\seqlen)/2 is not a literal. So, you can’t put it in a literal array.

Delete the #.

#[1, 2]  // OK

x = 1; y = 2;
#[x + y, x - y]  // not OK

[x + y, x - y]  // OK


hjh

Not working better. I have another error:
I limited to

\seqlen, 8, //{ rrand(2,10) }, // duration of the pattern
\freq, Pif(Ptime(inf) <= 8, Env(#[220, 440, 220], [Pkey(\seqlen)/2,Pkey(\seqlen)/2], \sin)), // frequency controled by envelop.


And the error is now:

'_ArrayEnvAt' failed.
Wrong type.
RECEIVER: [ 220, 2, -99, -99, 440, a Pbinop, 3, 0, 220, a Pbinop, 3, 0 ]


As if it was not interpreting correctly Pkey(\seqlen)/2

If I remove the /2 and thus keep only the Pkey(\seqlen), I’ve got

'_ArrayEnvAt' failed.
Wrong type.
RECEIVER: [ 220, 2, -99, -99, 440, a Pkey, 3, 0, 220, a Pkey, 3, 0 ]


The Pif is also leading to an error:
If I do:

		\seqlen, 8, // duration of the pattern
\freq, Pif(Ptime(inf) <= (Pkey(\seqlen)/2), Env(#[220, 440, 220], #[4,4], \sin)), // frequency controled by envelop.


It is working fine.
As soon as I randomize the seqlen I’ve an error…

		\seqlen, { rrand(2,10) }, // duration of the pattern SHOULD BE DONE ONCE for the duration of the PBind
\freq, Pif(Ptime(inf) <= (Pkey(\seqlen)/2), Env(#[220, 440, 220], #[4,4], \sin)), // frequency controled by envelop.


Error:

^^ The preceding error dump is for ERROR: Non Boolean in test.


I think that I’m a bit lost with what does the language behind the scene…

I don’t think Env stream can includes a pattern in the times or levels values. You have the choice to use Pseg or compute the Env in a Plazy to return a non-pattern-including Env stream

What is tricky is seqlen have a new value for each event, but the Env stream span several events, you have to think about the meaning of changing an env while already playing, it’s not obvious

1 Like

Thanks. I’ll have a look at your suggestions:

What is tricky is seqlen have a new value for each event,

This is not my intend. My intend is that it gets a new value at the start of the pattern and keeps it until the end.

Plazy is perfect.

Plazy({
var seqlen=rrand(2,10);// duration of the pattern
seqlen.postln;
Pbind(\instrument, \tic, // normal one
\pls, Env(#[0.8, 0.2, 0.6], [seqlen*0.5,seqlen*0.5], \sin), // average duration between tics
\amp, 0.5,
\pan, Pgauss(0,0.3,inf),
\freq, Pif(Ptime(inf) <= seqlen, Env(#[220, 440, 220], [seqlen*0.5,seqlen*0.5], \sin)), // frequency controled by envelop.
\dur, Pgauss(Pkey(\pls),Pfunc({|evt| evt[\pls]/8;}) ,inf) // time to next tic
)
})

1 Like