hey,
im currently trying to come up with a solution to subdivide an array into groups of unequal sizes, which i then can repeat individually. I have found a solution which works for all the test cases i have tried out so far, beside numGroups == numBuffers (but thats okay).
For subdividing the groups into unequal lengths im using Dbjorklund2. I have the feeling that the attempt can be simplified. The main problem is to derive a trigger from the withinGroupIndex
, which should only advance on group boundaries, but not on wrapping boundaries based on the repeating cycles with Ddup
. Then one could probably get rid of calculating the groupIndex
and deriving yet another trigger i guess. Im happy about any suggestions. I know thats a bit tricky
(
{
|numGroups = 2, repeatGroup = 2, numOfBuffers = 5|
//|numGroups = 3, repeatGroup = 3, numOfBuffers = 11|
var trig, wrapTrigger, changeGroupTrig, resetTrig;
var withinGroupIndex, groupIndex, baseOffset, bufferIndex;
var step;
trig = Impulse.ar(2);
// Create a counter for position within the current group
withinGroupIndex = Demand.ar(trig, DC.ar(0),
Dseq([Dseries(0, 1, Ddup(repeatGroup, Dbjorklund2(numGroups, numOfBuffers)))], inf)
);//.poll(trig, "withinGroupIdx");
// Detect when withinGroupIndex wraps back to 0
wrapTrigger = HPZ1.ar(withinGroupIndex) < 0 + Impulse.ar(0);
// Create a counter for which group we're in
groupIndex = Demand.ar(wrapTrigger, DC.ar(0),
Ddup(repeatGroup, Dseq([Dseries(0, 1, numGroups)], inf))
);//.poll(trig, "groupIdx");
// Detect when the group index changes
changeGroupTrig = Changed.ar(groupIndex) + Impulse.ar(0);
// Detect reset (back to group 0)
resetTrig = (groupIndex <= 0) * changeGroupTrig;
// Get the step size
step = Demand.ar(changeGroupTrig, resetTrig,
Ddup(repeatGroup, Dbjorklund2(numGroups, numOfBuffers))
);//.poll(changeGroupTrig, "step");
// Create an accumulator that only advances when we change to a different group
baseOffset = Demand.ar(changeGroupTrig + resetTrig, resetTrig,
Dseries(0, step, inf)
);//.poll(wrapTrigger, "baseOffset");
// Final buffer index
bufferIndex = (baseOffset + withinGroupIndex).poll(trig, "bufIdx");
Silent.ar;
}.play;
)
With numGroups = 2, repeatGroup = 2, numBuffers = 5 i get a sequence of [0,1, 0, 1, 2, 3, 4, 2, 3, 4, 0, 1, …]
which when using a multiplexer for buffer selection works perfectly at audio rate (used some different shapes here to visualize the result):