JavaScriptのAnalyzerNodeで拾った音の周波数を可視化してみる3までの記事で、

HTML5のWeb Audio APIにあるAnalyzerNodeでマイクから拾った音を周波数データとして取得してみた。


今回はこのデータを使って、

HTML5 Canvasで作成したアニメーションを制御してみる。


はじめに音は関係なく、丸がただ動くだけのアニメーションを作成してみる。

今回は前回のコードのdraw関数のみの修正となるので、

実際に書いたコードもdraw関数のみとする。

※一部グローバル変数をdraw関数の外に書く。


//グローバル変数として、円の描写位置と移動に関する変数をdraw関数の外で定義する
var x = 50;
var y = 50;
var moveX = 1;
var moveY = 1;

function draw() {
	/** 描写 **/
	ctx.beginPath();
	ctx.fillStyle = "white";
	ctx.rect(0, 0, canvas.width, canvas.height);
	ctx.fill();

	//半径5の円を描写
	ctx.beginPath();
	ctx.strokeStyle = "black";
	ctx.arc(x, y, 5, 0, Math.PI * 2);
	ctx.stroke();

	x += moveX;
	y += moveY;

	if (x < 0 || x > canvas.width) {
	    moveX *= -1;
	}

	if (y < 0 || y > canvas.height) {
	    moveY *= -1;
	}
}

このコードを実行してみると、


fft_circle_move


円が右斜め下に移動して画面端にぶつかると方向を変えるという何の変哲もないアニメーションが実行される。


このアニメーションに対して、FFTによる音の解析を追加して、

何らかの音を感知したら進行方向を変えるという処理を追加してみる。


//グローバル変数の追加
var timeoutId;

function draw() {

	/** 描写。前のコードと同じなので省略 **/

	/** 下記のコードが追加分 **/
	
	//音によって向きを変える
	var bufLen = analyser.frequencyBinCount;
	var data = new Uint8Array(bufLen);
	analyser.getByteFrequencyData(data);

	//取り出した周波数データの一部を使って判定。
	//data[20] > 15の2つの数字は適当に決めた
	if (!timeoutId && data[20] > 15) {
		//方向変更の向きはランダムで決める
		var r = parseInt(Math.random() * 2);
		if (r % 2 == 0) {
			moveX *= -1;
		} else {
			moveY *= -1;
		}

		//FFTは一度音を拾うと、音がなくなってもしばらくデータがあることになるため、
		//setTimeoutで一度音で処理を変更したら一定時間変更を受け付けないようにする
		timeoutId = setTimeout(function() {
			clearTimeout(timeoutId);
			timeoutId = null;
		}, 1000);
	}
}

音に関する処理を追加して実行してみると、

パソコンの前で拍手する度に円の進行方向が変化する。