ps コマンド v4.0.0 以降では PSS, USS も表示できる

プロセスごとのメモリ使用量ってどうやって調べるんだっけ、と手元の Ubuntu 24.04 で man ps を見ていて気づきました。表示できる項目の一覧に PSS, USS があります。

  $ ps --format rss,pss,uss --pid 4160681
  RSS   PSS   USS
3494784 3039359 2991156

  $ ps --version
ps from procps-ng 4.0.4

おやっと思って調べたところ v4.0.0 で追加されたようです。これは嬉しいですね。


以下、ちょっと追いかけてみたメモ。

  $ dpkg --search /usr/bin/ps
procps: /usr/bin/ps

  $ dpkg --status procps | grep Homepage:
Homepage: https://gitlab.com/procps-ng/procps

リポジトリを見に行くと……

gitlab.com

NEWS に載ってました。

NEWS · master · procps-ng / procps · GitLabgitlab.com

procps-ng-4.0.0
---------------
...
  * ps: Add PSS and USS fields                             issue #112

issue #112 はこれ。作成日は 2018-10-17。

gitlab.com


コミット。

gitlab.com


v4.0.0 のタグが付いたコミットの日付は 2022-03-22。

gitlab.com

Ruby関連のMastodon/Fediverseアカウント集


言語・処理系

イベント

カンファレンスなど。

コミュニティ

国内

海外

製品

Ruby on Rails

組織

企業

ニュース

その他

参考

Web Audio API/GainNode: デシベル指定で音量調整

結論としては

// gainNode.gain.value == 1.0 のときの音量を基準(0 dB)として
// -10 dB の音量にする場合の例
const db = -10;
gainNode.gain.value = Math.pow(10, db / 20);

でよさそう。

GainNode.gain.value に指定する値については一つ前の記事で書きましたのでそちらも参照してください。

memo88.hatenablog.com

メモ

対数スケール(dB)から線形スケールへの変換だから Math.pow が出てくるのは分かるけど db / 20 の 20 って何? というあたりは Wikipedia の説明を読むと分かる。

この式ですね。

 \displaylines{
L_V = 10 \log_{10} \left( \frac{{V_\text{out}}^2}{{V_\text{in}}^2} \right) = 10 \log_{10} \left( \frac{V_\text{out}}{V_\text{in}} \right)^2 = 20 \log_{10} \left( \frac{V_\text{out}}{V_\text{in}} \right) \text{dB}
}

音を扱う場合は

  •  V_{ \text{in} }
  •  V_{ \text{out} }

が波形データの振幅に対応するようです。


20 という数は 10 * 2 に分解できて、

10 は単に B(ベル)から dB(デシベル)に変換しているだけ、

2 の方は

一方、電圧や音圧などの交流信号の振幅からデシベルで表す利得  L_V を求める場合、パワーは振幅の2乗に比例すると仮定し、

この「2乗」から来ています(同じく Wikipedia から)。これはこういうものらしいです(この記事では深入りしません)。「波のエネルギー 振幅の2乗」とかで検索するといろいろ出てきます。

具体的な値を見てみる

dB    振幅の比
   0  1.0
  -1  0.8912509381337456
  -2  0.7943282347242815
  -5  0.5623413251903491
 -10  0.31622776601683794
 -20  0.1
 -24  0.06309573444801933
 -40  0.01
 -48  0.003981071705534973
 -60  0.001
 -64  0.000630957344480193
 -80  0.0001
 -96  0.00001584893192461114
-100  0.00001

逆の変換もできます。

const ampRatio = 0.5;
20 * Math.log10(ampRatio); //=> -6.020599913279624 (dB)

Audacity で見てみる

上記の計算で合ってるよね? という確認も兼ねて Audacity の動作も見てみます。

元の波形はこう。振幅 = 1.0 です。このときの音量を基準(0 dB)として変換します。

(メニューバー)エフェクト>音量と圧縮>増幅...
で変換します。

-6.021 (dB) を指定して変換すると振幅が 0.5 倍になる。

-20 (dB) を指定して変換すると振幅が 0.1 倍になる。

合ってますね。

参考

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

qiita.com

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