このページの本文へ

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

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

文●古籏一浩

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

テンポとオクターブの処理を追加する

 続いて、オクターブとテンポの処理を追加します。MMLではオクターブは「O2」、テンポは「T50」のようにそれぞれ指定します。ここまでに作ったプログラムと異なり、オクターブやテンポを処理したら次のMMLデータを解析しなければなりません。そこで、while(true){...}としてMMLの解析を無限に繰り返し実行し、オクターブやテンポの処理が済んだらcontinueで解析を継続します。

if (onkai == "O") {   // オクターブ指定
    octave = num;
    ptr++;
    continue;
}
if (onkai == "T") {   // テンポ指定
    tempo = num;
    ptr++;
    continue;
}

 オクターブやテンポ以外、つまり通常の音階であれば無限に解析する必要はないので、ループの最後でbreakを使ってループから抜けます。オクターブとテンポの処理を追加したのがサンプル3です。

【図】fig03.png

テンポやオクターブの指定ができる

サンプル3

<!DOCTYPE html> 
<html> 
<head> 
<meta charset="UTF-8" /> 
<title>MMLを使って演奏する3</title> 
</head> 
<body>
<h1>MMLを使って演奏する3</h1>
<form>
<input type="button" value="演奏" onclick="initMML()" /><br />
<textarea cols="20" rows="5" id="track1">T50 O4 C4 D4 E4 F4 G4 A4 B4 O2 C4</textarea>
</form>
<script type="text/javascript">
var freq = [];  // 音階に応じた周波数を入れる配列
freq["R"] = 1;
freq["C"] = 261;
freq["D"] = 293;
freq["E"] = 329;
freq["F"] = 349;
freq["G"] = 392;
freq["A"] = 440;
freq["B"] = 493;
freq["#C"] = 277;
freq["#D"] = 311;
freq["#F"] = 370;
freq["#G"] = 415;
freq["#A"] = 466;
for(i in freq) { freq[i] = freq[i] * 4;    }
// 演奏前の初期化を行う
function initMML(){
    octave = 4;   // オクターブ設定(グローバル変数)
    tempo = 60;   // テンポ設定(グローバル変数)
    ptr = 0;    // 読み出し位置を初期化(グローバル変数)
    playMML();
}
// 再生処理
function playMML(){
    var data = document.getElementById("track1").value;
    var MML = data.split(" ");  // 空白
    while(true){
        if (ptr >= MML.length) return;  // 最後まで演奏が終わっていたら以後の処理はしない
        var sdata = MML[ptr];
        var onkai = sdata.match(/[a-z]+/i)[0].toUpperCase();
        if (sdata.charAt(0) == "#") { onkai = "#"+onkai; }
        var num = sdata.match(/\d+/);
        if (onkai == "O") {   // オクターブ指定
            octave = num;
            ptr++;
            continue;
        }
        if (onkai == "T") {   // テンポ指定
            tempo = num;
            ptr++;
            continue;
        }
        break;
    }
    var sec = (60 / tempo) / num; // 音長を計算
    startAudio(freq[onkai]/octave, sec);
}
// 指定された周波数の音を指定時間出力する
function startAudio(freq, sec){
    var sampleRate = 44100;   // 44.1kHz
    var audio = new Audio();
    audio.mozSetup(1, sampleRate);  // 1ch, 44kHz
    var bufferSize = Math.ceil(sampleRate * sec); // 再生秒数
    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);
    setTimeout("ptr++;playMML()", sec*1000);
    audio.play();
}
</script> 
</body> 
</html>

この連載の記事

一覧へ

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