Pop noise

前の投稿でも書いたが音声を再生すると妙にプチノイズが入る。これをなんとかしたい。

まず環境から確認しておくとIntelチップセット内蔵のオーディオデバイスがあり、snd_hda_intelカーネルモジュールが読み込まれている。またUSB DACを刺しているので、snd_usb_audioモジュールも読み込まれている。ただしUSB側はあくまで出力用のデバイスなのでオーディオデータの生成はあくまでチップセットが行う。

ちなみに内蔵スピーカーやらHDMI出力やらを担当するために?ALC269VBも載っていて認識されているがこれはまあ気にしなくていいだろう。

さてこの問題自体は割とFAQらしいのでみんな大好きarchlinuxのwikiにトラブルシューティングがまとまっている。要するにデバイスに省電力状態というものがあり、その状態が変わるときにプチノイズが発生するっぽいので状態が遷移するのを禁止しようというわけだ。

とりあえずmodinfoしてみると:

filename:       /lib/modules/5.15.0-47-generic/kernel/sound/pci/hda/snd-hda-intel.ko
description:    Intel HDA driver
license:        GPL
srcversion:     EB88CE4FDDC8DBA5650936E
(snip)
depends:        snd-hda-core,snd-hda-codec,snd-pcm,snd,snd-intel-dspcfg
retpoline:      Y
intree:         Y
name:           snd_hda_intel
vermagic:       5.15.0-47-generic SMP mod_unload modversions 
sig_id:         PKCS#7
signer:         Build time autogenerated kernel key
(snip)
parm:           index:Index value for Intel HD audio interface. (array of int)
parm:           id:ID string for Intel HD audio interface. (array of charp)
parm:           enable:Enable Intel HD audio interface. (array of bool)
parm:           model:Use the given board model. (array of charp)
parm:           position_fix:DMA pointer read method.(-1 = system default, 0 = auto, 1 = LPIB, 2 = POSBUF, 3 = VIACOMBO, 4 = COMBO, 5 = SKL+, 6 = FIFO). (array of int)
parm:           bdl_pos_adj:BDL position adjustment offset. (array of int)
parm:           probe_mask:Bitmask to probe codecs (default = -1). (array of int)
parm:           probe_only:Only probing and no codec initialization. (array of int)
parm:           jackpoll_ms:Ms between polling for jack events (default = 0, using unsol events only) (array of int)
parm:           single_cmd:Use single command to communicate with codecs (for debugging only). (bint)
parm:           enable_msi:Enable Message Signaled Interrupt (MSI) (bint)
parm:           patch:Patch file for Intel HD audio interface. (array of charp)
parm:           beep_mode:Select HDA Beep registration mode (0=off, 1=on) (default=1). (array of bool)
parm:           dmic_detect:Allow DSP driver selection (bypass this driver) (0=off, 1=on) (default=1); deprecated, use snd-intel-dspcfg.dsp_driver option instead (bool)
parm:           power_save:Automatic power-saving timeout (in second, 0 = disable). (xint)
parm:           pm_blacklist:Enable power-management denylist (bool)
parm:           power_save_controller:Reset controller in power save mode. (bool)
parm:           align_buffer_size:Force buffer and period sizes to be multiple of 128 bytes. (bint)
parm:           snoop:Enable/disable snooping (bint)

なるほどとても親切だ。ところで件のwikiだとpower_saveだけを0にするか、さらにpower_save_controllerもオフにするか2つの選択肢を挙げているわけだが、前者に意味はあるのだろうか。power_saveを0にした場合(=disable)の動作の詳細が分からないが、デバイスが暇になった場合即省電力状態に入らせるということならプチノイズ回避にはならないのでは? いろいろ試してみよう。

まずpower_saveを0にしただけで様子を見たところ、10秒に一度プチ!が出る感じなのが20秒に一度くらいになったようだ。なるほど効果は少しはあるのか。次にpower_save_controllerに’N’を書き込んでみたところ、こちらは覿面にプチノイズがなくなった。なるほど。

というわけで、これを永続化した設定にするため/etc/modprobe.d/の下に適当なファイルを作って

options snd_hda_intel power_save=0 power_save_controller=N

という感じの内容で保存。wikiにも書いてあるがラップトップの場合電源状態によってこの辺の設定が再設定されうるので、そういう場合は/etc/pm/power.d/下にも何かいろいろと仕込む必要があるかもしれない。

ところで省電力機能というのは当然消費電力を通常より低くするのだろう。その代わり音質が犠牲になるトレードオフがあるのだとしたら、バッテリー駆動のときだけオーディオデバイスの省電力機能をオンにする…とかにすればいいと思うのだけど、なぜ常に省電力オンなのかはよく分からない。

Leave a Reply

Your email address will not be published. Required fields are marked *