Web Audio API で 8bit 音を鳴らす
JavaScript で Web Audio API を使って、プログラムだけで音を鳴らす覚書。
HTML
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="8bit.js" defer></script>
<title>Web Audio API のテスト</title>
</head>
<body>
<input type="button" onclick="soundplay()" value="再生" />
</body>
</html>
JavaScript ( 8bit.js )
const AudioContext = window.AudioContext || window.webkitAudioContext;
const audioCtx = new AudioContext();
let testOscillator;
function soundplay() {
testOscillator = new OscillatorNode(audioCtx);
testOscillator.connect(audioCtx.destination);
testOscillator.start();
setTimeout(() => { testOscillator.stop() }, 100);
}
コードの解説
const AudioContext = window.AudioContext || window.webkitAudioContext;
const audioCtx = new AudioContext();
Web Audio API を使うためにコンテキストを用意。
let testOscillator;
function soundplay() {
testOscillator = new OscillatorNode(audioCtx);
testOscillator.connect(audioCtx.destination);
testOscillator.start();
setTimeout(() => { testOscillator.stop() }, 100);
}
soundplay 関数では OscillatorNode を用いて正弦波を作成し、出力先のコンテキストに接続したのち再生し、100ミリ秒後に停止する処理を記述した。
最初は下記のように、正弦波の作成と接続を関数の外に記述していた。
let testOscillator = new OscillatorNode(audioCtx);
testOscillator.connect(audioCtx.destination);
function soundplay() {
testOscillator.start();
setTimeout(() => { testOscillator.stop() }, 100);
}
この書き方だと、1回目のクリックで音が鳴った後、2回目のクリックで下記のエラーが出た。
InvalidStateError: Cannot call start() more than once
stop() で止めたノードは start() が使えなくなるらしい。
let testOscillator = new OscillatorNode(audioCtx);
function soundplay() {
testOscillator.connect(audioCtx.destination);
testOscillator.start();
setTimeout(() => { testOscillator.stop() }, 100);
}
上記のように再生のたび接続しなおしてもエラーが出たので、変数を先に定義して正弦波作成と接続を関数内で処理した。