更新音频调试日志和修复脚本,添加 HDMI 监控工具

This commit is contained in:
Jack
2026-05-21 11:22:17 +08:00
parent e8073bc448
commit bd5a3e81d9
77 changed files with 15716 additions and 31339 deletions

View File

@@ -8,6 +8,7 @@
| [linux-hdmi/DEBUG_Reboot_No_Sound_and_Fix.md](linux-hdmi/DEBUG_Reboot_No_Sound_and_Fix.md) | 排障记录重启后无声的根因链路WirePlumber 状态恢复 / `set_hw_params`)与 `--fix` 一键恢复 |
| [linux-hdmi/LOCAL_Root_Cause_and_Fix.md](linux-hdmi/LOCAL_Root_Cause_and_Fix.md) | **本机判因(替代 Live**`kaisa-audio-doctor.sh` 流程、证据表、安装顺序、与 DEBUG 文档衔接 |
| [linux-hdmi/ROOTCAUSE_Reboot_Silent_Analysis.md](linux-hdmi/ROOTCAUSE_Reboot_Silent_Analysis.md) | **根因深读**`default-routes` 极低 HDMI 音量(机制 A 实测)与 `set_hw_params`(机制 B分工 |
| [linux-hdmi/FIX_HDMI_No_Sound_ProAudio_Session_20260410.md](linux-hdmi/FIX_HDMI_No_Sound_ProAudio_Session_20260410.md) | **应急兜底pro-audio**:卡 `off`/ `auto_null` 恢复、`pro-output-N` 与 IEC958 对照、检查点速查表(非 UCM/HiFi 主交付) |
| [README.md](README.md) | 本目录说明 |
**脚本(仓库根 `scripts/`**:禁用 pro-audio 片段 — [`disable-kaisa-pro-audio-wireplumber.sh`](../scripts/disable-kaisa-pro-audio-wireplumber.sh);安装 UCM overlay — [`install-kaisa-ucm-overlay.sh`](../scripts/install-kaisa-ucm-overlay.sh)。

View File

@@ -0,0 +1,221 @@
# 2026-04-10 会话复盘Kaisasof-rt5682HDMI 无声修复记录
适用Google KaisaChromebox 10 / `sof-rt5682`+ Ubuntu + PipeWire + WirePlumber。
目标把“HDMI 无声(甚至 3.5 也无声)”快速恢复到**可出声**。
**重要**:本文记录的是一次实际排障中采用的 **`pro-audio` 应急/兜底方案**(能快速恢复输出并精确选到 pcm=2/3/4
它**不是**仓库“UCM2 + HiFiJack-driven”主交付方案主线请看 `OPERATION_PipeWire_Kaisa_UCM_HiFi.md`
本文末尾保留了“如何回到 UCM/HiFi 主线”的建议路径。
---
## 结论(本次问题的真实根因)
- **最关键的故障态**不是 UCM 文件本身,而是 **WirePlumber 把 `device.profile` 固定成 `HiFi`,但 PipeWire 侧并没有导出 `HiFi:` profile**`pactl list cards` 里只有 `off`/`pro-audio`)。
结果:活动配置**卡在 `off`**,默认 sink 变成 `auto_null`,表现为 **HDMI 与 3.5 全无声**
- **HDMI 链路是否“插上/可用”要看 Jack + ELD**,不要只看物理 HDMI 口编号:
`Jack=on``ELD_bytes>0` 的 pcm 才是当前真实连着的显示器链路。
- **单屏 vs 双屏的枚举差异(重要实测)**:在 Kaisa 上观察到一个容易误判的现象:
- 仅插 **一个** 显示器时,桌面/ACP 往往只呈现为 **`pcm=2`HDMI1** 可用(即使换不同物理 HDMI 口);
- 同时插 **两个** 显示器时,常会出现 **`pcm=2``pcm=3` 都 Jack=on 且 ELD 有效**,这时桌面切换输出更直观。
因此,“插哪个物理口”不应直接等价为“使用哪个 pcm”请以 **Jack/ELD 实测**为准。
- 本次实际连着的是 **`pcm=2`HDMI1**,并且在 **`pro-audio`** profile 下对应 sink 名为:
`alsa_output.pci-0000_00_1f.3-platform-cml_rt5682_def.pro-output-2`
---
## 必做前置(避免 90% 误判)
- **必须在桌面会话、普通用户jack下运行**,不要 `sudo` 运行 doctor。
否则常见现象:`systemctl --user offline``/run/user/1000/pulse` 不存在、`pactl/wpctl` 连接失败、报告显示“找不到声卡/未安装”等假象。
快速自检:
```bash
echo "XDG_RUNTIME_DIR=$XDG_RUNTIME_DIR"
test -S "$XDG_RUNTIME_DIR/pipewire-0" && echo "pipewire socket OK" || echo "pipewire socket MISSING"
test -S "$XDG_RUNTIME_DIR/pulse/native" && echo "pulse socket OK" || echo "pulse socket MISSING"
systemctl --user is-system-running
```
---
## 一键诊断与(可选)修复
仓库根目录:
```bash
./scripts/kaisa-audio-doctor.sh -o ./_logs/doctor-$(date +%Y%m%d_%H%M%S).log
./scripts/kaisa-audio-doctor.sh --fix -o ./_logs/doctor-fix-$(date +%Y%m%d_%H%M%S).log
```
判因(高优先级看这三块):
- `pactl list cards`:是否有 `HiFi:`;活动配置是否卡 `off`
- `pactl list short sinks`:是否只有 `auto_null`
- `amixer Jack/ELD`:哪个 pcm 真正连接Jack=on + ELD>0
---
## 本次“从无声到有声”的最短操作pro-audio 方案)
当你发现:
- `pactl list cards` 里只有 `off`/`pro-audio`,没有 `HiFi:`
- 或活动配置卡 `off`、默认 sink = `auto_null`
先把活动配置切回 `pro-audio`(保证至少有声):
```bash
systemctl --user restart wireplumber pipewire pipewire-pulse
pactl set-card-profile alsa_card.pci-0000_00_1f.3-platform-cml_rt5682_def pro-audio
```
然后切到当前连接的 HDMI pcm本次为 `pcm=2`),并打开对应 IEC958
```bash
pactl set-default-sink "alsa_output.pci-0000_00_1f.3-platform-cml_rt5682_def.pro-output-2"
wpctl set-mute @DEFAULT_AUDIO_SINK@ 0
wpctl set-volume @DEFAULT_AUDIO_SINK@ 1.0
amixer -c0 sset 'IEC958',0 on
pw-play /usr/share/sounds/alsa/Front_Center.wav
```
如果你插的是别的 pcm对应关系为
- `pcm=2``pro-output-2``IEC958,0`
- `pcm=3``pro-output-3``IEC958,1`
- `pcm=4``pro-output-4``IEC958,2`
---
## 目标态:双显示器均可出声 + 桌面可正常切换输出(推荐维持的“正常态”)
我们在本机实测中确认:当 **两台显示器同时连接**时,更容易同时得到两路有效的 HDMI 音频链路(例如 `pcm=2``pcm=3` 都满足 `Jack=on + ELD_valid`),此时:
- GNOME 桌面输出设备可在两路 HDMI 间正常切换
- `pactl list short sinks` 通常可见 `pro-output-2``pro-output-3`(以及可选的 `pro-output-4`
### 快速检查(双屏是否都“真连接”)
```bash
amixer -c0 cget "iface=CARD,name='HDMI/DP,pcm=2 Jack'"
amixer -c0 cget "iface=PCM,name='ELD',device=2"
amixer -c0 cget "iface=CARD,name='HDMI/DP,pcm=3 Jack'"
amixer -c0 cget "iface=PCM,name='ELD',device=3"
```
### 观察点:双屏时 ELD slot 可能出现两个同时有效(口差异证据)
在“双屏正常态”下,我们观测到 `/proc/asound/card0/eld#*` 可能同时出现两条 `present=1 valid=1`,并且它们的内部路径可能不同(例如 `pin/cvt` 不同):
- `eld#2.0 ... pin=0x5 cvt=0x3`
- `eld#2.3 ... pin=0x6 cvt=0x2`
查看命令:
```bash
for f in /proc/asound/card0/eld#*; do
mp=$(awk '$1=="monitor_present"{print $2}' "$f" 2>/dev/null)
ev=$(awk '$1=="eld_valid"{print $2}' "$f" 2>/dev/null)
if [ "$mp" = "1" ] || [ "$ev" = "1" ]; then
awk '$1 ~ /monitor_present|eld_valid|monitor_name|connection_type|codec_pin_nid|codec_cvt_nid|codec_dev_id/ {print}' "$f"
echo "---"
fi
done
```
### (可选)把默认输出固定到某一路 HDMIpro-audio
当双屏都可用时,你可以把默认输出固定到目标 pcm例如 `pcm=3`
```bash
pactl set-card-profile alsa_card.pci-0000_00_1f.3-platform-cml_rt5682_def pro-audio
pactl set-default-sink "alsa_output.pci-0000_00_1f.3-platform-cml_rt5682_def.pro-output-3"
wpctl set-mute @DEFAULT_AUDIO_SINK@ 0
wpctl set-volume @DEFAULT_AUDIO_SINK@ 1.0
amixer -c0 sset 'IEC958',1 on
pw-play /usr/share/sounds/alsa/Front_Center.wav
```
---
## pro-audio 方案:检查点速查表(位置 + 具体设置)
按优先级从上到下;**卡名 / sink 前缀**以你机上的 `pactl list cards short` / `pactl list short sinks` 为准(本机常见为 `alsa_card.pci-0000_00_1f.3-platform-cml_rt5682_def`)。
| 优先级 | 要查什么 | 期望 / 典型设置 | 怎么查 / 怎么设 |
|--------|----------|-----------------|-----------------|
| P0 | 桌面用户会话 | `XDG_RUNTIME_DIR` 存在;`pipewire-0` / `pulse/native` socket 存在 | 见上文「必做前置」 |
| P1 | 默认 sink | **不是** `auto_null`HDMI 应对应 `...pro-output-2/3/4` | `pactl info`(看默认音频入口);`pactl list short sinks` |
| P2 | 卡 profile | **活动配置**为 `pro-audio`,不要卡在 `off` | `pactl list cards`(筛 `cml_rt5682_def` 一段);`pactl set-card-profile <卡名> pro-audio` |
| P3 | 路由 + 音量 | 默认 sink 已切到目标 `pro-output-N`;未静音;音量满 | `pactl set-default-sink <sink>``wpctl set-mute @DEFAULT_AUDIO_SINK@ 0``wpctl set-volume @DEFAULT_AUDIO_SINK@ 1.0` |
| P4 | HDMI 真连接 | **Jack=on****ELD 非空** 的 pcm 才当作当前显示器链路 | `amixer -c0 cget "iface=CARD,name='HDMI/DP,pcm=N Jack'"``amixer -c0 cget "iface=PCM,name='ELD',device=N"`N=2/3/4 |
| P5 | IEC958 | `pcm=2→IEC958,0``pcm=3→IEC958,1``pcm=4→IEC958,2`Playback 为 `on` | `amixer -c0 sget 'IEC958',0``amixer -c0 sset 'IEC958',0 on`(其余类推) |
| P6 | WirePlumber 持久化 | `default-profile` 里卡为 `pro-audio``default-nodes` 不要把 sink 锁在 `auto_null``default-routes` 无异常低 `channelVolumes` | `sed -n '1,240p' ~/.local/state/wireplumber/default-profile` 等 |
| P7 | WirePlumber 规则 | 系统 `60-kaisa-ucm.lua` 等是否把 `device.profile` 指到不存在的 `HiFi` 导致卡 `off`;用户/系统 `*kaisa*` 片段是否冲突 | `ls -l /usr/share/wireplumber/main.lua.d/60-kaisa-ucm.lua``ls ~/.config/wireplumber/wireplumber.conf.d/*kaisa*` 等 |
| P8 | 内核/SOF | 若路由与开关都对仍无声,查 `ipc tx error -5` / `hw_params` | 见下「内核/SOF 一行命令」 |
### 内核/SOF 一行命令P8
```bash
journalctl -k -b --no-pager | grep -nE 'sof-audio|sof_ipc3_pcm_hw_params|ipc tx error|ASoC error|set_hw_params|HDMI|pcm[234]' | tail -n 200
```
**pro-audio 下 sink 命名(本机 Kaisa / cml_rt5682_def**
- 模拟Port1 / device 0`alsa_output.pci-0000_00_1f.3-platform-cml_rt5682_def.pro-output-0`
- HDMI`pro-output-2`pcm=2`pro-output-3`pcm=3`pro-output-4`pcm=4
**一键复制块(把 `N` 换成 2/3/4与 Jack+ELD 一致的 pcm**
```bash
CARD="alsa_card.pci-0000_00_1f.3-platform-cml_rt5682_def"
N=2
systemctl --user restart wireplumber pipewire pipewire-pulse
pactl set-card-profile "$CARD" pro-audio
pactl set-default-sink "alsa_output.pci-0000_00_1f.3-platform-cml_rt5682_def.pro-output-${N}"
wpctl set-mute @DEFAULT_AUDIO_SINK@ 0
wpctl set-volume @DEFAULT_AUDIO_SINK@ 1.0
case "$N" in
2) amixer -c0 sset 'IEC958',0 on ;;
3) amixer -c0 sset 'IEC958',1 on ;;
4) amixer -c0 sset 'IEC958',2 on ;;
esac
pw-play /usr/share/sounds/alsa/Front_Center.wav
```
---
## 如何判断“不是路由问题,而是内核/SOF 打不开 HDMI”
当你把默认 sink 切到了对应 `pro-output-N`,依然无声时,看内核窗口是否出现类似:
- `sof_ipc3_pcm_hw_params: pcmN ... ipc tx error ... -5`
- `ASoC error (-5): ... HDMI*`
出现这类信息通常表示 **kernel/SOF 层打开该路 HDMI 失败**UCM/WirePlumber 只能做绕行(换 pcm/换口/单屏测试),根因在驱动/固件侧。
---
## 回到“主交付 UCM/HiFi插线才出现 HDMI”的建议路径
1. 先确保 `pactl list cards` 的配置文件里真的出现 `HiFi:`(见 `docs/linux-hdmi/OPERATION_PipeWire_Kaisa_UCM_HiFi.md` §3.2)。
2. 确认出现后,再把 WirePlumber 的默认 profile 固定到 `HiFi`,并重启用户音频栈。
---
## 会话中对仓库做过的改动(目的:减少卡死与误判)
- `wireplumber/main.lua.d/60-kaisa-ucm.lua`
- 默认从强制 `HiFi` 调整为 **默认 `pro-audio`**(避免 `HiFi:` 未导出时卡 `off` -> `auto_null`)。
- `scripts/kaisa-audio-doctor.sh`
- `--fix`:若检测不到 `HiFi` profile**自动回退到 `pro-audio`**,避免把系统锁死到无声状态。
- `--verify`:在 `pro-audio` 时能用 `pro-output-N` 作为 sink 名(避免硬找 `HiFi__...` 而“Sink missing”

View File

@@ -0,0 +1,19 @@
# 周期性verify严格退出码失败则 PCI reset + doctor --fix再 verify。
# 需1) 桌面用户登录会话 2) sudoers NOPASSWD 指向 reset-sof-hdmi-pci.sh 绝对路径
#
# 安装(将 @REPO@ 换成仓库路径):
# mkdir -p ~/.config/systemd/user
# sed "s|@REPO@|$HOME/文档/chromebox_10th_audio_driver|g" kaisa-hdmi-watchdog.service > ~/.config/systemd/user/kaisa-hdmi-watchdog.service
# chmod +x @REPO@/scripts/kaisa-audio-hdmi-watchdog.sh @REPO@/scripts/kaisa-audio-doctor.sh @REPO@/scripts/reset-sof-hdmi-pci.sh
# systemctl --user daemon-reload
# systemctl --user enable --now kaisa-hdmi-watchdog.timer
#
[Unit]
Description=Kaisa HDMI: verify then reset+fix on failure (watchdog one-shot)
After=wireplumber.service pipewire-pulse.service pipewire.service
Wants=wireplumber.service
[Service]
Type=oneshot
# 单次周期;间隔由 .timer 控制。默认仅测已连接 HDMI--only-connected
ExecStart=@REPO@/scripts/kaisa-audio-hdmi-watchdog.sh --loops 1

View File

@@ -0,0 +1,13 @@
# 每 5 分钟触发一次 kaisa-hdmi-watchdog.service可按需修改 OnUnitActiveSec
#
[Unit]
Description=Timer for Kaisa HDMI watchdog (verify / reset+fix)
[Timer]
OnBootSec=3min
OnUnitActiveSec=5min
AccuracySec=1min
Persistent=true
[Install]
WantedBy=timers.target