#!/usr/bin/perl #!/home/jmc/bin/perl # # abcpar [+|-]interval [file].. # # Read an abc file (or passage from stdin), and write output that has # the same melody plus a harmony line in parallel at the given # interval. The default interval is +2, i.e., a third higher. # # Note that the interval is one less than the musical interval. Maybe # this should be changed ... $| = 1; $| = 1; ($me = $0) =~ s'.*/''; $V = $ENV{"V_$me"} || $ENV{"T_$me"} || $ENV{"D_$me"} || 1; @S = ( "C,,","D,,","E,,","F,,","G,,","A,,","B,,", "C,", "D,", "E,", "F,", "G,", "A,", "B,", "C", "D", "E", "F", "G", "A", "B", "c", "d", "e", "f", "g", "a", "b", "c'", "d'", "e'", "f'", "g'", "a'", "b'", "c''","d''","e''","f''","g''","a''","b''", ); for ($i=0; $i<@S; $i++) { $I{$S[$i]} = $i; } if (($dir, $int) = ($ARGV[0] =~ /^([-+])(\d+)/)) { if ($dir eq '+') { $diff = $int - 1; # Convert to upward difference. } else { $diff = 1 - $int; # Downward difference. } shift; } else { $diff = 2; # Up third. } $A = '[\^=_]*'; # Accidental. $N = '[A-Ga-g][\',]*'; # Note. $L = '[/\d.\<>]*'; # Length. line: for $line (<>) { while ($line) { if ($line =~ s/^(\s+)//) {print $1} if ($line =~ /^([A-Z]:)(\s*)/) { print $line; next line; } elsif ($line =~ s'^("[^"]*"\s*)'') {print $1; next; } elsif ($line =~ s'^(\(\d*\s*)'') {print $1; next; } elsif ($line =~ s'^(\)\s*)'') {print $1; next; } elsif ($line =~ s'^(\[\|\s*)'') {print $1; next; } elsif ($line =~ s'^(\|\]*\s*)'') {print $1; next; } elsif ($line =~ s'^(\[.*\]\s*)'') {print $1; next; } elsif ($line =~ s/^($A)($N)($L)(\s*)//) { $a = $1; $n = $2; $l = $3; $s = $4; $i = $I{$n}; $j = $i + $diff; if ($h = $S[$j]) { # if ($l) { print "[$a$n$l$a$h$l]$s"; # } else { # print "[$a$n$a$h]$l$s"; # } next; } } if ($line =~ s'^(.)'') {print $1; next; } print "Left: \"$line\"\n" if $V>1; } }