ブラウザーピアノをAudio Data APIで作り直す
最後に、本連載で以前作った、HTML5 Audioを使ってピアノ演奏できる「ブラウザーピアノ」をAudio Data APIで実装し直してみましょう。Audio Data APIを使えばサウンドファイルが不要になるので、データの読み込みのタイムラグがなくなります。
- ・第37回「iPad対応!HTML5 Audioで作るブラウザーピアノ」
- http://ascii.jp/elem/000/000/533/533100/
基本的にはサンプル6のstartAudio()をそのまま利用し、鍵盤がクリックされたとき(キーボードが入力されたとき)に音を出す処理を加えます。出力する音の周波数は以下のようにハッシュ(連想配列)を使って設定しておきます。これで、freq[クリックされた要素のID名]とするだけで簡単に出力すべき周波数を求められます。
freq["C3"] = 261;
freq["D3"] = 293;
freq["E3"] = 329;
freq["F3"] = 349;
freq["G3"] = 392;
freq["A3"] = 440;
freq["B3"] = 493;
freq["C4"] = 523;
freq["Cp3"] = 277;
freq["Dp3"] = 311;
freq["Fp3"] = 370;
freq["Gp3"] = 415;
freq["Ap3"] = 466;
実際のプログラムはサンプル7です。以前のプログラムからの変更箇所にはコメントに★印をつけてあります。サンプルは同時に音が出ないようにしてありますが、先頭行とstartAudio()内の一行を変更するだけで同時に複数の音を出せます。
●サンプル7[HTML]
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>Audio Data APIを使った楽器</title>
<link rel="stylesheet" href="css/main.css" type="text/css" media="all">
</head>
<body>
<div id="kenban">
<div id="C3">ド<br>z</div>
<div id="D3">レ<br>x</div>
<div id="E3">ミ<br>c</div>
<div id="F3">ファ<br>v</div>
<div id="G3">ソ<br>b</div>
<div id="A3">ラ<br>n</div>
<div id="B3">シ<br>m</div>
<div id="C4">ド<br>,</div>
<div id="Cp3">ド#<br>s</div>
<div id="Dp3">レ#<br>d</div>
<div id="Fp3">ファ#<br>g</div>
<div id="Gp3">ソ#<br>h</div>
<div id="Ap3">ラ#<br>j</div>
</div>
<script type="text/javascript" src="js/sound.js"></script>
</body>
</html>
●サンプル7[sound.js]
var audio = new Audio(); // 同時に和音を出せないようにする
var freq = []; // ★音階に応じた周波数を入れる配列
freq["C3"] = 261;
freq["D3"] = 293;
freq["E3"] = 329;
freq["F3"] = 349;
freq["G3"] = 392;
freq["A3"] = 440;
freq["B3"] = 493;
freq["C4"] = 523;
freq["Cp3"] = 277;
freq["Dp3"] = 311;
freq["Fp3"] = 370;
freq["Gp3"] = 415;
freq["Ap3"] = 466;
// クリックイベントを設定
var list = ["C3", "D3", "E3", "F3", "G3", "A3", "B3", "C4",
"Cp3", "Dp3", "Fp3", "Gp3", "Ap3" ];
for(var i=0; i<list.length; i++){
var ele = document.getElementById(list[i]);
ele.addEventListener("click", function(){
startAudio(freq[this.id]); // ★指定した周波数の音を出す
}, true);
}
// キーボード入力に対応させる
var keydata = [
{ key : "Z", sound : "C3" },
{ key : "X", sound : "D3" },
{ key : "C", sound : "E3" },
{ key : "V", sound : "F3" },
{ key : "B", sound : "G3" },
{ key : "N", sound : "A3" },
{ key : "M", sound : "B3" },
{ key : String.fromCharCode(188), sound : "C4" },
{ key : "S", sound : "Cp3" },
{ key : "D", sound : "Dp3" },
{ key : "G", sound : "Fp3" },
{ key : "H", sound : "Gp3" },
{ key : "J", sound : "Ap3" }
]
document.addEventListener("keydown", function(e){
var k = String.fromCharCode(e.keyCode);
for(var i=0; i<keydata.length; i++){
if (k == keydata[i].key){
startAudio(freq[keydata[i].sound]); // ★指定した周波数の音を出す
}
}
}, true);
// ★指定された周波数の音を出す
function startAudio(freq){
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 k = 2* Math.PI * freq / sampleRate;
for(var i=0; i<data.length; i++){
data[i] = Math.sin(k * i);
}
audio.mozWriteAudio(data);
audio.play();
}
◆
次回はAudio Data APIとMML (Music Macro Language) を組み合わせて、音楽を演奏してみます。お楽しみに。