10 オリヴィエ・メシアンの様式に基づく即興の自動生成パッチ
オリヴィエ・メシアンは、その著書「わが音楽語法 Mon langage musical (1944)」(日本語版は平尾貴四男訳、昭和29年(1954年)出版で現在は絶版。フランス語原語版はAlphonse Leduc社から2014年現在も発売中)
追記:2018年に 細野 孝興 (翻訳) 「音楽言語の技法」としてヤマハミュージックエンタテイメントホールディングスから新規発売された。
で、その当時の彼自身の語法を詳しく説明している。これによって、メシアン初期の楽曲、例えば「主の降誕」「キリストの昇天」「アーメンの幻影」「時の終わりのための四重奏曲」(「世の終わりのための四重奏曲」という訳が日本では出回っているが、あくまでもfin du temps時の終わりであり、fin du monde世の終わりではない。)などの様式に基づいた即興をOpenMusic上で再現することは、比較的簡単にできる。
このパッチでは、音高を「移調の限られた旋法 Mode de transpositions limitées」「ヴィトライユ Vitrail (英語で言うステンドグラスのこと。昭和29年の日本語版(平尾訳)では「焼絵硝子の効果」と訳されている)」の2つに基づき、また小節線を「素数」で指定し、リズムを「添加された音価 valeurs ajoutés」「非逆行リズム rythme non-rétrograde」「拡大・縮小リズム rythmes augmentés ou diminués」に基づき生成する。
全てのパートの音高
まずサブパッチMTLを作成する。
ここではメシアンの示した7つのモードをそれぞれchordで表している。それらはlistで一つにまとめられ、あとから指定できるようになっている。
listのinput 0には、中央ド(6000)の1音だけが指定されている。これは2つの理由からである。まず(前のチュートリアルでも繰り返し述べた通り)LISPは0からものを数えるということ。0にダミーの値が入っていれば、これによりMTL1を指定したい時には1を、MTL2は2を指定すれば良い。0から数え始めてMTL1に0を、MTL2に1を指定するのはわかりにくいからである。もう一つの理由は、ピアノパートでヴィトライユを移調する時に、0を指定すれば「移調無し」と見なすからである。
ここではメシアンの示した7つのモードをそれぞれchordで表している。それらはlistで一つにまとめられ、あとから指定できるようになっている。
listのinput 0には、中央ド(6000)の1音だけが指定されている。これは2つの理由からである。まず(前のチュートリアルでも繰り返し述べた通り)LISPは0からものを数えるということ。0にダミーの値が入っていれば、これによりMTL1を指定したい時には1を、MTL2は2を指定すれば良い。0から数え始めてMTL1に0を、MTL2に1を指定するのはわかりにくいからである。もう一つの理由は、ピアノパートでヴィトライユを移調する時に、0を指定すれば「移調無し」と見なすからである。
次のサブパッチvitrailの中身はこのようになっている。
listにはそれぞれlistに2つずつの和音が入っており、それぞれ2つ目は完全4度(2番目がfa, la#となっているのはご愛嬌。表示が気になる人は中身のウィンドウで音符を右クリックしてsi♭に変えて下さい)が指定されている。上の完全4度音はそれぞれ長2度ずつ下がり、下の和音は保続される。
listにはそれぞれlistに2つずつの和音が入っており、それぞれ2つ目は完全4度(2番目がfa, la#となっているのはご愛嬌。表示が気になる人は中身のウィンドウで音符を右クリックしてsi♭に変えて下さい)が指定されている。上の完全4度音はそれぞれ長2度ずつ下がり、下の和音は保続される。
小節
サブパッチrythmeを見てみよう。(ここではフランス語の綴りで書いているが、名前は自由なので英語でrhythmと書いてももちろん良い。)
リズムを決める前に、まずは「素数」に基づく小節を生成する。
prime-serを用意し、20を与える。この関数は20までに含まれる素数の列を返す。結果は (1 2 3 5 7 11 13 17 19) となる。
ここから3つずつ並んだ素数の列をランダムに取ることとする。例えば (3 5 7) (7 11 13) などである。これをinput 0で指定された回数分繰り返すこととする。
このサブパッチでは小節数を指定するが、それぞれの小節の中のリズムを生成するわけではない。ただし、それぞれの小節はピアノパートの中のリズムの配分を決めるのに使われる。
リズムを決める前に、まずは「素数」に基づく小節を生成する。
prime-serを用意し、20を与える。この関数は20までに含まれる素数の列を返す。結果は (1 2 3 5 7 11 13 17 19) となる。
ここから3つずつ並んだ素数の列をランダムに取ることとする。例えば (3 5 7) (7 11 13) などである。これをinput 0で指定された回数分繰り返すこととする。
このサブパッチでは小節数を指定するが、それぞれの小節の中のリズムを生成するわけではない。ただし、それぞれの小節はピアノパートの中のリズムの配分を決めるのに使われる。
このサブパッチは、ワンスモードでブロックしておくこと。そうしないと、各パートごとの小節がバラバラになってしまう。
ピアノパート
まずはピアノパートから作って行こう。
リズム:「添加価値」を素数の小節から生み出し、それらを最終的に反転させたものを加えることによって「非逆行リズム」を生み出す。ここで生み出されたリズムは、他のパートで「拡大リズム」として引き延ばされて用いられる。
音高:「ヴィトライユ」和音を「移調の限られた旋法」に基づいて移高させる。
音高:「ヴィトライユ」和音を「移調の限られた旋法」に基づいて移高させる。
まずはサブパッチの中身を見てみよう。input 0には生成された小節線のリズムが与えられている。
リズムを生成するためのomloopを見てみよう。
このomloopの内部では、先ほど生成された小節線のリズムである1から19までの素数の数列の値が1つずつ与えられる。
om-randomは2以上・与えられた素数以下の数値をランダムに生成する。この数値は各小節をその数値で割り、その剰余を末尾につけたリストを生成する。すなわち、13を3で割ったとしたら (3 3 3 3 1)というリストを、om//, repeat-n, x-appendによって生成する。ここでもし0が生成された場合はそれをremoveで除去する。例えば1/2=0…1といった場合である。
次に、permut-randomによってこのリストを例えば (3 3 3 3 1) を (3 3 1 3 3) のように並び替える。これでメシアンの言う「添加価値」を再現する。このpermut-randomは、ワンスモードでブロックしておくこと。
次のomifが2重になった部分は、最初または最後に異なる価値を持つリズムが来た場合、それをrotateで回転させている。これによりもしリスト全体が2より大きい個数の値を持っていた場合、添加価値はリストの端ではなく中ほどに置き換わることとなる。
ここまでを一旦collectでまとめる。eachtimeはcollectの直下に繋ぐ。
ところが、finallyに通す前にもう一仕事必要である。ここでメシアンの言う「非逆行リズム」を再現するためである。
reverseを置き、以下のようなomloopを置く。
om-randomは2以上・与えられた素数以下の数値をランダムに生成する。この数値は各小節をその数値で割り、その剰余を末尾につけたリストを生成する。すなわち、13を3で割ったとしたら (3 3 3 3 1)というリストを、om//, repeat-n, x-appendによって生成する。ここでもし0が生成された場合はそれをremoveで除去する。例えば1/2=0…1といった場合である。
次に、permut-randomによってこのリストを例えば (3 3 3 3 1) を (3 3 1 3 3) のように並び替える。これでメシアンの言う「添加価値」を再現する。このpermut-randomは、ワンスモードでブロックしておくこと。
次のomifが2重になった部分は、最初または最後に異なる価値を持つリズムが来た場合、それをrotateで回転させている。これによりもしリスト全体が2より大きい個数の値を持っていた場合、添加価値はリストの端ではなく中ほどに置き換わることとなる。
ここまでを一旦collectでまとめる。eachtimeはcollectの直下に繋ぐ。
ところが、finallyに通す前にもう一仕事必要である。ここでメシアンの言う「非逆行リズム」を再現するためである。
reverseを置き、以下のようなomloopを置く。
ここでもし ((3 3 3 1 3) (2 1 2) (4 3)) というリズムが生成されていた場合、このomloopを通すことによって ((4 3) (2 1 2) (3 1 3 3 3)) のように反転される。これらをx-appendで合体させる。
しかし、このピアノパートでは「ヴィトライユ」に基づいた和音を生成している。つまり各和音は対になっており、右手は指定された完全4度の和音を弾いた後にそこから長2度下がった音を弾くが、左手はその間に和音を保続し、右手の2打音ごとに別の和音に推移する。ということは左手用の和音は、2打音目にはそれ以前の音からタイで繋がっている必要がある。
OpenMusicでは、タイは小数点で表現される。簡単な例を見てみよう。 ((1 2 1.0) (1 1.0 1 1.0)) と書いたときのリズムは以下の通りになる。
先ほどの ((3 3 3 1 3) (2 1 2) (4 3)) の例で見ると、リズムを2つごとにタイで繋げるには、 ((3 3.0 3 1.0 3) (2.0 1 2.0) (4 3.0)) となる必要がある。そのためには、omloopの中でlistloopあるいはforloopとnthの組み合わせを使うには、括弧が1重のみになっていると便利である。flatを使って複重括弧を1つに取り去ろう。もちろんこの括弧は後でもう一度複重にまとめ直す。
omloop 1の中身を見てみよう。
このforloopは、LISPの原則に基づき、0から数え始める。次のoddpは奇数であるかどうかを判断する。forloopは最初のループでは0を出力する(1ではない!)。0は偶数である。判定は偽なので、ここでoddpはnilを返す。omifは判定によってfloatを通すかそのままnthの出力を返すが、ここではnilなので3(整数)のまま返す。
2番目のループに入る。forloopは1を返し、これは奇数なのでoddpは真であるtを返す。omifはその結果により、今度はfloatを通した数を返す。floatは与えられた数を小数にするので、3.0が返される。
collectまでによってここでは (3 3.0 3 1.0 3 2.0 1 2.0 4 3.0) が返される。
2番目のループに入る。forloopは1を返し、これは奇数なのでoddpは真であるtを返す。omifはその結果により、今度はfloatを通した数を返す。floatは与えられた数を小数にするので、3.0が返される。
collectまでによってここでは (3 3.0 3 1.0 3 2.0 1 2.0 4 3.0) が返される。
ここでも「非逆行リズム」を生み出すための反転処理を加えることとする。しかしreverseだけを通した場合、中間点以降で以下のようなエラーが発生することとなる。
もしここまでの左手のリズムの合計が奇数だった場合、右手と左手の和音にずれが生じるここととなる。
そこで、reverseによる反転の後で、整数と小数を逆にしておく必要がある。omloop 3を見てみよう。
そこで、reverseによる反転の後で、整数と小数を逆にしておく必要がある。omloop 3を見てみよう。
integerpは値が整数かどうかを判定する。もしそうであれば、floatを介して小数に変換する。そうでなければ、ここではその値は小数なので、om-roundを使って整数に変換する。
このomloop 3の後で、x-appendによって逆転したリストを合体させる。これによって結果は (3 3.0 3 1.0 3 2.0 1 2.0 4 3.0 3 4.0 2 1.0 2 3.0 1 3.0 3 3.0) のようになる。
ただし、この後で先ほどのような複重括弧に戻す必要がある。そこで omloop 2を見てみよう。
ただし、この後で先ほどのような複重括弧に戻す必要がある。そこで omloop 2を見てみよう。
先ほどの ((3 3 3 1 3) (2 1 2) (4 3) (3 4) (2 1 2) (3 1 3 3 3)) という結果の場合、ここではlistloopは「リスト内のリスト」を順に返す。つまり最初に (3 3 3 1 3) 、次に (2 1 2) 、その次に (4 3) といった具合である。それらの各リストの長さを length で得ると、その結果は (5 3 2 2 3 5) となる。
このリズム生成のためのメインのomloopの終わりに、group-listを使ってリストを複重括弧にまとめ直すと、 ((3 1.0 3 3.0 3) (2.0 1 2.0) (4 3.0) (3 4.0) (2 1.0 2) (3.0 1 3.0 3 3.0)) となる。
これで左手のためのタイを持つリズムが作成できたが、これをさらに reducetree に通すことによって、 ((3 4.0) (2 1.0 2) (3.0 1 3.0 3 3.0)) と表記していたタイが一つの音価にまとまり、 ((7) (3 2) (3.0 4 6)) となる。
この例の中で3つめのリストの1つ目の値である3.0は小数を保持しているが、それは小節をまたいでタイで繋がるためである。
試しに reducetree を通したものと通さないものの2つの声部を見てみると、このようになる。
この例の中で3つめのリストの1つ目の値である3.0は小数を保持しているが、それは小節をまたいでタイで繋がるためである。
試しに reducetree を通したものと通さないものの2つの声部を見てみると、このようになる。
音高
では、先ほどのサブパッチの右の部分を見てみよう。
まず、何個の和音が必要なのかを考える。これは先ほどのomloop 2と同じように各リストの長さを求めておき、その合計値をapplyと関数+で求めれば良い。
しかしヴィトライユは和音が対になって構成されているため、om//で2で割っておく。om/だと分数になってしまうので、om//で整数で割って余りは切り捨てる。(ここでは常に偶数が生成されるのでom/でも2で割り切れるが、一応om//にしておく。)
さて、input 2に与えられたヴィトライユは全部で4つの対からなっている。なのでここのlengthは4を返す。これをom//に与えて4で割り、余りが0以外なら1を足した数を返す。これをrepeat-nに入れて繰り返す。repeat-nは括弧を足すので、それをflatで取り去る。それをpermut-randomで並び替える。このpermut-randomはワンスモードにしておく。
次に2つのomloopを見てみよう。(画面で指定された名前のhautはフランス語で「高い」、basは「低い」を意味する。名前は何でも良いので、英語でhigh, lowと名付けても良い)
しかしヴィトライユは和音が対になって構成されているため、om//で2で割っておく。om/だと分数になってしまうので、om//で整数で割って余りは切り捨てる。(ここでは常に偶数が生成されるのでom/でも2で割り切れるが、一応om//にしておく。)
さて、input 2に与えられたヴィトライユは全部で4つの対からなっている。なのでここのlengthは4を返す。これをom//に与えて4で割り、余りが0以外なら1を足した数を返す。これをrepeat-nに入れて繰り返す。repeat-nは括弧を足すので、それをflatで取り去る。それをpermut-randomで並び替える。このpermut-randomはワンスモードにしておく。
次に2つのomloopを見てみよう。(画面で指定された名前のhautはフランス語で「高い」、basは「低い」を意味する。名前は何でも良いので、英語でhigh, lowと名付けても良い)
まずhautから見てみよう。メシアンの「ヴィトライユ」語法によると、右手の完全4度は第2打では常に長2度下がる。なので、listloopで取り出されるそれぞれの対のうちの2番目の値をom-で200下げた後、listで合わせる(x-appendでも同様。)collectした後、最後にflatで括弧を取り去る。
次にbasだが、これは至って単純に、listloopからfirstを取り出すだけである。
次にbasだが、これは至って単純に、listloopからfirstを取り出すだけである。
さて、input 3には、メインパッチで与えられたリストが入って来る。 (2 500) のように指定され、最初の値はMTLのモード番号を、次の値は移調の音程を(セントで)示している。
もし最初の値に0が指定されると、それは中央ド(6000)のみを返すことになる。1以降であればMTLの番号であり、例えば1なら(6000 6200 6400 6600 6800 7000)となり、2なら(6000 6100 6300 6400 6600 6700 6900 7000)となる。
移調には元の音高との差を求めることとなる。メシアンの「ヴィトライユ」の原型は常にdo#(6100)が基音となるように指定されているので、ここでは6100の値となるdo#をnoteで指定し、その差を求めている。
それからnth-randomで、それらの音階の中からランダムな音高を取り出す。これは先ほどapplyで求めた数だけrepeat-nで繰り返される。このrepeat-nはワンスモードでブロックしておく。(もしnth-randomをワンスモードにすると、常に一つの音のみが繰り返し指定されることになる)
左手が1つの和音を弾く間、右手はその音高に基づいた和音を長2度下降しながら2回ずつ弾くことになる。その間同じ音高で移調しなければならないので、1つの値を2度繰り返して与えることとなる。それには以下の単純なomloopを作ってやれば良い。
もし最初の値に0が指定されると、それは中央ド(6000)のみを返すことになる。1以降であればMTLの番号であり、例えば1なら(6000 6200 6400 6600 6800 7000)となり、2なら(6000 6100 6300 6400 6600 6700 6900 7000)となる。
移調には元の音高との差を求めることとなる。メシアンの「ヴィトライユ」の原型は常にdo#(6100)が基音となるように指定されているので、ここでは6100の値となるdo#をnoteで指定し、その差を求めている。
それからnth-randomで、それらの音階の中からランダムな音高を取り出す。これは先ほどapplyで求めた数だけrepeat-nで繰り返される。このrepeat-nはワンスモードでブロックしておく。(もしnth-randomをワンスモードにすると、常に一つの音のみが繰り返し指定されることになる)
左手が1つの和音を弾く間、右手はその音高に基づいた和音を長2度下降しながら2回ずつ弾くことになる。その間同じ音高で移調しなければならないので、1つの値を2度繰り返して与えることとなる。それには以下の単純なomloopを作ってやれば良い。
これで、2つの和音のセリーが出来たことになる。これを2つのchord-seqにそれぞれ入れる。
それぞれのMIDIチャンネルは、ここでは1を指定する。
それを2つのvoiceに入れ、リズムをそれぞれ指定する。ここでサブパッチのアウトプットをそれぞれ指定するが、output 0は右手のvoiceのoutput 0 (self)を、output 1は左手のそれを指定する。output 2に右手のvoiceのoutput 1 (rhythm tree)を出力する。
それぞれのMIDIチャンネルは、ここでは1を指定する。
それを2つのvoiceに入れ、リズムをそれぞれ指定する。ここでサブパッチのアウトプットをそれぞれ指定するが、output 0は右手のvoiceのoutput 0 (self)を、output 1は左手のそれを指定する。output 2に右手のvoiceのoutput 1 (rhythm tree)を出力する。
このピアノパートのサブパッチは、ワンスモードでブロックしておくこと。そうしないと、右手と左手の和音指定がずれてしまう。
その他のパート
その他のパートはピアノパートよりも単純である。
この部分のパッチはomloopで連続的に計算されるようになっている。なぜならピアノパート以外は同じ事を計算させるためである。
このパートにはパラメータをリスト化して指定することとする。すなわち(リズム拡大比率の分数、モードの整数、移調の音程のセント単位の整数)である。このコンビネーションは一つの括弧にまとめて与えられ、さらにもう一つの括弧でくくられる。例えば ((4/3 1 1300) (3/2 3 300) (6/5 6 -700)) となる。
この部分のパッチはomloopで連続的に計算されるようになっている。なぜならピアノパート以外は同じ事を計算させるためである。
このパートにはパラメータをリスト化して指定することとする。すなわち(リズム拡大比率の分数、モードの整数、移調の音程のセント単位の整数)である。このコンビネーションは一つの括弧にまとめて与えられ、さらにもう一つの括弧でくくられる。例えば ((4/3 1 1300) (3/2 3 300) (6/5 6 -700)) となる。
OpenMusicでリズムを拡大することは簡単にできる。単純な例を見てみよう。
ここでは元のリズムを3/2に拡大している。結果は1小節足りないが、それはget-signaturesがオリジナルの小節構造を返しているためである。ここをうまく拡大すれば(分母を小さくすれば良い)小節線も拡大できることになるが、このメシアン・パッチではそこまでは要求せず、ピアノパートが終わったら他のパートもそこで終わることとする。
それではこのパート作成omloopを部分ごとに見てみよう。
ここではパラメータの数を数えている。たとえば先ほどの例 ((4/3 1 1300) (3/2 3 300) (6/5 6 -700)) だと、3つのリストがある。ここでは14までを数えることとする。なぜ14か?MIDIは16チャンネルある。チャンネル1は既にピアノパートで用いている。チャンネル10はパーカッションに指定されるので、これを避ける必要がある。そうすると16-2=14となる。
ここでも同じようにMIDIパートを指定している。1は既にピアノで使っているので、2から数え始める。10はパーカッションなのでこれを避けるため、10以上の場合はさらに1を足す。
ここの部分では、先ほどの例のように、リズムを拡大させている。
ここではメロディを作成している。先ほどの移調の例と同じように、MTLの1つをまず指定し、その音階からランダムな1音を選び出している。それからom+で移調させている。
出力結果は、例えば以下のようになる。
出力結果は、例えば以下のようになる。
最終的に、x-appendで全てのパートを合体させ、polyに出力させる。
pgmoutで音色を指定してみよう。例えば「時の終わりのための四重奏曲」の編成ならピアノ、クラリネット、ヴァイオリン、チェロだから(0 72 40 42)のように指定してやれば良いし、全体をオルガンのようにするのなら、(オルガンの音色そのものでなく)リコーダー75を中心に、いくつかの管楽器を指定してやればよい。
polyはMIDIやMusicXMLで出力できるので、finaleやSibeliusで開くことも出来る。
非公式チュートリアル 前後
添付ファイル
- unofficial-tutorial10-01.png
- unofficial-tutorial10-02.png
- unofficial-tutorial10-03.png
- unofficial-tutorial10-04.png
- unofficial-tutorial10-05.png
- unofficial-tutorial10-06.png
- unofficial-tutorial10-07.png
- unofficial-tutorial10-08.png
- unofficial-tutorial10-09.png
- unofficial-tutorial10-10.png
- unofficial-tutorial10-11.png
- unofficial-tutorial10-12.png
- unofficial-tutorial10-13.png
- unofficial-tutorial10-14.png
- unofficial-tutorial10-15.png
- unofficial-tutorial10-16.png
- unofficial-tutorial10-17.png
- unofficial-tutorial10-18.png
- unofficial-tutorial10-19.png
- unofficial-tutorial10-20.png
- unofficial-tutorial10-21.png
- unofficial-tutorial10-22.png
- unofficial-tutorial10-23.png
- unofficial-tutorial10-24.png
- unofficial-tutorial10-25.png
- unofficial-tutorial10-26.png
- unofficial-tutorial10-27.png