Rotate patterns in FoxDot and still have them depend on other patterns?

What I want to test out is having p2 rotate but still being able to change p1
and the p2 updates:
p1 >> bass(var([0,4,5,3],4), dur=2)
p2 >> pads().follow(b1) + [2,4,7] <- tried placing it after …(b1).rotate(2) or (b1).every(4,“rotate”,2)

Additionally I would also like to be able to duplicate the p2 and then have it rotate. Everything should still be able to update to p1. Is this possible?

I’m a little confused by the variable names; at the start you say you want p2 to rotate but then use b1.rotate() - should that be p1 or is b1 a different line or code not shown here? The answer to your question depends on which you want to rotate.

If you want to rotate p1, it’s a bit complicated as you’re using a var which is less of sequence of values, but a single value that changes over time. There are a couple of hacky ways around that though.

If you want to rotate p2 that is quite possible:

p2 >> pads().follow(b1).every(4, "rotate", 2) + [2, 4, 7]

You could then also do:

p3 >> pluck().follow(p2).every(4, "rotate", 2) + [0, 1, 2, 3]

Hope that helps!

Thanks alot! sorry I meant p1. And it works! But is there away to rotate without every()? And if I use .every(4,“rotate”,2) having it then go back to the default step after lets say 2 bars?

You can use the Cycle object to rotate a with a different value each time, if that’s what you’re after. So if you want to rotate back after 8 beats, you can do this:

p2 >> pads().follow(p1).every([4, 8], "rotate", Cycle([2, -2])) + [2, 4, 7]

The [4, 8] at the start of every() automatically become a Cycle so you don’t have to use it there, but other values in the every method call can be alternated by using it. In this instance the pitch values will rotate 2 after 4 beats, then back 2 to original state after the next 8 beats. Is that what you were after? FoxDot is really centered around repetition, and it’s sometimes hard to think about things as repeating forever. If you just want to rotate p2 once then back again you can schedule the action explicitly in the Clock:

Clock.future(4, p2.rotate, args=[2])
Clock.future(12, p2.rotate, args=[-2])

Thanks! Yes that is really nice! Does it approve to offset odd cycles? I tired this
to offset by smaller syncopations
1)

p9 >> play("x [--] - ")   (for referencing)
p8 >> play("o o o ").every([4, 8], "rotate", Cycle([1, 2.5]))

It didn’t work so i tired this:
2)

p8 >> play("o[  ]o[  ]o[  ]").every([4, 8], "rotate", Cycle([1, 3]))
The pattern with claps instead of rests.
p8 >> play("o[**]o[**]o[**]").every([4, 8], "rotate", Cycle([1, 3]))

But it is either buggy or doesn’t play.

p8 >> play("o[ *]o[ *]o[ *]").every([4, 8], "rotate", Cycle([0, 1.75]))

This is maybe another subject and question…

I’ve edited your post to make it a bit easier to read if that’s ok. You can use `backticks around your code` to apply syntax highlighting - the asterix is used to make font bold, which made the post a bit hard to read.

You can only rotate by whole numbers. It’s sometimes hard to distinguish between duration (time in beats) and steps (single events as denoted in lists of values) in FoxDot and I think that’s where you’re getting stuck. A Pattern is essentially a transform-able list of values with no idea about durations (mostly) so rotating the list [1, 2, 3, 4] by 1.5 steps doesn’t make sense. You can rotate by 1 (i.e. [2, 3, 4, 1]) or by 2 (i.e. [3, 4, 1, 2]) but not 1.5. What you could do is rotate and then delay values by 0.5 beats using the delay keyword e.g.

p1 >> pluck([1, 2, 3, 4], delay=var([0, 0.5], 4)).every(4, "rotate", 1)

Or if you don’t wish to use a var:

p1 >> pluck([1, 2, 3, 4]).every(4, "rotate", 1).every(4, "delay.alt", 0.5)

It is definitely ok that you edited my post and thank you for letting me know how it is done.
Yes, you right I wasn’t sure about the difference between steps and duration and thanks for explaining it thoroughly. I’ve red about the alt(seq) in the pattern methods and has that anything to do with the “delay.alt”, Could you use the same principle with other effects like “amen.alt”, “rotate.alt”. Not sure were I can read up on this.

This bit of the documentation is still a bit lacking unfortunately as the syntax is subject to change but I’ll explain how it works currently. When specifying a method name with every, FoxDot first checks whether the method belongs to the player, e.g. “stop”. If there isn’t a method on the Player class, it checks the Pattern class. If there is a valid method on the Pattern class, FoxDot applies that method to the Pattern representing the Player’s pitch. However, it would be useful to apply methods to other attributes, such as ‘delay’.

Now the every method also checks if the name given fits the form "attribute.method" e.g. "delay.alt" and will apply (then un-apply) the method to the Pattern for the given attribute every x number of beats. So in this instance, every 4 beats FoxDot is setting the delay to p1.delay.alt(0.5), which essentially replaces the contents of the Pattern with a given value. So if the delay of p1 is 0 (default) then using “alt” would be like doing P[0].alt(0.5) which returns P[0.5]. You can’t combine multiple attributes/method names but it’d be nice if there was a simple of doing something like that. Hope that clears it up a bit?

Thanks for the explanation. Will take some time to digest. Really appreciate the help and time.