-
Notifications
You must be signed in to change notification settings - Fork 5
/
guidonian
79 lines (67 loc) · 1.64 KB
/
guidonian
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#!/usr/bin/env perl
use strict;
use warnings;
# Write-up: https://ology.github.io/2022/01/15/text-to-guidonian-melodies/
use Getopt::Long;
use Music::Guidonian;
use Music::Scales qw(get_scale_nums);
use MIDI::Util qw(setup_score);
use Mojo::File;
my %opts = (
file => undef,
text => 'Lorem ipsum dolor sit',
scale => 'major',
regex => 'aeiouy',
bpm => 200,
patch => 4,
vol => 120,
min => 48,
max => 72,
num => 1,
rand => 0,
);
GetOptions(\%opts,
'file=s',
'text=s',
'scale=s',
'regex=s',
'bpm=i',
'patch=i',
'vol=i',
'min=i',
'max=i',
'num=i',
'rand=i',
) or die "Can't get options: $!";
my @intervals;
if ($opts{rand}) {
# Get random intervals
@intervals = map { int(rand $opts{rand}) + 1 } 1 .. 7;
}
else {
# Get the named scale intervals
my @scale = (get_scale_nums($opts{scale}), 12);
@intervals = map { $scale[$_ + 1] - $scale[$_]} 0 .. $#scale - 1;
}
my $mg = Music::Guidonian->new(
key_set => {
intervals => \@intervals,
keys => [ split //, $opts{regex} ],
min => $opts{min},
max => $opts{max},
}
);
if ($opts{file}) {
my $file = Mojo::File->new($opts{file});
$opts{text} = $file->slurp;
}
# Only use the first vowel of a dipthong
$opts{text} =~ s/([$opts{regex}])[$opts{regex}]/$1/g;
my @vowels = lc($opts{text}) =~ m/([$opts{regex}])/g;
my $iter = $mg->iterator(\@vowels);
my $phrase = $iter->();
my $score = setup_score(bpm => $opts{bpm}, patch => $opts{patch}, volume => $opts{vol});
for (1 .. $opts{num}) {
$score->n('qn', $_) for @$phrase;
}
$score->write_score("$0.mid");