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に分類されています。互換性の心配なく本番利用可能です。
関連
- ・モスキート音・耳年齢チェック本体: 実際にOscillatorNodeを動かして確認
- ・StereoPannerNode仕様解説: 左右パンニングの仕組み
- ・加齢性難聴の予防ライフハック