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 と楽譜。
まともな作曲システムにするための最優先は、このプログラムの単純マルコフ過程を N 階マルコフ過程に変えること。
しかし Awk では難しそう。
まして、N の値をパラメータで変更できるようにするには…、無茶か。
すさまじい曲ができてしまったが、先に結果の 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 の値をパラメータで変更できるようにするには…、無茶か。