I was messing around with patterns trying to do a stuttering pattern and found a cool ‘hack’.
My original idea was to find a way to easily switch a pattern and the same pattern being ‘stuttered’ in subdivisions:
( // base pattern, subdivision = 1/16th notes
Pdef(\test,
Pbind(
\midinote, Pseq([50, 55, 60], inf),
\dur, Pseq([0.75, 0.75, 0.5], inf)
)
).play
)
( // 'stuttered' version, subdivision = 1/16th notes
Pdef(\test,
Pbind(
\midinote, Pstep(Pseq([50, 55, 60], inf), Pseq([0.75, 0.75, 0.5], inf)),
\dur, 0.25
)
).play
)
Pdef(\test).stop
But my patterns are pretty complex with lots of different keys and the chance of altering the patterns on the fly in different ways, so I gave up doing a key-by-key version. Then I came up with this cool Prout ‘hack’ - hack because the original pattern is muted and sort of taken over by the Prout. The super cool thing about this is that it allows the stuttering to be in any subdivision so it’s a bit like having two timelines going at once, where the stuttering is starting on a beat quantized to the first timeline but with independent control over the subsequent timing of the stuttered notes. Also, this is a add-on with no need to adjust the existing pattern which can be of any complexity, contain randomness etc. It is a bit like a ‘MIDI delay line with ducking’. Better shown than explained:
(
~stutNum = 6;
~stutter = 0;
~stutterAmpDecay = 1;
Pdef(\test,
Pchain(
Prout({|ev|
while { ev.notNil }
{
var pb = ev.copy;
var subD = ~stutNum.reciprocal;
var num = pb.dur.div(subD).max(1);
pb.dur = if (~stutter == 0) { Pseq([pb.dur]) } { Pseq([subD], num) };
if (~stutterAmpDecay == 1) { pb.amp = Pseq(num.collect{|i|1/(i + 1) * ev.amp}, num) };
Pbind(*pb.asPairs).play();
ev.amp = \rest;
ev = ev.yield
}
}),
Pbind(
\midinote, Pseq([50, 55, 60, 48, 53, 52], inf),
\dur, Pseq([0.5, 0.5, 1, 0.75, 0.75, 0.5], inf),
\amp, 0.3
)
)
).play() // plays normal at first
);
~stutter = 1; // turn on to hear the stutter effect
~stutNum = rrand(3, 8).debug(\stutNum); // try different values
~stutterAmpDecay = 0; // all notes will be same amp as the original
~stutterAmpDecay = 1; // decaying amplitudes
Pdef(\test).stop