-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathcope
54 lines (44 loc) · 1.23 KB
/
cope
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper::Compact qw(ddc);
use Algorithm::Combinatorics qw(combinations);
use Music::Chord::Namer qw(chordname);
use Music::Tension::Cope ();
use Music::Scales qw(get_scale_notes);
my $size = shift || 2;
my @notes = get_scale_notes('C', 'chromatic');
my %intervals = (
1 => 'half-step',
2 => 'whole-step',
3 => 'minor 3rd',
4 => 'major 3rd',
5 => 'perfect 4th',
6 => 'tritone',
7 => 'perfect 5th',
8 => 'minor 6th',
9 => 'major 6th',
10 => 'flat 7',
11 => '7th',
);
my $tension = Music::Tension::Cope->new;
my %tensions;
my $iter = combinations([0 .. 11], $size);
while (my $v = $iter->next) {
my $t = $tension->vertical($v);
my $c;
if ($size == 2) {
$c = $intervals{ $v->[1] - $v->[0] };
}
else {
$c = chordname(map { $notes[$_] } @$v);
}
$tensions{ join(' ', @$v) } = { chord => $c, tension => $t };
}
my $w = length(keys %tensions);
my $i = 0;
for my $chord (sort { $tensions{$a}->{tension} <=> $tensions{$b}->{tension} || $a cmp $b } keys %tensions) {
$i++;
printf "%*d. %-13s = %-23s => %s\n",
$w, $i, "[$chord]", $tensions{$chord}->{chord}, $tensions{$chord}->{tension};
}