※この記事は「はじめての<脱>音楽 やさしい現代音楽の作曲法」における私執筆の「OpenMusic」の基礎及び,前回までのOpenMusicの基礎 番外編シリーズをお読みください.
前回はomloopの非常に基礎的な考え方をご紹介しました.少し難しい(と私は感じるの)ですが,慣れてくるとだんだん意図通りの繰り返し制御ができるようになります.ここからもう少しアルゴリズム作曲に活かせるようなomloopの使い方を紹介したいのですが,その前にご紹介しておきたい話題があります.これを知らないと,複雑なプログラムを意図通りに動作させることができません.
まず,いつも引き合いに出しているMaxで例題となる処理を作ってみます.説明のためだけに作る,全く必然性のない処理ですが,こんな処理です.
①乱数 r(0~10) を発生させる
②乱数 r の値を表示する
③r+r を計算する
④r+rの値を表示する
※「乱数 r 」というのは,勿論便宜的に設定した変数であって,MaxやOpenMusicのようなビジュアルプログラミング環境では,実際にはこのような変数を設定して代入することはしません.
乱数 r の値がいくつであっても,必ずrの2倍の値が表示されるはずです.
こんなパッチになります.Maxのrandomオブジェクトは,アーギュメントの値-1が乱数の最大値となることに注意してください.
このパッチの処理手順は図のようになります.順番が左右あちこちに飛んでいて分かりづらいですが,順番をしっかり確認しましょう.
ここで押さえておきたいのは,一回のbangで①〜⑥の全ての処理が一気に行われるということです.randomオブジェクトは,第1インレットにbangが入力されるまで乱数を新たに発生させませんから,このパッチの+オブジェクトで,まさに r+r の計算が行われることになります.
OpenMusicでも同じように作ってみましょう.これで良いでしょうか?Maxの時のように,1回のEvalBoxごとに1回乱数が発生して,その乱数の2倍の値が出力されるでしょうか?
OM+オブジェクトをEval Boxしてみましょう.
"OM >"となっている行がprintオブジェクトに入力された値,"OM =>"となっている行がOM+オブジェクトをEval Boxした処理結果です.ということは,この処理は,乱数が2回発生して,その和を求めているということになります.
これは,OpenMusicの制御構造を思い出すと,納得できると思います.OpenMusicはMaxとは逆に下から上のオブジェクトへデータを要求していく制御構造になっています.これを踏まえると,このパッチはこのような処理手順で処理を実行しています.図に書き込むと行ったり来たり,非常にややこしくなるので箇条書きにしますが,パッチと見比べながら処理手順を追ってみてください.
① OM+オブジェクトがEval Boxされる(ユーザ操作)
② OM+オブジェクトの第1インレットにデータが未到着なので,上のオブジェクトにデータを要求.
③ PRINTオブジェクトは更に上のオブジェクトにデータを要求
④ OM-RANDOMオブジェクトはデータを要求されたので,乱数を生成してアウトレットから出力
⑤ PRINTオブジェクトは乱数を表示してアウトレットからそのまま出力
⑥ 今回はあくまでOM+オブジェクトの第1インレットからの要求なので,OM+オブジェクトの第1インレットにのみ出力する
⑦ OM+オブジェクトの第2インレットにデータが未到着なので,上のオブジェクトにデータを要求.
⑧ PRINTオブジェクトは更に上のオブジェクトにデータを要求
⑨ OM-RANDOMオブジェクトはデータを要求されたので,乱数を生成してアウトレットから出力
(10) PRINTオブジェクトは乱数を表示してアウトレットからそのまま出力
(12) 今回はあくまでOM+オブジェクトの第2インレットからの要求なので,OM+オブジェクトの第2インレットにのみ出力する
(13) 両方のインレットにデータが到着したので和を計算して表示
PRINTオブジェクトのアウトレットから出ている線の数だけ同じ処理が繰り返されているのです.データが到着していないインレットの数だけ要求が発生するので当然です.そしてそのたびに,OM-RANDOMオブジェクトは乱数を生成しているのです.
これは,1つの要求が終わって,次の要求が始まるまでの間に,それまでのオブジェクトの状況が保持されていないために起こります.
だったら保持するようにしようというのが「ワンスモード」です.
OM-RANDOMオブジェクトを選択してキーボードの"1"キーを押すと,OM-RANDOMオブジェクトの左上に"1"というアイコンがオーバーラップ表示されました.これは,OM-RANDOMオブジェクトがワンスモードに入ったことを意味します.
ワンスモードになったオブジェクトは,1回のEval Boxの間,一回要求に答えたら,処理結果を保持しておき,その後新たな要求が来てもその処理結果をアウトレットから出力するだけになります.このパッチをEval Boxするとこうなります.乱数による偶然ではなく,ちゃんと意図通りの動作をしていることを示すために何度かEval Boxしてみます.
OM-RANDOMオブジェクトが2回とも同じ値を出力していて,r+r が計算できていることがわかります.この時の処理手順は以下のようになります.
① OM+オブジェクトがEval Boxされる(ユーザ操作)
② OM+オブジェクトの第1インレットにデータが未到着なので,上のオブジェクトにデータを要求.
③ PRINTオブジェクトは更に上のオブジェクトにデータを要求
④ OM-RANDOMオブジェクトはデータを要求されたので,乱数を生成してアウトレットから出力.ワンスモードなのでこの値は最後まで保持しておく.
⑤ PRINTオブジェクトは乱数を表示してアウトレットからそのまま出力
⑥ 今回はあくまでOM+オブジェクトの第1インレットからの要求なので,OM+オブジェクトの第1インレットにのみ出力する
⑦ OM+オブジェクトの第2インレットにデータが未到着なので,上のオブジェクトにデータを要求.
⑧ PRINTオブジェクトは更に上のオブジェクトにデータを要求
⑨ OM-RANDOMオブジェクトはデータを要求されたが,ワンスモードなので乱数を生成せず, ④で生成した値をアウトレットから出力
(10) PRINTオブジェクトは乱数を表示してアウトレットからそのまま出力
(12) 今回はあくまでOM+オブジェクトの第2インレットからの要求なので,OM+オブジェクトの第2インレットにのみ出力する
(13) 両方のインレットにデータが到着したので和を計算して表示
これで,r+r の値を計算することはできたのですが,OM-RANDOMオブジェクトが2回動作しているのは変わりません.そこで,PRINTオブジェクトをワンスモードにすることで,2回目の要求でOM-RANDOMオブジェクトの動作を省略することができます.
この時の手順は以下のようになります.
① OM+オブジェクトがEval Boxされる(ユーザ操作)
② OM+オブジェクトの第1インレットにデータが未到着なので,上のオブジェクトにデータを要求.
③ PRINTオブジェクトは更に上のオブジェクトにデータを要求
④ OM-RANDOMオブジェクトはデータを要求されたので,乱数を生成してアウトレットから出力.
⑤ PRINTオブジェクトは乱数を表示してアウトレットからそのまま出力.ワンスモードなのでこの値は最後まで保持しておく.
⑥ 今回はあくまでOM+オブジェクトの第1インレットからの要求なので,OM+オブジェクトの第1インレットにのみ出力する
⑦ OM+オブジェクトの第2インレットにデータが未到着なので,上のオブジェクトにデータを要求.
⑧ PRINTオブジェクトは,ワンスモードなのでOM-RANDOMオブジェクトに値を要求せず, ⑤で生成した値をアウトレットから出力
⑨ PRINTオブジェクトは乱数を表示してアウトレットからそのまま出力
(10) 今回はあくまでOM+オブジェクトの第2インレットからの要求なので,OM+オブジェクトの第2インレットにのみ出力する
(11) 両方のインレットにデータが到着したので和を計算して表示
いかがでしょうか?複雑なプログラムを作ろうとすると,ワンスモードを使いこなす必要があります.特にomloopを使う時は,非常に重要なテクニックになります.
2018年6月5日火曜日
2018年5月24日木曜日
OpenMusicの基礎 番外編 〜omloopの基礎〜
※この記事は「はじめての<脱>音楽 やさしい現代音楽の作曲法」における私執筆の「OpenMusic」の基礎及び,前回のOpenMusicの基礎 番外編をお読みください.
「はじめての<脱>音楽 やさしい現代音楽の作曲法」,すでに重版になったようで,ご好評いただいているようです.私が担当したのはほんの一部だけですが,非常に嬉しく思います.
OpenMusicの特徴は,ソースコードを書かなくても良いグラフィカル・プログラミングですが,グラフィカル・プログラミングは見た目の難しさが少なく,直感的にプログラムを作成しても何らかの結果を得やすいという利点がありますが,一方で,プログラムの制御構造が,グラフィカル・プログラミングという名前とは裏腹に,見ただけでは分からないという欠点もあります.(その制御構造の分かりづらさは前回の記事でお分かりいただけたと思います.)なので,込み入ったプログラムを書こうとすると途端に難しくなってきます.今日ご紹介する繰り返し処理もその一つ.パッチの見た目からこの制御構造を理解するのはほぼ不可能だと思います.
プログラミングでよく使うテクニックに,繰り返し処理があります.その名の通り,同じ処理を指定した回数繰り返す処理です.例えば,10000個の整数全部に100を足す等の処理です.正攻法でいけば,10000回同じ処理を書かないといけないように思えますが,繰り返し処理を使えば,一回だけ処理を書いておいて,それを10000回繰り返させる,といった書き方が可能です.この処理はプログラミングの常識的なテクニックなので,何らかのプログラミング言語を学んだことがある人ならご存知のはずです.
OpenMusicでも繰り返し処理を記述することができます.繰り返し処理を行うオブジェクトが"omloop"オブジェクトです.
パッチ内でomloopオブジェクトを出して,ダブルクリックすると,画像の右側のようなウィンドウが出てきます.このウィンドウが,omloopの中身のパッチを作成するウィンドウで,このウィンドウで作った処理が,繰り返し処理されることになります.
"eachTime"と"finally"というオブジェクトが既にあります.この2つのオブジェクトは繰り返し処理に必須のオブジェクトなので,最初から出ています.
omloopの処理がどのように行われるか知るために,このようなパッチを作りました.Eval Boxすると,OM Listenerウィンドウにこのように表示されます."forloop"オブジェクトは,所謂for文を実装するオブジェクトで,第1インレットの値から第2インレットの値まで内部変数の値を1ずつ増やしながら繰り返しを行うオブジェクトです.
前回の記事で,OpenMusicは,パッチの下から上のオブジェクトにデータの要求を行うという制御構造を説明しました.その考え方でこのパッチを見ると,以下のようなことが起きています.重要なのは,eachTimeの使い方です.eachTimeは,ループの各回の開始時点でデータの要求を行い,データが到着すると,ループが終了するまで,次のデータ要求を繰り返します.
① forloopオブジェクトの内部変数は0(第1インレットで設定したので)
② eachTimeオブジェクトがprintオブジェクトに値を要求
③ printオブジェクトはデータを持っていないのでさらに上のテキストボックスにデータを要求
④ テキストボックスは"hello"を出力
⑤ printオブジェクトはOM Listenerウィンドウに"hello"を表示し,アウトレットからも出力
⑥ eachTimeオブジェクトに"hello"が入力されたので,この回は終了.forloopオブジェクトの内部変数が1増える
⑦ ②〜⑥をforloopオブジェクトの内部変数が9になるまで繰り返す
⑧ forloopオブジェクトの内部変数が9になったのでループは終了.finallyオブジェクトがデータ要求を行い,データを受け取るとomloopオブジェクトの処理は終結.(この時,finallyオブジェクトに入力された値が,omloopオブジェクトのアウトレットから出力される)
このようになります.この処理の結果が,上の画像のOM Listenerウィンドウの表示です.尚,最後,"finish"が2回表示されているのは,1個目は,omloop内のprintオブジェクトに入力された時点の"finish",2個目は,omloopをEval Boxした結果としての"finish"です.
また,forloopオブジェクトの内部変数は,forloopオブジェクトのアウトレットから整数で出力されます.
値の範囲を変えると,この通り.
また,omloopウィンドウ左上にある,緑色の矢印ボタンをクリックすると,インレットオブジェクトが出てきます.そして,パッチウィンドウのomloopオブジェクトには,インレットが増えています.この操作を繰り返すと,インレットをいくつでも増やすことができます.このようにして,omloopオブジェクトの外からomloopオブジェクトに入力した値を,omloopオブジェクトの処理で使うことができるのです.
この他によく使うループの方法として,listloopがあります.listloopオブジェクトは,インレットに入力されたリストの要素をループ毎に順番に1つずつ出力していくオブジェクトです.
長くなりそうなので今回はここまで.
「はじめての<脱>音楽 やさしい現代音楽の作曲法」,すでに重版になったようで,ご好評いただいているようです.私が担当したのはほんの一部だけですが,非常に嬉しく思います.
OpenMusicの特徴は,ソースコードを書かなくても良いグラフィカル・プログラミングですが,グラフィカル・プログラミングは見た目の難しさが少なく,直感的にプログラムを作成しても何らかの結果を得やすいという利点がありますが,一方で,プログラムの制御構造が,グラフィカル・プログラミングという名前とは裏腹に,見ただけでは分からないという欠点もあります.(その制御構造の分かりづらさは前回の記事でお分かりいただけたと思います.)なので,込み入ったプログラムを書こうとすると途端に難しくなってきます.今日ご紹介する繰り返し処理もその一つ.パッチの見た目からこの制御構造を理解するのはほぼ不可能だと思います.
プログラミングでよく使うテクニックに,繰り返し処理があります.その名の通り,同じ処理を指定した回数繰り返す処理です.例えば,10000個の整数全部に100を足す等の処理です.正攻法でいけば,10000回同じ処理を書かないといけないように思えますが,繰り返し処理を使えば,一回だけ処理を書いておいて,それを10000回繰り返させる,といった書き方が可能です.この処理はプログラミングの常識的なテクニックなので,何らかのプログラミング言語を学んだことがある人ならご存知のはずです.
OpenMusicでも繰り返し処理を記述することができます.繰り返し処理を行うオブジェクトが"omloop"オブジェクトです.
パッチ内でomloopオブジェクトを出して,ダブルクリックすると,画像の右側のようなウィンドウが出てきます.このウィンドウが,omloopの中身のパッチを作成するウィンドウで,このウィンドウで作った処理が,繰り返し処理されることになります.
"eachTime"と"finally"というオブジェクトが既にあります.この2つのオブジェクトは繰り返し処理に必須のオブジェクトなので,最初から出ています.
omloopの処理がどのように行われるか知るために,このようなパッチを作りました.Eval Boxすると,OM Listenerウィンドウにこのように表示されます."forloop"オブジェクトは,所謂for文を実装するオブジェクトで,第1インレットの値から第2インレットの値まで内部変数の値を1ずつ増やしながら繰り返しを行うオブジェクトです.
前回の記事で,OpenMusicは,パッチの下から上のオブジェクトにデータの要求を行うという制御構造を説明しました.その考え方でこのパッチを見ると,以下のようなことが起きています.重要なのは,eachTimeの使い方です.eachTimeは,ループの各回の開始時点でデータの要求を行い,データが到着すると,ループが終了するまで,次のデータ要求を繰り返します.
① forloopオブジェクトの内部変数は0(第1インレットで設定したので)
② eachTimeオブジェクトがprintオブジェクトに値を要求
③ printオブジェクトはデータを持っていないのでさらに上のテキストボックスにデータを要求
④ テキストボックスは"hello"を出力
⑤ printオブジェクトはOM Listenerウィンドウに"hello"を表示し,アウトレットからも出力
⑥ eachTimeオブジェクトに"hello"が入力されたので,この回は終了.forloopオブジェクトの内部変数が1増える
⑦ ②〜⑥をforloopオブジェクトの内部変数が9になるまで繰り返す
⑧ forloopオブジェクトの内部変数が9になったのでループは終了.finallyオブジェクトがデータ要求を行い,データを受け取るとomloopオブジェクトの処理は終結.(この時,finallyオブジェクトに入力された値が,omloopオブジェクトのアウトレットから出力される)
このようになります.この処理の結果が,上の画像のOM Listenerウィンドウの表示です.尚,最後,"finish"が2回表示されているのは,1個目は,omloop内のprintオブジェクトに入力された時点の"finish",2個目は,omloopをEval Boxした結果としての"finish"です.
また,forloopオブジェクトの内部変数は,forloopオブジェクトのアウトレットから整数で出力されます.
値の範囲を変えると,この通り.
また,omloopウィンドウ左上にある,緑色の矢印ボタンをクリックすると,インレットオブジェクトが出てきます.そして,パッチウィンドウのomloopオブジェクトには,インレットが増えています.この操作を繰り返すと,インレットをいくつでも増やすことができます.このようにして,omloopオブジェクトの外からomloopオブジェクトに入力した値を,omloopオブジェクトの処理で使うことができるのです.
この他によく使うループの方法として,listloopがあります.listloopオブジェクトは,インレットに入力されたリストの要素をループ毎に順番に1つずつ出力していくオブジェクトです.
長くなりそうなので今回はここまで.
2018年5月2日水曜日
「はじめての<脱>音楽 やさしい現代音楽の作曲法」にて付録記事を掲載しました 〜OpenMusicの基礎 番外編〜
随分久しぶりの投稿になってしまいました.仕事がバタバタし(これは毎年のこと),音楽活動もこれまでのmacaroomに加え,新しい活動も始めました.また,他にもいくつか個人的に引き受けたこともあり,そろそろ何足ものわらじを履くのがキツくなってきました.
そんな中の1つ,この度自由現代社から発売された「はじめての<脱>音楽 やさしい現代音楽の作曲法」において,巻末の付録部分に「OpenMusicの基礎」と題してIRCAMによる作曲支援ソフトウエアOpenMusicの初歩的な使い方を掲載する部分を執筆させていただきました.
OpenMusicは,現代音楽の作曲において多く用いられていながら,日本国内においては紹介される機会も少なく,あまり武器として使っている作曲家は見かけません.しかし,現代音楽史上でも存在感のある作曲家が多く使っていることも事実で,彼らの足跡を辿る良い手がかりにもなり得るソフトウエアです.
しかし,付録として掲載したので,簡単な操作方法の説明と,私が例題として作ったプログラム例を載せるのみにとどまってしまっています.正直な話,あの記事を読んだ結果,OpenMusicの使い方がわかったとして,それを使いこなして創作を行えるかというと,かなり難しいかもしれません.そこで,本ブログで,少しずつではありますが,本付録の補填記事を掲載していきたいと思います.(本記事を読む前に,「はじめての<脱>音楽 やさしい現代音楽の作曲法」を買って読んでくださいね〜)
今回は,プログラマであれば一番気になるところ「OpenMusicプログラミングにおける制御構造」です.本来,プログラミング言語や環境を紹介するときは,これを真っ先に説明しなければならないのですが,本書は作曲法を説明する本であり,プログラミングの本ではないので,省略しました.
まず,比較のために,Maxの制御構造も確認してみましょう.今回作ったのは,非常に簡単なプログラム「100に1を足して100+1=101をコンソールに表示するプログラム」です.こんな感じ.
そんな中の1つ,この度自由現代社から発売された「はじめての<脱>音楽 やさしい現代音楽の作曲法」において,巻末の付録部分に「OpenMusicの基礎」と題してIRCAMによる作曲支援ソフトウエアOpenMusicの初歩的な使い方を掲載する部分を執筆させていただきました.
OpenMusicは,現代音楽の作曲において多く用いられていながら,日本国内においては紹介される機会も少なく,あまり武器として使っている作曲家は見かけません.しかし,現代音楽史上でも存在感のある作曲家が多く使っていることも事実で,彼らの足跡を辿る良い手がかりにもなり得るソフトウエアです.
しかし,付録として掲載したので,簡単な操作方法の説明と,私が例題として作ったプログラム例を載せるのみにとどまってしまっています.正直な話,あの記事を読んだ結果,OpenMusicの使い方がわかったとして,それを使いこなして創作を行えるかというと,かなり難しいかもしれません.そこで,本ブログで,少しずつではありますが,本付録の補填記事を掲載していきたいと思います.(本記事を読む前に,「はじめての<脱>音楽 やさしい現代音楽の作曲法」を買って読んでくださいね〜)
今回は,プログラマであれば一番気になるところ「OpenMusicプログラミングにおける制御構造」です.本来,プログラミング言語や環境を紹介するときは,これを真っ先に説明しなければならないのですが,本書は作曲法を説明する本であり,プログラミングの本ではないので,省略しました.
まず,比較のために,Maxの制御構造も確認してみましょう.今回作ったのは,非常に簡単なプログラム「100に1を足して100+1=101をコンソールに表示するプログラム」です.こんな感じ.
実践的なMaxプログラミングに慣れている方は状況に応じてもっと違った作り方をするかもしれませんが,今回は,制御構造を説明しやすいように画像のように作っています.
Maxのプログラム制御で押さえておきたいのが,
・データが第1インレットに入力されたらアウトレットからデータを出力し,次のオブジェクトに入力される(これがオブジェクトの繋がっている分だけ繰り返される)
・あるオブジェクトからの出力は,右→左の順番でデータが出力される
の2点です.これらを踏まえてこのパッチを見てみると,このような順で処理が行われているということになります.
上記2点の法則に従った順番になっていることを確認してみてください.
Maxはインタラクティブ操作を前提としたイベントドリブンプログラミングになっており,そのため,入力→出力というデータの流れが視覚的にうまく表現されている,非常に優れたプログラミング環境だと思います.
さて,同様の処理をOpenMusicでやると以下のようになります.
このパッチのprintオブジェクトを右クリックして,"Eval Box"をクリックすると,OM Listenerウィンドウに計算結果が表示されるわけです.
この,Eval Boxをクリックした時に,プログラムが実行されるのですが(Maxのインタラクティブなイベントドリブンプログラミングに慣れているとここが分かりづらい),この時,次のようなことが起こります.
・あるオブジェクトがEval Boxされると,そのオブジェクトのインレットに接続されているオブジェクトにデータを要求する
・データを要求されたオブジェクトがデータを持っていればそれを出力する
・データを要求されたオブジェクトがデータを持っていなければ,さらにそのオブジェクトのインレットに接続されているオブジェクトにデータを要求する
・要求の結果,データがインレットに入力されれば,処理してアウトレットから出力
・これをEval Boxしたオブジェクトから上のオブジェクトのつながりの数だけ繰り返す
この箇条書きで分かりましたでしょうか?とても難しいですね.これも,図に処理手順を書くと下のようになります.
Maxとは違い,下から上に要求が伝わり,データが処理されていることに注意してください.
尚,上の図において③と④の順番は,左から右の順でデータが到着しており,Maxとは逆です.この点については,私も現状そこまで詳しくないので,もしかしたら逆かもしれません.しかし,他の処理での挙動を見ていると,どうやら左から右の順でデータが処理されているように思います.
ごく簡単なパッチでのご紹介になりましたが,これがOpenMusicにおけるプログラミングの制御構造になります.このような面倒なことを知らなくても,冒頭紹介した本の付録で紹介した程度のプログラムを作成することは可能です.しかし,omloopや条件分岐等,プログラミングの醍醐味と言える処理を取り入れたパッチを作成しようと思うと,こうした制御構造の理解なしでは自分の意図通りの処理を実装することはかなり困難です.
それではよいアルゴリズム作曲ライフを!!
登録:
投稿 (Atom)




















