音に反応する
コンピュータに内蔵の、あるいは接続されたマイクから音を入力し、それに応答するようなプログラムを作ります。p5.jsが提供するp5.soundライブラリを使います。Processingのメニュー[スケッチ][ライブラリをインポート] でp5.soundを選択すると、ライブラリがスケッチフォルダのlibraryフォルダ内に取り込まれ、スケッチを保存すると、index.html内に次のscriptタグが追加されます。
<script language="javascript" type="text/javascript" src="libraries/p5.sound.min.js"> </script>
マイクからの音の大きさに応答
マイクからの入力音に応じて、描く円の大きさが変化するスケッチが、リスト6_1です。音声入力を処理するオブジェクトp5.AudioInを使います。 マイクからの入力を処理するいわばプログラムの部品で、実際に働くオブジェクトを作って、スケッチの中で使います。JavaScriptのオブジェクトに関しては、このページで説明しています。
p5.AudioInオブジェクトを作るには new演算子を使います。 次のように、p5.AudioInオブジェクトを作り、マイクから音を入力し、グラフィックスに反映させます。
- (1) マイクからの音声を取得するためp5.AudioInputオブジェクト用の変数を定義。
- (2) setup()の中で、p5.AudioInオブジェクトを作り、変数に格納。
- (3) setup()の中で、p5.AudioInオブジェクトの働きを開始する。
- (4) draw()の中で、p5.AudioInオブジェクトのgetLevel()メソッドを使い、音量を取得。getLevel()の返す値は0~1.0なので、直径の値として適切な大きさ(この例だと0~画面幅の2倍の間の値)になるように、map()関数を使って比例換算する。
- (5) draw()の中で、上の(4)で計算した値を直径とした円を描く。
【リスト6-1】 let mic; //AudioInオブジェクト用変数←(1) function setup() { createCanvas(250, 250); mic = new p5.AudioIn(); //AudioInの生成←(2) mic.start(); //AudioIn機能を開始←(3) fill(200, 0, 0); } function draw() { background(0); let vol = mic.getLevel(); //音量を取得←(4) //↓(5) 入力値(0から1)を0から500に換算 let d = map(vol, 0, 1, 0, width*2); ellipse(width/2, width/2, d, d); //描画 }
マイク入力のノイズ除去とイージング効果
リスト6_1は、マイクからの入力を0~500の間の値に換算し、それを円の直径としていました。これだと、入力のノイズもそのまま円の大きさに反映するため、動きが細かく変化します。 そこで、今の値と、次の入力値の差が一定以上の場合だけ、円の大きさを変えるようにします。加えて、音の変化を直接そのまま円の大きさの変化とせず、徐々にその大きさに近づいていくように、 イージング効果を付けます。リスト6_1より、スムーズに変化することを、実際に確かめてください。
【リスト6-2】 let mic; //マイクからの音声を取得するAudioInオブジェクト用変数←(1) let easing = 0.15; //イージングの係数、大きい数値は大きく変化 let adjD = 0; //イージングで調整した円の直径 function setup() { createCanvas(250, 250); mic = new p5.AudioIn();//AudioInの生成←(2) mic.start(); //AudioIn機能を開始←(3) fill(200, 0, 0); } function draw() { background(0); let vol = mic.getLevel(); // 音量を取得 (0から1.0の間の値)←(4) let d = map(vol, 0, 1, 0, width*2); //入力値(0から1)を0から500に換算←(5) adjD = lerp(adjD, d, easing); //今のadjDから新しい値Dの差を補間し、15%分変化させる ellipse(width/2, width/2, adjD, adjD); //描画 }
図形を組み合わせ、その位置や大きさをマウスに応答して動くようにすることで、人とコミュニケーションを取っているように見える動くグラフィックスを作ることができます。例えば、話す猫
音声ファイルの再生と応答
リスト6_1は、マイクから入力した音量に応答するスケッチでした。これを音声ファイルの音に応じて、円の大きさが変わるようにします。音声ファイルへのアクセスは、p5.SoundFileオブジェクトを使って行います。音声ファイルへのパスを指定して、p5.SoundFileオブジェクトを生成しておき、p5.SoundFileオブジェクトのメソッドにより、音声を再生、停止します。
音の大きさは、振幅(amplitude)と関係しています。p5 soundライブラリのp5.Amplitudeオブジェクトを使って、値を得ます。
電気信号の世界では、値(実効値)を、一定の時間区間の信号の平均的な大きさとして表します。「平均的な大きさ」とは、測定した値の二乗平均平方根(Root Mean Square:二乗した値の平均値の平方根、RMS値)です。 p5.AmplitudeオブジェクトのgetLevel()メソッドは、1024回データを読み、そのRMS値を計算します(0?1.0の値)。
次のように、音声ファイルをロードし、その振幅を、グラフィックスに反映させます。
- (1) p5.SoundFileとp5.Amplitude用の変数を定義。
- (2) 音声ファイルを用意、前もってロードしておく。preload()関数は、setup関数が実行される前に、自動的に呼び出される。
- (3) setup()の中で、p5.Amplitude()オブジェクトを作り、変数に格納。
- (4) setup()の中で、p5.Amplitude()オブジェクトの働きを開始する。
- (5) draw()の中で、p5.Amplitude()オブジェクトのgetLevel()メソッドを使い、振幅を取得。 getLevel()の返す値は0~1.0なので、直径の値として適切な大きさ(この例だと0~画面幅の2倍の間の値)になるように、map()関数を使って比例換算する。
- (6) draw()の中で、上の(5)で計算した値を直径とした円を描く。
- (7) マウスクリック時に実行されるmousePressed関数を定義。音声が再生されていたら(isPlaying()メソッドの値がtrue)音声を停止、そうでなければ、再生する。
クリックで音声を再生、停止
【リスト6-3】 var song, analyzer; //p5.SoundFileとp5.Amplitude用の変数を定義←(1) function preload() { //音声ファイルをロードしておく←(2) song = loadSound('data/funaJingle.mp3'); } function setup() { createCanvas(250, 250); fill(200, 0, 0); analyzer = new p5.Amplitude();//Amplitudeの生成←(3) analyzer.setInput(song);//Amplitudeからの入力開始←(4) } function draw() { background(0); var rms = analyzer.getLevel(); // 振幅の平均値を取得 (0から1.0の間の値)←(5) var d = map(rms, 0, 1, 0, width*2); //入力値(0から1)を0から500に換算←(6) ellipse(width/2, width/2, d, d); //描画 } function mousePressed() { //マウスクリックで音声を再生、停止←(7) if (song.isPlaying()){ song.stop(); } else { song.loop(); } }
リスト6-3は円の大きさが変わるだけですが、図形を組みわせて人や楽器などのイラストを描き、 音声ファイルに合わせて、各部分の大きさや位置を変化させることで、イラストが音を発しているような印象のアニメーションを作ることができます。 例えば、オタマトーン
演習問題
左図は、9枚の猫のあくびの連続写真を用意し、マイクからの音が大きい時は口を大きく開けた写真を、音が小さい時は口を閉じた写真を表示するようにしています。 入力値が一定以上の時は、最後2枚の写真を交互に表示し、大あくびをしているような効果をつけました。
声を出していっしょにあくびをするような感覚を楽しめるでしょうか。
左図で使っている画像(9枚の猫のあくび写真)をcatフォルダにまとめた圧縮ファイルcat.zipを用意しました。リンクをマウスで右クリックし、メニューから[対象をファイルに保存]。
この写真を使って、あるいは、自分が用意した別の写真やイラストを使って、音と画像が関連するおもしろい内容のコンテンツを考えてみてください。
一つの例を次に載せます。 Happy Birthday