On Sunday 18 January 2009, Tim Woodall wrote: > And, of course, I found some bugs as soon as I'd posted. > > Quick breakdown of how it works incase anyone really wants to hack on > it. > > First it splits the three parts out into three files. Basically all it > does is remove the other two notes from inside <>. It does depend on the > chord all being on one line to do this. It also makes sure each chord on a > separate line in the output files. Note that line n in one file > corresponds to line n in the other files as well. > > Next it reads in what it has written into three arrays. > > For each chord it then calculates the number of notes from the first > note in the previous chord to the first note in this chord (d1) and from > the first note in this chord to the other two notes in this chord (d2 > and d3) > > It subtracts the distance from the first note of the previous chord to > the other notes in that chord (od1 and od2). Then it calculates how many > octave changes are needed for each step. v1, v2 and v3. > > It replaces any existing ', in the chord with the values in v1, > v2 and v3 (note that replacing v1 should be a no-op) > > And finally it writes the arrays back into the files it read them from. > > Tim. > > > #!/bin/bash > > cat test.ly | sed 's/<[^<>a-g]*\([a-g][a-g]*[^a-g>]*\) [^>]*>\([^<]*\)/\n<\1>\n\2/g' >part1.ly > cat test.ly | sed 's/<[^<>a-g]*[a-g][a-g]*[^>a-g]*\([a-g] [a-g]*[^a-g>]*\)[^>]*>\([^<]*\)/\n<\1>\n\2/g' >part2.ly > cat test.ly | sed 's/<[^<>a-g]*[a-g][a-g]*[^>a-g]*[a-g] [a-g]*[^>a-g]*\([a-g][a-g]*[^a-g>]*\)[^>]*>\([^<]*\)/\n<\1>\n\2/g' >part3.ly > > c=0 > while read -r line; do > line1[$c]="$line" > c=$(($c+1)) > done <<EOF > $( < part1.ly ) > EOF > > c=0 > while read -r line; do > line2[$c]="$line" > c=$(($c+1)) > done <<EOF > $( < part2.ly ) > EOF > > c=0 > while read -r line; do > line3[$c]="$line" > c=$(($c+1)) > done <<EOF > $( < part3.ly ) > EOF > > c=0 > > note_cannonical() { > local note > local val=0 > local accidental="" > local octave=0 > note=$( echo $1 | sed "s/[^a-gis',]//g" ) > > case $note in > a*) val=0 ;; > b*) val=1 ;; > c*) val=2 ;; > d*) val=3 ;; > e*) val=4 ;; > f*) val=5 ;; > g*) val=6 ;; > *) echo "Error bad note $note"; exit 1 ;; > esac > note=${note#?} > > while [[ "$note" != "" ]]; do > case $note in > es*) accidental="${accidental}es"; note=${note#es} ;; > is*) accidental="${accidental}is"; note=${note#is} ;; > \'*) octave=$(($octave+1)); note=${note#?} ;; > ,*) octave=$(($octave-1)); note=${note#?} ;; > *) echo "Error bad adjust $note"; exit 1 ;; > esac > done > > echo "$val:$accidental:$octave" > } > > calc_delta() { > local p1=${1%%:*} > local p2=${2%%:*} > local o2=${2##*:} > local dn > > if [[ $p2 -gt $p1 ]]; then > if [[ $(($p2-$p1)) -le 3 ]]; then > dn=$(($p2-$p1)) > else > dn=$(($p1-7-$p2)) > fi > else > if [[ $(($p2-$p1)) -ge -3 ]]; then > dn=$(($p2-$p1)) > else > dn=$((7-$p1+$p2)) > fi > fi > > dn=$(($o2*7+$dn)) > > echo $dn > } > > calcoctave() { > local off=$1 > local n="" > > while [[ $off -ge 4 ]]; do > n="${n}'" > off=$(($off-7)) > done > > while [[ $off -le -4 ]]; do > n="${n}," > off=$(($off+7)) > done > > echo $n > } > > note() { > local p=${1%%:*} > local a=${1#*:} > local n=("a" "b" "c" "d" "e" "f" "g") > > echo "${n[$p]}${a%:*}" > } > > replace_note() { > local from="$1" > local r=$2 > local innote=0 > local d > local ret="" > > > while [[ "$from" != "" ]]; do > d=$( echo "$from" | sed "s/\(.\).*/\1/" ) > from="${from#?}" > case $d in > [a-g]) > if [[ $innote == 0 ]]; then > ret="$ret$r" > innote=1 > elif [[ $innote != 1 ]]; then > ret="$ret$d" > fi > ;; > [is\',]) > if [[ $innote != 1 ]]; then > ret="$ret$d" > fi > ;; > \ ) > ret="$ret$d" > ;; > *) > if [[ $innote == 1 ]]; then > innote=2 > fi > ret="$ret$d" > ;; > esac > done > echo $ret > } > > n1="2" > od2=0 > od3=0 > > while [[ $c -lt ${#line1[*]} ]]; do > if [[ ! -z "${line1[$c]}" && "${line1[$c]#*>}" == "" && "${line1 [$c]%<*}" = "" ]]; then > nc1=$( note_cannonical "${line1[$c]}" ) > nc2=$( note_cannonical "${line2[$c]}" ) > nc3=$( note_cannonical "${line3[$c]}" ) > echo $nc1 $nc2 $nc3 > d1=$( calc_delta $n1 $nc1 ) > d2=$(($d1 + $( calc_delta $nc1 $nc2 ) )) > d3=$(($d2 + $( calc_delta $nc2 $nc3 ) )) > echo $d1 $d2 $d3 > v1=$( calcoctave $d1 ) > v2=$( calcoctave $(($d2-$od2)) ) > v3=$( calcoctave $(($d3-$od3)) ) > echo $v1 $v2 $v3 > out1="$(note $nc1)$v1" > out2="$(note $nc2)$v2" > out3="$(note $nc3)$v3" > od2=$( calc_delta $nc1 $nc2 ) > od3=$(($od2 + $( calc_delta $nc2 $nc3 ) )) > echo $od2 $od3 > > line1[$c]=$( replace_note "${line1[$c]}" $out1 ) > line2[$c]=$( replace_note "${line2[$c]}" $out2 ) > line3[$c]=$( replace_note "${line3[$c]}" $out3 ) > n1=${nc1%%:*} > fi > c=$(($c+1)) > done > > c=0; while [[ $c -lt ${#line1[*]} ]]; do echo ${line1[$c]}; c=$(($c+1)); done >part1.ly > c=0; while [[ $c -lt ${#line2[*]} ]]; do echo ${line2[$c]}; c=$(($c+1)); done >part2.ly > c=0; while [[ $c -lt ${#line3[*]} ]]; do echo ${line3[$c]}; c=$(($c+1)); done >part3.ly > > exit 0
Wow. I am impressed, honestly. I am not a programmer, but whether notes are written in \relative or absolute pitch all of the information is already present. I don't think it is necessary to do anything but carry all "," and "'" marks to all following pitches and reduce. \relative --> absolute --> reduce a, b a c ... --> a, b, a, c, ... a,, b' a, c --> a,, b,,' a,,', c,,', --> a,, b, a,, c,, I've always thought \relative to be quicker for a single simple melodic line, but a nightmare for anything with chords in it, so I didn't expect that the OP was dealing with it. If he was. I'm also not sure whether \relative is always necessarily completely linear any more. I haven't used it for a while. CRS. Regards, daveA -- Free download of technical exercises worth a lifetime of practice: http://www.openguitar.com/dynamic.html :::: You can play the cards you're dealt, or improve your hand with DGT. Very easy guitar music, solos, duets, exercises.., To contact, visit openguitar.com _______________________________________________ lilypond-user mailing list lilypond-user@gnu.org http://lists.gnu.org/mailman/listinfo/lilypond-user