手軽屋
ツール一覧

Web Audio API OscillatorNodeで純音を生成する仕組み: 波形・周波数・ノイズ防止

モスキート音・耳年齢チェックツールの中核で使われているOscillatorNodeの技術仕様を、MDN Web Docsベースで整理します。

OscillatorNodeとは

Web Audio APIのノードのひとつで、指定した周波数の単音(純音)をリアルタイム生成します。マイク入力や音声ファイルが不要で、JavaScriptから直接「正弦波の440Hz」のような音を出せます。

楽器アプリ・聴力チェックツール・着信音生成・効果音などに広く使われています。

type別の波形と音色の違い

type波形聞こえ方用途
sine正弦波柔らかい純音聴力検査・サイン音
square矩形波ファミコン風レトロゲーム効果音
sawtoothノコギリ波金属的シンセサイザー
triangle三角波柔らかめのsquareシンセ・効果音

モスキート音のような「特定周波数の純粋な音」を出すにはsine一択。 squareやsawtoothは倍音成分を含むため、19kHzを指定しても38kHz・57kHzなどの倍音成分が低周波域に折り返して耳に届き、純粋な高周波テストになりません。

frequency.valueの設定方法

const ctx = new AudioContext();
const osc = ctx.createOscillator();
osc.type = "sine";
osc.frequency.value = 17000;  // 17kHz
osc.connect(ctx.destination);
osc.start();

frequencyはAudioParam型のため、.valueに直接代入してもいいし、setValueAtTime()で時刻指定できます。 後者のほうがオーディオエンジンと正確に同期するため、レコーディング系では推奨。

プチノイズを防ぐgainランプ技法

OscillatorNodeをそのままstart()すると、音量0→100%への瞬間立ち上がりで「プツッ」というクリックノイズが鳴ります。これは音の波形が中途半端な位相で切れるのが原因。

解決策: GainNodeを間に挟んで30ms程度のフェードを入れる:

const gain = ctx.createGain();
gain.gain.setValueAtTime(0, ctx.currentTime);
gain.gain.linearRampToValueAtTime(
  targetVolume,
  ctx.currentTime + 0.03  // 30ms
);
osc.connect(gain);
gain.connect(ctx.destination);
osc.start();

停止時も同様に30msフェードアウト→0.05秒後にstop()するとクリックノイズが完全に消えます。

OscillatorNodeは「使い捨て」

OscillatorNodeは一度stop()すると再利用できません。再生のたびにcreateOscillator()で新しいインスタンスを作る必要があります。 GainNode・StereoPannerNodeは使い回し可能。

Baseline Widely available

MDN記載: OscillatorNodeは2021年4月以降、全主要ブラウザ(Chrome/Edge/Firefox/Safari/iOS/Android Chrome)で実装され、Baseline Widely availableに分類されています。互換性の心配なく本番利用可能です。

関連