lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: splitting chords entered as <<c e g>>^"with stuff" \etc


From: David Raleigh Arnold
Subject: Re: splitting chords entered as <<c e g>>^"with stuff" \etc
Date: Mon, 19 Jan 2009 07:05:03 -0500
User-agent: KMail/1.9.9

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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]