グローバル変数 変数としてこれまで扱ってきたものが、実は2種類ある。1つは通常の変数、もう1つはアル ファベット1文字で表される変数である。 通常、変数は実行するコード全体の冒頭で宣言しておかないと、使うことができない。しかも、 いったん実行してしまったら、その後で宣言した名前の変数にアクセスすることはできない。つまり、 その変数の値を後から変えることもできなければ、その変数の値を知ることすらできないのである。 こうした性質は、アルファベット1文字の変数になると異なってくる。アルファベット1文字の 変数の場合、宣言することなく用いることができる。さらに、いったんコードを実行した後で、その 中で使われているアルファベット1文字の変数にアクセスすることができる。 アルファベット1文字の変数の持つ、こうした性質を使って、前回までの例では音の載ってい るノードのID番号や、メロディーを演奏させるためのRoutineなどに用いてきた。それより前から、既 にServer.localで与えられるサーバには、sという変数が当てはめられている。 こうした変数を不必要に多用するのは、コンピューターの処理効率上、推奨されない。さらに、 アルファベットの数には限りがある。しかし、扱わなければならないノードのID番号やRoutineなど が増えてくると、同様の特徴を持つ変数がもっと必要になるだろう。 そこで用意されているのが、グローバル変数である。グローバル変数は ~ (チルダー)で始め、 その後に適当な文字を続けて、名前を付ける。これをあらかじめ宣言しておく必要はなく、一度作っ てしまえば、SuperColliderの起動中、ずっとそのまま扱うことができる。 変数の種類 宣言 有効期間 通常の変数 必要あり コード実行の瞬間のみ アルファベット1文字の変数、及びグローバル変数 必要なし SuperColliderの起動中 例えば、 ~melody1 = Routine.new({ loop({ ... }) }); ~melody1.play; として、演奏を始めたRoutineを ~melody1.stop; として途中で停止させたり、またその後で ~melody1.reset; ~melody1.play; として演奏を開始させたりすることができる。 [問題1] Routineでメロディーを演奏させながら、その音にディレイをかけるまでのプログラムに関して、s 以外 のアルファベット1文字の変数を、全てグローバル変数に書き直して実行しなさい。 バッファを使う(1)──加算合成 音に含まれる様々な周波数の中でも、基本となる周波数(基音)の整数倍にあたる周波数は、 「倍音」と言われ、重要な音の成分と見なされる。SuperColliderでは、基音と倍音の大きさを制御す ることによって波形を合成し、音作りを行なうことができる。これを「加算合成」と呼ぶ。 まず、倍音を持たず、基音のみで構成されるサイン波の波形は、下のようになる。 これに対し、基音に加えて、基音の2倍の周波数の音が基音の半分の大きさで、さらに基音の3 倍の周波数の音が基音の4分の1の大きさで含まれるサイン波の音は、下のようになる。 このように合成された音を出そうとする場合、合成した波形のグラフをいったんコンピュー ター上に記憶させておき、音を出す際にそのグラフを呼び出して用いることとなる。その、グラフを 記憶しておく場所のことを「バッファ」と言う。 音の波形のグラフを使うとなると、そのグラフがどの程度の精度を持つのかが問題となる。例 えば、波形を表すため1秒間を何コマかに分割して捉えようとすれば、そのコマ数が多ければ多い程、 グラフとしての精度は高まる。 この、1秒間を何コマにするかを示した数値を「サンプリング・レート」と言う。現在、一般 的なオーディオCDにおいては、44100Hzのサンプリング・レートが規格として統一されている。 さて、実際にSuperColliderで倍音の加算合成を行なうプロセスを見てみることにしよう。まず、 加算合成で波形のグラフを元に音を出すには、その音源としてOscクラスの.arメソッドを使う。 Osc.ar( グラフの記憶されたバッファ, 周波数, 位相, 増幅値, 加減値 ) 最初の引数が独特だが、後はSinOsc.arの引数がそのまま入る。そして、波形を記憶するバッ ファを用意しなければならない。 Buffer.alloc( サーバ, フレーム数 ) サーバとは、バッファを用意するサーバのことで、ローカル上に設ける場合には s が入る。 フレーム数とは、1周期分の波形のグラフを描くのに用いる、コマ数のことである。 用意されたバッファにサイン波の音を重ねていくには、.sine1メソッドを使うことができる。 .sine1( [増幅値の配列] ) 増幅値の配列は、 [ 基音の増幅値, 2倍音の増幅値, 3倍音の増幅値, 4倍音の増幅値, 5倍音の増幅値, ... ] といった具合に、加えたい倍音の数まで増やすことができる。 バッファを使い終わったら、他の処理のために使用していた領域を開放しておく必要がある。 そのためには、.freeメソッドを用いる。 以上の道具を使って、次のように音を出すことができる。 SynthDef.new( \addSyn1, { arg freq, amp, pos, buffer; var src, env, out; src = Osc.ar( buffer, freq ); env = EnvGen.kr( Env.new( [0, 1, 0.3, 0], [0.01, 0.2, 0.25] ), levelScale: amp, doneAction: 2 ); out = Pan2.ar( src*env, pos ); Out.ar( 0, out ) }).send(s); ~buf = Buffer.alloc( s, 512 ); // フレーム数が512のバッファを用意する ~buf.sine1( [ 1, 0.6, 0.4, 0.3, 0.1 ] ); // 基音の大きさ1に対して、2倍音が0.6、3倍音が0.4、4倍音が0.3、5倍音が0.1の大きさ // となるように、グラフを描く s.sendMsg( \s_new, \addSyn1, n=s.nextNoodeID, 0, 1, \buffer, ~buf ); // 音を鳴らす ~buf.free; // 使い終わったバッファを開放する [問題2] 倍音の加算合成に加え、その位相の値を-piからpiまでの間で変調させ、さらにそれに何らかのフィル ターをかけた音を出すためのSynthDefを作り、その音を鳴らしなさい。 リモートサーバ ここまで、音を鳴らすための音響合成は、SCLangを扱うのと同じコンピューター内の SCSynth、すなわちs = Server.local が行なってきた。 しかし、ネットワークで繋がった他のコンピューター上でも、SCSynthさえ起動していれば、 そこへ向けてコマンドを送ることができ、つまりはそのコンピューターから音を出すことができる。 そのように、ネットワークで繋がった他のコンピューター上のSCSynthのことを、「リモート サーバ」と呼ぶことにする。 リモートサーバは、次のようにServerクラスとNetAddrクラスを使って特定することができる。 Server.new( サーバの名前, NetAddr.new( “IPアドレス”, 57110 ) サーバの名前は、\ (バックスラッシュ)で始めて、適当な名前を付ければ良い。 ここで、リモートサーバとはLANの内部で繋がっているものと仮定すれば、IPアドレスはロー カルのアドレスとなる。57110は、サーバ間でOSCのデータをやりとりする際のポート番号である。 実際にリモートサーバで音を鳴らすまでを見てみよう。 ~remoteSvr = Server.new( \remote1, NetAddr.new( “192.168.1.10”, 57110 ) ); SynthDef.new( \test, { arg freq, … ; … } ).send( ~remoteSvr ); ~remoteSvr.sendMsg( \s_new, \test, … ); [問題3] い。 [問題2]で作った音でメロディーを奏でるRoutineを作り、それを特定のリモートサーバから鳴らしなさ
© Copyright 2024 ExpyDoc