2023-04-13

定期的に PulseAudio の daemon.conf を調整したくなる病が出た

世の中にはいろいろな沼があると思いますが、ワタシがたまに訪れるのは PulseAudio という Linux で音声を再生するパラメーターを調整する沼です。

Linux Mint 21.1 は Ubuntu 22.04 がベースなので、デフォルトのサウンドサーバーは PulseAudio です。PipeWire 0.3.48 もインストールはされているのですが、デフォルトではありません。

しばらくデフォルトのサウンドサーバーを PulseAudio から PipeWire に替えていたのですが、標準リポジトリには当然のように PipeWire のアップデートは配信されないため、カスタマイズもちょっと面倒だし PulseAudio に戻してみようと思ったのが始まりです。

久しぶりにに PulseAudio に戻してみたところ、「なんか音がいいんじゃない?」と思い、削除してしまった daemon.conf を再びデフォルトから個人ディレクトリーに持ってきてカスタマイズを始めました。

カスタマイズを始めると、ちょびちょびとパラメーターの設定値を変えるので微妙な差がわからなくなってきて、最後はもう投げやりになってしまいます。

 

というわけで、今回の調整で変更した daemon.conf のパラメーターは以下の通りです。

 resample-method = ffmpeg
 avoid-resampling = yes
 default-fragments = 2
 default-fragment-size-msec = 125

 

調整中に迷ったのは音声を再生するアプリケーションを主とするのか、最終的に再生する機器を主とするのかです。

こちらは再生するアプリケーションである Spotify の状況を確認した結果です。

$ pactl list sink-inputs
シンク入力 #80
	ドライバー: protocol-native.c
	所有者モジュール: 15
	クライアント: 90
	シンク: 2
	サンプル仕様: float32le 2ch 44100Hz
	チャンネルマップ: front-left,front-right
	形式: pcm, format.sample_format = "\"float32le\""  format.rate = "44100"  format.channels = "2"  format.channel_map = "\"front-left,front-right\""
	コルク: はい
	ミュート: いいえ
	ボリューム: front-left: 35938 /  55% / -15.66 dB,   front-right: 35938 /  55% / -15.66 dB
	        バランス 0.00
	バッファー待機時間: 194 usec
	シンク待機時間: 38124 usec
	リサンプル方法: ffmpeg
	プロパティ:
		media.role = "music"
		media.name = "Spotify"
		application.name = "spotify"
		native-protocol.peer = "UNIX socket client"
		native-protocol.version = "35"
		application.icon_name = "com.spotify.Client"
		application.process.id = "6"
		application.process.user = ""
		application.process.host = ""
		application.process.binary = "spotify"
		application.language = "ja_JP.UTF-8"
		window.x11.display = ":99.0"
		application.process.machine_id = ""
		application.process.session_id = ""
		module-stream-restore.id = "sink-input-by-media-role:music"

そして、こちらは再生する機器である USB スピーカーの状況を確認した結果です。

$ pactl list sinks
シンク #2
	状態: RUNNING
	名前: alsa_output.usb-0c76_USB_PnP_Audio_Device-00.analog-stereo
	説明: USB PnP Audio Device アナログステレオ
	ドライバー: module-alsa-card.c
	サンプル仕様: s16le 2ch 48000Hz
	チャンネルマップ: front-left,front-right
	所有者モジュール: 10
	ミュート: いいえ
	ボリューム: front-left: 32852 /  50% / -18.00 dB,   front-right: 32852 /  50% / -18.00 dB
	        バランス 0.00
	ベースボリューム: 65536 / 100% / 0.00 dB
	モニターソース: alsa_output.usb-0c76_USB_PnP_Audio_Device-00.analog-stereo.monitor
	待機時間: 40968 usec, configured 26000 usec
	フラグ: HARDWARE HW_MUTE_CTRL HW_VOLUME_CTRL DECIBEL_VOLUME LATENCY 
	プロパティー:
		alsa.resolution_bits = "16"
		device.api = "alsa"
		device.class = "sound"
		alsa.class = "generic"
		alsa.subclass = "generic-mix"
		alsa.name = "USB Audio"
		alsa.id = "USB Audio"
		alsa.subdevice = "0"
		alsa.subdevice_name = "subdevice #0"
		alsa.device = "0"
		alsa.card = "4"
		alsa.card_name = "USB PnP Audio Device"
		alsa.long_card_name = "USB PnP Audio Device at usb-0000:06:00.4-2, full speed"
		alsa.driver_name = "snd_usb_audio"
		device.bus_path = "pci-0000:06:00.4-usb-0:2:1.0"
		sysfs.path = "/devices/pci0000:00/0000:00:08.1/0000:06:00.4/usb5/5-2/5-2:1.0/sound/card4"
		udev.id = "usb-0c76_USB_PnP_Audio_Device-00"
		device.bus = "usb"
		device.vendor.id = "0c76"
		device.vendor.name = "JMTek, LLC."
		device.product.id = "161f"
		device.product.name = "USB PnP Audio Device"
		device.serial = "0c76_USB_PnP_Audio_Device"
		device.string = "front:4"
		device.buffering.buffer_size = "384000"
		device.buffering.fragment_size = "192000"
		device.access_mode = "mmap+timer"
		device.profile.name = "analog-stereo"
		device.profile.description = "アナログステレオ"
		device.description = "USB PnP Audio Device アナログステレオ"
		module-udev-detect.discovered = "1"
		device.icon_name = "audio-card-usb"
	ポート:
		analog-output: Analog Output (type: Analog, priority: 9900, availability unknown)
	活動中ポート: analog-output
	形式:
		pcm

PulseAudio に接続してくるアプリケーション(Spotify)はサンプル仕様が 44100Hz で、それを音として再生する機器(USB Audio)のサンプル仕様は 48000Hz なので一致せず、リサンプリングが発生しています。

ちなみに、Firefox で YouTube を再生するとサンプル仕様がどちらも 48000Hz で一致するためリサンプリングは発生しません。

アプリケーションによってサンプル仕様が異なるため、どんなアプリケーションを使ってもリサンプリングを発生させないことは不可能だと悟り、リサンプリングについてはあまり気にしないようにしました。


さて、今回に新たに調整したのは default-fragments というパラメーターです。これはdevice.buffering.buffer_size と device.buffering.fragment_size の比率で設定すると良いそうです。それぞれが 384000、192000 なのでちょうど 2倍になっています。

default-fragments の初期値は 4 ですが、この比率から 2 へと変更しています。



というわけで、追求し出すと終わりがなく、ちょっとずつ調整しても微妙な変化は感じられないという沼からはひとまず脱出します。