Different note durations not in sync

Perhaps to shift perspective on the question –

I think the tricky thing here is not (primarily) the programming.

What is an algorithm doing, if it’s using random number generators to produce musical data?

The field of possible results is very large, and most of it sounds like nonsense (because “sense” in music is about recognizing culturally-coded patterns).

So, algorithmic composition is about constraining the randomness to exclude nonsense parts of this field, and steer the results toward “sensible” territories.

var seq2 = Pxrand([
	Pseq([0.50], 4),  // = 2
	Pseq([0.25, 0.25, 0.25, 0.25], 8), // = 8
	Pseq([0.50, 0.50, 1, 1], 2 ),  // = 6
	Pseq([0.0625], 8 )  // = 0.5
], inf);

This rhythm algorithm constrains rhythmic values to duple divisions. But you also said “In the picture it shows a 1 bar loop but the notes have different lengths but it’s still a 1 bar pattern” – so metrical structure is part of your goal, but the sub-sequences all have different lengths that are not multiples of the bar’s duration. In particular, this pattern allows a half-beat offset (last entry).

So the tricky thing is to understand the rhythmic territory you want to allow, and figure out how to constrain the randomness to that.

This should not be expected to be a simple problem! This is the core of algorithmic composition. Your solution is what will distinguish your algorithmic music from other people’s – that is, this is exactly where the creative struggle is.

The key question, I think, is, what are the metrical structures within the bar that are important to you?

I won’t try to answer that for you, but I’ll add a couple of other notes:

SC patterns are oriented toward time deltas (or “inter-onset intervals” = IOIs). It’s difficult to express “positions within the bar” in terms of deltas – so, if the idea of placing events at specific beats to the bar is important to you, then it’s better to have something to convert time points into deltas. The ddwPatterns quark has PTimePoints, but you could find your own way. Assuming 4 beats to the bar, this pattern will play an E always on beats 2 and 4, with some extra 8ths. If you try to do this only with deltas, it will drive you nuts.

(
p = Ppar([
	// metronome
	Pbind(
		\midinote, Pseq([72, 60, 60, 60], inf),
		\dur, 1,
		\legato, 0.1
	),
	// backbeats
	PTimePoints(
		Pbind(
			\midinote, 76,
			\timept, Pn(Plazy {
				var pts = [1.0, 3.0] ++ Array.fill(rrand(1, 4), { 8.rand * 0.5 });
				// remove duplicates
				pts = pts.as(IdentitySet).as(Array).quickSort { |a, b| a < b };
				Pseq(pts, 1)
			}, inf),
			\sustain, 0.5
		)
	)
]).play(quant: -1);
)

And…

1 – Of course SC can do this… the difference is that it’s a built-in feature of a groovebox. 2 – Much of what I’m saying in this post is about creating a translation layer between the way you want to do things, and the way the underlying SC mechanisms work. Don’t give up just because SC doesn’t already have exactly the translation layer you wanted.

I’d suggest a pattern that will repeat and subdivide events. The Pbind would be responsible for generating the rhythmic structure; this filter pattern, wrapping around the Pbind, would handle retriggering.

If you update my ddwPatterns quark, it could be done a bit clumsily like this. Or you could create a new pattern class that does it more conveniently.

(
p = Psmartdup(
	Pkey(\structuralDur) / Pkey(\dur),
	Pbind(
		\degree, Pn(Pseries(0, 1, 8), inf),
		\structuralDur, Pwhite(1, 3, inf) * 0.5,
		\dur, Pwrand([
			Pfin(1, Pkey(\structuralDur)),
			0.125
		], [0.9, 0.1], inf),
		\legato, Pif(Pkey(\dur) |!=| Pkey(\structuralDur), 0.05, 0.9)
	)
).play;
)

hjh

3 Likes