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);
}

上記のように再生のたび接続しなおしてもエラーが出たので、変数を先に定義して正弦波作成と接続を関数内で処理した。

この記事が気に入ったらサポートをしてみませんか?