このページの本文へ

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

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

文●古籏一浩

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

最初の1音だけを処理する

 最初に、音階を処理するプログラムを作ります。音の周波数は前回のピアノ演奏のプログラムと同様にfreq配列に入れ、音を生成して出力する処理は関数startAudio()に再生秒数を指定できるようにして流用しています。startAudio()関数内の処理については前回の記事を参照してください。

 演奏するMMLはHTMLの入力フォームのテキストエリアに入力します。テキストエリアにはID名を割り当てておき、JavaScriptから以下のようにして内容を読み出します。

var data = document.getElementById("track1").value;

 読み出した内容(MML)は半角空白で区切られているので、split()を使って分割し、1音ずつ配列データに格納します。

var MML = data.split(" ");  // 空白

 次に、配列に格納したデータを1音ごとに処理していきます。まず、最初の1音だけ処理してみましょう。最初の1音は以下のようにして取り出せます。

var sdata = MML[0];

 sdataには「C4」や「#A16」といった文字列が入っているので、取り出した後に音階と音長に分解します。音階は正規表現を使って以下のように指定します。

var onkai = sdata.match(/[a-z]+/i)[0].toUpperCase();

 これで変数onkaiに「C」や「#A」といった音階だけが入ります。同様に正規表現を使って今度は音長を取り出します。

var num = sdata.match(/\d+/);

 音階には#が付いている場合があるので、sdataに#が含まれている場合は変数onkaiに#を付けます。

if (sdata.charAt(0) == "#") { onkai = "#"+onkai; }

 以上で音階と音長が求められました。音長にはテンポも関係してくるので、実際に演奏する秒数を以下のようにして求めます。

var sec = (60 / tempo) / num;

 あとはstartAudio()関数を呼び出すとMMLで指定した最初の音が再生されます。

startAudio(freq[onkai], sec);

 実際のプログラムはサンプル1です。演奏ボタンをクリックするとテキストエリアに入力されたMMLが処理されて指定した音が出力されます。

【図】fig01.png

演奏ボタンをクリックするとMMLで指定して音が出力される

サンプル1

<!DOCTYPE html> 
<html> 
<head> 
<meta charset="UTF-8" /> 
<title>MMLを使って演奏する1</title> 
</head> 
<body>
<h1>MMLを使って演奏する1</h1>
<form>
<input type="button" value="演奏" onclick="playMML()" /><br />
<textarea cols="20" rows="5" id="track1">A4</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;
var tempo = 60;   // テンポ設定(グローバル変数)
var ptr = 0;    // 読み出し位置(グローバル変数)
// 再生処理
function playMML(){
    var data = document.getElementById("track1").value;
    var MML = data.split(" ");  // 空白
    var sdata = MML[ptr];
    var onkai = sdata.match(/[a-z]+/i)[0].toUpperCase();
    var num = sdata.match(/\d+/);
    if (sdata.charAt(0) == "#") { onkai = "#"+onkai; }
    var sec = (60 / tempo) / num; // 音長を計算
    startAudio(freq[onkai], 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);
    audio.play();
}
</script> 
</body> 
</html> 

この連載の記事

一覧へ

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