このページの本文へ

Audio Data APIでブラウザーをシーケンサーに! (6/6)

2010年11月02日 10時00分更新

文●古籏一浩

  • この記事をはてなブックマークに追加
本文印刷

Canvasに描かれた絵を音にして演奏する

 最後に応用編として、HTML5のCanvas上にマウスで描いた絵を音に変換して演奏するプログラムを紹介します(サンプル6)。Canvasの線の横位置を音の周波数と見なして、上から下方向に向かって処理していくことで変わった音を鳴らします。

 また、演奏中の場所が分かるように、以下のようにdiv要素のY座標を変更して黄色いバーを表示しています。


document.getElementById("scan").style.top = audioY+"px";


【図】fig06.png

Canvasに描かれた絵を音に変換して演奏する

サンプル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ベータ版でしか動作しませんし、バグなのか仕様なのか不明な部分も多くあります。それでもプログラムで自由に音が生成できるのは大きな魅力です。ぜひ試してみてください。

前へ 1 2 3 4 5 6 次へ

この連載の記事

一覧へ

この記事の編集者は以下の記事をオススメしています