空间音频与三维声场

空间音频要让听者分辨声源的方向与距离。本文讲解 ITD、ILD 与 HRTF 三类定位线索、双耳渲染与 HRTF 数据获取、Ambisonics 从一阶到高阶的编码与解码、对象音频与基于声道的格式差异、房间声学建模与距离感知,并给出实时空间音频与 Web Audio 空间化节点的工程实现。

引言

空间音频的目标是让听者判断出声源的方向、距离与所处空间。在耳机上实现这一点比在扬声器阵列上更难,因为耳机只有两个声道,全部信息必须压缩进左右耳的差异里。人类正是靠这些差异定位的,所以空间音频本质是逆向工程听觉系统。

工程上的核心矛盾是:物理精确的模型算力昂贵且个性化依赖强。每个 HRTF(头相关传递函数)都与人头尺寸、耳廓形状强相关,用别人的 HRTF 会导致前后混淆(front-back confusion)甚至定位完全错误。这就是为什么空间音频的"通用方案"总是不如"个性化方案"好听。

本文从人耳定位的物理线索出发,依次讲解 HRTF 与双耳渲染、Ambisonics 的编码解码体系、对象音频格式、房间声学建模,最后给出实时实现与 Web Audio 的落地方法。

目录

  1. 人耳定位线索:ITD、ILD 与 HRTF
  2. HRTF 数据与双耳渲染
  3. 距离感知与多普勒效应
  4. Ambisonics:从 FOA 到 HOA
  5. 对象音频与基于声道的格式
  6. 房间声学与混响建模
  7. 实时空间音频的实现
  8. Web Audio 的空间化节点
  9. 性能与质量权衡

1. 人耳定位线索:ITD、ILD 与 HRTF

人类定位声源依赖三类线索,它们在不同频段起主导作用。

1.1 ITD(Interaural Time Difference)

声音到达两耳的时间差。声源在侧面时,两耳距离差最大约 21~23 cm:

最大 ITD ≈ 0.21 m / 343 m/s ≈ 0.6 ms

ITD 在低频(< 1.5 kHz)最有效,因为低频波长长,相位差可以无歧义地测量。1.5 kHz 以上波长小于头围,相位差出现多值歧义,人耳转而依赖 ILD。

1.2 ILD(Interaural Level Difference)

声音到达两耳的强度差。头部对高频的遮挡(声影效应)造成 220 dB 的差异,频率越高差异越大。ILD 在 28 kHz 最有效。

ITD 与 ILD 只是粗略模型。完整的定位线索由 HRTF 描述:从某个方向到耳膜的传递函数,包含了耳廓、头部、躯干对声波的散射与共振。

HRTF(θ, φ, f) = 耳膜处声压 / 自由场声压(该方向)

HRTF 的幅度谱有若干特征峰谷(pinna notch),这些峰谷的位置随声源俯仰角变化,是区分上下与前后的关键。没有耳廓的贡献,仅靠 ITD/ILD 无法区分前方与后方。

1.4 三种线索的分工

线索有效频段提供的信息
ITD< 1.5 kHz水平方向(左右)
ILD2~8 kHz水平方向(左右)
谱特征(HRTF)4~16 kHz俯仰、前后

2. HRTF 数据与双耳渲染

2.1 HRTF 的测量

测量方法是把微型麦克风放入受试者的耳道,在消声室中从数百个方向播放扫频信号,对每个方向求脉冲响应(HRIR)。

常用公开数据集:

数据集方向数特点
CIPIC25 方位 × 50 俯仰经典,45 名受试者
MIT KEMAR710人工头,广泛使用
IRCAM Listen1550高分辨率
SADIE II1550 + 多受试者带 Ambisonics 版本

2.2 双耳渲染的基本结构

单声道源 ──┬──▶ 卷积(HRIR_left)  ──▶ 左耳
           └──▶ 卷积(HRIR_right) ──▶ 右耳

每个声源需要两次卷积(左右耳各一)。HRIR 长度典型为 128512 抽头(2.710.7 ms @ 48 kHz)。

2.3 算力问题与优化

直接卷积的开销:

单声源 = 2 × 256 抽头 × 48000 = 24.6 M MAC/s
32 个声源 = 787 M MAC/s(单核吃紧)

