どうも!LSSです!!
WebAudioAPIで色々試していますが、今回はそのうち「ドレミ」12音階を鳴らしてみるものを作ってみました!
なお、基準となる音「ラ」の音の周波数は440Hzだったり442Hzだったりするようですが、今回は「442Hz」で計算しています。
スライダーでオクターブや音階を選び、「音を鳴らす」ボタンを押すと、3秒間、指定した音が鳴る、というサンプルになります。
サンプル
コード
<p><input id="oto1" type="button" value="音を鳴らす" /></p>
<p><span id="octg"></span><br /><input id="oct" style="width: 100%;" max="6" min="2" type="range" value="4" /></p>
<p><span id="onkaig"></span><br /><input id="onkai" style="width: 100%;" max="11" min="0" type="range" value="9" /></p>
<p><span id="gaing"></span><br /><input id="rg1" style="width: 100%;" max="1" min="0" step="0.1" type="range" value="0.3" /></p>
<script>// <![CDATA[
otolist=['ド','ド#','レ','レ#','ミ','ファ','ファ#','ソ','ソ#','ラ','ラ#','シ'];
oto1.addEventListener('click',oc0p,false);
oct.addEventListener('input',gw,false);
onkai.addEventListener('input',gw,false);
rg1.addEventListener('input',gw,false);
AudioContext = window.AudioContext || window.webkitAudioContext;
ctxa=new AudioContext();
gw();
function shs(){
return 442*(Math.pow(2,parseInt(oct.value)-4+(parseInt(onkai.value)-9)/12));
}
function oc0p() {
oc0=ctxa.createOscillator();
oc0g=ctxa.createGain();
oc0t=ctxa.currentTime;
oc0.type='triangle';
oc0.frequency.value=shs();
oc0g.gain.value=parseFloat(rg1.value);
oc0.connect(oc0g);
oc0g.connect(ctxa.destination);
oc0.start();
oc0.stop(oc0t + 3);
}
function gw(){
octg.innerHTML='オクターブ : '+oct.value;
onkaig.innerHTML='音階 : '+otolist[parseInt(onkai.value)];
gaing.innerHTML='音量 : '+rg1.value;
}
// ]]></script>
あとがき
なんとなく、「オクターブがひとつ上がると、周波数は倍になる」事だけ知っていました。
1オクターブ=12音階(ピアノの黒鍵と白鍵が1オクターブあたり合わせて12個)で、1音階はどう表現するのかと思ったら、「2の1/12乗」という直感的に分かり辛い計算になるようですw
JavaScriptには「Math.pow」関数という、べき乗を算出してくれる関数があり、例えば「Math.pow(2,4)」なら「2の4乗=16」という計算をしてくれるんですね。
これが都合よく、1/12とかでもしれっと計算してくれるので、例えば
「ラの次の音(ラ#)」
の周波数を出そうと思ったら、
442*Math.pow(2,1/12)
で算出してくれます^^
「1オクターブ上のラ」なら、
442*Math.pow(2,1)
となり、
「1オクターブ上のラ#」なら、
442*Math.pow(2,1+1/12)
という感じですね。
ってなとこで、今回はこのへんで!
次回もまた、よろしくお願いします^^