This is part of an ongoing process to build a series of patterns that are useful for ‘groovebox’ style patterns. This is for a root pattern that provides bar/beat/time awareness for it’s children. As part of that obviously I wanted to make sure swing is supported, so I’ve been working on that. This isn’t the actual code (still working on that), but wanted to share the prototype object that calculates whether ‘swing’ duration for the current beat in case people find it useful (this value is then used to update the duration in the event that is sent to the server):
(~swing = (\calcNewBeat : {|self, beat, dur, remainingDur| beat + (dur - remainingDur)},
\swingBeatPos : {|self, currBeat, swingBase| currBeat - currBeat.trunc( 2 * swingBase)},
\adjFstBeat : {|self, dur, swingAmount| dur * 2 * swingAmount},
\adjSndBeat : {|self, dur, swingAmount| dur * 2 * (1 - swingAmount)},
\calcSwingDur : {|self,dur, currBeat, swingAmount, swingBase|
var lower, higher;
lower = min(dur, max(0, 0.5 - self.swingBeatPos(currBeat, swingBase)));
higher = max(0, (dur-lower).clip2(0.5));
[self.adjFstBeat(lower, swingAmount) + self.adjSndBeat(higher, swingAmount), lower+higher];
},
\calcNonSwingDur : {|self, dur, currBeat, swingBase|
min(dur, 1 - self.swingBeatPos(currBeat, swingBase));
},
\atSwingBeatStart : {|self,beat, swingBase| beat % (2 * swingBase) == 0},
\isSwingBeat : {|self, dur, swingBase, swingThreshold|
if (dur >= (2 * swingBase)){
false
}{
if (dur absdif: swingBase <= swingThreshold)
{
true;
}{
false
}
};
},
\onSwingBeat : false,
\swingEvent : {|self, currBeat, dur, swingBase=0.5, swingAmount=0.7, swingThreshold=0.0|
var remainingDur = dur;
var swingDur = 0;
while({remainingDur.round(0.001) > 0.0},{
if(self.atSwingBeatStart(currBeat, swingBase))
{
self.onSwingBeat = self.isSwingBeat(remainingDur.round(0.001), swingBase, swingThreshold);
};
if(self.onSwingBeat){
var actualSwingDur, logicalDur;
# actualSwingDur, logicalDur = self.calcSwingDur(remainingDur, currBeat, swingAmount, swingBase);
remainingDur = remainingDur - logicalDur;
swingDur = swingDur + actualSwingDur;
logicalDur.postln;
currBeat = currBeat + logicalDur;
}{
var logicalDur = self.calcNonSwingDur(remainingDur, currBeat, swingBase);
remainingDur = remainingDur - logicalDur;
swingDur = logicalDur + swingDur;
currBeat = currBeat + logicalDur;
};
});
currBeat.postln;
self.beat = currBeat;
swingDur;
}
)
)