68db84a10c
- 两个虚拟声卡: 5.1 直通版 / 立体声矩阵上混版 - 全链路 96kHz/24bit, SADIE-II 真人 HRTF 96K/512tap - 命令: 空间音频(开关) / mpv-影院(单程序) - deb 打包 + 验收测试脚本 - README 记录 9 个实测踩坑(增益校准/采样率/相位等)
57 lines
2.4 KiB
Bash
57 lines
2.4 KiB
Bash
#!/bin/bash
|
|
# 生成 PipeWire filter-chain 配置: 5.1 -> 双耳 HRTF (KEMAR)
|
|
# 输出目标自动取当前默认输出设备; 换耳机/音箱后重跑本脚本即可。
|
|
set -eu
|
|
IR="/home/lou/桌面/工作区/实验/空间音频/hrir/gain"
|
|
OUT="/home/lou/.config/pipewire/pipewire.conf.d/90-cinema-spatial.conf"
|
|
D="FL FR FC LFE BL BR"
|
|
mkdir -p "$(dirname "$OUT")"
|
|
|
|
TARGET=$(wpctl inspect @DEFAULT_AUDIO_SINK@ 2>/dev/null | grep -oP 'node\.name = "\K[^"]+' | head -1 || true)
|
|
[ -n "${TARGET:-}" ] || TARGET="alsa_output.usb-EDIFIER_Technology_EDIFIER_Fit900NB_4250315939393214-00.iec958-stereo"
|
|
echo "输出目标: $TARGET"
|
|
|
|
{
|
|
echo "# 电影院空间音频: 6 声道 -> 双耳 HRTF(KEMAR) 自动生成 $(date '+%F %T')"
|
|
echo "context.modules = ["
|
|
echo " { name = libpipewire-module-filter-chain"
|
|
echo " flags = [ nofail ]"
|
|
echo " args = {"
|
|
echo " node.description = \"电影院空间音频 (5.1 虚拟环绕)\""
|
|
echo " media.name = \"Cinema Spatial\""
|
|
echo " filter.graph = {"
|
|
echo " nodes = ["
|
|
for d in $D; do for e in L R; do
|
|
echo " { type = builtin label = convolver name = c${d}_${e} config = { filename = \"$IR/${d}_${e}.wav\" } }"
|
|
done; done
|
|
for d in $D; do
|
|
echo " { type = builtin label = copy name = cp${d} }"
|
|
done
|
|
for e in L R; do
|
|
echo " { type = builtin label = mixer name = mix${e} control = { \"Gain 1\" = 1 \"Gain 2\" = 1 \"Gain 3\" = 1 \"Gain 4\" = 1 \"Gain 5\" = 1 \"Gain 6\" = 1 } }"
|
|
done
|
|
echo " ]"
|
|
echo " links = ["
|
|
for d in $D; do
|
|
echo " { output = \"cp${d}:Out\" input = \"c${d}_L:In\" }"
|
|
echo " { output = \"cp${d}:Out\" input = \"c${d}_R:In\" }"
|
|
done
|
|
n=1; for d in $D; do
|
|
echo " { output = \"c${d}_L:Out\" input = \"mixL:In $n\" }"; n=$((n+1))
|
|
done
|
|
n=1; for d in $D; do
|
|
echo " { output = \"c${d}_R:Out\" input = \"mixR:In $n\" }"; n=$((n+1))
|
|
done
|
|
echo " ]"
|
|
IN=""; for d in $D; do IN="$IN \"cp${d}:In\""; done
|
|
echo " inputs = [${IN} ]"
|
|
echo " outputs = [ \"mixL:Out\" \"mixR:Out\" ]"
|
|
echo " }"
|
|
echo " capture.props = { node.name = cinema_spatial_sink media.class = Audio/Sink audio.channels = 6 audio.position = [ FL FR FC LFE BL BR ] }"
|
|
echo " playback.props = { node.name = cinema_spatial_out node.passive = true node.target = \"$TARGET\" audio.channels = 2 audio.position = [ FL FR ] }"
|
|
echo " }"
|
|
echo " }"
|
|
echo "]"
|
|
} > "$OUT"
|
|
echo "已生成 $OUT ($(wc -l < "$OUT") 行)"
|