10 KiB
JustOneCacophony — 双耳渲染数学
本文说明 pcm16 + ID11/OAMD → stereo 路径中的计算、状态和时间对齐。双耳渲染直接接在对象重建之后,不经过 ADM BWF 或 AXML。
1. 总体路径与记号
pcm16:LFE + 15 路对象 PCM
→ 64-band QMF analysis
→ 77-band hybrid analysis
→ 逐对象方向、距离、双耳传递函数和 room send
→ 对象累加 + room network
→ hybrid synthesis
→ QMF synthesis
→ 961-sample 延迟补偿
→ stereo WAV
主要记号:
| 符号 | 含义 |
|---|---|
s=0\ldots15 |
输入源;s=0 为 LFE,s=1\ldots15 为对象 |
e\in\{L,R\} |
左右输出耳 |
p=0\ldots63 |
QMF phase / 时域 hop 内采样 |
k=0\ldots63 |
QMF 子带 |
h=0\ldots76 |
hybrid 子带 |
j=0\ldots35 |
方向 basis 项 |
m |
64-sample QMF 时槽 |
n |
时域采样位置 |
每个 QMF hop 为 64 samples,每个双耳控制块为
N_b=512=8\times64,
每个 E-AC-3/JOC 音频帧为
N_f=1536=3N_b.
2. 输入与控制块
输入矩阵为
x_s[n],\qquad s=0\ldots15.
pcm16 的通道约定为:
ch0 special LFE
ch1..15 JOC 对象 1..15
渲染器按连续采样流推进。QMF、hybrid、room 和 synthesis 状态不会在 1536-sample 帧边界清零。
3. 64-band QMF analysis
令 a_{p,\ell} 为固定的 64×10 polyphase 系数,r_{s,\ell,p}[m] 为当前和前 9 个 hop 的 phase 历史。奇偶 lag 分别累加:
E_{s,p}[m]
=\sum_{\substack{\ell=0\\\ell\text{ even}}}^{9}
a_{p,\ell}r_{s,\ell,p}[m],
O_{s,p}[m]
=\sum_{\substack{\ell=0\\\ell\text{ odd}}}^{9}
a_{p,\ell}r_{s,\ell,p}[m].
对任一 64-vector $v[p]$,定义调制变换
\mathcal Q(v)_k
=
\operatorname{FFT}_{128}
\left(
\left[v[p]e^{-j\pi p/128}\right]_{p=0}^{63},
0_{64}
\right)_k
e^{-j3\pi(k+1/2)/128}.
analysis 输出为
X_{s,k}[m]
=
\mathcal Q(O_s)_k
+j(-1)^k\mathcal Q(E_s)_k.
所有历史、乘加和 FFT 结果使用 float64/complex128。
4. 77-band hybrid analysis
低 3 个 QMF 子带使用 13-slot FIR 拆分为 16 个 hybrid bands。把复数的实部和虚部分量记为 $i,o\in{0,1}$,固定核为 $K_{p,i,\ell,h,o}$:
H_{s,h,o}[m]
=
\sum_{p=0}^{2}
\sum_{i=0}^{1}
\sum_{\ell=0}^{12}
X_{s,p,i}[m-\ell]K_{p,i,\ell,h,o},
\qquad h=0\ldots15.
其余 61 个 hybrid bands 是 QMF 3..63 的 6-slot 延迟:
H_{s,16+q}[m]=X_{s,3+q}[m-6],
\qquad q=0\ldots60.
因此 hybrid vector 的顺序为:
0..15 低 3 个 QMF bands 的细分
16..76 延迟后的 QMF bands 3..63
5. OAMD 坐标与时间轴
5.1 Q15 坐标到 Cartesian
对象状态中的 q_1,q_2,q_3 先恢复到离散位置网格:
u_1=\min\left(1,\frac{\operatorname{round}(62q_1/32767)}{62}\right),
u_2=\min\left(1,\frac{\operatorname{round}(62q_2/32767)}{62}\right),
u_3=\operatorname{clip}\left(
\frac{\operatorname{round}(15q_3/32767)}{15},-1,1\right).
ADM Cartesian 坐标为
(X,Y,Z)=(2u_1-1,\ 1-2u_2,\ u_3).
5.2 更新时间
一条位置更新的编码时刻为
n_{\mathrm{coded}}
=n_{\mathrm{frame}}
+n_{\mathrm{outer}}
+n_{\mathrm{block}}.
首个有效状态作为 sample 0 的初始位置。后续更新加入对象 PCM 延迟 $D_o$,默认
D_o=1473.
若 ramp duration 为 $R>64$,连续运动为
n_{\mathrm{start}}=n_{\mathrm{coded}}+D_o+64,
R_{\mathrm{eff}}=R-64,
\mathbf p[n]
=(1-\alpha)\mathbf p_0+\alpha\mathbf p_1,
\qquad
\alpha=\frac{n-n_{\mathrm{start}}}{R_{\mathrm{eff}}}.
当 R\le64 时,目标位置在 n_{\mathrm{coded}}+D_o 直接生效。
Rosella 参数在每个 512-sample block 起点求值,并用于该块的 8 个 hybrid slots。
6. 距离 profile 与方向
普通对象只使用 Near、Mid、Far 三个 profile。每个 profile 包含:
- 三轴负/正边界 $b_{x-},b_{x+},b_{y-},b_{y+},b_{z-},b_{z+}$;
- 距离尺度
D和倒数尺度 $D^{-1}$; - 三轴内部尺度 $a_x,a_y,a_z$;
- 最小归一化半径 $\rho_{\min}$。
Cartesian 坐标经过 Q15 metadata grid 后换成内部前、侧、上轴,乘以 profile 尺度:
\mathbf s=(a_zq_f,\ a_xq_l,\ a_yq_v).
若射线超出 profile 边界,则用单一比例 \lambda\le1 缩放:
\mathbf s' = \lambda\mathbf s.
随后
\rho=\|\mathbf s'\|_2,
\qquad
\rho_c=\max(\rho,\rho_{\min}),
\qquad
\alpha=\frac{\rho}{\rho_c},
\mathbf d=
\begin{cases}
\mathbf s'/\rho,&\rho>0,\\
(1,0,0),&\rho=0,
\end{cases}
物理半径为
R=D\rho.
7. 36 项方向 basis
方向 \mathbf d=(x,y,z) 被展开为 36 项实值多项式:
\mathbf b(\mathbf d)=
[1,x,y,z,x^2-\tfrac13,xy,xz,y^2-\tfrac13,yz,\ldots]^T.
完整顺序由 rosella_model.direction_basis() 固定。最高次数为 5;所有 field 系数必须按该顺序点积,不能交换 basis 项。
逐耳 basis 会根据耳偏移重新归一化。令耳偏移标量为 $e$:
\epsilon=\frac{eD^{-1}}{\rho_c},
\mathbf d_-=
\frac{(x,y-\epsilon,z)}{\|(x,y-\epsilon,z)\|_2},
\qquad
\mathbf d_+=
\frac{(x,y+\epsilon,z)}{\|(x,y+\epsilon,z)\|_2}.
8. 逐耳路径与 ITD
归一化路径长度为
\ell_-=\rho_c\sqrt{x^2+(y-\epsilon)^2+z^2},
\ell_+=\rho_c\sqrt{x^2+(y+\epsilon)^2+z^2}.
模型允许通过 36-vector 对路径加入非负方向修正:
\ell'_e
=
\ell_e
+
\max(\mathbf v_e^T\mathbf b_e,0)\,2cD^{-1}.
耳间延迟为
\tau
=|\ell'_+-\ell'_-|\,D\frac{f_s}{343.3}\alpha,
\qquad f_s=48000.
路径较长的一耳应用 hybrid-band 相位:
P_h=e^{j\omega_h\tau},
其中 \omega_h 由模型的 20 个 hybrid group 参数递推到 77 个 bands。
9. 方向 field 与直达增益
左右耳各有一个 77×36 complex field:
C_{e,h}(\mathbf d_e)
=
\sum_{j=0}^{35}F_{e,h,j}b_j(\mathbf d_e).
另一次耳路径计算给出左右权重:
w_L=\frac{\ell_+}{\sqrt{\ell_-^2+\ell_+^2}},
\qquad
w_R=\frac{\ell_-}{\sqrt{\ell_-^2+\ell_+^2}}.
有效距离为
R_e=\rho\,s_dD,
其中 s_d 为模型距离标量。Mid/Far 的公共衰减和 room send 为
g_c=\frac{1}{\sqrt{1+s_rR_e^2}},
g_{\mathrm{room}}=R_eg_c.
Near 使用
g_c=1,
\qquad
g_{\mathrm{room}}=0.
令 C_{e,h}^{(0)} 为 field 的第 0 个 basis 系数,中心保护项为 $1-\alpha$。普通直达传递函数可写成
G_{L,h}
=g_c\left[C_{L,h}w_L\alpha+C_{L,h}^{(0)}c_L(1-\alpha)\right],
G_{R,h}
=g_c\left[C_{R,h}w_R\alpha+C_{R,h}^{(0)}c_R(1-\alpha)\right].
c_L,c_R 由模型的耳权重配置选择;路径较长的一耳再乘 $P_h$。
10. LFE 传递函数
LFE 不进入普通对象方向计算。其传递函数为
G_{L,h}^{\mathrm{LFE}}=G_{R,h}^{\mathrm{LFE}}=
\begin{cases}
g_h,&0\le h<16,\\
0,&16\le h<77.
\end{cases}
前 16 个固定系数为
2.60290003, 1.80741799, 0.659342408, -0.0275855921,
-0.105803289, -0.0699509233, 0.0749056414, -0.00919809937,
0.00349014648,-0.0158600751,-0.000723021978,0.00188189559,
-0.000421735429,0.0000329252762,0.0000317397971,0.000000580376991
LFE 的 room send 恒为 0。
11. 对象累加与 room input
每个 hybrid slot 的直达输出为
Y^{\mathrm{direct}}_{e,h}
=
\sum_{s=0}^{15}H_{s,h}G_{s,e,h}.
room 输入为
U_h
=
\sum_{s=1}^{15}H_{s,h}g_{\mathrm{room},s}.
LFE 不进入该和式。
12. Room network
room 只处理前 64 个 hybrid bands。输入先乘
g_0=0.70710677.
对每级 all-pass,设延迟样本为 $d[n]$、系数为 $a$:
r[n]=x[n]-ad[n],
y[n]=ar[n]+d[n].
all-pass 输出复制到 4 个 FDN branches。设延迟输出为 $\mathbf d_h[m]$、4×4 混合矩阵为 $M$:
\mathbf b_h[m]
=U_h[m]\mathbf 1+M\mathbf d_h[m].
每个 branch 使用复反馈系数 $f_{h,i}$:
m_{h,i}[m]=f_{h,i}b_{h,i}[m].
主 tap、可选额外 tap 和左右输出矩阵合成为
Y^{\mathrm{room}}_{e,h}[m]
=
\sum_{i=0}^{3}O_{e,h,i}z_{h,i}[m].
最终 hybrid 输出为
Y_{e,h}=Y^{\mathrm{direct}}_{e,h}+Y^{\mathrm{room}}_{e,h}.
Python 后端把该递归网络展开为有限 complex FIR 并使用 overlap-add;C++ 后端直接保持递归状态。两者均跨帧连续。
13. Hybrid synthesis
hybrid synthesis 是 154 项稀疏即时映射。令映射项为 $(h,i,k,o,w)$,其中 i,o 表示实部或虚部,则
Q_{e,k,o}[m]
\mathrel{+}=
Y_{e,h,i}[m]w.
输出是每耳 64 个 complex QMF bands。
14. QMF synthesis
每耳 QMF vector 先展开为 128 项实向量
\mathbf q_e=[\Re Q_{e,0},\Im Q_{e,0},\ldots,\Re Q_{e,63},\Im Q_{e,63}]^T.
对每个 phase p 和 rank $r=0\ldots3$:
f_{e,p,r}[m]
=\mathbf b_{p,r}^T\mathbf q_e[m].
使用 10-slot taps 合成时域样本:
y_e[64m+p]
=
\sum_{\ell=0}^{9}
\sum_{r=0}^{3}
t_{p,\ell,r}f_{e,p,r}[m-\ell].
15. 延迟、尾声和输出
完整 filterbank 的固定延迟为
L=961\ \text{samples}.
只在连续流起点丢弃一次前 L 个输出 samples。输入结束后继续送零,以释放 QMF、hybrid 和 room 状态。尾声裁切只作用于文件末端:
\max(|y_L[n]|,|y_R[n]|) > 10^{-8}
的最后一个 sample 被保留,同时输出长度不得短于源 PCM 长度。
所有内部状态、参数计算和对象累加使用 float64/complex128。最终 writer 才转换为 float32 或 PCM24。
16. Python 与 C++ 后端
两套后端共享:
- 同一份 QMF/hybrid 固定表;
- 同一份模型解析结果;
- 同一套 512-sample 参数更新时间轴;
- 同一组逐对象 complex gains 和 room sends;
- 同一 961-sample 延迟补偿与尾声策略。
C++ 后端以 512-sample block 为处理单位,内部持有 QMF、hybrid、room 和 synthesis 状态。Python 只负责模型解析、OAMD 时间轴和每块参数更新。
17. 模型文件
默认路径为
HRTF/binaural.personalized_headphone
也可通过
--personalized-headphone PATH
指定其它文件。
.personalized_headphone 中的 int32/Q15 参数在解析后提升为 float64。任意 SOFA FIR 不能只通过数组重排变成该参数模型;若要转换,需要拟合方向 fields、ITD、距离 profile、耳几何和 room 参数。
18. 适用范围
当前路径处理 15 个普通点对象和 1 路 special LFE。对象 extent、spread、diffuse、divergence、channel lock,以及未实现的 OAMD element 变体不在本公式范围内。