Concatenation of TimeVars

Hello everyone!

I’m pretty new to FoxDot and live coding in general, so to practice a little bit I tried to reproduce the melody of the song “Children” of Robert Miles using TimeVars. After some time of playing around I obtained this:

Clock.bpm = 136
Scale.default = "minor"
Scale.key = "f"

pat1 = [0,2,1,-1,2,1,-3,2,1,-5]
dur1 = [6,1,.5,6.5,1,.5,6.5,1,.5,8.5]

p1 >> piano(var(pat1, dur1), dur=dur1, oct=6)

Then, I realized the pattern [2,1,X] is repeated, so I checked this:

p2 >> piano(var([2,1,[-1,-3,-5]], [1,.5,[6.5,6.5,8.5]]), dur=[1,.5,[6.5,6.5,8.5]], oct=6)

So far so good. The problem comes when I try to add the “0” at the start of the sequence. All the things that I tried ended with the TimeVar var([0,2,1,[-1,-3,-5]], [6,1,.5,[6.5,6.5,8.5]]), which does not yield the same pattern as var(pat1, dur1).

My question is the following: is there any way to concatenate TimeVars in a similar way as we can concatenate patterns? For example, var(0,6) | var([2,1,[-1,-3,-5]], [1,.5,[6.5,6.5,8.5]]) == var([0,2,1,-1,2,1,-3,2,1,-5], [6,1,.5,6.5,1,.5,6.5,1,.5,8.5]).

To try to solve this problem I implemented this custom function, but maybe there is an easier way to do that:

import functools

def flatten(pat, dur):
    pat_flat = functools.reduce(lambda a, b: list(a) + list(b), pat)
    dur_flat = functools.reduce(lambda a, b: list(a) + list(b), dur)
    return pat_flat, dur_flat

pat2_raw, dur2_raw = [P[0],P[2,1,[-1,-3,-5]]], [P[6],P[1,.5,[6.5,6.5,8.5]]]
pat2, dur2 = flatten(pat, dur)

p3 >> piano(var(pat2, dur2), dur=dur2, oct=6)

Thank you for your help and sorry if the question is too basic, keep rocking!


I have been thinking about this for a while and the main issue is what to do about nested values, such as those you have in your code. Should the var with nested values go through all of its nested values or should they be laced over the new, concatenated var? E.g.

var([0, 1]) | var([2, [3, 4]])

Should this return values in the order 0, 1, 2, 3, 0, 1, 2, 4 or 0, 1, 2, 3, 2, 4? From your code above it seems that the latter would be preferable? Either way could easily added to TimeVar functionality, but it’s getting the behaviour right that needs to be addressed.

One thing to say, however, is that if you’re using a var with the same duration as the duration values as the Player it’s being used in, you probably don’t need to use the var at all. If I understand the code correctly, you could probably use:

p3 >> piano(0 | P[2,1,[-1,-3,-5]], dur=6 | P[1, .5, [6.5,6.5,8.5]], oct=6)

Or am I misunderstanding and you want a bit more flexibility with things?

Hey Ryan! Thank you for your reply!

It’s true that there is some kind of ambiguity in the concatenation of TimeVars and both options seem reasonable to me. As you pointed out, for my case the second one fits better, but I don’t know if that would be the case for other users.

Regarding the second part (and as far as I understood patterns), wouldn’t these two patterns be equivalent?

0 | P[2,1,[-1,-3,-5]] == P[0,2,1,[-1,-3,-5]]

If that’s the case, this would create the pattern [0,2,1,-1,0,2,1,-3, …]. The problem I found is that I don’t know how to prevent the first zero from being laced with the rest of the pattern (i.e. [0,2,1,-1,2,1,-3, …]).

However, it may be true that the answer could be not using TimeVars at all, as I want to use the same durations on the TimeVar and the player.

Thank you for your attention!