Interactive pattern modification

Hi (again) guys,

I would like to interactively change the notes of a playing pattern: as an example, while the pattern is playing I would like to change the root note.

I’ve tryied different approaches (here I’m usign an extra simplyfied pattern for the sake of clarity).

Approach 1

(
a = 0;
Pbind(
\degree, 0,
\root, a,
).play;
)

Now trying to change the variable “a” evaluating a line like that:

a = 2;

nothing happens.

Approach 2

(
a = 0;
Pbind(
\degree, 0,
\root, {a},
).play;
)

Now trying to change the variable “a”, it works pretty well!

Approach 3

Now I want to make variable “a” a global one so I’ve changed the code this way

(
~a = 0;
Pbind(
\degree, 0,
\root, {~a},
).play;
)

And it has stopped working. Why?

One possible reason is because ~ is making the variable local to the scope of the Pbind, or the resultant event environment it generates.

1 Like

If you do \root, Pfunc({~a}), this might work instead.

Thank you @spacetimed!
I’ve just tried this snippet


(
~root = 1;
Pbind(
	\degree, 0,
	\root, Pfunc({~root}),
).play;
)

but unfortunately it doesn’t work. The console output is showing me this message one time a second:

WARNING: BinaryOpPlug: Cannot calculate this value. Use direct mapping only.

Pfunc should do the trick:

(

  ~a = 0;

  Pbind(

  \degree, 0,

      \root, Pfunc({~a}),

  ).play;

  )

best,

mstep

Unfortunately this is not working…

No problem! This code you’ve just given seems to be working for me, it runs and I’m able to change ~root outside of the Pbind without any warnings.

1 Like

Sorry @spacetimed , @mstep.
definitively my fault: now I’ve restarted my interpreter and it seems to work properly!
Thank you very much for your help!

2 Likes

Hi @spacetimed,
are your experienced also with something like this ?

(
~degrees = Scale.majorPentatonic.degrees;
Pbind(
	\degree, Pseq( Pfunc({~degrees}).asCollection, inf),
	\root, 0,
).play;
)

here I would like to make something similar to what we discussed before, but using arrays…
Unfortunately this snippet causes 5 synths to be played harmonically instead of melodically as I would have liked.

How to transform the Pfunc output properly for the Pseq to use it as been in the following form:

(
Pbind(
	\degree, Pseq( Scale.majorPentatonic.degrees, inf),
	\root, 0,
).play;
)

??

thank you very much

Check out Pbindef (don’t have time now to post an example)

This is working for me:

(
~degrees = Scale.majorPentatonic.degrees;
Pbind(
\degree, Pseq( Pfunc({~degrees}).asCollection.flatten, inf),
\root, 0,
\dur, 0.2
).play;
)

~degrees = Scale.minorPentatonic.degrees;
~degrees = [0, 1, 2, 3];

So we’re using Pfunc to get the degrees each time instead of setting it initially, which is ‘lazy’ so we should use Plazy instead to be conceptually clearer.

Then I’m not sure, but it seems like your .asCollection code turns the Pfunc into a collection containing a collection of the degrees, rather than just a collection of the degrees, so it’s like this:

a = [[0, 1, 2, 3]]

Which is why we would hear the whole array play back each time as it’s iterating through the top level array and always finding [0, 1, 2, 3]… So we want to .flatten a, which turns [[]] into [].

I’m not entirely certain of what’s going on under the hood, but the above seems to work for me.

1 Like
Pdefn(\a, 0) // Pdefn can act as global variable
Pbindef(\test, \degree, 0, \root, Pdefn(\a)).play
Pbindef(\test2, \degree, 5, \root, Pdefn(\a)).play
Pdefn(\a, 1)
Pdefn(\a, Pseq([0,1],inf).stutter(8))

Hi,

it’s right, Plazy would be a good way to go. Note that above syntax doesn’t work with Prand and many other list patterns, the Plazy approach does (check with Prand, Pshuf etc.):

(
~degrees = Scale.majorPentatonic.degrees;

Pbind(
    \degree, Pn(Plazy { Pseq(~degrees) }, inf),
    \root, 0,
    \dur, 0.2
).play;
)

~degrees = Scale.minorPentatonic.degrees;
~degrees = [0, 1, 2, 3];

As this scheme is nice for live coding, I’ve written a whole suite of patterns for this kind of (“dynamic scope”) replacement: PLx, contained in miSCellaneous_lib quark

(
~degrees = Scale.majorPentatonic.degrees;

Pbind(
    \degree, PLseq(\degrees),
    \root, 0,
    \dur, 0.2
).play;
)

~degrees = Scale.minorPentatonic.degrees;
~degrees = [0, 1, 2, 3];

There exist PLrand, PLshuf etc.

Note that behaviour is not totally the same with PLseq and Pn(Plazy { Pseq … }) because PLx patterns
follow an immediate replacement paradigm, whereas with Pn + Plazy the Pseq is finished before replacement, PLn mimics this.

Greetings

Daniel

2 Likes

I’m not sure what Plazy buys you that you don’t get with Pdefn.

The behaviour is different: The Pn + Plazy approach ensures finishing the loop before replacement, Pdefn (as PLx) follows the immediate replacement paradigm.

(
Pbind(
    \degree, Pdefn(\a, Pseq([0, 1, 2, 3], inf)),
    \root, 0,
    \dur, 0.2
).play;
)


Pdefn(\a, Pseq([0, 1, 2, 3] + 10, inf))

The difference between Pdefn and Plazy (and PLx) is that you replace the pattern with the first and with the latter you can choose if you replace pattern or list.

Besides the technical differences it is very much a question of taste. But I must say that regarding the fact that a short syntax is crucial for live-coding, I find the the Pdefn syntax e.g. of

Pdefn(\a, Pseq((0..3), inf))

a bit lengthy. I prefer to write

~a = (0..3)

if I know I want just a new list for a loop.

3 Likes

Thanks Daniel, that’s really useful: I’m going to give that approach a try.

+1 for the new forum, I guess.

Thank you all for your support!
thumbs up for the new forum :slight_smile:

Thanks Daniel. That approach seems like it would solve quite a few problems.