I keep coming back to this thread because this idea of an index that advances only on phrase boundaries lines up neatly with list patterns’ embedding of items – that is, in Pseq([pattern1, pattern2])
, first pattern1
takes complete control and runs until the end, before pattern2
takes over.
The catch is that the data structure contains the data to Pseq, but not Pseqs themselves – and the data need to be directly available to the L-system.
One way to hack it might be to create a function to update the data storage. Then, have one dictionary for the arrays and one dictionary for patterns.
(
~absDict = ();
~patDict = ();
~putL = { |key, array|
~absDict.put(key, array);
~patDict.put(key, Pseq(array, 1));
};
// or, wipe out the whole system and start again with 'arrays'
~resetL = { |arrays|
~absDict.clear;
~patDict.clear;
arrays.do { |array, i|
~putL.(i, array);
};
};
)
… and all changes to the dictionaries go through this.
I usually try to avoid parallel collections, but in this case, it would enable you to do:
~resetL.([ [ 4.0 ], [ 2.125, 1.875 ], [ 1.25, 0.875, 1.875 ], [ 1.25, 0.875, 1.25, 0.625 ], [ 1.25, 0.875, 0.5, 0.75, 0.625 ] ]);
~absDict
-> ( 1: [ 2.125, 1.875 ], 0: [ 4.0 ], 2: [ 1.25, 0.875, 1.875 ], 4: [ 1.25, 0.875, 0.5, 0.75, 0.625 ],
3: [ 1.25, 0.875, 1.25, 0.625 ] )
(
p = Pbind(
\degree, Pn(Pseries(-7, 1, 15), inf),
\dur, Pdict(~patDict, Pn(Pseries(0, 1, 5), inf))
).play;
// or
(
var index = Pn(Pseries(0, 1, 5), inf).asStream;
p = Pn(Pbind(
\degree, Pseries(0, 1, inf),
\dur, Pdict(~patDict, Pfin(1, index))
), inf).play;
)
hjh