目次: ALSA
未だにPipeWireの音切れがなくなりません。結論から書いておくと音切れは解決できませんでした。もう飽きました。今回はサーバー側PipeWire PulseAudioモジュールのレイテンシ調整をしました。
以前の日記(2025年10月11日の日記参照)で紹介したとおり、pipewireそのものにはリモート音声再生する機能はなくて、PulseAudioのプロトコルを受け付けるpipewire-pulseモジュールを使います。
モジュール(pipewire-pulse)の動作をstraceで追うと、設定ファイルは下記の3つが有効みたいです。
このうち/usr/share/pipewire/pipewire-pulse.confしか存在していなかったので、/usr/shareの設定ファイルを使います。
pulse.properties = {
#...
pulse.min.req = 64/48000
pulse.default.req = 128/48000
pulse.min.frag = 128/48000
pulse.default.frag = 96000/48000
pulse.default.tlength = 96000/48000
pulse.min.quantum = 64/48000
#...
}
とりあえずこんな感じに設定してみました。PipeWireの設定と何が違うんでしょうねえ。
S ID QUANT RATE WAIT BUSY W/Q B/Q ERR FORMAT NAME S 30 0 0 --- --- --- --- 0 Dummy-Driver S 31 0 0 --- --- --- --- 0 Freewheel-Driver S 47 0 0 --- --- --- --- 0 Midi-Bridge R 51 8192 48000 1.2ms 1.2ms 0.01 0.01 0 S24_32 2 48000 alsa_output.platform-es8316-s R 74 23744 48000 252.6us 692.1us 0.00 0.00 0 F32LE 2 48000 + mpv S 52 0 0 --- --- --- --- 0 alsa_input.platform-es8316-so S 53 0 0 --- --- --- --- 0 alsa_output.platform-hdmi0-so S 55 0 0 --- --- --- --- 0 alsa_output.platform-hdmi1-so S 56 0 0 --- --- --- --- 0 alsa_input.platform-hdmiin-so
PulseAudioモジュール側のバッファサイズが24000に近づきましたが、微妙に値が違います。まだ何か設定が要るんです??
しかし困ったことに、PipeWireのドキュメントは本当に意味がわからないです。読んでも「そんなこと聞いてないんだけど?」状態になります。設定項目のブロック構造もわからんし、何の設定項目があって、どの範囲の値が指定できて、どの値で何が起きるのか、全然分かりません。もうイヤ。
これ以上PipeWireに関してやる気が起きません……。PipeWireで何かトラブったら、PipeWireを即削除してPulseAudioを入れ直しをオススメします。
目次: ALSA
PipeWireに変えてから音切れがなくなりません。PulseAudioのときも音切れはしてましたが、PipeWireになってから頻度が段違いに多いです。なぜー?結論から書いておくと、音切れは多少はマシになった気がしますが、完全には解決できていません。今回はサーバー側PipeWireのレイテンシ調整をしました。
PipeWireの設定ファイルはいくつかの場所を認識するみたいです。straceで追ってみると、
この3つが認識されるみたいで、私の環境では/usr/share/pipewire/pipewire.confのみ存在していたので、/usr/share以下にあるファイルを変更します。
設定変更前の状態を再掲しておきます。
S ID QUANT RATE WAIT BUSY W/Q B/Q ERR FORMAT NAME S 30 0 0 --- --- --- --- 0 Dummy-Driver S 31 0 0 --- --- --- --- 0 Freewheel-Driver S 47 0 0 --- --- --- --- 0 Midi-Bridge R 51 2048 48000 594.1us 320.5us 0.01 0.01 1 S24_32 2 48000 alsa_output.platform-es8316-s R 56 8192 48000 245.6us 253.7us 0.01 0.01 1 S32LE 2 48000 + mpv S 52 0 0 --- --- --- --- 0 alsa_input.platform-es8316-so S 53 0 0 --- --- --- --- 0 alsa_output.platform-hdmi0-so S 54 0 0 --- --- --- --- 0 alsa_output.platform-hdmi1-so S 55 0 0 --- --- --- --- 0 alsa_input.platform-hdmiin-so
RATEがサンプリング周波数で、QUANT(※)がバッファサイズのようです。ALSAデバイス側は2048サンプル、PulseAudioモジュール(mpvの話し相手)は8192サンプルです。mpvはpulse-buffer=500を指定したので、500msつまり24000サンプルになるはずですが、なぜか8192です。
ローカル再生なら2桁msのバッファサイズ量で問題ないし、むしろレイテンシがデカすぎなくらいですが、リモート再生だと音がブチブチ切れまくって聞くに堪えません。仕方ないのでバッファを増量する設定を追加します。context.propertiesにある「default.clock.*」系の設定が効くっぽいです。
context.properties = {
#...
default.clock.rate = 48000
default.clock.allowed-rates = [ 48000 ]
default.clock.quantum = 64
default.clock.min-quantum = 32
default.clock.max-quantum = 8192
default.clock.quantum-limit = 48000
こんな感じにしてみました。大事なのはmax-quantum(デフォルト値2048)とquantum-limit(デフォルト値8192)でした。max-quantumはALSAデバイス側に使われるようで、quantum-limitはmpvから指定された値の上限になるみたいです。mpvから長いレイテンシを指定しても、quantum-limitまで切り詰められ意味がなかったのです。
S ID QUANT RATE WAIT BUSY W/Q B/Q ERR FORMAT NAME S 30 0 0 --- --- --- --- 0 Dummy-Driver S 31 0 0 --- --- --- --- 0 Freewheel-Driver S 47 0 0 --- --- --- --- 0 Midi-Bridge R 51 8192 48000 508.0us 1.2ms 0.00 0.01 160 S24_32 2 48000 alsa_output.platform-es8316-s R 54 22080 48000 233.0us 181.7us 0.00 0.00 0 F32LE 2 48000 + mpv S 52 0 0 --- --- --- --- 0 alsa_input.platform-es8316-so S 53 0 0 --- --- --- --- 0 alsa_output.platform-hdmi0-so S 55 0 0 --- --- --- --- 0 alsa_output.platform-hdmi1-so S 56 0 0 --- --- --- --- 0 alsa_input.platform-hdmiin-so
設定変更後、ALSAデバイス側は8192サンプル、PulseAudioモジュール(mpvの話し相手)は22080サンプルになりました。mpvはpulse-buffer=500を指定しているので、24000になってほしいんですけど。なぜこんな微妙な値になるの……??
目次: ブラウザー/メーラー
LinuxデスクトップマシンのFirefox(140.3.1esr 64bit)をアップデートしたところ、アドレスバーの上下に黒い線が表示されるようになりました。何も害はないですが、目立つなあ。Windows版でこのような線は見たことがありません。
昨今のブラウザってシステムのデザインはガン無視で、オレオレGUIコンポーネントを描画してるはずで。それでもデザイン統一できないのはバグなのか、Linux版に何か特有の事情があるのか……?
目次: ALSA
PipeWireに変えてから音切れがなくなりません。PulseAudioのときも音切れはしてましたが、PipeWireになってから頻度が段違いに多いです。なぜー?今回はサーバー側PipeWireのレイテンシ調整に備えて、設定反映方法と設定確認方法を紹介します。
設定を反映するにはpipewire-pulse.socket, pipewire-pulse.service, pipewire.socket, pipewire.service, wireplumber.serviceのうち設定を変更したサービスを再起動すれば良いはずです。良くわからないときは全部再起動しましょう。
$ systemctl --user daemon-reload $ systemctl --user restart pipewire.service #### もし何かおかしかったら下記もやってみると吉 $ systemctl --user restart pipewire.socket $ systemctl --user restart wireplumber.service $ systemctl --user restart pipewire-pulse.service $ systemctl --user restart pipewire-pulse.socket
デバッグ出力を見たければ、上記の5つのサービスを全部stopしてからPipeWireと仲間たちを直接起動すると良いでしょう。
#### サービスを全部止める $ systemctl --user stop pipewire.socket $ systemctl --user stop pipewire.service $ systemctl --user stop wireplumber.service $ systemctl --user stop pipewire-pulse.socket $ systemctl --user stop pipewire-pulse.service #### 直接起動する $ /usr/bin/pipewire -v $ /usr/bin/wireplumber $ /usr/bin/pipewire-pulse -v
ちなみにデバッグログを出すとわかりますが、めちゃくちゃ大量に出ます……私には意味がわかりません。
PipeWireは設定確認にはリモート音声再生している状態でpw-topコマンドを起動して確認すると便利です。
S ID QUANT RATE WAIT BUSY W/Q B/Q ERR FORMAT NAME S 30 0 0 --- --- --- --- 0 Dummy-Driver S 31 0 0 --- --- --- --- 0 Freewheel-Driver S 47 0 0 --- --- --- --- 0 Midi-Bridge R 51 2048 48000 594.1us 320.5us 0.01 0.01 1 S24_32 2 48000 alsa_output.platform-es8316-s R 56 8192 48000 245.6us 253.7us 0.01 0.01 1 S32LE 2 48000 + mpv S 52 0 0 --- --- --- --- 0 alsa_input.platform-es8316-so S 53 0 0 --- --- --- --- 0 alsa_output.platform-hdmi0-so S 54 0 0 --- --- --- --- 0 alsa_output.platform-hdmi1-so S 55 0 0 --- --- --- --- 0 alsa_input.platform-hdmiin-so
RATEがサンプリング周波数で、QUANT(※)がバッファサイズのようです。ALSAデバイス側は2048サンプル、PulseAudioモジュール(mpvの話し相手)は8192サンプルです。mpvはpulse-buffer=500を指定したので、500msつまり24000サンプルになるはずですが、なぜか8192です。
(※)QUANT = quantumのこと。バッファサイズを決めるための数値らしく、単位はサンプルだと思われます。PipeWireのドキュメントを見てもquantumについて説明している部分が見当たらなくて困りました。
目次: ALSA
先日(2025年10月11日の日記参照)の設定により、x86_64なPCからROCK 5Bにて動作しているPipeWireに対し、リモートオーディオ再生ができるようになりました。無事動いたまでは良いのですが、PipeWireにしてから音切れがひどくなり困ってしまいました。
クライアント側はx86_64、mplayer v0.40.0(今はmpvですね)+ libpipewire 1.4.8で、サーバー側はaarch64、libpipewire 1.4.2です。
一般的に音が切れるのはクライアントかサーバーかどちらかの音声用のバッファが足りない可能性が高いです。クライアント側の設定を確認するためにmpvに-vオプションを付けて実行します。
$ PULSE_SERVER=192.168.1.x mplayer --audio-device=pulse -v a.mp4 ...(略)... [ao] Trying audio driver 'pulse' [ao/pulse] requested format: 48000 Hz, stereo channels, floatp [ao/pulse] Library version: 17.0.0 [ao/pulse] Proto: 35 [ao/pulse] Server proto: 35 [ao/pulse] Channel layouts: [ao/pulse] - #fl [ao/pulse] - #fr [ao/pulse] - #fc [ao/pulse] - #lfe [ao/pulse] - #bl [ao/pulse] - #br [ao/pulse] - #flc [ao/pulse] - #frc [ao/pulse] - #bc [ao/pulse] - #sl [ao/pulse] - #sr [ao/pulse] - #tc [ao/pulse] - #tfl [ao/pulse] - #tfc [ao/pulse] - #tfr [ao/pulse] - #tbl [ao/pulse] - #tbc [ao/pulse] - #tbr [ao/pulse] result: stereo [ao/pulse] device buffer: 4800 samples. ★デバイスバッファが4800/48000 = 0.1秒 [ao/pulse] using soft-buffer of 9600 samples. ★バッファが9600/48000 = 0.2秒 ...
ログからバッファサイズをチェックしたところデフォルト100ms + 200msのようです。変更にはpulse-bufferオプションを使用します。値の単位はミリ秒です。
$ PULSE_SERVER=192.168.1.x mplayer --audio-device=pulse --pulse-buffer=1000 -v a.mp4 ... [ao/pulse] result: stereo [ao/pulse] device buffer: 48000 samples. [ao/pulse] using soft-buffer of 48000 samples. ...
ひとまず1000msくらいに変更してしばらく様子を見ようと思います。
今回は特に変えていませんが、サーバー側の設定は/usr/share/pipewire/pipewire-pulse.confにあります。設定を変更したらpipewire-pulseを再起動で反映されるはずです。ユーザー権限で動いているのでsudoは不要です。
$ systemctl --user restart pipewire-pulse
このファイルを書き換えると次のアップデートで上書きされてしまうらしいですが、他の場所にある設定ファイルが見当たらないんですよね。どこにあるんだろう。。。
目次: ARM
Debian StableがTrixieに変わったことをすっかり忘れており、ROCK 5Bをapt-get dist-upgradeしたところ環境が壊れました。ARM SBC(SBC = Single Board Computer)のベンダーがDebianを提供してくれるのは大変ありがたいですが、大抵変なパッケージか変な改造が入っていて年単位で運用すると困ったことが起きがちです。
SBCはアップデートしない派もいるでしょうけど、ネットワークに繋いでいるし可能な限りアップデートを適用したいです。取れる選択肢は下記の二つでしょうか。
正直、良し悪しは互角ですね……。
Debianは多少壊れても元に戻せますが、今回は盛大に壊れましてapt --fix-broken installはエラーになります。致命的なのはsystemdとlibsystemd0のバージョン不一致でsystemdが消えたことで、bookwormにも戻してもsystemdがインストールできなくなりました。もしこの状態で再起動したら二度と起動しないでしょう。
Preparing to unpack .../systemd_257.8-1~deb13u2_arm64.deb ... Unpacking systemd (257.8-1~deb13u2) over (252.38-1~deb12u1) ... dpkg: error processing archive /var/cache/apt/archives/systemd_257.8-1~deb13u2_arm64.deb (--unpack): trying to overwrite '/usr/lib/systemd/system/serial-getty@.service', which is also in package rockchip-overlay 4.1 dpkg: considering removing systemd in favour of udev ... dpkg: systemd is not properly installed; ignoring any dependencies on it dpkg: yes, will remove systemd in favour of udev Preparing to unpack .../udev_257.8-1~deb13u2_arm64.deb ... Unpacking udev (257.8-1~deb13u2) over (252.38-1~deb12u1) ... Removing systemd (252.38-1~deb12u1), to allow configuration of udev (257.8-1~deb13u2) ... Preparing to unpack .../libudev1_257.8-1~deb13u2_arm64.deb ... Unpacking libudev1:arm64 (257.8-1~deb13u2) over (252.38-1~deb12u1) ... Errors were encountered while processing: /var/cache/apt/archives/systemd_257.8-1~deb13u2_arm64.deb E: Sub-process /usr/bin/dpkg returned an error code (1)
エラーメッセージを見るとrockchip-overlayなるパッケージが邪魔しているようです。試行錯誤の結果、
としたところ、元気に動き始めました。代償として画面が出なくなりましたが、今のところ画面を使っていないので問題ありません。面倒なSDカードイメージの書き直しを避けることができてラッキーでした。
目次: ALSA
最近はPulseAudioがPipeWireに置き換わっているそうです。今はPulseAudioをリモートオーディオ再生機として使っているので、PipeWireで同じことをする方法を紹介します。
やりたいことはLinuxデスクトップからARM SBC上のPulseAudioへオーディオを飛ばすこと(2022年5月27日の日記参照)です。PulseAudioの場合はmodule-native-protocol-tcpを有効にして、TCPでオーディオを送るようにしました。
まずSinkデバイスの設定を行います。大抵HDMI、ヘッドフォン端子、あるいは別の出力端子があるはずですので、どこから音を鳴らすかを決めます。オーディオデバイスが1つしかない場合は設定不要かもしれませんが、一応チェックしておくと良いと思います。
設定にはWirePlumberの設定ツールwpctlを使います。wpctl statusで現在の様子を見ることができます。
$ wpctl status Audio ├─ Devices: │ 48. Built-in Audio [alsa] │ 49. Built-in Audio [alsa] │ 50. Built-in Audio [alsa] │ 51. Built-in Audio [alsa] │ ├─ Sinks: │ 35. Built-in Audio Stereo [vol: 1.00] │ 46. Built-in Audio Stereo [vol: 1.00] │ * 56. Built-in Audio Stereo [vol: 1.00] │ ├─ Sources: │ 44. Built-in Audio Stereo [vol: 1.00] │ * 57. Built-in Audio Stereo [vol: 1.00] │ ├─ Filters: │ └─ Streams:
SourcesとSinksのデフォルトデバイスを変更して、音声の入出力先を変更するにはset-defaultを使用します。wpctlはDevice、Source、Sinkの全てがユニークなIDを持っているので、SourceだとかSinkだとか指定する必要はなくて、IDのみ指定します。入出力先を変更後、もう一度statusを見るとSettingsの内容が変わるはずです。
例えば上記のstatusなら、set-defaultに指定できるのはSink系(35, 46, 56)かSource系(44, 57)のIDのうちどれか1つです。もし35か46か56を指定した場合は、IDからSinkデバイスだとわかるのでデフォルトSinkデバイスが変更されます。44か57を指定した場合はデフォルトSourceデバイスが変更されます。直感的じゃない、辛い……。
$ wpctl set-default 56 $ wpctl set-default 57 $ wpctl status ... Settings └─ Default Configured Devices: 0. Audio/Sink alsa_output.platform-es8316-sound.stereo-fallback 1. Audio/Source alsa_input.platform-es8316-sound.stereo-fallback
余談でWirePlumberが出てくる理由を紹介します。PipeWireは音声の入出力経路を管理しないため、PipeWire以外のソフトウェアをインストールして音声の経路管理しなければならないからです。WirePlumberもPipeWireもこだわりというか思想の強さがにじみ出ていて、私は仲良くなれなさそうです……。
動作確認は音を鳴らしてみて鳴れば方法は問いませんが、一例としてALSAを使った方法を紹介します。PipeWireとALSAやV4L2を繋ぐためのモジュールとalsa-utilsをインストールします。
$ sudo apt-get install pipewire-alsa pipewire-audio pipewire-v4l2 alsa-utils $ speaker-test -c 2 -r 48000 -D pipewire speaker-test 1.2.14 Playback device is pipewire Stream parameters are 48000Hz, S16_LE, 2 channels Using 16 octaves of pink noise Rate set to 48000Hz (requested 48000Hz) Buffer size range from 64 to 1048576 Period size range from 32 to 524288 Periods = 4 was set period_size = 12000 was set buffer_size = 48000 0 - Front Left
左右のスピーカーから交互にノイズ音(サーー)がなれば成功です。鳴らない場合は設定とボリューム(wpctlで確認できます)、もしくはALSAデバイス側のボリューム、ミュート設定の問題も有り得るので、alsamixerで確認してみてください。
次はPulseAudioモジュールの設定変更です。PipeWireと一緒にインストールされるはずですが、もし下記の設定ファイルが存在しなければpipewire-pulseをインストールしてください。
# /usr/share/pipewire/pipewire-pulse.conf ... pulse.properties = { # the addresses this server listens on server.address = [ "unix:native" #"unix:/tmp/something" # absolute paths may be used #★★この行を有効にする "tcp:4713" # IPv4 and IPv6 on all addresses #"tcp:[::]:9999" # IPv6 on all addresses #"tcp:127.0.0.1:8888" # IPv4 on a single address # #{ address = "tcp:4713" # address # max-clients = 64 # maximum number of clients # listen-backlog = 32 # backlog in the server listen queue # client.access = "restricted" # permissions for clients #} ] ...
$ systemctl --user restart pipewire-pulse
設定を変更したら再起動をお忘れなく。
#### クライアント側で操作 $ PULSE_SERVER=192.168.1.x speaker-test -c 2 -r 48000 -D pulse
リモートオーディオ再生のクライアント側でPULSE_SERVERにサーバーのIPアドレスを指定して音声を再生します。サーバー側から音が鳴れば成功です。
目次: Linux
Makefileの達人には常識かもしれませんが、makeがリンクを行うときのデフォルトルール(LINK.o)が使うコマンドはLDではなくCCです。私はリンク時にldが直接呼ばれるのは見たことがないにも関わらず、ずっとLDが使われると思いこんでいました。
話は以上で終わり……だとつまらないので、実験もしましょう。Makefileとコンパイラの代わりにスクリプトを呼びます。makeはGNU Make 4.4.1を使いました。
CC = ./cc-dummy
CXX = ./cxx-dummy
CPP = ./cpp-dummy
LD = ./ld-dummy
CFLAGS = cflags-dummy
CXXFLAGS = cxxflags-dummy
CPPFLAGS = cppflags-dummy
LDFLAGS = ldflags-dummy
LOADLIBES = loadlibes-dummy
LDLIBS = ldlibs-dummy
all: target-c target-cxx
target-c: target-c.o
target-cxx: target-cxx.o
$ cat ./cc-dummy #!/bin/sh touch target-c.o $ cat ./cxx-dummy #!/bin/sh touch target-cxx.o
コマンドが見つからないエラーを防ぐため、CCやCXXに指定した名前のスクリプトも作ります。スクリプトではコンパイラがオブジェクトファイル(*.o)を作成する動きのみを模しておけば十分です。
オブジェクトファイルの生成でデフォルトのコンパイルのルール、バイナリファイルの生成でリンクのルールが呼ばれます。このときCCやCXXが使われるか?LDが使われるか?がわかるはずです。実行します。
$ make #### C言語プログラムのコンパイルとリンク、どちらもCCを使う ./cc-dummy cflags-dummy cppflags-dummy -c -o target-c.o target-c.c ./cc-dummy ldflags-dummy target-c.o loadlibes-dummy ldlibs-dummy -o target-c #### C++言語プログラムのコンパイルとリンク、コンパイルはCXX、リンクはCCを使う ./cxx-dummy cxxflags-dummy cppflags-dummy -c -o target-cxx.o target-cxx.cc ./cc-dummy ldflags-dummy target-cxx.o loadlibes-dummy ldlibs-dummy -o target-cxx
C言語でもC++言語でもリンクは一緒で、CCを呼び出しました。LDは使われません。
オプション-pでmakeのデフォルトルールを見ることができます。"%: %.o"はオブジェクトファイルからバイナリを生成するときに当てはまるデフォルトルールです。コロンの左が生成ファイル、右が依存ファイルです。%はワイルドカードです。
UNIX系の慣例で、実行ファイル名は拡張子なし(例えばhoge)、オブジェクトファイル名は*.o(例えばhoge.o)にします。そのペアにうまく当てはまるルールになっています。
# デフォルト LINK.o = $(CC) $(LDFLAGS) $(TARGET_ARCH) #...(略)... %: %.o # 実行するレシピ (ビルトイン): $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@
当たり前ですが、実験で見た結果と一緒です。
GNU Makeのソースコードも眺めてみました。おそらくdefault.cがデフォルトルールの定義だと思います。デフォルトルールと一緒です。そりゃそうですね。
// make/src/default.c
static const char *default_variables[] =
{
#ifdef VMS
//...
#else /* !VMS */
//...
"LINK.o", "$(CC) $(LDFLAGS) $(TARGET_ARCH)",
"COMPILE.c", "$(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c",
"LINK.c", "$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
"COMPILE.m", "$(OBJC) $(OBJCFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c",
"LINK.m", "$(OBJC) $(OBJCFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)",
"COMPILE.cc", "$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c",
//...
ソースコードを見て初めて知ったことが、VAX用のVMSというOSだとCCではなくLDを使うことです。しかし今の時代にVMS使っている人はいないでしょう……たぶん。
< | 2025 | > | ||||
<< | < | 10 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
- | - | - | 1 | 2 | 3 | 4 |
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 | - |
合計:
本日: