Little Strange Software

スマホアプリの開発を行う LittleStrangeSoftware のブログです。

【JavaScript】WebAudioAPIで音を生成してみるテスト

 どうも!LSSです!!

 

昨日、

【JavaScript】できないと思ってたらできた!? Web Audio API でJavaScriptから音を生成(サンプル第一歩目w)

で新たな扉を開いてしまいましたw

 

で、色々と試していたんですが、どう設定したらどんな音になるか?は、想像がつきにくいですよね。

なので、主に自分用にですが、
「手軽に設定変更して即座にどんな音になるか試せるツール」
を作ってみました!

 

「特に何かの役にたつ」というものではありませんが、…とりあえず遊べますw

 

 

f:id:little_strange:20210322232812p:plain

 

音生成テスト

以下の各項目を変更するか、最後のボタンを押すか、いずれかを行うたびに音が鳴ります^^

音色

変化




 

 

コード

一応、このツールのコードを晒しておきます。

<p>音色</p>
<select id="freq" size="4">
<option selected="selected" value="sine">sine</option>
<option value="square">square</option>
<option value="triangle">triangle</option>
<option value="sawtooth">sawtooth</option>
</select>
<p>変化</p>
<select id="tov" size="2">
<option selected="selected" value="0">直線的</option>
<option value="1">指数的</option>
</select>
<p><span id="rg0t"></span><br /><input id="rg0" style="width: 100%;" max="999" min="0" type="range" value="523" /></p>
<p><span id="rg1t"></span><br /><input id="rg1" style="width: 100%;" max="999" min="0" type="range" value="261" /></p>
<p><span id="rg2t"></span><br /><input id="rg2" style="width: 100%;" max="5" min="0" step="0.1" type="range" value="0.5" /></p>
<p><input id="oto1" type="button" value="音を鳴らす" /></p>
<script>// <![CDATA[
rgw();
oto1.addEventListener('click',oc0p,false);
freq.addEventListener('click',oc0p,false);
tov.addEventListener('click',oc0p,false);
rg0.addEventListener('change',oc0p,false);
rg1.addEventListener('change',oc0p,false);
rg2.addEventListener('change',oc0p,false);
AudioContext = window.AudioContext || window.webkitAudioContext;
ctxa=new AudioContext();

function oc0p() {
oc0=ctxa.createOscillator();
oc0g=ctxa.createGain();
oc0t=ctxa.currentTime;
oc0.type=freq.options[freq.selectedIndex].value;
oc0.frequency.setValueAtTime(parseInt(rg0.value),oc0t);
oc0.frequency.linearRampToValueAtTime(parseInt(rg1.value), oc0t + parseFloat(rg2.value));
if(tov.options[tov.selectedIndex].value==0){
oc0.frequency.linearRampToValueAtTime(parseInt(rg1.value), oc0t + parseFloat(rg2.value));
}else{
oc0.frequency.exponentialRampToValueAtTime(parseInt(rg1.value), oc0t + parseFloat(rg2.value));
}
oc0g.gain.setValueAtTime(0.4, oc0t);
if(tov.options[tov.selectedIndex].value==0){
oc0g.gain.linearRampToValueAtTime(0.01, oc0t + parseFloat(rg2.value));
}else{
oc0g.gain.exponentialRampToValueAtTime(0.01, oc0t + parseFloat(rg2.value));
}
oc0.connect(oc0g);
oc0g.connect(ctxa.destination);
oc0.start();
oc0.stop(ctxa.currentTime + parseFloat(rg2.value));
rgw();
}

function rgw(){
rg0t.innerHTML='最初の音 : '+rg0.value+' Hz';
rg1t.innerHTML='最後の音 : '+rg1.value+' Hz';
rg2t.innerHTML='音の長さ: '+rg2.value+' 秒';
}
// ]]></script>

 

一番分かりにくいのは「変化」の項目

音の高さと音量を変化させるのに、

linearRampToValueAtTime

と、

exponentialRampToValueAtTime

の2種類あり、参考にしたサイトでは「直線的に変化」「指数的に変化」との説明がありました。

微妙に変化の度合いが変わっているのが、分かるような、分からないような?w

 

 

 

他にも色々試してみています

「音楽演奏できるのかな?」と思っていましたが、どうやらそれもできそうです^^

そのうち披露したいと思いますが、打ち込みにちょっと手間どりそうでもありますw

(副産物的に、ドレミ音階の周波数の計算の仕方を覚えました!)

 

あと「複数の音を同時に鳴らす」のもうまく行ってます^^

 

そのあたりは後日、乞うご期待!って事で!!

 

 

 

ってなとこで、今回はこのへんで!

次回もまた、よろしくお願いします^^