Canvasに描かれた絵を音にして演奏する
最後に応用編として、HTML5のCanvas上にマウスで描いた絵を音に変換して演奏するプログラムを紹介します(サンプル6)。Canvasの線の横位置を音の周波数と見なして、上から下方向に向かって処理していくことで変わった音を鳴らします。
また、演奏中の場所が分かるように、以下のようにdiv要素のY座標を変更して黄色いバーを表示しています。
document.getElementById("scan").style.top = audioY+"px";
●サンプル6 [HTML]
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>画像を音にして出力する</title> <link rel="stylesheet" href="css/main.css" type="text/css" media="all"> </head> <body> <canvas id="myCanvas" width="500" height="200"> HTML5 Canvasに対応したブラウザを使用してください。 </canvas> <form> <input type="button" value="演奏する" onClick="playAudio()"> </form> <div id="scan"></div> <script type="text/javascript" src="js/draw.js"></script> <script type="text/javascript" src="js/audio.js"></script> </body> </html>
●サンプル6 [draw.js]
var drawFlag = false; var oldX = 0; var oldY = 0; window.addEventListener("load", function(){ var can = document.getElementById("myCanvas"); can.addEventListener("mousemove", draw, true); can.addEventListener("mousedown", function(e){ drawFlag = true; oldX = e.clientX; oldY = e.clientY; }, false); can.addEventListener("mouseup", function(){ drawFlag = false; }, false); }, true); // 描画処理 function draw(e){ if (!drawFlag) return; var x = e.clientX; var y = e.clientY; var can = document.getElementById("myCanvas"); var context = can.getContext("2d"); context.strokeStyle = "rgba(255,255,255,1)"; context.lineWidth = 1; context.lineJoin= "round"; // 連結部分を丸にする context.lineCap = "round"; context.beginPath(); context.moveTo(oldX, oldY); context.lineTo(x, y); context.stroke(); context.closePath(); oldX = x; oldY = y; }
●サンプル6 [audio.js]
var audioY; var canvasWidth = document.getElementById("myCanvas").width; // キャンバスの横幅 var canvasHeight = document.getElementById("myCanvas").height; // キャンバスの縦幅 var context = document.getElementById("myCanvas").getContext("2d"); // Canvasデータを音データに変換して出力する function playAudio(){ audioY = 0; pixels = context.getImageData(0, 0, canvasWidth, canvasHeight).data; outputSound(); } function outputSound(){ var soundData = []; for(var x=0; x<canvasWidth; x++){ var ptr = (audioY * canvasWidth + x) * 4; soundData[x] = pixels[ptr]; // 赤の輝度だけで処理する } startAudio(soundData); audioY++; if (audioY < canvasHeight) setTimeout("outputSound()", 100); // 1 Line = 0.1sec document.getElementById("scan").style.top = audioY+"px"; } function startAudio(pixelData){ var sampleRate = 44100; // 44.1kHz var audio = new Audio(); audio.mozSetup(1, sampleRate); // 1ch, 44kHz var bufferSize = sampleRate * 1; // 1000ms var data = new Float32Array(bufferSize); var p = sampleRate / canvasWidth; for(var i=0; i<data.length; i++){ if (pixelData[Math.floor(i/p)] < 250) continue; var k = 2* Math.PI * i / sampleRate; for(var j=0; j<p; j++){ data[i+j] += Math.sin(k * i); } } audio.mozWriteAudio(data); audio.play(); }
◆
Audio Data APIは現時点ではFirefox 4ベータ版でしか動作しませんし、バグなのか仕様なのか不明な部分も多くあります。それでもプログラムで自由に音が生成できるのは大きな魅力です。ぜひ試してみてください。