I've been playing guitar for 31 years (good lord I'm old). But I only recently got interested in learning the theory behind chord progressions. I wrote this simple piece of code to calculate major triad chord progressions in all of the keys. I suppose it could be extended easily to create minor chord progressions as well.
use strict;
sub chord_progression
{
# The parameter is the index of the root note in the @notes array
my $i = shift;
my @notes = ('C', 'C#/Db', 'D', 'D#/Eb', 'E', 'F', 'F#/Gb',
'G', 'G#/Ab', 'A', 'A#/Bb', 'B');
my @intervals = (0, 2, 4, 5, 7, 9, 11, 12);
# Create a scale based on the intervals in a major scale
my @scale = map {$notes[($i + $intervals[$_]) % 12]} (0..7);
# Create triads. Increment each note within the scale.
# All notes in the chord progression fall within the
# major scale.
my ($root, $third, $fifth) = (0, 2, 4);
my @name = ('Maj', 'min', 'min', 'Maj', 'Maj', 'min', 'Dim', 'Maj');
for (0..7) {
printf "%6s %3s: %6s, %6s, %6sn",
$scale[$root], $name[$_], $scale[$root],
$scale[$third], $scale[$fifth];
$root++;
$third++;
$fifth++;
$root %= 7;
$third %= 7;
$fifth %= 7;
}
print "n";
}
# Call the subroutine for each note in the scale
for (0..11)
{
chord_progression($_);
}
This produces output like this for the 12 root notes:
C Maj: C, E, G
D min: D, F, A
E min: E, G, B
F Maj: F, A, C
G Maj: G, B, D
A min: A, C, E
B Dim: B, D, F
C Maj: C, E, G
----------------------------------
C#/Db Maj: C#/Db, F, G#/Ab
D#/Eb min: D#/Eb, F#/Gb, A#, Bb
F min: F, G#/Ab, C
F#/Gb Maj: F#/Gb, A#, Bb, C#/Db
G#/Ab Maj: G#/Ab, C, D#/Eb
A#, Bb min: A#, Bb, C#/Db, F
C Dim: C, D#/Eb, F#/Gb
C#/Db Maj: C#/Db, F, G#/Ab
...