docs(kaisa): ProAudio 主路线、WirePlumber default-profile 与一键脚本
- 新增 OPERATION_PipeWire_Kaisa_ProAudio / UCM_HiFi,核心问题复盘与恢复 Ubuntu 重测手顺;HDMI 旧文改为 stub。 - 脚本:apply / verify-pro-audio、strip default-profile、reapply-session、remove deb 与 UCM overlay、verify-audio-environment。 - systemd-user:kaisa-pro-audio-reapply.service 示例。 - README、docs 索引、REPO_INDEX、REPRO deb 存档说明;deb 标为未来计划;reference/ucm2 与采集脚本小改。 - debian 与 _bmad-output 规划文件随本次工作区一并更新。 Made-with: Cursor
This commit is contained in:
240
scripts/apply-kaisa-pro-audio.sh
Executable file
240
scripts/apply-kaisa-pro-audio.sh
Executable file
@@ -0,0 +1,240 @@
|
||||
#!/usr/bin/env bash
|
||||
# 一键应用 Kaisa pro-audio 基线(见 docs/linux-hdmi/OPERATION_PipeWire_Kaisa_ProAudio.md)。
|
||||
# deb 不作为当前交付(见 ProAudio §4.4 存档);默认仍会 purge 已装的 kaisa-hdmi-pipewire-fix,避免历史安装与脚本路线冲突。
|
||||
# 默认:purge kaisa-hdmi-pipewire-fix、reinstall alsa-ucm-conf、禁用 60-kaisa-ucm.lua、
|
||||
# 禁用系统级 50-kaisa*.conf、安装用户 50-kaisa、重启 PipeWire 栈、pactl + IEC958、跑 verify-kaisa-pro-audio.sh。
|
||||
#
|
||||
# 用法(仓库根,登录用户图形/会话):
|
||||
# ./scripts/apply-kaisa-pro-audio.sh
|
||||
# ./scripts/apply-kaisa-pro-audio.sh --keep-deb
|
||||
# ./scripts/apply-kaisa-pro-audio.sh --verify-only
|
||||
# ./scripts/apply-kaisa-pro-audio.sh --restore-only /path/to/baseline-stash/...
|
||||
# ./scripts/apply-kaisa-pro-audio.sh --restore /path/to/baseline-stash/...
|
||||
# ./scripts/apply-kaisa-pro-audio.sh --restore-stash-substring 20260406
|
||||
# ./scripts/apply-kaisa-pro-audio.sh --no-verify
|
||||
#
|
||||
# 若只想卸载历史 deb(purge + reinstall alsa-ucm-conf)、不跑整套 apply:
|
||||
# ./scripts/remove-kaisa-hdmi-deb.sh
|
||||
#
|
||||
# 需要:sudo、systemctl --user、pactl、amixer;建议 pulseaudio-utils。
|
||||
set -euo pipefail
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
VERIFY_SH="${REPO_ROOT}/scripts/verify-kaisa-pro-audio.sh"
|
||||
RESTORE_SH="${REPO_ROOT}/scripts/restore-ubuntu-audio-baseline.sh"
|
||||
CONF_SRC="${REPO_ROOT}/docs/linux-hdmi/wireplumber/50-kaisa-sof-rt5682-hdmi.conf"
|
||||
|
||||
KEEP_DEB=0
|
||||
VERIFY_ONLY=0
|
||||
NO_VERIFY=0
|
||||
RESTORE_DIR=""
|
||||
RESTORE_ONLY=0
|
||||
RESTORE_SUBSTR=""
|
||||
|
||||
resolve_stash_substring() {
|
||||
local sub="$1"
|
||||
local base="${REPO_ROOT}/audio_topology/baseline-stash"
|
||||
if [[ ! -d "$base" ]]; then
|
||||
echo "apply-kaisa-pro-audio: 无目录 $base(请先 capture-ubuntu-audio-baseline.sh)" >&2
|
||||
exit 1
|
||||
fi
|
||||
local matches=()
|
||||
shopt -s nullglob
|
||||
for d in "$base"/*"${sub}"*/; do
|
||||
[[ -d "$d" ]] || continue
|
||||
matches+=("$d")
|
||||
done
|
||||
shopt -u nullglob
|
||||
if ((${#matches[@]} == 0)); then
|
||||
echo "apply-kaisa-pro-audio: 未找到基线目录名含「${sub}」于 $base" >&2
|
||||
echo "现有目录:" >&2
|
||||
ls -la "$base" 2>/dev/null | head -20 >&2 || true
|
||||
exit 1
|
||||
fi
|
||||
local latest
|
||||
latest="$(ls -td "${matches[@]}" | head -1)"
|
||||
realpath "$latest"
|
||||
}
|
||||
|
||||
usage() {
|
||||
sed -n '2,18p' "$0" | sed 's/^# \{0,1\}//'
|
||||
exit "${1:-0}"
|
||||
}
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--keep-deb) KEEP_DEB=1 ;;
|
||||
--verify-only) VERIFY_ONLY=1 ;;
|
||||
--no-verify) NO_VERIFY=1 ;;
|
||||
--restore-only)
|
||||
RESTORE_ONLY=1
|
||||
if [[ -n "${2:-}" && "${2:0:1}" != - ]]; then
|
||||
RESTORE_DIR="$2"
|
||||
shift
|
||||
fi
|
||||
;;
|
||||
--restore)
|
||||
RESTORE_DIR="${2:?--restore 需要目录参数}"
|
||||
shift
|
||||
;;
|
||||
--restore-stash-substring)
|
||||
RESTORE_SUBSTR="${2:?--restore-stash-substring 需要子串,如 20260406}"
|
||||
shift
|
||||
;;
|
||||
-h|--help) usage 0 ;;
|
||||
*)
|
||||
echo "未知参数: $1" >&2
|
||||
usage 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if [[ "$VERIFY_ONLY" -eq 1 ]]; then
|
||||
exec "$VERIFY_SH"
|
||||
fi
|
||||
|
||||
if [[ -n "$RESTORE_SUBSTR" ]]; then
|
||||
RESTORE_DIR="$(resolve_stash_substring "$RESTORE_SUBSTR")"
|
||||
echo ">>> 解析基线目录: $RESTORE_DIR"
|
||||
fi
|
||||
if [[ "$RESTORE_ONLY" -eq 1 && -z "$RESTORE_DIR" ]]; then
|
||||
echo "apply-kaisa-pro-audio: --restore-only 需要目录参数,或与 --restore-stash-substring 同用。" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $EUID -eq 0 && -z "${SUDO_USER:-}" ]]; then
|
||||
echo "apply-kaisa-pro-audio: 请勿以 root 直接运行(无法正确操作 user pipewire)。请用登录用户执行。" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f "$CONF_SRC" ]]; then
|
||||
echo "apply-kaisa-pro-audio: 缺少仓库 conf: $CONF_SRC" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v sudo &>/dev/null; then
|
||||
echo "apply-kaisa-pro-audio: 需要 sudo。" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# pactl 前缀:root+sudo 时代理会话用户
|
||||
PACTL_PREFIX=()
|
||||
if [[ $EUID -eq 0 && -n "${SUDO_USER:-}" ]] && id -u "$SUDO_USER" &>/dev/null; then
|
||||
_VU="$(id -u "$SUDO_USER")"
|
||||
if [[ -d "/run/user/${_VU}" ]]; then
|
||||
_VH="$(getent passwd "$SUDO_USER" | cut -d: -f6)"
|
||||
_VH="${_VH:-/home/$SUDO_USER}"
|
||||
PACTL_PREFIX=(sudo -u "$SUDO_USER" env XDG_RUNTIME_DIR="/run/user/${_VU}" HOME="$_VH")
|
||||
fi
|
||||
fi
|
||||
|
||||
run_pactl() { "${PACTL_PREFIX[@]}" pactl "$@"; }
|
||||
|
||||
restart_audio_stack() {
|
||||
if ((${#PACTL_PREFIX[@]})); then
|
||||
sudo -u "${SUDO_USER}" env XDG_RUNTIME_DIR="/run/user/$(id -u "$SUDO_USER")" \
|
||||
systemctl --user restart wireplumber pipewire pipewire-pulse
|
||||
else
|
||||
systemctl --user restart wireplumber pipewire pipewire-pulse
|
||||
fi
|
||||
}
|
||||
|
||||
if [[ -n "$RESTORE_DIR" ]]; then
|
||||
echo ">>> 执行基线恢复: $RESTORE_SH $RESTORE_DIR"
|
||||
"$RESTORE_SH" "$RESTORE_DIR"
|
||||
if [[ "$RESTORE_ONLY" -eq 1 ]]; then
|
||||
echo ">>> --restore-only:已恢复,跳过 pro-audio 应用。"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "$KEEP_DEB" -eq 0 ]]; then
|
||||
if dpkg -s kaisa-hdmi-pipewire-fix &>/dev/null; then
|
||||
echo ">>> apt purge -y kaisa-hdmi-pipewire-fix"
|
||||
sudo apt purge -y kaisa-hdmi-pipewire-fix
|
||||
else
|
||||
echo "(未安装 kaisa-hdmi-pipewire-fix,跳过 purge)"
|
||||
fi
|
||||
echo ">>> apt install --reinstall -y alsa-ucm-conf"
|
||||
sudo apt install --reinstall -y alsa-ucm-conf
|
||||
else
|
||||
echo "(--keep-deb:跳过 purge / reinstall alsa-ucm-conf)"
|
||||
fi
|
||||
|
||||
LUA="/usr/share/wireplumber/main.lua.d/60-kaisa-ucm.lua"
|
||||
if [[ -f "$LUA" ]]; then
|
||||
echo ">>> sudo mv $LUA -> ${LUA}.disabled"
|
||||
sudo mv -n -- "$LUA" "${LUA}.disabled"
|
||||
else
|
||||
echo "(无激活的 $LUA,跳过)"
|
||||
fi
|
||||
|
||||
if [[ -d /etc/wireplumber/wireplumber.conf.d ]]; then
|
||||
echo ">>> 禁用系统级 50-kaisa*.conf(避免与用户级重复)"
|
||||
sudo bash -c '
|
||||
shopt -s nullglob
|
||||
for f in /etc/wireplumber/wireplumber.conf.d/50-kaisa*.conf; do
|
||||
[[ -f "$f" ]] || continue
|
||||
t="${f}.disabled"
|
||||
[[ -e "$t" ]] && t="${f}.disabled.$(date +%s)"
|
||||
echo "mv $f -> $t"
|
||||
mv -n -- "$f" "$t"
|
||||
done
|
||||
'
|
||||
fi
|
||||
|
||||
USER_CONF_DIR="${HOME}/.config/wireplumber/wireplumber.conf.d"
|
||||
mkdir -p "$USER_CONF_DIR"
|
||||
echo ">>> cp $CONF_SRC -> $USER_CONF_DIR/50-kaisa-sof-rt5682-hdmi.conf"
|
||||
cp -f -- "$CONF_SRC" "$USER_CONF_DIR/50-kaisa-sof-rt5682-hdmi.conf"
|
||||
|
||||
echo ">>> strip-kaisa-default-profile-state(避免 WirePlumber 从 default-profile 恢复 stereo-fallback)"
|
||||
"$REPO_ROOT/scripts/strip-kaisa-default-profile-state.sh" || true
|
||||
|
||||
if systemctl --user is-system-running &>/dev/null; then
|
||||
echo ">>> systemctl --user restart wireplumber pipewire pipewire-pulse"
|
||||
restart_audio_stack
|
||||
sleep 2
|
||||
else
|
||||
echo "apply-kaisa-pro-audio: 警告:user systemd 会话不可用,请登录桌面后手动: systemctl --user restart wireplumber pipewire pipewire-pulse" >&2
|
||||
fi
|
||||
|
||||
if ! command -v pactl &>/dev/null; then
|
||||
echo "apply-kaisa-pro-audio: 未找到 pactl,无法 set-card-profile。请安装 pulseaudio-utils 后重试。" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CARD="$(run_pactl list cards short 2>/dev/null | awk '/cml_rt5682/ {print $2; exit}')" || true
|
||||
if [[ -z "$CARD" ]]; then
|
||||
echo "apply-kaisa-pro-audio: 无法从 pactl list cards short 解析 cml_rt5682 卡名(PCI 是否与 conf 中 pci-0000_00_1f.3 一致?)" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo ">>> pactl set-card-profile $CARD pro-audio"
|
||||
run_pactl set-card-profile "$CARD" pro-audio
|
||||
|
||||
SINK="$(run_pactl list short sinks 2>/dev/null | awk '/cml_rt5682/ && /\.pro-output-2/ {print $2; exit}')" || true
|
||||
if [[ -z "$SINK" ]]; then
|
||||
echo "apply-kaisa-pro-audio: 未找到 …pro-output-2 sink;请核对 profile 是否已为 pro-audio。" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo ">>> pactl set-default-sink $SINK"
|
||||
run_pactl set-default-sink "$SINK"
|
||||
|
||||
echo ">>> amixer IEC958 0/1/2 on"
|
||||
amixer -c0 sset 'IEC958',0 on
|
||||
amixer -c0 sset 'IEC958',1 on
|
||||
amixer -c0 sset 'IEC958',2 on
|
||||
|
||||
if [[ "$NO_VERIFY" -eq 1 ]]; then
|
||||
echo ">>> --no-verify:跳过门禁(不推荐)。"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo ">>> $VERIFY_SH"
|
||||
if ! "$VERIFY_SH"; then
|
||||
echo "" >&2
|
||||
echo "apply-kaisa-pro-audio: 门禁未通过。可查看上文,或运行: $REPO_ROOT/scripts/verify-kaisa-audio-environment.sh --output /tmp/kaisa-verify.txt" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "apply-kaisa-pro-audio: 完成。"
|
||||
@@ -2,7 +2,7 @@
|
||||
# 在安装 kaisa-hdmi-pipewire-fix 或其它大改前,采集「Ubuntu / 当前机」音频基线并落盘。
|
||||
# 输出目录默认:audio_topology/baseline-stash/<时间戳>_<hostname>/
|
||||
# 用法:./scripts/capture-ubuntu-audio-baseline.sh [输出目录]
|
||||
# 详见:docs/linux-hdmi/OPERATION_PipeWire_Kaisa_HDMI.md「基线备份与恢复」
|
||||
# 详见:docs/linux-hdmi/OPERATION_PipeWire_Kaisa_ProAudio.md「基线备份与恢复」
|
||||
set -euo pipefail
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
|
||||
@@ -62,4 +62,4 @@ else
|
||||
echo "(无 user systemd 会话,请登录桌面后手动执行 restart)" >&2
|
||||
fi
|
||||
|
||||
echo "完成。随后请安装 UCM overlay 与 wireplumber/main.lua.d/60-kaisa-ucm.lua(见 OPERATION)。"
|
||||
echo "完成。随后请安装 UCM overlay 与 wireplumber/main.lua.d/60-kaisa-ucm.lua(见 docs/linux-hdmi/OPERATION_PipeWire_Kaisa_UCM_HiFi.md)。"
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
# 将仓库内 UCM2 overlay 与 WirePlumber Lua 安装到系统路径(需 sudo)。
|
||||
# 用法:在仓库根目录执行 ./scripts/install-kaisa-ucm-overlay.sh
|
||||
# 安装前请先运行 ./scripts/disable-kaisa-pro-audio-wireplumber.sh
|
||||
# 卸载同路径 overlay:./scripts/remove-kaisa-ucm-overlay.sh
|
||||
set -euo pipefail
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
@@ -32,4 +33,4 @@ fi
|
||||
|
||||
echo "完成。请先验证 UCM 能解析(应列出 HiFi,不应报 parse 错误):"
|
||||
echo " alsaucm -c sof-rt5682 list _verbs"
|
||||
echo "再按 OPERATION「UCM Jack 自动显示/隐藏」验收 pactl / GNOME。"
|
||||
echo "再按 docs/linux-hdmi/OPERATION_PipeWire_Kaisa_UCM_HiFi.md 验收 pactl / GNOME。"
|
||||
|
||||
51
scripts/kaisa-reapply-pro-audio-session.sh
Executable file
51
scripts/kaisa-reapply-pro-audio-session.sh
Executable file
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env bash
|
||||
# 在用户会话里把 cml_rt5682 拉回 pro-audio + 默认 pro-output-2 + IEC958。
|
||||
# 用于:开机/登录后 profile 变回 stereo-fallback,导致 pro-output-*「出现又消失」。
|
||||
# 根因常为 ~/.local/state/wireplumber/default-profile 里持久了 stereo-fallback(见 strip-kaisa-default-profile-state.sh)。
|
||||
# 可重复执行;建议由 systemd --user oneshot 在 pipewire-pulse 之后延迟调用(见 systemd-user/kaisa-pro-audio-reapply.service)。
|
||||
set -euo pipefail
|
||||
|
||||
# 与 strip-kaisa-default-profile-state.sh 同逻辑(本脚本常被单独 symlink 到 ~/.local/bin,勿依赖同目录 strip)
|
||||
_wp_state="${HOME}/.local/state/wireplumber/default-profile"
|
||||
if [[ -f "$_wp_state" ]] && grep -q 'cml_rt5682' "$_wp_state" 2>/dev/null; then
|
||||
_tmp="${_wp_state}.tmp.$$"
|
||||
grep -v 'cml_rt5682' "$_wp_state" > "$_tmp"
|
||||
mv -f -- "$_tmp" "$_wp_state"
|
||||
echo "kaisa-reapply-pro-audio-session: 已清除 default-profile 中含 cml_rt5682 的持久行" >&2
|
||||
fi
|
||||
|
||||
if ! command -v pactl &>/dev/null; then
|
||||
echo "kaisa-reapply-pro-audio-session: 未找到 pactl" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
apply_once() {
|
||||
local card sink
|
||||
card="$(pactl list cards short 2>/dev/null | awk '/cml_rt5682/ {print $2; exit}')" || true
|
||||
[[ -z "$card" ]] && return 1
|
||||
pactl set-card-profile "$card" pro-audio 2>/dev/null || true
|
||||
# 给 WirePlumber 一点时间生成 sink
|
||||
sleep 0.4
|
||||
sink="$(pactl list short sinks 2>/dev/null | awk '/cml_rt5682/ && /\.pro-output-2/ {print $2; exit}')" || true
|
||||
[[ -n "$sink" ]] && pactl set-default-sink "$sink" 2>/dev/null || true
|
||||
if command -v amixer &>/dev/null; then
|
||||
amixer -c0 sset 'IEC958',0 on 2>/dev/null || true
|
||||
amixer -c0 sset 'IEC958',1 on 2>/dev/null || true
|
||||
amixer -c0 sset 'IEC958',2 on 2>/dev/null || true
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# 首次:栈可能尚未完全就绪
|
||||
for _ in 1 2 3 4 5 6 7 8 9 10; do
|
||||
if apply_once; then
|
||||
# 再等一会:GNOME 常在登录后数秒内改 profile,第二次拉回去
|
||||
sleep 6
|
||||
apply_once || true
|
||||
exit 0
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo "kaisa-reapply-pro-audio-session: 超时未找到 cml_rt5682 卡(pactl list cards short)" >&2
|
||||
exit 1
|
||||
52
scripts/remove-kaisa-hdmi-deb.sh
Executable file
52
scripts/remove-kaisa-hdmi-deb.sh
Executable file
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env bash
|
||||
# 卸载历史上可能安装过的 kaisa-hdmi-pipewire-fix(apt purge),并 reinstall alsa-ucm-conf
|
||||
# 以恢复发行版自带的 UCM 文件(与 apply-kaisa-pro-audio.sh 中 KEEP_DEB=0 时前两步一致)。
|
||||
#
|
||||
# 不改动用户级 WirePlumber;不自动重启 PipeWire。若曾用手工 UCM overlay,另见
|
||||
# ./scripts/remove-kaisa-ucm-overlay.sh
|
||||
# 若要走 pro-audio 主路线,purge 完成后可执行:
|
||||
# ./scripts/apply-kaisa-pro-audio.sh --keep-deb
|
||||
#
|
||||
# 用法:
|
||||
# ./scripts/remove-kaisa-hdmi-deb.sh
|
||||
# ./scripts/remove-kaisa-hdmi-deb.sh --no-reinstall-ucm # 仅 purge,不 touch alsa-ucm-conf
|
||||
set -euo pipefail
|
||||
|
||||
NO_REINSTALL=0
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--no-reinstall-ucm) NO_REINSTALL=1 ;;
|
||||
-h|--help)
|
||||
sed -n '2,18p' "$0" | sed 's/^# \{0,1\}//'
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "未知参数: $1(用 --help)" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if ! command -v sudo &>/dev/null; then
|
||||
echo "需要 sudo。" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if dpkg -s kaisa-hdmi-pipewire-fix &>/dev/null; then
|
||||
echo ">>> apt purge -y kaisa-hdmi-pipewire-fix"
|
||||
sudo apt purge -y kaisa-hdmi-pipewire-fix
|
||||
else
|
||||
echo "(dpkg 无已登记包 kaisa-hdmi-pipewire-fix,跳过 purge;若曾改名安装请自行 apt purge 包名)"
|
||||
fi
|
||||
|
||||
if [[ "$NO_REINSTALL" -eq 0 ]]; then
|
||||
echo ">>> apt install --reinstall -y alsa-ucm-conf"
|
||||
sudo apt install --reinstall -y alsa-ucm-conf
|
||||
else
|
||||
echo "(--no-reinstall-ucm:跳过 alsa-ucm-conf reinstall)"
|
||||
fi
|
||||
|
||||
echo "remove-kaisa-hdmi-deb: 完成。建议登录用户会话下: systemctl --user restart wireplumber pipewire pipewire-pulse"
|
||||
echo "若仍有手工 UCM: ./scripts/remove-kaisa-ucm-overlay.sh"
|
||||
echo "若应用 pro-audio: ./scripts/apply-kaisa-pro-audio.sh --keep-deb"
|
||||
55
scripts/remove-kaisa-ucm-overlay.sh
Executable file
55
scripts/remove-kaisa-ucm-overlay.sh
Executable file
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env bash
|
||||
# 卸载本仓库安装的 Kaisa UCM2 overlay 与系统级 60-kaisa-ucm.lua(需 sudo)。
|
||||
# 不卸载 alsa-ucm-conf 整包;仅删除 install-kaisa-ucm-overlay.sh 写入的路径。
|
||||
# 用法:在仓库根目录执行 ./scripts/remove-kaisa-ucm-overlay.sh
|
||||
# 卸载后若走 pro-audio,请再执行 ./scripts/apply-kaisa-pro-audio.sh
|
||||
set -euo pipefail
|
||||
|
||||
if ! command -v sudo &>/dev/null; then
|
||||
echo "需要 sudo。" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
removed=0
|
||||
|
||||
echo ">>> 删除 /usr/share/alsa/ucm2/GoogleKaisa/(若存在)"
|
||||
if [[ -d /usr/share/alsa/ucm2/GoogleKaisa ]]; then
|
||||
sudo rm -rf -- /usr/share/alsa/ucm2/GoogleKaisa
|
||||
removed=1
|
||||
echo " 已删除。"
|
||||
else
|
||||
echo " (不存在,跳过)"
|
||||
fi
|
||||
|
||||
echo ">>> 删除 /usr/share/alsa/ucm2/conf.d/sof-rt5682/(若存在)"
|
||||
if [[ -d /usr/share/alsa/ucm2/conf.d/sof-rt5682 ]]; then
|
||||
sudo rm -rf -- /usr/share/alsa/ucm2/conf.d/sof-rt5682
|
||||
removed=1
|
||||
echo " 已删除。"
|
||||
else
|
||||
echo " (不存在,跳过)"
|
||||
fi
|
||||
|
||||
LUA="/usr/share/wireplumber/main.lua.d/60-kaisa-ucm.lua"
|
||||
echo ">>> 禁用 $LUA(若存在)"
|
||||
if [[ -f "$LUA" ]]; then
|
||||
sudo mv -n -- "$LUA" "${LUA}.disabled"
|
||||
removed=1
|
||||
echo " 已移至 ${LUA}.disabled"
|
||||
elif [[ -f "${LUA}.disabled" ]]; then
|
||||
echo " (已是 .disabled,跳过)"
|
||||
else
|
||||
echo " (不存在,跳过)"
|
||||
fi
|
||||
|
||||
if systemctl --user is-system-running &>/dev/null; then
|
||||
echo ">>> systemctl --user restart wireplumber pipewire pipewire-pulse"
|
||||
systemctl --user restart wireplumber pipewire pipewire-pulse
|
||||
else
|
||||
echo "(无 user 会话,请登录后执行: systemctl --user restart wireplumber pipewire pipewire-pulse)" >&2
|
||||
fi
|
||||
|
||||
echo "完成。sof-rt5682 将不再使用本仓库的 HiFi UCM(HDMI1/2/3 等端口名来自该 overlay)。"
|
||||
if [[ "$removed" -eq 1 ]]; then
|
||||
echo "建议:走 pro-audio 时在仓库根执行 ./scripts/apply-kaisa-pro-audio.sh"
|
||||
fi
|
||||
21
scripts/strip-kaisa-default-profile-state.sh
Executable file
21
scripts/strip-kaisa-default-profile-state.sh
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env bash
|
||||
# 从 WirePlumber 持久状态里删掉 cml_rt5682 声卡那一行。
|
||||
# 原因:default-profile 模块会读取 ~/.local/state/wireplumber/default-profile,
|
||||
# 若其中保存了 output:stereo-fallback+input:stereo-fallback,会在每次启动时
|
||||
# 覆盖 monitor.alsa.rules 里设的 pro-audio,表现为「pro-output 出现一下又变回 stereo-fallback」。
|
||||
#
|
||||
# 由 apply-kaisa-pro-audio.sh(重启栈之前)与 kaisa-reapply-pro-audio-session.sh 调用;也可单独执行。
|
||||
set -euo pipefail
|
||||
|
||||
STATE_DIR="${HOME}/.local/state/wireplumber"
|
||||
F="${STATE_DIR}/default-profile"
|
||||
|
||||
[[ -f "$F" ]] || exit 0
|
||||
if ! grep -q 'cml_rt5682' "$F" 2>/dev/null; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
tmp="${F}.tmp.$$"
|
||||
grep -v 'cml_rt5682' "$F" > "$tmp"
|
||||
mv -f -- "$tmp" "$F"
|
||||
echo "strip-kaisa-default-profile-state: 已从 $F 移除含 cml_rt5682 的行(请保持 pro-audio 后由 WirePlumber 再写回正确 profile)"
|
||||
287
scripts/verify-kaisa-audio-environment.sh
Executable file
287
scripts/verify-kaisa-audio-environment.sh
Executable file
@@ -0,0 +1,287 @@
|
||||
#!/usr/bin/env bash
|
||||
# Kaisa(Google-Kaisa / sof-rt5682 / cml_rt5682)音频环境一次性全面验证。
|
||||
# 覆盖:PCI、ALSA 枚举、UCM2、已安装 overlay、PipeWire/Pulse、WirePlumber、
|
||||
# IEC958/Jack(amixer)、HDMI ELD、近期用户态日志片段。
|
||||
#
|
||||
# 用法(在图形会话或 SSH 带 XDG_RUNTIME_DIR 时):
|
||||
# ./scripts/verify-kaisa-audio-environment.sh
|
||||
# ./scripts/verify-kaisa-audio-environment.sh --output ~/kaisa-audio-verify.txt
|
||||
# sudo ./scripts/verify-kaisa-audio-environment.sh # 会经 sudo -u $SUDO_USER 调用 pactl/journalctl(勿裸 root 登录)
|
||||
#
|
||||
# 注意:PipeWire-Pulse 的 pactl 必须「以会话用户 + 其 /run/user/<uid>」连接;root 进程不能直接占用普通用户的 XDG_RUNTIME_DIR。
|
||||
#
|
||||
# 详见:docs/linux-hdmi/OPERATION_PipeWire_Kaisa_ProAudio.md
|
||||
set -uo pipefail
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
export REPO_ROOT
|
||||
OUT_FILE=""
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--output|-o)
|
||||
OUT_FILE="${2:?}"
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
sed -n '2,20p' "$0" | sed 's/^# \{0,1\}//'
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "未知参数: $1 (使用 --help)" >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# root + sudo:pactl / wpctl / journalctl --user 必须代会话用户执行(不能 root 直连用户 PipeWire)
|
||||
PACTL_PREFIX=()
|
||||
JOURNAL_PREFIX=()
|
||||
WCONF_HOME="${HOME}"
|
||||
if [[ $EUID -eq 0 && -n "${SUDO_USER:-}" ]] && command -v sudo &>/dev/null && id -u "$SUDO_USER" &>/dev/null; then
|
||||
_VU="$(id -u "$SUDO_USER")"
|
||||
if [[ -d "/run/user/${_VU}" ]]; then
|
||||
_VH="$(getent passwd "$SUDO_USER" | cut -d: -f6)"
|
||||
_VH="${_VH:-/home/$SUDO_USER}"
|
||||
PACTL_PREFIX=(sudo -u "$SUDO_USER" env XDG_RUNTIME_DIR="/run/user/${_VU}" HOME="$_VH")
|
||||
JOURNAL_PREFIX=(sudo -u "$SUDO_USER" env XDG_RUNTIME_DIR="/run/user/${_VU}")
|
||||
WCONF_HOME="$_VH"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n "$OUT_FILE" ]]; then
|
||||
exec > >(tee -a "$OUT_FILE")
|
||||
exec 2>&1
|
||||
echo "# 报告文件: $OUT_FILE"
|
||||
fi
|
||||
|
||||
hr() { printf '%s\n' "================================================================================"; }
|
||||
sec() { printf '\n'; hr; echo "### $*"; hr; echo ""; }
|
||||
|
||||
run() {
|
||||
local title="$1"
|
||||
shift
|
||||
echo "# $title"
|
||||
echo "\`\`\`"
|
||||
if "$@" 2>&1; then
|
||||
:
|
||||
else
|
||||
echo "(命令返回非零: exit $?)"
|
||||
fi
|
||||
echo "\`\`\`"
|
||||
echo ""
|
||||
}
|
||||
|
||||
have() { command -v "$1" &>/dev/null; }
|
||||
|
||||
echo "verify-kaisa-audio-environment"
|
||||
echo "时间: $(date -Iseconds)"
|
||||
echo "主机: $(hostname)"
|
||||
echo "用户: ${USER:-?} EUID=$EUID"
|
||||
echo "XDG_RUNTIME_DIR=${XDG_RUNTIME_DIR:-<unset>}"
|
||||
echo "仓库: $REPO_ROOT"
|
||||
if [[ $EUID -eq 0 ]]; then
|
||||
if ((${#PACTL_PREFIX[@]})); then
|
||||
echo "提示: 当前 root;pactl/journalctl/用户 WirePlumber 路径将经 sudo -u ${SUDO_USER}(会话 UID $(id -u "$SUDO_USER"))。"
|
||||
else
|
||||
echo "提示: 当前 root 且无法解析 SUDO_USER 或 /run/user/<uid>;pactl 与 --user 日志可能失败(建议普通用户执行本脚本,或 sudo -u <登录用户> ./scripts/...)。"
|
||||
fi
|
||||
fi
|
||||
echo ""
|
||||
|
||||
sec "1) 系统与软件包"
|
||||
run "uname -a" uname -a
|
||||
if have dpkg; then
|
||||
run "dpkg 相关包版本" bash -c "dpkg -l 2>/dev/null | grep -E '^(ii|rc)\s+(alsa-ucm-conf|alsa-utils|libasound|wireplumber|pipewire|pipewire-pulse|pipewire-bin|pipewire-audio-client-libraries)\s' || true"
|
||||
fi
|
||||
for c in pipewire wireplumber pactl wpctl alsaucm aplay amixer; do
|
||||
if have "$c"; then
|
||||
echo "# $c: $(command -v "$c")"
|
||||
else
|
||||
echo "# $c: (未安装)"
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
|
||||
sec "2) PCI 音频"
|
||||
if have lspci; then
|
||||
run "lspci -nn | grep -iE 'audio|multimedia'" bash -c "lspci -nn 2>/dev/null | grep -iE 'audio|multimedia|display' || true"
|
||||
else
|
||||
echo "(无 lspci)"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
sec "3) ALSA 声卡与 PCM"
|
||||
run "/proc/asound/cards" cat /proc/asound/cards
|
||||
run "/proc/asound/pcm(节选)" bash -c "head -120 /proc/asound/pcm 2>/dev/null || true"
|
||||
if have aplay; then
|
||||
run "aplay -l" aplay -l
|
||||
run "aplay -L(节选 HDMI/sof/0)" bash -c "aplay -L 2>/dev/null | grep -iE 'hdmi|display|sof|card 0|plughw' | head -80 || true"
|
||||
else
|
||||
echo "(无 aplay)"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
sec "4) HDMI ELD(有接线时才有内容)"
|
||||
shopt -s nullglob
|
||||
eld_files=(/proc/asound/card*/eld*)
|
||||
if ((${#eld_files[@]})); then
|
||||
for f in "${eld_files[@]}"; do
|
||||
echo "# $f"
|
||||
echo "\`\`\`"
|
||||
cat "$f" 2>/dev/null || echo "(无法读取)"
|
||||
echo "\`\`\`"
|
||||
echo ""
|
||||
done
|
||||
else
|
||||
echo "(未找到 /proc/asound/card*/eld*)"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
sec "5) UCM2(alsaucm)与系统路径"
|
||||
run "vendor/overlay UCM 文件是否存在" bash -c '
|
||||
for p in \
|
||||
/usr/share/alsa/ucm2/conf.d/sof-rt5682/sof-rt5682.conf \
|
||||
/usr/share/alsa/ucm2/GoogleKaisa/sof-rt5682/HiFi.conf \
|
||||
"$REPO_ROOT/reference/ucm2/conf.d/sof-rt5682/sof-rt5682.conf" \
|
||||
"$REPO_ROOT/reference/ucm2/GoogleKaisa/sof-rt5682/HiFi.conf"
|
||||
do
|
||||
if [[ -f "$p" ]]; then echo "OK $p"; else echo "NO $p"; fi
|
||||
done
|
||||
'
|
||||
UCM_NAME=""
|
||||
if grep -q 'sof-rt5682' /proc/asound/cards 2>/dev/null; then
|
||||
UCM_NAME="sof-rt5682"
|
||||
fi
|
||||
if have alsaucm; then
|
||||
if [[ -n "$UCM_NAME" ]]; then
|
||||
run "alsaucm -c ${UCM_NAME} list _verbs" alsaucm -c "$UCM_NAME" list _verbs
|
||||
else
|
||||
run "alsaucm(未在 /proc/asound/cards 识别 sof-rt5682;尝试 sof-rt5682)" alsaucm -c sof-rt5682 list _verbs
|
||||
fi
|
||||
else
|
||||
echo "(未安装 alsaucm,跳过 UCM 列表)"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
sec "6) WirePlumber / 桌面侧配置"
|
||||
run "系统 Lua 60-kaisa-ucm.lua" bash -c '
|
||||
f=/usr/share/wireplumber/main.lua.d/60-kaisa-ucm.lua
|
||||
if [[ -f "$f" ]]; then echo "OK $f"; wc -l "$f"; head -25 "$f"; else echo "NO $f"; fi
|
||||
'
|
||||
run "用户 ~/.config/wireplumber 中含 kaisa 的片段(主目录: ${WCONF_HOME})" bash -c '
|
||||
d="'"$WCONF_HOME"'/.config/wireplumber/wireplumber.conf.d"
|
||||
if [[ -d "$d" ]]; then
|
||||
find "$d" -maxdepth 1 -type f \( -iname "*kaisa*" -o -iname "50-kaisa*" \) -print 2>/dev/null | while read -r p; do echo "FILE $p"; done
|
||||
if ! find "$d" -maxdepth 1 -type f \( -iname "*kaisa*" -o -iname "50-kaisa*" \) -print -quit 2>/dev/null | grep -q .; then
|
||||
echo "(未找到 kaisa 相关片段)"
|
||||
fi
|
||||
else
|
||||
echo "(目录不存在: $d)"
|
||||
fi
|
||||
'
|
||||
|
||||
sec "7) PipeWire / Pulse(pactl)"
|
||||
if have pactl; then
|
||||
if ((${#PACTL_PREFIX[@]})); then
|
||||
echo "#(经 ${PACTL_PREFIX[0]} ${PACTL_PREFIX[1]} … 调用 pactl,连接用户 PipeWire-Pulse)"
|
||||
echo ""
|
||||
fi
|
||||
run "pactl 版本" "${PACTL_PREFIX[@]}" pactl --version
|
||||
echo "# 默认 sink / source"
|
||||
echo "\`\`\`"
|
||||
echo -n "default-sink: "
|
||||
"${PACTL_PREFIX[@]}" pactl get-default-sink 2>&1 || echo "?"
|
||||
echo -n "default-source: "
|
||||
"${PACTL_PREFIX[@]}" pactl get-default-source 2>&1 || echo "?"
|
||||
echo "\`\`\`"
|
||||
echo ""
|
||||
run "pactl list short cards" "${PACTL_PREFIX[@]}" pactl list short cards
|
||||
run "pactl list short sinks" "${PACTL_PREFIX[@]}" pactl list short sinks
|
||||
run "pactl list short sources" "${PACTL_PREFIX[@]}" pactl list short sources
|
||||
run "pactl list cards(全文)" "${PACTL_PREFIX[@]}" pactl list cards
|
||||
else
|
||||
echo "(无 pactl,无法检测 PipeWire-Pulse 会话;请登录图形会话或设置 XDG_RUNTIME_DIR)"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
sec "8) wpctl(若可用)"
|
||||
if have wpctl; then
|
||||
if ((${#PACTL_PREFIX[@]})); then
|
||||
echo "#(经 sudo -u … 调用 wpctl,与 pactl 同一会话 PipeWire)"
|
||||
echo ""
|
||||
fi
|
||||
run "wpctl status" "${PACTL_PREFIX[@]}" wpctl status
|
||||
else
|
||||
echo "(无 wpctl)"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
sec "9) amixer:IEC958 / Jack(卡 0,常见为 Kaisa)"
|
||||
if have amixer; then
|
||||
run "amixer -c0(节选)" bash -c "amixer -c0 2>/dev/null | grep -iE 'IEC958|Jack|Simple' | head -80 || true"
|
||||
else
|
||||
echo "(无 amixer)"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
sec "10) 内核环缓冲(需 root 时更完整)"
|
||||
if [[ -r /dev/kmsg ]] || dmesg &>/dev/null; then
|
||||
run "dmesg | grep -iE 'sof|snd|hda|audio|hdmi|ASoC|rt5682|iDisp' | tail -60" bash -c "dmesg 2>/dev/null | grep -iE 'sof|snd|hda|audio|hdmi|ASoC|rt5682|iDisp' | tail -60 || true"
|
||||
else
|
||||
echo "(dmesg 受限;可 sudo 重跑本脚本)"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
sec "11) 用户态 pipewire / wireplumber 日志(本启动项)"
|
||||
if have journalctl; then
|
||||
if ((${#JOURNAL_PREFIX[@]})); then
|
||||
echo "# journalctl --user -u pipewire -u wireplumber(经 sudo -u ${SUDO_USER})| tail -40"
|
||||
echo "\`\`\`"
|
||||
"${JOURNAL_PREFIX[@]}" journalctl --user -u pipewire -u wireplumber -b --no-pager 2>/dev/null | tail -40 || echo "(无条目或失败)"
|
||||
echo "\`\`\`"
|
||||
echo ""
|
||||
else
|
||||
run "journalctl --user -u pipewire -u wireplumber -b --no-pager | tail -40" bash -c "journalctl --user -u pipewire -u wireplumber -b --no-pager 2>/dev/null | tail -40 || true"
|
||||
fi
|
||||
else
|
||||
echo "(journalctl 未安装)"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
sec "12) 摘要(自动推断,仅供参考)"
|
||||
KAISA_IN_CARDS=0
|
||||
grep -q 'sof-rt5682' /proc/asound/cards 2>/dev/null && KAISA_IN_CARDS=1
|
||||
|
||||
HIFI_UCM=0
|
||||
if have alsaucm && [[ "$KAISA_IN_CARDS" -eq 1 ]]; then
|
||||
alsaucm -c sof-rt5682 list _verbs 2>/dev/null | grep -q HiFi && HIFI_UCM=1 || true
|
||||
fi
|
||||
|
||||
PACTL_HIFI_PROFILE=0
|
||||
USE_UCM_TRUE=0
|
||||
PC_TEXT=""
|
||||
if have pactl; then
|
||||
PC_TEXT="$("${PACTL_PREFIX[@]}" pactl list cards 2>/dev/null)" || true
|
||||
if [[ -n "$PC_TEXT" ]]; then
|
||||
echo "$PC_TEXT" | grep -qiE 'HiFi[[:space:]]*:' && PACTL_HIFI_PROFILE=1 || true
|
||||
echo "$PC_TEXT" | grep -q 'api.alsa.use-ucm = "true"' && USE_UCM_TRUE=1 || true
|
||||
fi
|
||||
fi
|
||||
|
||||
LUA_SYS=0
|
||||
[[ -f /usr/share/wireplumber/main.lua.d/60-kaisa-ucm.lua ]] && LUA_SYS=1
|
||||
|
||||
echo "- 内核 /proc/asound/cards 含 sof-rt5682: $([[ "$KAISA_IN_CARDS" -eq 1 ]] && echo OK || echo FAIL)"
|
||||
echo "- alsaucm 列出 HiFi verb: $([[ "$HIFI_UCM" -eq 1 ]] && echo OK || echo FAIL/WARN)"
|
||||
echo "- pactl 声卡段出现 HiFi profile(HiFi: 行): $([[ "$PACTL_HIFI_PROFILE" -eq 1 ]] && echo OK || echo WARN(可与 UCM 不一致,见 OPERATION))"
|
||||
echo "- pactl api.alsa.use-ucm = true: $([[ "$USE_UCM_TRUE" -eq 1 ]] && echo OK || echo WARN)"
|
||||
echo "- /usr/share/.../60-kaisa-ucm.lua 存在: $([[ "$LUA_SYS" -eq 1 ]] && echo OK || echo WARN)"
|
||||
echo ""
|
||||
echo "说明:「alsaucm 有 HiFi」但「pactl 无 HiFi profile」时,属 ACP 未注册该 profile,"
|
||||
echo " 不要以 pactl set-card-profile … HiFi 作为唯一验收依据。"
|
||||
echo ""
|
||||
|
||||
hr
|
||||
echo "完成。"
|
||||
exit 0
|
||||
108
scripts/verify-kaisa-pro-audio.sh
Executable file
108
scripts/verify-kaisa-pro-audio.sh
Executable file
@@ -0,0 +1,108 @@
|
||||
#!/usr/bin/env bash
|
||||
# Kaisa pro-audio 基线门禁:检查 WirePlumber 片段、UCM Lua、卡 profile、sinks、IEC958。
|
||||
# 退出码 0 = 通过,1 = 未满足(stdout 说明缺项)。
|
||||
#
|
||||
# 须在图形/用户会话下执行(pactl 连接 PipeWire-Pulse);勿裸 root 占用普通用户 XDG_RUNTIME_DIR。
|
||||
# 若用 sudo 调用本脚本,需带 SUDO_USER,脚本会经 sudo -u $SUDO_USER + XDG_RUNTIME_DIR 调用 pactl。
|
||||
#
|
||||
# 用法:./scripts/verify-kaisa-pro-audio.sh
|
||||
set -uo pipefail
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
|
||||
PACTL_PREFIX=()
|
||||
WCONF_HOME="${HOME}"
|
||||
if [[ $EUID -eq 0 && -n "${SUDO_USER:-}" ]] && command -v sudo &>/dev/null && id -u "$SUDO_USER" &>/dev/null; then
|
||||
_VU="$(id -u "$SUDO_USER")"
|
||||
if [[ -d "/run/user/${_VU}" ]]; then
|
||||
_VH="$(getent passwd "$SUDO_USER" | cut -d: -f6)"
|
||||
_VH="${_VH:-/home/$SUDO_USER}"
|
||||
PACTL_PREFIX=(sudo -u "$SUDO_USER" env XDG_RUNTIME_DIR="/run/user/${_VU}" HOME="$_VH")
|
||||
WCONF_HOME="$_VH"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ $EUID -eq 0 && ${#PACTL_PREFIX[@]} -eq 0 ]]; then
|
||||
echo "verify-kaisa-pro-audio: 当前为 root 且无法解析 SUDO_USER/会话;请用登录用户执行,或: sudo -u <用户> $0" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
fail() { echo "verify-kaisa-pro-audio: FAIL — $*" >&2; exit 1; }
|
||||
ok() { echo "verify-kaisa-pro-audio: OK — $*"; }
|
||||
|
||||
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
|
||||
sed -n '2,15p' "$0" | sed 's/^# \{0,1\}//'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! command -v pactl &>/dev/null; then
|
||||
fail "未找到 pactl(建议安装 pulseaudio-utils)"
|
||||
fi
|
||||
if ! command -v amixer &>/dev/null; then
|
||||
fail "未找到 amixer(alsa-utils)"
|
||||
fi
|
||||
|
||||
if ! grep -q 'sof-rt5682' /proc/asound/cards 2>/dev/null; then
|
||||
fail "/proc/asound/cards 中无 sof-rt5682"
|
||||
fi
|
||||
ok "ALSA 卡 sof-rt5682 存在"
|
||||
|
||||
if [[ -f /usr/share/wireplumber/main.lua.d/60-kaisa-ucm.lua ]]; then
|
||||
fail "仍存在可加载的 /usr/share/wireplumber/main.lua.d/60-kaisa-ucm.lua(应改为 .disabled 或删除)"
|
||||
fi
|
||||
ok "60-kaisa-ucm.lua 未处于激活路径"
|
||||
|
||||
conf="${WCONF_HOME}/.config/wireplumber/wireplumber.conf.d/50-kaisa-sof-rt5682-hdmi.conf"
|
||||
if [[ ! -f "$conf" ]]; then
|
||||
fail "缺少用户 WirePlumber 片段: $conf"
|
||||
fi
|
||||
ok "用户级 50-kaisa-sof-rt5682-hdmi.conf 存在"
|
||||
|
||||
wp_state="${WCONF_HOME}/.local/state/wireplumber/default-profile"
|
||||
if [[ -f "$wp_state" ]] && grep 'cml_rt5682' "$wp_state" 2>/dev/null | grep -qF 'stereo-fallback'; then
|
||||
fail "WirePlumber 状态文件仍要求 cml_rt5682 使用 stereo-fallback(会在重启后顶掉 pro-audio)。请执行: ${REPO_ROOT}/scripts/strip-kaisa-default-profile-state.sh 后 systemctl --user restart wireplumber pipewire pipewire-pulse,或重新运行 apply-kaisa-pro-audio.sh"
|
||||
fi
|
||||
|
||||
pactl_cards="$("${PACTL_PREFIX[@]}" pactl list cards 2>/dev/null)" || fail "pactl list cards 失败"
|
||||
if ! grep -qF 'cml_rt5682' <<< "$pactl_cards"; then
|
||||
fail "pactl list cards 中无 cml_rt5682(PCI/卡名是否与仓库 conf 一致?)"
|
||||
fi
|
||||
# 在「含 cml_rt5682 的卡」块内取第一条 活动配置 / Active Profile(避免匹配到「配置文件」里的 pro-audio 行)
|
||||
active_line="$(awk '
|
||||
/^卡 #[0-9]+/ || /^Card #[0-9]+/ { in_c=0 }
|
||||
/cml_rt5682/ { in_c=1 }
|
||||
in_c && (/活动配置/ || /Active Profile/) { print; exit }
|
||||
' <<< "$pactl_cards")"
|
||||
if [[ -z "$active_line" ]]; then
|
||||
fail "无法在 cml_rt5682 卡块内解析 活动配置/Active Profile 行"
|
||||
fi
|
||||
if [[ "$active_line" != *pro-audio* ]]; then
|
||||
_al="$(echo "$active_line" | tr -d '\t' | sed 's/^[[:space:]]*//')"
|
||||
fail "该卡活动配置不是 pro-audio(当前: ${_al})。请执行: ${REPO_ROOT}/scripts/apply-kaisa-pro-audio.sh(勿加 --verify-only)"
|
||||
fi
|
||||
ok "pactl 声卡活动配置为 pro-audio"
|
||||
|
||||
sinks="$("${PACTL_PREFIX[@]}" pactl list short sinks 2>/dev/null)" || fail "pactl list short sinks 失败"
|
||||
for po in pro-output-0 pro-output-2 pro-output-3 pro-output-4; do
|
||||
if ! grep -F 'cml_rt5682' <<< "$sinks" | grep -qF "$po"; then
|
||||
fail "缺少 sink …${po}(pro-audio 下应暴露 Port1 + HDMI1/2/3)"
|
||||
fi
|
||||
done
|
||||
ok "pactl short sinks 含 pro-output-0/2/3/4(cml_rt5682)"
|
||||
|
||||
def="$("${PACTL_PREFIX[@]}" pactl get-default-sink 2>/dev/null)" || fail "pactl get-default-sink 失败"
|
||||
if [[ "$def" != *pro-output-2* ]]; then
|
||||
fail "默认 sink 应为 …pro-output-2,当前: $def"
|
||||
fi
|
||||
ok "默认 sink 为 pro-output-2"
|
||||
|
||||
for i in 0 1 2; do
|
||||
out="$(amixer -c0 sget "IEC958",$i 2>/dev/null || true)"
|
||||
if ! grep -qiE '\[on\]|\[开启\]' <<< "$out"; then
|
||||
fail "IEC958',$i' 非开启状态(需 amixer -c0 sset 'IEC958',$i on)"
|
||||
fi
|
||||
done
|
||||
ok "IEC958',0/1/2 均为 on"
|
||||
|
||||
echo "verify-kaisa-pro-audio: 全部检查通过。"
|
||||
exit 0
|
||||
Reference in New Issue
Block a user