LoginSignup
18
17

More than 5 years have passed since last update.

Javascriptでドレミを再生

Last updated at Posted at 2015-09-06

「JavaScript で Beep 音を鳴らす方法」を見て、Waveファイルを動的に作成してドレミを鳴らしてみました。

IE9 IE10~ Chrome FireFox Safari iOS
(Safari)
× ×
(遅い)

(遅い)

使い方

play(node, sec)

指定音階(ドレミ)を再生する

引数

  • node
    音階を指定(ド=48,ド#=49…)

  • sec
    長さを指定(秒)

stop()

停止する

ソース

波形を作って音を出すJavascript
<script type="text/javascript">
var audio;

//音階を再生
//node ノード(ド=48,ド#=49…)
//sec 再生秒数
function play(node,sec)
{
    stop();
    if(node>=96)return;

    Hz=11025;//サンプリングレート

    //Waveデータ
    var bytes=new Uint8Array(Math.floor(Hz*sec)+100);

    //Waveヘッダー作成
    var header="524946460000000057415645666D74201000000001000100112B0000112B0000010008006461746100000000";
    for(fp = 0; fp < header.length/2; fp++){
        bytes[fp]=parseInt(header.substr(fp*2,2),16);
    }

    //音階(ドド#レ…シ)の周波数(1オクターブ下がると1/2倍)
    var freqs=[4180, 4428, 4708, 4968, 5264, 5592, 5884, 6300, 6676, 6988, 7476, 7848];

    //1サンプルあたりの位相計算
    octave = Math.floor(node/12); //オクターブ
    freq = freqs[node%12] / (1<<(7-octave)); //周波数
    phase = 6.28 / (Hz / freq);

    //波形作成
    for (t = 0; t < Math.floor(Hz*sec); t++){
        bytes[fp++] = Math.floor(Math.sin(phase*t)*127)+128;
    }

    //データ補正
    setLittleEndian(bytes,4,fp-8);  //ファイルサイズ
    setLittleEndian(bytes,24,Hz);   //サンプリングレート
    setLittleEndian(bytes,40,fp-44);//波形サイズ

    //BASE64変換してオーディオ作成
    str="";
    for (i=0;i<fp;i++){str+=String.fromCharCode(bytes[i]);}
    audio=new Audio("data:audio/wav;base64,"+btoa(str));
    audio.play();
}

function stop()
{
    if (audio&&!audio.ended){audio.pause();audio.currentTime=0;}
}

function setLittleEndian(bytes,p,data)
{
    bytes[p] = (data & 0xFF);
    bytes[p+1] = ((data >> 8) & 0xFF);
    bytes[p+2] = ((data >> 16) & 0xFF);
    bytes[p+3] = ((data >> 24) & 0xFF);
}
</script>
音階再生ボタン
<input type="button" value="ド" onclick="javascript:play(48,1)">
<input type="button" value="レ" onclick="javascript:play(50,1)">
<input type="button" value="ミ" onclick="javascript:play(52,1)">
<input type="button" value="ファ" onclick="javascript:play(53,1)">
<input type="button" value="ソ" onclick="javascript:play(55,1)">
<input type="button" value="ラ" onclick="javascript:play(57,1)">
<input type="button" value="シ" onclick="javascript:play(59,1)">
<input type="button" value="ド" onclick="javascript:play(60,1)">
<input type="button" value="停止" onclick="javascript:stop()">

参考

JavaScript で Beep 音を鳴らす方法
音声処理:WAVEファイルのフォーマット

18
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
17