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: Tim Woodall
Subject: Re: splitting chords entered as <<c e g>>^"with stuff" \etc
Date: Sun, 18 Jan 2009 23:50:32 +0000 (GMT)

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


--
God said, "div D = rho, div B = 0, curl E = - @B/@t, curl H = J + @D/@t,"
and there was light.

   http://www.woodall.me.uk/




reply via email to

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