Web Audio API でピアノを作ってみる

HTML5 には Web Audio API という JavaScript だけで音を出す API があります。

自分の勉強も兼ねて、とてつもなく簡単にですがピアノを CSS + JavaScript だけで作ってみたいと思います。

Web Audio API

ピアノデモ

鍵盤をクリックすると音が出ます。

Web Audio API

ラ(A)の音が周波数 442Hz のピアノです。音は電子音だし全くピアノっぽくないのですが、Web Audio API の初歩の初歩ですので取り敢えずこれで完成です。

対応ブラウザは InternetExplorer 以外のブラウザで、クロスブラウザ対策が必要ですが使うことが出来ます。IE も 12 で対応予定のようです。Microsoft Egde は対応しています。

JavaScript

window.AudioContext = window.AudioContext || window.webkitAudioContext; //クロスブラウザ対応
var audioCtx = new AudioContext();
 
//引数のヘルツの高さの音を出す関数
function play(hz) {
 
    //正弦波の音を作成
    var osciillator = audioCtx.createOscillator();
 
    //ヘルツ(周波数)指定
    osciillator.frequency.value = hz;
 
    //音の出力先
    var audioDestination = audioCtx.destination;
 
    //出力先のスピーカーに接続
    osciillator.connect(audioDestination);
 
    //音を出す
    osciillator.start = osciillator.start || osciillator.noteOn; //クロスブラウザ対応
    osciillator.start();
 
    //音を0.5秒後にストップ
    setTimeout(function() {
        osciillator.stop();
    }, 500);
}
 
//ピアノの鍵盤を取得
var pianoKey = document.getElementsByClassName("pianokey");
var pianoKeyL = pianoKey.length;
for (i = 0; i < pianoKeyL; i++) {
 
    //クロージャ
    (function(i) {
        pianoKey[i].addEventListener("click", function() {
 
            //鍵盤の位置で周波数を計算
            var h = 442 * Math.pow(2, (1 / 12) * (i - 9));
            play(h);
        }, false)
    })(i)
}

Hz(周波数)の計算

ラ(A)の音を 442Hz として計算をしています。

h = 442 * Math.pow(2, (1 / 12) * (i - 9));

音程が1つ上がるごとヘルツが 2 の 12乗根倍になります。それを JavaScript で計算すると上記のようになります。

ラの音は鍵盤のド(C)の位置から数えて9番目であることを注意して計算するのですが、それを「i-9」の部分で調整しています。

Math.pow は「べき乗」を計算するメソッドで、分数乗も計算できるのでそれを利用します。
2の12乗根 = 2の1/12乗です。

これ以上詳しく話すと JavaScript の話というよりは数学の話になってしまうので、ここまでにしますが興味のある方は紙と鉛筆で計算してみてください!

ピアノのHTML、CSS

大して参考になるような出来ではないですが、下記のような構造になっています。

HTML

<div id="piano">
    <span class="pianokey"></span>
    <span class="pianokey sharp"></span>
    <span class="pianokey"></span>
    <span class="pianokey sharp"></span>
    <span class="pianokey"></span>
    <span class="pianokey"></span>
    <span class="pianokey sharp"></span>
    <span class="pianokey"></span>
    <span class="pianokey sharp"></span>
    <span class="pianokey"></span>
    <span class="pianokey sharp"></span>
    <span class="pianokey"></span>
    <span class="pianokey"></span>
</div>

CSS

.pianokey {
    border: 1px solid #999;
    cursor: pointer;
    display: inline-block;
    height: 200px;
    width: calc(100% / 8 - 2px);
    width: -webkit-calc(100% / 8 - 2px);
}
 
.sharp {
    background-color: black;
    height: 120px;
    margin-left: -4%;
    position: absolute;
    width: 8%;
}
 
#piano {
    margin: 50px auto;
    max-width: 420px;
    position: relative;
}

ピアノの音に近づけたり、音量の調節等も出来るので今後やっていきたいと思います。

不具合関係

iPhone Safari は音がならない

解決できそうなら解決します。

参考ページ

Web Audio API(MDN)
HTML5 の Web Audio API で音楽してみる(CYOKODOG)
ドレミファ音階のHz対応表