to top page
2013-01-31
LilyPond と Awk による自動作曲システム ver.minus1.0
楽譜制作ソフトの LilyPond と Awk で自動作曲システムを作った。
すさまじい曲ができてしまったが、先に結果の MIDI と楽譜から示すと次の通り。

bwv997.midi



考え方と具体的にやったことは次の通り。

LilyPond のプログラムでは、メロディを次のような記法で書く。
  r8 a16 b c8 e gis a r a ....
スペースで区切られたひと続きの文字が音の高さと長さを示している。
この形式のソースを読み込んでマルコフ連鎖アルゴリズムで再構成すれば、原曲に似た新曲ができるはずである。

ソースは LilyPond のアーカイブにあるバッハの Prelude to Suite in C Major を借りた。
- Music Listing - without preview images
これを次の Awk プログラムで処理して新しい ly ファイル(LilyPond 形式のファイル)を作り、その ly ファイルを LilyPond のコマンドで処理した結果が上の MIDI と楽譜。

BEGIN {
  maxlines = 4
  parent = PARENT = ""
  print "\\version \"2.14.2\""
  print "\\score {"
  print "\\relative c'' {"
  print "\\key c \\major"
  print "\\time 4/4"
}
{
  for (i = 1; i <= NF; i++) {
    token = $i == "|" ? PARENT : $i
    ++childcnt[parent]
    childlist[parent, childcnt[parent]] = token
    parent = token
  }
}
END {
  while (maxlines--) {
    line = ""
    parent = PARENT
    while (childcnt[parent]) {
      i = int(childcnt[parent] * rand()) + 1
      line = line " " childlist[parent, i]
      parent = childlist[parent, i]
      if (parent == PARENT) break
    }
    print line
  }
  print "}"
  print "\\layout { }"
  print "\\midi { } }"
}

まともな作曲システムにするための最優先は、このプログラムの単純マルコフ過程を N 階マルコフ過程に変えること。
しかし Awk では難しそう。
まして、N の値をパラメータで変更できるようにするには…、無茶か。