优化手段:

  • FFT 分块卷积:复杂度从 O(N) 降到 O(log N),但引入分块延迟。
  • 球谐域渲染:把 HRTF 分解到球谐域,按方向插值,避免每个方向都存一份。
  • 近似模型:用 ITD + 简化谱滤波(如 2 个峰值/谷值的 IIR)代替完整 HRIR,算力降低一个数量级,定位精度损失有限。
  • 最小相位分解:把 HRIR 分解成最小相位部分(用 IIR 近似)+ 纯延迟(ITD),大幅降低阶数。

2.4 个性化

通用 HRTF 的主要问题是前后混淆率可达 30~50%。改进路径:

  • 挑选最佳匹配:从数据库中选出与听者最接近的 HRTF(用耳廓照片或主观测试匹配)。
  • 个性化测量:用手机麦克风 + 扫描做简化测量,精度有限但优于通用。
  • 结构模型:用听者的头部尺寸参数化生成 HRTF(如用边界元法仿真),成本高但精度好。

这与滤波器设计的思路相通,见 audio-dsp-filters 中最小相位与 IIR 近似的内容。

3. 距离感知与多普勒效应

3.1 距离线索

人耳判断距离依赖:

  • 响度:距离加倍衰减约 6 dB(自由场)。
  • 直达/混响比(DRR):距离越远,混响占比越高。这是最强的距离线索。
  • 高频衰减:空气吸收使高频衰减更快,远距离声音"更闷"。
  • 早期反射模式:近处的反射到达角度更分散。
自由场衰减:L(d) = L(1m) - 20·log10(d)   dB
空气吸收:10 kHz 在 20°C/50% 湿度下约 0.1 dB/m,100 m 处衰减 10 dB

3.2 多普勒效应

移动声源的频率偏移:

f_obs = f_src × (c + v_obs) / (c - v_src)

c = 343 m/s。一辆以 30 m/s 驶过的车,1 kHz 鸣笛在接近时约 1096 Hz,远离时约 918 Hz。

实现上,多普勒只是对播放速率做微调:把 playbackRate 乘以多普勒因子。注意多普勒会改变音高,这在游戏里可能不被期望(音乐会被"拉变调"),因此常做成可关闭的选项。

3.3 距离衰减模型

游戏与 VR 中常用几种简化模型:

模型公式特点
线性1 - d/dmax简单,不自然
反比dref / (dref + rolloff·(d - dref))自然,可调
指数exp(-k·d)衰减快,适合近距离
对数1 / (1 + k·log(d/dref))平滑

Web Audio 的 PannerNode 内置了 linear / inverse / exponential 三种距离模型。

4. Ambisonics:从 FOA 到 HOA

Ambisonics 用球谐函数表示声场,是一种与扬声器布局无关的中间格式。

4.1 一阶 Ambisonics(FOA)

FOA 用 4 个通道表示声场:

W:全向分量(omni)
X:前后分量(figure-8 指向 ±X)
Y:左右分量
Z:上下分量

编码一个方向为 (θ, φ) 的单声道源:

import numpy as np
def encode_foa(azimuth, elevation):
    w = 1.0
    x = np.cos(azimuth) * np.cos(elevation)
    y = np.sin(azimuth) * np.cos(elevation)
    z = np.sin(elevation)
    return np.array([w, x, y, z]) * 0.5    # 归一化因子

4.2 解码到扬声器或双耳

解码就是把 B-format 信号按各扬声器方向加权求和:

def decode_foa(bformat, speaker_dirs):
    """speaker_dirs: [(az, el), ...]"""
    out = []
    for az, el in speaker_dirs:
        dec = encode_foa(az, el)          # 每个扬声器的解码系数
        out.append(np.dot(dec, bformat))
    return out

双耳解码则是把 B-format 与一组"虚拟扬声器"的 HRIR 卷积。

4.3 高阶 Ambisonics(HOA)

FOA 的空间分辨率很低(只能大致分辨左右,定位模糊)。阶数 N 对应的通道数为 (N+1)²:

阶数通道数角分辨率(近似)
1(FOA)4~90°
29~60°
316~40°
425~30°
764~15°

HOA 的空间精度显著提升,但通道数平方增长,传输与算力成本陡增。实用场景多取 3 阶(16 通道)。

4.4 Ambisonics 的优势与局限

优势:

  • 格式无关:录一次,可解码到任意扬声器布局或耳机。
  • 可旋转:在球谐域旋转声场只需一次矩阵乘法,适合 VR 头动补偿。
  • 可压缩:HOA 信号的相关性高,压缩效率好。

