L-systemを使った作曲
「マッチ箱の脳」というとっても平易な人工知能の入門書がある。WEBバージョンもある。素晴らしい。
- 作者: 森川幸人
- 出版社/メーカー: 新紀元社
- 発売日: 2000/12
- メディア: 単行本
- 購入: 3人 クリック: 60回
- この商品を含むブログ (36件) を見る
L-systemの仕様としては、初期状態が「ド」で、置換規則が
◆ルール1:ドはミ、レ、ファに分裂する
ほぼ日刊イトイ新聞 - がんばれ森川くんの遺伝子くん
◆ルール2:レはドに変化する
◆ルール3:ミはミのまま
◆ルール4:ファはソ、シに分裂する
◆ルール5:ソはレ、ラに分裂する
◆ルール6:ラはファに変化する
◆ルール7:シはシのまま
となっている。この表現では文字とその解釈が一体化しているけれど、本来L-systemそのものは置換規則に従って単に文字列を生成するだけで、文字列を何に応用するか(どう解釈するか)はL-systemとは独立している。
実装では7種類の文字 ドレミファソラシ をそれぞれ 0123456 に変換した。
14 => int N; // 置換規則を適用する回数 .3::second => dur T; StifKarp karp => JCRev rev => dac; .1 => karp.gain; .7 => rev.mix; class Symbol { int symbol; // 文字 null @=> Symbol @ next; } Symbol @ str; // 文字列 init([0]); for (int i; i < N; i++) next(); play(); fun void init(int axiom[]) { new Symbol @=> str; axiom[0] => str.symbol; str @=> Symbol tail; for (1 => int i; i < axiom.cap(); i++) { add(tail, axiom[i]) @=> tail; } } // 置換規則の実装 fun void next() { int s; for (str @=> Symbol @ p; p != null; p.next @=> p) { p.symbol => s; if (s == 0) { 2 => p.symbol; add(add(p, 1), 3) @=> p; } else if (s == 1) { 0 => p.symbol; } else if (s == 2) { // do nothing } else if (s == 3) { 4 => p.symbol; add(p, 6) @=> p; } else if (s == 4) { 1 => p.symbol; add(p, 5) @=> p; } else if (s == 5) { 3 => p.symbol; } else if (s == 6) { // do nothing } } } // 文字列の解釈の実装 fun void play() { [0, 2, 4, 5, 7, 9, 11] @=> int scale[]; for (str @=> Symbol @ p; p != null; p.next @=> p) { 60 + scale[p.symbol] => Std.mtof => karp.freq; 1 => karp.pluck; T => now; } T => now; } fun Symbol add(Symbol pre, int s) { Symbol ns; s => ns.symbol; pre.next @=> ns.next; ns @=> pre.next; return ns; }
StifKarpはSTKのユニットジェネレータで、撥弦楽器の音をシミュレートする。
自己相似的なメロディ。