Web Audio API: GainNode.gain.value に指定する値について調べたメモ

MDN の関連ページ(たとえば GainNode: GainNode() コンストラクター - Web API)を見ると

公称の範囲は (-∞,+∞) です。デフォルト値は 1 です。

などと書いてあるのですが、それだけじゃどういう値を指定すればいいのか、指定した値がどのように使われるのかよく分からない……ということで軽く調べてみました。

※ Web Audio API やオーディオ処理一般に詳しい人が書いているわけではありませんので、鵜呑みにせず適宜一次情報に当たるなどしてください。

仕様を見てみる

MDN のページに Web Audio API の仕様ページへリンクがある。 2025-01-19 時点では v1.1。

1.20. The GainNode Interface

https://webaudio.github.io/web-audio-api/#GainNode

Each sample of each channel of the input data of the GainNode MUST be multiplied by the computedValue of the gain AudioParam.

https://g200kg.github.io/web-audio-api-ja/#GainNode

GainNode の入力データの各チャンネルの各サンプルは gain AudioParam の computedValue が乗じられます ( MUST )。

  • 「multiply」「乗じる」とのことなので何かしら乗算に使われるのだな、ということは分かる。
  • computedValue はよく分かりませんでした(computedValue 自体の説明にも目を通したけどよく分からなかった)。
  • (日本語訳ありがとうございます)

ソースも見るとよさそう。

波形が実際にどうなるか見てみる

音を再生して別のアプリや別のPCに繋いで録音して波形を見る……でもよいのですが、 AnalyserNode を使うと GainNode で加工した結果を直にモニターすることができます。 手軽で確実そうなのでこれを使って確認しました。


調査に使ったコード(HTML + JavaScript)は gist に置きました。

https://gist.github.com/sonota88/015f30ffd7d2d4c6dc047d5fe12d62ec


  srcNode
    .connect(gainNode)
    .connect(analyserNode)
    .connect(context.destination)
  ;

のように srcNode => gainNode => analyserNode => destination となるように接続しています。gainNode によって加工された波形データを、そのすぐ後ろに繋いだ analyserNode で取得します。


ブラウザ(Ubuntu 24.04 + Firefox 133.0.3)で実行すると、 analyserNode.getFloatTimeDomainData(...) で取得したデータの波形と各サンプルの値、サンプルの値の最小値・最大値が以下のように表示されます。

1行が1サンプルに対応し、時間の向きは上から下、左端が -1.5, 右端が +1.5。

gainNode.gain.value = 1.0 の場合:

入力となる波形データが -1, 0, -0.5, 0, 0.5, 0, 1, 0 をそれぞれ 4 サンプルずつに伸ばして繰り返すというものなので、それがそのまま analyserNode に渡っていることが確認できます。

中間の gainNode を外して srcNode => analyserNode のように直結させた場合も同じ結果でした。


ちなみに Chrome 131.0.6778.139 では理由は不明ですが以下のような波形になりました。余分な加工が加わらない方が嬉しいので以降は Firefox で試します。


gainNode.gain.value = 0.5 にすると振幅が半分になります。


gainNode.gain.value = 0.1 の場合:


gainNode.gain.value = 0 だと完全に無音になるようです(この場合何も表示されなくなるのでスクリーンショットは省略)。


1 より大きい値を指定した場合(gainNode.gain.value = 1.2):

analyserNode に渡ってきた段階ではクリッピングはされてないようです(Chrome でも同様)。


gainNode.gain.value = -1 のように負の値を指定すると各サンプルの値の正負が反転します。ほんとにただ乗算してるだけっぽいですね。

関連

memo88.hatenablog.com

参考

4. Volume and Loudness (webaudioapi.com)

The main way to affect the loudness of a sound is using GainNodes. As previously mentioned, these nodes have a gain parameter, which acts as a multiplier on the incoming sound buffer. The default gain value is one, which means that the input sound is unaffected. Values between zero and one reduce the loudness, and values greater than one amplify the loudness. Negative gain (values less than zero) inverts the waveform (i.e., the amplitude is flipped).


2024-12-11 Web Audio API 1.1 の日本語訳を公開しました | g200kg Music & Software

この記事を読んだ人は(ひょっとしたら)こちらも読んでいます

qiita.com