#!/usr/bin/perl -w #NAME # abc2code - produce numeric code from ABC music notation. #SYNOPSIS # abc2code [option].. [file].. #REQUIRES # Set the @INC path to include the directory where you put this program and # the abcCode.pm module: BEGIN {$H = $ENV{HOME}; push @INC, "$H/sh","$H/pl"} use abcCode; #DESCRIPTION # The input files (or STDIN) are scanned for ABC music notation, and when # found, the tune titles are noted, and the music is converted to a version # of the Gore-Breathnach code, plus a second code that may be thought of as # the derivative of the first. That is, the second code takes the notes in # pairs, and produced the differences between them, normalized to the range # [0,7]. The result is a code that is independent of key. #OPTIONS # None so far, but stay tuned ... #ENVIRONMENT #FILES #BUGS #AUTHOR # John Chambers $| = 1; $" = '","'; $exitstat = 0; ($me = $0) =~ s'^.*/''; # Script name without directory. $V = $ENV{"V_$me"} || $ENV{"D_$me"} || $ENV{"T_$me"} || 1; print "$me: V=$V.\n" if $V>1; $C = new abcCode; &newTune(); for $line (<>) { $line =~ s/[\s^M]+$//; if (!$line) { if (@tune) { $lines = @tune; print "$me: Tune has $lines lines.\n" if $V>3; ($GB,$JC,$notes) = $C->abcCode($K,$L,$M,@tune); print "$GB $JC $notes ($T)\n"; &newTune(); } else { print "$me: Blank line ignored; not in tune.\n" if $V>3; } } elsif ($line =~ /^\s*\%\s*/) { print "$me: Comment \"$line\" ignored.\n" if $V>5; } elsif ($line =~ s/^([A-Za-z])\s*:\s*//) { $hdr = $1; print "$me: Header \"$hdr\" rest \"$line\"\n" if $V>4; if ($hdr eq 'X') { if ($line =~ s/(\d+)\s*//) { $X = $1; print "$me: X: \"$X\"\n" if $V>1; } else { } } elsif ($hdr eq 'K') { if (!$K) { $K = $line; print "$me: K: \"$K\"\n" if $V>1; if ($K =~ /^hp\b/i) { print "$me: K: \"$K\" treated as A.\n" if $V>1; $K = 'Amix'; } } } elsif ($hdr eq 'L') { if (($n,$d) = ($line =~ m"^(\d+)/(\d+)")) { $L = "$n/$d"; print "$me: L: \"$L\"\n" if $V>1; } else { print STDERR "$me: Can't parse \"$hdr: $line\"\n" if $V>1; } } elsif ($hdr eq 'M') { if (($n,$d) = ($line =~ m"^(\d+)/(\d+)")) { $M = "$n/$d"; print "$me: M: \"$M\"\n" if $V>1; unless ($L) {($L = $M) =~ s/^\d*/1/} } elsif ($line =~ /^C/) { # C or C| $M = "4/4"; # Treat both as 4/4. $L = "1/4" unless $L; } elsif ($line =~ /^O/) { # O or O| (not standard yet) $M = "3/4"; # Treat both as 3/4. $L = "1/4" unless $L; } else { print STDERR "$me: Can't parse \"$hdr: $line\"\n" if $V>1; } print "$me: M: \"$M\" L: \"$L\"\n" if $V>1; } elsif ($hdr eq 'T') { if (!$T) { $T = $line; print "$me: T: \"$T\"\n" if $V>1; } } else { print "$me: Header \"$hdr\" ignored.\n" if $V>2; } } else { print "$me: Line \"$line\"\n" if $V>3; push @tune, $line; } } if (@tune) { $lines = @tune; print "$me: Tune has $lines lines.\n" if $V>3; print "$me: $C->abcCode(\"$K\",\"$L\",\"$M\",\"@tune\")\n" if $V>3; ($GB,$JC,$notes) = $C->abcCode($K,$L,$M,@tune); print "$GB $JC $notes ($T)\n"; } exit $exitstat; sub newTune { $X = $T = $K = $L = $M = ''; $lines = 0; @tune = (); }