小学校教員のためのプログラミング入門
今回は音をいろいろ扱ってみるスケッチを作っていきます.
Processing で音を扱うためにはライブラリを利用することになります.Processing ではライブラリを利用することで,いろいろなことを行うことができるようになります.ライブラリについては http://processing.org/learning/libraries/ を見てください.
音を扱うためのライブラリには様々なものがありますが,標準でついてくる Minim というライブラリを使います.このライブラリを使うには,メニューから [Sketch] - [Import Library] - [minim] を選びます.スケッチコードの一行目に
import ddf.minim.*;
が挿入されれば準備完了です.
最初に音楽ファイルを読み込んで,その曲を演奏するスケッチを作ってみます.
演奏する音楽ファイルを準備してください.ファイル形式は wav や mp3 など様々な形式が扱えます.なお,音楽ファイルは作成しているスケッチの pde ファイルと同じ場所に保存してください.音楽ファイルがない場合は下のものを利用してください.
Minim ライブラリに含まれている様々な機能(メソッド)を利用するためには,まず Minim クラスのインスタンス(Minim オブジェクト)を生成します.なお,Minim オブジェクトはコード全体で利用するのでグローバル変数として宣言します.
Minim minim; void setup() { minim = new Minim( this ); }
minim オブジェクトの準備ができたら,メンバメソッドである loadFile を用いて音源ファイルを読み込みます.loadFIle の引数は音源ファイルのファイル名です.loadFile メソッドは AudioPlayer クラスのインスタンス(AudioPlayerオブジェクト)を戻しますので,それを変数に格納しておきます.この変数はコード全体で利用するのでグローバル変数として宣言します.一方,読み込みは準備的なことですので setup メソッド中でよいでしょう.
AudioPlayer song; : void setup() { : song = minim.loadFile( "moon_p.mp3" );
Minim クラス,AudioPlayer クラスのインスタンスを生成し利用した場合は,スケッチが終了するときに必ず後始末として,AudioPlayerクラスのメンバメソッド close,Minimクラスのメンバメソッド stop,および,super.stop を呼び出す必要があります.
これらのコードは,スケッチが開始するときに必ず呼び出される setup,実行中常に呼び出される draw と同じように用意されている,スケッチが終了するときに必ず呼び出される組み込みメソッド stop の中に書きます.
void stop() { song.close(); minim.stop(); super.stop(); }
読み込んだ音源を演奏するには,読み込んだときに生成された AudioPlayer オブジェクトに対してメンバメソッド play を呼び出します.今回は生成された AudioPlayer オブジェクトは song に格納されていますので,
song.play();
と書けば演奏が開始されます.
いつ演奏させるかについては,今回はキーボード上の P キーが押されたらとしてみます.キーボードが押されたときに呼び出されるメソッドは keyPressed です.また,どのキーが押されたかに関しては,組み込み変数 key に入力された文字が格納されますので,次のようにすることで,P キーが押されたときに演奏を開始することができます.
void keyPressed() { if( key == 'p' ) { song.play(); } }
以上からできあがるスケッチコードを次に示します.なお,draw メソッドの中身はありませんが,これがないとスケッチは終了してしまいますので,必ず書く必要があります.
なお,P キーが押されるたびに,演奏をしなおすようにしたいときは,play メソッドを呼び出す前に rewind メソッドを呼び出すと,頭出しをしてから演奏するという動きになります.一方,演奏終了後 rewind メソッドを呼び出さないと,play メソッドを呼び出しても曲の末尾から演奏を開始することになってしまいますので,再演奏を開始してくれませんので,注意してください.
では,自分でスケッチを完成させてみてください.
効果音など短い音を鳴らす時には AudioPlayer クラスではなく,AudioSnippet クラスを利用します.このクラスを利用するためには,音源ファイルを読み込むときに Minim クラスの loadSnippet メソッドを利用します.
次に示す音源を鳴らすスケッチは,先のコードを次のように変更します.なお,play メソッドの前に rewind メソッドを入れておかないと一回しか音が出ないスケッチになってしまいます.
AudioPlayer song; → AudioSnippet song; song = minim.loadFile("moon_p.mp3"); → song = minim.loadSnippet("pi.mp3");
ここまでは音源ファイルを鳴らすということをしてきました.Processing では音を作って鳴らすことも簡単です.
下のスケッチは,440Hz の正弦波が作る音を発生するものです.
import ddf.minim.*; import ddf.minim.signals.*; Minim minim; AudioOutput out; SineWave sine; void setup() { minim = new Minim(this); out = minim.getLineOut(Minim.STEREO); sine = new SineWave(440, 0.5, out.sampleRate()); out.addSignal(sine); } void draw() { } void stop() { out.close(); minim.stop(); super.stop(); } |
音は空気の振動であることは知っていると思います.音の高低は空気の振動(波)の周波数で決まります.ドレミは周波数の違いということです.上のスケッチで出ている音のドレミの何であるかわかるでしょうか?音名はA,ハ長調ならラの音を鳴らしています.
SineWave メソッドは任意の周波数の正弦波を生成することができ,それを AudioOutput オブジェクトに addSignal メソッドで設定してあげることで,正弦波の音波を出すことができます.周波数を倍にすると 1 オクターブ上,半分にすると 1 オクターブ下になるので,
sine = new SineWave(440, 0.5, out.sampleRate());
の 440 の部分を 880 や 220 に変えると,1 オクターブ上と下のラの音が聞こえるはずです.
ピアノのラもハーモニカのラも周波数は同じです.では,なぜ聞こえる音が違うのかというと,音波の形状(波形)です.実際のラはその周波数を持ったきれいな正弦波ではありません.
ここであらゆる波形は,複数の周波数の正弦波を合成することでできるということを知っているでしょうか.フーリエ解析という数学の技術を使うと,あらゆる波を正弦波に分解することができるのです.これを使って,あるラを分析してみると,複数の高さを持ったラが同時に鳴っていることがわかります.
Processing で複数の周波数の正弦波を合成して出力するには次のようにします.
sine1 = new SineWave(440, 0.5, out.sampleRate()); sine2 = new SineWave(880, 0.2, out.sampleRate()); sine3 = new SineWave(1320, 0.1, out.sampleRate()); out.addSignal(sine1); out.addSignal(sine2); out.addSignal(sine3);
さっきとはちょっと違った音が出たと思います.なお,SineWave メソッドの 2 番目のパラメータは音の強さを指示するもので 0.0 から 1.0 の値を設定することができます.
Processing では正弦波だけでなく,矩形波や三角波(のこぎり派),さらには,自由に形状を指定した波を作って,合成することができます.興味のある人は Minim ライブラリのリファレンスを眺めてみてください.
前回の「図形を動かす」で作成したスケッチ(ドラえもんなどの絵が動くやつ)で,絵が壁にあたったおきに音が鳴るようにしてみましょう.音はたとえば ULTIMATEゲーム事業部フリー効果音 などからダウンロードしてください.
スケッチ名は半角英数字で 学籍番号_K11 とし,pde ファイルを WebClass から提出してください.