- 新增 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
241 lines
7.6 KiB
Bash
Executable File
241 lines
7.6 KiB
Bash
Executable File
#!/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: 完成。"
|