局限:

  • 低频定位模糊(FOA 尤甚),听感像"包在头周围"而不是明确的点声源。
  • HOA 通道数增长快,不适合大量独立声源。
  • 与"对象音频"相比,失去了对单个声源独立处理的能力。

5. 对象音频与基于声道的格式

三种空间音频范式的对比:

范式表示例子优势
基于声道固定声道数5.1、7.1.4兼容性好,实现简单
基于对象元数据 + 单声道Dolby Atmos可独立处理,自适应渲染
基于场景球谐系数Ambisonics格式无关,可旋转

5.1 对象音频

每个对象是"单声道音频 + 元数据(位置、增益、大小)"。渲染时按播放环境动态映射到实际扬声器。Dolby Atmos 的影院版支持 128 个对象 + 床声道(bed)。

Atmos 码流 = 床声道(7.1.2)+ N 个对象(各带位置元数据)

5.2 实际系统的混合

现实中三者常混用:

  • VR/游戏:对象音频(每个声源一个对象)+ Ambisonics(环境声场)。
  • 电影:床声道 + 对象。
  • 音乐:多为基于声道(立体声/环绕声)的混音。

6. 房间声学与混响建模

空间感的一半来自房间反射,而不是直达声的 HRTF。

6.1 房间脉冲响应(RIR)

RIR 由三部分构成:

1. 直达声(0~1 ms)
2. 早期反射(1~80 ms):决定房间大小与形状感知
3. 晚期混响(> 80 ms):指数衰减,决定"空间感"的浓度

6.2 关键参数

参数含义典型值
RT60混响时间(衰减 60 dB)小房间 0.3 s,大厅 2.0 s
DRR直达/混响比近处高,远处低
早期衰减时间EDT常小于 RT60
清晰度 C50早期/晚期能量比语音 > 0 dB

6.3 实现方式

  • 卷积:直接用 RIR 卷积,质量最好但无法随位置动态变化。
  • 几何声学:射线追踪/镜像源法实时计算早期反射,算力高但支持动态。
  • 算法混响:FDN 等结构,参数可控,适合动态场景。
  • 混合:早期反射用几何法,晚期用算法混响。

游戏引擎通常采用混合方案,与 game-engine-architecture-ecs 中音频系统的集成方式一致:场景信息(房间几何、材质)驱动混响参数。

7. 实时空间音频的实现

7.1 处理链

单声道源 → 距离衰减 → 多普勒 → HRTF 卷积 → 早期反射 → 混响 → 混音 → 双耳输出

7.2 声源数与管理

VR 场景可能有上百个潜在声源。必须做优先级管理:

  • 响度优先:按距离衰减后的响度排序,只渲染最响的 N 个。
  • 重要性加权:对话、关键音效给予更高优先级。
  • 虚拟化:远处的声源不做 HRTF 卷积,只用简单的增益与低通(听起来"远"即可)。

典型预算是同时 16~32 个完整 HRTF 渲染的声源,其余虚拟化。

7.3 头动跟踪

VR 中头部转动需要声场同步旋转。两条路径:

  • 旋转 B-format:若用 Ambisonics,旋转是球谐域的矩阵乘法,成本低。
  • 重算 HRTF:对象音频需要按新方向重新选 HRTF 并做交叉淡化,避免切换时的"咔哒"声。

头动到音频的延迟必须低于约 20 ms,否则会与前庭感知冲突,产生眩晕。

7.4 与视觉的同步

音频延迟与视觉延迟的不匹配比绝对延迟更影响沉浸感。经验规则:音频可以比视觉晚 20~40 ms 而不被察觉,但早了会明显不自然。

8. Web Audio 的空间化节点

Web Audio 提供两个空间化节点。

8.1 StereoPannerNode

只有左右声像,基于等功率定律:

const panner = ctx.createStereoPanner();
panner.pan.value = -0.5;      // -1 全左,+1 全右

不涉及 HRTF,成本极低,适合简单场景。

8.2 PannerNode

完整的 3D 空间化:

const panner = ctx.createPanner();
panner.panningModel = 'HRTF';          // 'equalpower' | 'HRTF'
panner.distanceModel = 'inverse';      // 'linear' | 'inverse' | 'exponential'
panner.refDistance = 1;
panner.maxDistance = 10000;
panner.rolloffFactor = 1;
panner.coneInnerAngle = 360;
panner.positionX.value = 10;
panner.positionY.value = 0;
panner.positionZ.value = -5;

