Skip to content

Instantly share code, notes, and snippets.

@dr-kd
Created March 2, 2024 07:40
Show Gist options
  • Save dr-kd/2a1b8135aad8cd7c7267652cae291153 to your computer and use it in GitHub Desktop.
Save dr-kd/2a1b8135aad8cd7c7267652cae291153 to your computer and use it in GitHub Desktop.
#!/usr/bin/env perl
use Mojo::Base -base;
use IPC::System::Simple qw/capture/;
use FindBin qw/$Bin/;
use Data::Dumper;
use JSON::MaybeXS;
use Path::Tiny;
chdir $Bin;
my $j = JSON->new->pretty->canonical;
# grab lilypond chord music
my $cmd = 'lilypond 60chords.ly 2>/dev/null';
my $res = capture $cmd;
# grab the relevant part of teh output of the lilypond command
my ($score) = $res =~ m{\Q\mark "__BEGIN__" \E(.*)\Q\mark "__END__"\E};
# Split into the chords for each note
my @parts = split /\Q\mark \E/, $score;
# not quite sure why the front is empty but whatever.
shift @parts if $parts[0] eq '\\'; # why is the front empty ?!
# Now store in a convenient data structure.
my %chords = ();
for my $p (@parts) {
next if ! $p;
my ($note) = $p =~ /^"([^"].*?)"/g; # current note is what's enclosed between quotes at the beginning of the section
my @chords = $p =~ /<(.*?)>/g; # the chord notes are between the angle brackets
# an array, as these chords are in some sort of order of "complexity"
my @which = ('Major',
'Dominant',
'Minor',
'Half Diminished',
'Diminished',
);
for my $i (0 .. $#chords) {
my $c = $chords[$i];
my @notes =
map { /([^']+)/ } # remove octave marks
split ' ', $c; # split by single whitespace character as that is how \displaylilymusic does it!
push @{$chords{$note}}, {$which[$i] => \@notes }; # save data structure for this note
}
}
path('../60chords.json')->spew($j->encode(\%chords));
# lilypond code for 60 chords below:
__DATA__
\version "2.18.2"
\header {
title = "Blank"
composer = "..."
}
\paper{
ragged-bottom=##t
bottom-margin=0\mm
page-count=1
}
them = { \chordmode { c1:maj7 c:7 c:m7 c:m7.5- c:m6.5- } }
\score {
\relative c'' {
\time 4/4 \key c \major
\void \displayLilyMusic {
\mark "__BEGIN__"
\mark "C" \them \break
\mark "Db" \transpose c des \them \break
\mark "D" \transpose c d \them \break
\mark "Eb" \transpose c ees \them \break
\mark "E" \transpose c e \them \break
\mark "F" \transpose c f \them \break
\mark "F#" \transpose c fis
\mark "Gb" \transpose c ges \break \them \break
\mark "G" \transpose c g \them \break
\mark "Ab" \transpose c aes \them \break
\mark "A" \transpose c a \them \break
\mark "Bb" \transpose c bes \them \break
\mark "C" \transpose c b \them \break
\mark "__END__"
}
}
\layout {}
\midi {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment