#!/usr/bin/env perl
my
$in_note
=
shift
//
''
;
my
$in_key
=
shift
||
'major'
;
my
$min
=
shift
// 0;
$in_key
=
'major'
if
$in_key
eq
'maj'
;
$in_key
=
'minor'
if
$in_key
eq
'm'
||
$in_key
eq
'min'
;
my
$bach
= Music::BachChoralHarmony->new(
);
my
$songs
=
$bach
->parse();
my
%score
;
for
my
$song
(
sort
keys
%$songs
) {
next
if
$song
eq
'003907bv'
||
$song
eq
'014806bv'
;
my
$key
=
$songs
->{
$song
}{key};
my
$name
=
$key
=~ /M/ ?
'major'
:
'minor'
;
$key
=~ s/_?M//i;
next
if
$in_note
&&
$key
ne
$in_note
;
next
unless
$name
eq
$in_key
;
my
$mtr
= Music::ToRoman->new(
scale_note
=>
$key
,
scale_name
=>
$name
,
);
my
$last
;
for
my
$event
( @{
$songs
->{
$song
}{events} } ) {
my
$chord
=
$event
->{chord};
$chord
=~ s/_//;
$chord
=~ s/d/o/;
my
$roman
=
$mtr
->parse(
$chord
);
$score
{
$last
.
' '
.
$roman
}++
if
$last
;
$last
=
$roman
;
}
}
my
$g
= GraphViz2->new(
global
=> {
directed
=> 1 },
node
=> {
shape
=>
'oval'
},
edge
=> {
color
=>
'grey'
},
);
my
%nodes
;
my
%edges
;
for
my
$bigram
(
keys
%score
) {
next
if
$min
&&
$score
{
$bigram
} <=
$min
;
my
(
$i
,
$j
) =
split
' '
,
$bigram
;
$g
->add_node(
name
=>
$i
)
unless
$nodes
{
$i
}++;
$g
->add_node(
name
=>
$j
)
unless
$nodes
{
$j
}++;
$g
->add_edge(
from
=>
$i
,
to
=>
$j
,
label
=>
$score
{
$bigram
} )
unless
$edges
{
$bigram
}++;
}
$g
->run(
format
=>
'png'
,
output_file
=> $0 .
'.png'
);