The Bebop Machine

I was practicing a certain way of moving through minor6 chords on guitar and could not resist turning the exercise into SC code. The principle is derived from ‘block chords’ which is a harmonic approach most famously associated with the jazz pianist George Shearing. As you might hear this also is closely related to Bach.

The idea is that you can play alternating minor6 and dim7 chords. This also works in major but for now I will stick to minor. The dim7 chords functionally act as dom7(b9) chords (with the root omitted). So instead of playing 2 bars of Cm6 we can play

| Cm6 G7(b9)| Cm6 G7(b9)|

or more precisely

|Cm6 Ddim7 |Cm6 (1st. inversion) Fdim7 |

So different inversions of the minor6 chord and different inversions of the dim7 chord. When combining the four notes of the minor6 chord with the four notes of the dim7 chord we get a scale of 8 notes which can be seen as harmonic minor + melodic minor put together. We can also think of it as a minor scale with both b6 and 6 and a raised 7. In SC terms the scale is [0, 2, 3, 5, 7, 8, 9, 11].

The example below uses this principle on a C minor blues. A pretty standard jazzy C minor blues has the following changes:

|| Cm | Cm | Cm | Cm (C7)|
| Fm | Fm | Cm | Cm |
| Ab7 | G7 | Cm | (G7) ||

Now we extend the chords by using the principle above

|| Cm6 G7(b9) | Cm6 G7(b9) | Cm6 G7(b9) | Cm6 C7(b9) |
| Fm6 C7(b9) | Fm6 G7(b9) | Cm6 G7(b9) | Cm6 |
| Ab7 | G7 | Cm6 G7(b9) | Cm6 G7(b9) ||

Over the Ab7 we can play notes from the Eb minor6 chord which gives us the following scale degrees (seen from Ab) - 5, 7, 9, 3 (in musical terms, not SC terms). Over G7 we can play notes from the Ab minor 6 chord which gives us (seen from G) - b9, 3, b13, 7 (again, as we denote degrees in music theory, not in SC).

The code below utilizes the fact that all even numbered indices of the scale belong to the minor6 chord and all odd numbered indices belong to dim7. I added a ‘piano player’ and a ‘bass player’ to the mix.

The ‘dur’ variable is the duration of an eighth note. So setting dur to 0.2 equals a tempo of 0.4 bps or 150 bpm. If you want to check the code at Charlie Parker speed, set dur to 0.1 = 300 bpm. The amount of swing corresponds to the tempo, the faster you play, the less the 8th notes swing. This mimics what happens when humans play.

The direction of the phrase can change every 4 notes within the chosen range, given endless variation of the same principle.

Just for fun:)

(
var dur = 0.2; // try values between 0.4 and 0.1
var swing = dur.linlin(0.1, 0.5, 0.005, 0.08);
var curNote = 48;
var degrees = [0, 2, 3, 5, 7, 8, 9, 11]; // minor6 - dim7
var allScaleDegrees = 8.collect{|i|(i * 12) + degrees}.flat;
var calcDir = {|val, curNote|
	case
	{ curNote < 58 } { val }
	{ curNote > 73 } { val * -1 }
	{ true } { [val, val.neg].choose}
};
var dir = 1;
var scale, root;
Pdef.removeAll;

Pdef(\basePb,
	Pbind(
		\root, Pstep(Pseq([0, 5, 0, 3, 8, 0], inf), Pseq([28, 16, 20, 8, 8, 16] * dur, inf), inf),
		\assignRoot, Pfunc{|ev|root = ev.root},
		\dur, Pseq([dur + swing, dur - swing], inf),
		\scale, Pfunc{|ev|
			var tmpScale = (allScaleDegrees + ev.root);
			var temp = tmpScale[tmpScale.indexInBetween(48).asInteger..tmpScale.indexInBetween(83).asInteger];
			scale = temp;
		},
		\dir, Pstep(
			Pseq([
				Pseq([
					Pfuncn({|ev|dir = calcDir.(2, curNote)}),
					Pfuncn({|ev|dir = calcDir.(1, curNote)}),
				], 14),
				Pseq([
					Pfuncn({|ev|dir = calcDir.(2, curNote)}),
				], 12),
				Pseq([
					Pfuncn({|ev|dir = calcDir.(2, curNote)}),
					Pfuncn({|ev|dir = calcDir.(1, curNote)}),
				], 4)
			]),
			Pseq([
				Pseq([3, 1], 14),
				Pseq([3, 1], 12),
				Pseq([3, 1], 4)
		]) * dur, inf)
)).play;

Pdef(\line,
	Pbind(
		\dur, Pseq([dur + swing, dur - swing], inf),
		\midinote, Pseries(16, Pfunc { dir }, inf)
		.collect { |i|
			curNote = scale.wrapAt(i);
			curNote;
		},
		\amp, Pseq([0.4, 0.2, 0.3, 0.2], inf) * 0.5,
)).play;

Pdef(\chords,
	Pbind(
		\dur, Pseq([dur * 3 + swing, dur * 5 - swing], inf),
		\midinote, Pfunc{
			var index = scale.indexIn(curNote);
			[0, 2, 4, 6].collect{|j|scale.wrapAt(index + j)}.wrap(50, 73)
		},
		\sustain, Prand([
			Pseq([dur, dur * 2.5], inf),
			Pseq([dur, dur * 2.5], inf)
		]),
		\amp, Prand([0, 0.05], inf),
)).play;

Pdef(\bass,
	Pbind(
		\legato, 0.2,
		\dur, dur * 2,
		\amp, 0.2,
		\midinote, Prand([
			Pseq([0, 2, 4, 6]),
			Pseq([0, 1, 2, 3]),
			Pseq([0, 4, 8, 4]),
			Pseq([4, 2, 1, 0]),
		], inf).collect{|i|scale[i + scale.indexIn(root + 48)] - 12},
		\t, Pseq([\note, Prand([\note, \rest])], inf)
	)
).play
);

Pdef.removeAll;
1 Like