#!/bin/bash # 逐方向精确测试: 每个方向单独生成一个 5.1(只有该声道有声), 渲染后看左右能量比 set -eu cd "/home/lou/桌面/工作区/实验/空间音频" SOFA=/usr/share/libmysofa/MIT_KEMAR_normal_pinna.sofa mkdir -p 方向测试 cd 方向测试 i=0 for name in FL FR FC LFE BL BR; do expr="" j=0 while [ "$j" -lt 6 ]; do [ "$j" -gt 0 ] && expr="$expr|" if [ "$j" -eq "$i" ]; then expr="${expr}0.6*sin(2*PI*440*t)" else expr="${expr}0" fi j=$((j + 1)) done ffmpeg -y -hide_banner -loglevel warning -f lavfi \ -i "aevalsrc='$expr':d=0.4:s=48000:c=5.1" -c:a pcm_s16le "$name.wav" ffmpeg -y -hide_banner -loglevel warning -i "$name.wav" \ -af "sofalizer=sofa=$SOFA:type=freq:radius=1.2" -c:a pcm_s16le "${name}_hrtf.wav" i=$((i + 1)) done python3 - <<'PY' import os import struct import wave NAMES = ["FL", "FR", "FC", "LFE", "BL", "BR"] EXPECT = {"FL": ">1 偏左", "FR": "<1 偏右", "FC": "~1 居中", "LFE": "~1 居中", "BL": ">1 偏左", "BR": "<1 偏右"} def ratio(path: str) -> float: with wave.open(path) as w: ch, n = w.getnchannels(), w.getnframes() raw = w.readframes(n) s = struct.unpack("<%dh" % (len(raw) // 2), raw) left = [float(s[i * 2]) for i in range(len(s) // 2)] right = [float(s[i * 2 + 1]) for i in range(len(s) // 2)] el = (sum(x * x for x in left) / len(left)) ** 0.5 er = (sum(x * x for x in right) / len(right)) ** 0.5 return el / er if er else 999.0 print("%-5s %14s %14s %s" % ("方向", "原始 L/R", "HRTF L/R", "期望")) print("-" * 56) for nm in NAMES: a, b = nm + ".wav", nm + "_hrtf.wav" if os.path.isfile(a) and os.path.isfile(b): ra = ratio(a) rb = ratio(b) flag = "" ok = (rb > 1.05) if EXPECT[nm].startswith(">1") else \ ((rb < 0.95) if EXPECT[nm].startswith("<1") else (0.8 < rb < 1.25)) flag = "OK" if ok else "偏了" print("%-5s %14.2f %14.2f %-9s %s" % (nm, ra, rb, EXPECT[nm], flag)) PY