// 听者位置(在 AudioListener 上设置)
ctx.listener.positionX.value = 0;
ctx.listener.forwardZ.value = -1;
ctx.listener.upY.value = 1;

注意:

  • panningModel: 'HRTF' 使用浏览器内置的 HRTF 数据集,算力显著高于 'equalpower'。
  • 位置参数支持 AudioParam(positionX/Y/Z),可以做平滑移动;旧 API 的 setPosition() 已被废弃。
  • 听者方向通过 AudioListener 设置,VR 中每帧更新。

8.3 与 ConvolverNode 组合

要模拟房间,把 PannerNode 的输出送入卷积混响:

const dry = ctx.createGain();
const wet = ctx.createGain();
dry.gain.value = 0.7;
wet.gain.value = 0.3;

const conv = ctx.createConvolver();
conv.buffer = await loadIR('/ir/small_room.wav');

panner.connect(dry).connect(ctx.destination);
panner.connect(conv);
conv.connect(wet).connect(ctx.destination);

ConvolverNode 的算力与 IR 长度成正比,细节见 audio-web-audio-api 。多个声源共享同一个 ConvolverNode 可以显著节省算力(但会失去按声源独立控制混响的能力)。

9. 性能与质量权衡

维度方案 A方案 B建议
HRTF通用数据集个性化测量消费级用通用 + 最佳匹配挑选
渲染完整 HRIR 卷积ITD + IIR 近似声源多时用近似,主角用完整
声场Ambisonics(FOA/HOA)对象音频环境声用 Ambisonics,声源用对象
混响卷积(静态)算法(动态)静态场景卷积,动态场景算法
距离反比模型指数模型开放场景反比,室内指数
声源数全量渲染优先级 + 虚拟化超过 32 个必须虚拟化
头动重算 HRTF旋转 B-format用 Ambisonics 时优先旋转

权衡取舍

维度方案 A方案 B建议
HRTF通用数据集个性化测量消费级用通用 + 最佳匹配挑选
渲染完整 HRIR 卷积ITD + IIR 近似声源多时用近似,主角用完整
声场Ambisonics(FOA/HOA)对象音频环境声用 Ambisonics,声源用对象
混响卷积(静态)算法(动态)静态场景卷积,动态场景算法
距离反比模型指数模型开放场景反比,室内指数
声源数全量渲染优先级 + 虚拟化超过 32 个必须虚拟化
头动重算 HRTF旋转 B-format用 Ambisonics 时优先旋转

常见坑清单

  1. 用通用 HRTF 期待精确定位:前后混淆率可达 30~50%,必须做最佳匹配挑选或个性化。
  2. 只用 ITD/ILD 不做谱滤波:无法区分前后与上下,声像"贴在头两侧"。
  3. HRIR 长度不足:截断过早会丢失耳廓共振特征,定位精度下降,至少保留 128 抽头。
  4. 切换 HRTF 不做交叉淡化:头动时听到"咔哒"声,必须平滑过渡。
  5. 多普勒改变音乐音高:游戏里常需可关闭,或只对音效启用。
  6. 忽略 DRR 只调响度:距离感不自然,远处的声源必须同时提高混响占比。
  7. HOA 通道数爆炸:7 阶需要 64 通道,实时传输不可行,实用取 1~3 阶。
  8. 每个声源独立 ConvolverNode:算力线性增长,共享一个混响节点是常见优化。
  9. 头动到音频延迟过大:超过 20 ms 会与前庭感知冲突,引起眩晕。
  10. 音频比视觉早:音频提前超过 20 ms 会被明显察觉,宁晚勿早。

小结

空间音频的实现是"物理模型 + 心理声学 + 算力约束"三者的妥协。HRTF 提供定位线索,Ambisonics 提供格式无关的声场表示,房间混响提供空间感。三者组合才能让听者真正"身临其境"。

工程上最值得投入的是:HRTF 的最佳匹配挑选(性价比最高)、声源的优先级与虚拟化(决定能支持多少声源)、以及头动到音频的低延迟(决定 VR 的沉浸感)。

继续深入建议读 audio-dsp-filters 理解卷积混响与 IIR 近似的实现细节,读 audio-web-audio-api 掌握 PannerNode 与 ConvolverNode 的完整 API,读 audio-mixing-mastering 了解空间化之后的混音与总线处理。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「音频工程」更多文章

  1. 音视频同步与时间码
  2. 音频硬件接口与驱动栈
  3. 响度标准化与交付规范