42 lines
1.6 KiB
Bash
42 lines
1.6 KiB
Bash
|
|
#!/bin/bash
|
||
|
|
# 从指定 SOFA 提取 12 个单声道 IR 给 PipeWire convolver 用
|
||
|
|
# 用法: 换HRTF.sh <sofa文件> <输出目录名>
|
||
|
|
# 例: 换HRTF.sh H4_..._48K_24bit_256tap_FIR_SOFA.sofa H4-48k
|
||
|
|
# 提取方式: 给 5.1 里只有一路单位脉冲的输入, 让 sofalizer 时域渲染,
|
||
|
|
# 输出即该方向到两耳的脉冲响应。
|
||
|
|
# ★ 增益必须按 SOFA 实测再给: MIT KEMAR 电平低, +10dB 才不小声;
|
||
|
|
# 而 SADIE-II 的 IR 本身就顶到 0dBFS, 再加就削波爆音。默认 0。
|
||
|
|
set -eu
|
||
|
|
SOFA="$(readlink -f "$1")"
|
||
|
|
NAME="$2"
|
||
|
|
GAIN="${3:-0}"
|
||
|
|
BASE="/home/lou/桌面/工作区/实验/空间音频"
|
||
|
|
OUT="$BASE/hrir/$NAME"
|
||
|
|
[ -f "$SOFA" ] || { echo "找不到 SOFA: $SOFA"; exit 1; }
|
||
|
|
|
||
|
|
rm -rf "$OUT"; mkdir -p "$OUT"
|
||
|
|
cd "$OUT"
|
||
|
|
|
||
|
|
i=0
|
||
|
|
for name in FL FR FC LFE BL BR; do
|
||
|
|
exp=""
|
||
|
|
for j in 0 1 2 3 4 5; do
|
||
|
|
[ "$j" -gt 0 ] && exp="$exp|"
|
||
|
|
if [ "$j" -eq "$i" ]; then exp="${exp}between(t,0,1/48000)"; else exp="${exp}0"; fi
|
||
|
|
done
|
||
|
|
ffmpeg -y -hide_banner -loglevel error -f lavfi \
|
||
|
|
-i "aevalsrc='${exp}':d=0.05:s=48000:c=5.1" \
|
||
|
|
-af "sofalizer=sofa=${SOFA}:type=time:gain=${GAIN}" -c:a pcm_f32le "${name}_bi.wav"
|
||
|
|
i=$((i + 1))
|
||
|
|
done
|
||
|
|
|
||
|
|
for f in FL FR FC LFE BL BR; do
|
||
|
|
ffmpeg -y -hide_banner -loglevel error -i "${f}_bi.wav" -af "pan=mono|c0=c0" -c:a pcm_f32le "${f}_L.wav"
|
||
|
|
ffmpeg -y -hide_banner -loglevel error -i "${f}_bi.wav" -af "pan=mono|c0=c1" -c:a pcm_f32le "${f}_R.wav"
|
||
|
|
rm -f "${f}_bi.wav"
|
||
|
|
done
|
||
|
|
|
||
|
|
echo "完成 -> $OUT"
|
||
|
|
printf " %-8s %s Hz\n" "$(ls *.wav | head -1)" "$(ffprobe -v error -show_entries stream=sample_rate -of csv=p=0 FL_L.wav)"
|
||
|
|
echo " 文件数: $(ls *.wav | wc -l)"
|