中EN
概念页

音频引擎架构

Audio Engine Architecture

音频渲染软件和多数系统一样是分层的"栈":硬件 → 驱动 → 底层 API → 3D 音频引擎,功能集通常模仿录音棚的多通道调音台。每个 2D/3D 声音是一条语音 (voice),沿语音总线经过编解码、增益、预发送滤波、辅助发送分出干湿两路、混响、后发送滤波和声像,然后由主混音器合成多声道信号,再经主输出总线(预放、LFE 生成、EQ、压缩、主音量)送到扬声器。资产上分片段、音效提示 (cue)、声音库和流式声音;混音靠分组、闪避、总线预设与混音快照、实例限制和语音抢占(GEA4 卷 II 15.5)。

音频软硬件栈

(卷 II 15.5)

  • 硬件:至少驱动数字或模拟输出;也可能提供编解码器、混音器、混响单元、效果器、波形合成器或 DSP 芯片等"加速",PC 上常叫声卡;
  • 驱动层(PC):让操作系统支持不同厂商的声卡;
  • 底层 API:屏蔽硬件和驱动细节;
  • 3D 音频引擎:构建在以上之上。

功能集模仿多通道调音台:接收大量输入,滤波、均衡、加混响和效果,按设计师设定的相对音量混合,最后送到扬声器或多轨录音的各声道。音频栈同样要接收大量 2D/3D 声音,处理、混合、设定增益,最后平移到扬声器声道。与 运行时引擎分层架构 的整体分层一致。

音频处理图

每个 3D 声音要经过:合成干声 PCM → 距离衰减与混响(产生湿声) → 干湿两路各自声像定位 → 所有声音的多声道信号混合 → 经 DAC 与功放驱动模拟输出,或直接送 HDMI/S/PDIF。由于同时有很多声源,这条管线有很多实例同时在跑,所以也叫音频处理图 (audio processing graph)(卷 II 15.5.1)。

语音 (voice):通过音频图的每个 2D 或 3D 声音。术语来自合成器的波形发生器。系统能同时支持的最大语音数由音频图中独立并行通路的数量决定,受内存、硬件和算力限制,也叫复音数 (polyphony)(卷 II 15.5.2.1)。

2D 语音与 3D 的区别:2D 声音本来就是每个扬声器一路的多声道信号,不经过声像;可能已"烘焙"了混响,不用引擎混响。所以 2D 声音通常在主混音器之前才进入管线(卷 II 15.5.2.1)。

总线 (bus):音频图中组件之间的连接。在软件里只是描述"存在连接"的逻辑结构(卷 II 15.5.2.2)。

语音总线

单个 3D 语音的组件顺序如下图(对应 GEA 图 15.40):预发送滤波作用于干湿两路,辅助发送把信号一分为二,湿路经混响,后发送滤波只作用于干路,最后干湿各自声像定位。

flowchart LR
  C["编解码器 Codec"] --> G["增益 Gain"] --> PRE["预发送滤波 Pre-Send Filter"]
  PRE --> AUX{"辅助发送 Aux Send"}
  AUX -->|"干声"| POST["后发送滤波 Post-Send Filter"] --> PD["声像 Pan 干"]
  AUX -->|"湿声"| RV["混响 Reverb"] --> PW["声像 Pan 湿 可加宽聚焦"]
  PD --> MM["主混音器"]
  PW --> MM
组件作用(卷 II 15.5.3)
编解码器解析源格式、必要时解压,把片段转成音频图的"标准"格式裸 PCM 放上总线;也可以程序化合成,但游戏几乎都用预录片段
增益控制除了录音电平和离线工具调整外,运行时动态调音量
辅助发送来自调音台把信号送出去过效果器再回来的"aux send";在图中是分叉点,一路干声、一路湿声
混响可以用卷积;实时卷积不可行(缺 DSP 硬件或预算不够)时用混响槽 (reverb tank):缓存若干延迟副本与原信号混合,模拟早期反射和晚期混响,再加滤波模拟干涉和高频衰减
预发送滤波在分叉前,干湿都受影响;模拟声源处的现象,如戴防毒面具说话
后发送滤波只作用于干声;模拟遮挡/阻挡造成的发闷。顽皮狗也用它实现随频率的大气吸收
声像每条 3D 语音总线以两个或更多声像器结束:干声按真实位置平移;湿声可以用更宽的聚焦角,窄门口来声只有几度,大厅中央则可设 360°(所有扬声器等量)

主混音器

每个声像器输出一条多声道总线;主混音器把它们混成一路多声道信号(卷 II 15.5.4)。可以在硬件中做(模拟或数字混音),也可以全在软件里做(只能数字混音)。

  • 模拟混音:本质是求和电路,相加后再衰减回目标电压范围。
  • 数字混音:输入 PCM 流可能采样率、位深不同,先统一格式再逐时间点相加,必要时调整总幅值。
  • 采样深度转换:反量化成浮点,再按目标位深重新量化(量化细节见 GEA 13.8.2,本库对应页面为 动画压缩)。
  • 采样率转换:原理上是转回模拟再重采样,但模拟方式引入噪声,实际总是直接在 PCM 上做数字算法。例如采样率翻倍时可以在相邻样本间插值插入新样本,但要注意避免引入走样。

主输出总线

(卷 II 15.5.5,图 15.41)

组件作用
前置放大 (Pre-amp)整体增益微调
LFE 生成器声像只驱动主扬声器;它提取混合信号中最低频的部分驱动低音炮
均衡器 (EQ)把频谱分为 4 到几十个可独立调节的频段
压缩器 (Compressor)动态范围压缩 (DRC):自动压低最响部分和/或抬高最安静部分
主音量控制整个游戏的音量
输出各扬声器的线路电平模拟信号,或 HDMI/S/PDIF 数字多声道信号

总线的实现

  • 模拟总线:并行导线,单声道需要信号线和地线两根;几乎瞬时传输,主要难点是电平和阻抗匹配(卷 II 15.5.6.1)。
  • 数字总线:组件不可能严格同步,所以在输入和/或输出端用环形缓冲 (ring buffer):一个读者、一个写者,各持读头和写头,前进到末尾回绕,两者互不越过,因此读者不会读到未写数据,写者也不会覆盖正在读的数据。最简单的是编解码器和 DAC 共享同一个环形缓冲;跨进程共享需要操作系统把同一块物理内存映射进两个虚拟地址空间。不能共享内存时(如 PC 与插卡声卡),各自有缓冲,由 DMA 控制器(如 PS3 PPU 与 SPU 之间)或 PCIe 总线拷贝(卷 II 15.5.6.2)。单读单写环形缓冲的并发要点见 无锁编程与内存序,游戏代码里同结构的请求队列见 事件队列。

总线延迟:游戏周期性地往编解码器喂数据叫服务音频 (servicing the audio)。喂得太慢缓冲下溢,声音短暂中断;喂得太快缓冲上溢,数据包丢失,声音"跳"。缓冲大小决定延迟:缓冲小延迟低但 CPU 要更频繁地喂;缓冲大则相反。延迟用毫秒而不是字节衡量,因为字节数依格式和压缩而变(卷 II 15.5.6.3)。

  • 专业音频要求约 0.5 ms;
  • 游戏只需音画同步:60 FPS 下一帧 16.6 ms,音频延迟不超过 16 ms 即可;渲染双/三缓冲再加电视延迟,三缓冲 60 Hz 游戏能容忍 3×16=483\times16=48 ms 甚至更多;
  • PS3 的 DMA 控制器每 5.5 ms 运行一次,所以音频缓冲通常配成 5.5 ms 的整数倍。

资产管理

(卷 II 15.5.7)

  • 片段 (clip):最基本的音频资产,有自己的局部时间线(类比动画片段),也叫声音缓冲。3D 用单声道,2D 或 3D 立体声源用多声道。
  • 音效提示 (sound cue):片段集合 + 描述如何处理和播放的元数据,通常是游戏请求播放声音的主要方式;也是分工手段:音效设计师在离线工具里做 cue,程序只管在合适的事件里播放。cue 可以是 5.1 音乐的六个声道、供随机挑选的一组变体、按顺序播放的一组声音;指定单次或循环;可以带中断时才播放的可选片段(对白被打断时的喉塞音、机枪循环停止时的回声"尾巴")。元数据还可以包括 2D/3D、FO min/max 与衰减曲线、所属分组、特殊效果、滤波或 EQ。索尼 Scream 引擎(顽皮狗《神秘海域》《最后生还者》所用)里 cue 甚至能包含任意脚本代码。
  • 播放 cue 的 API 通常可以指定 2D/3D、位置速度、循环与否、内存中还是流式、音量等,并返回声音句柄 (sound handle)。句柄通常是全局句柄表的索引而不是裸指针,所以声音自然结束时句柄可以自动"置空";也能用来做线程安全:一个线程停掉声音,其他线程持有的句柄自动失效。
  • 声音库 (sound bank):片段太多太细,不能逐个管理,所以打包成粗粒度的库。有的启动时加载常驻(如主角的声音),有的按关卡动态加载卸载。例如《最后生还者》里雨声、流水和梁木吱嘎声只在波士顿倾斜大楼里加载。有些引擎允许库在内存中重定位,以消除不同大小的库反复加载卸载产生的碎片(见 自定义内存分配器 的内存整理与重定位)。整体加载策略与 资源管理器 相同。
  • 流式声音:音乐和语音太长,只需当前时间点附近的数据。每个流式声音维护一个较小的环形缓冲,播放前预载一小段,边播边从磁盘补充,只要补得比消耗快就能无缝播放(I/O 见 引擎文件系统与异步文件读写)。

混音

把每个对象发出的每个声音都物理正确地播放,结果是一片嘈杂。好游戏与伟大游戏的区别在于混音:听到什么、听到多少、不听到什么。目标是真实沉浸、不刺耳、有效传达玩法和剧情信息、始终符合情绪基调(卷 II 15.5.8)。

  • 分组 (group):先把各声音的相对音量设对(脚步比枪声小)。分组借自调音台的编组:软件里通常只是给 cue 分类(音乐、音效、武器、语音……),用一个值控制整类的增益,还能整类暂停、恢复、静音。有些引擎也真的把一组信号混成一路,Scream 里叫预主混 (pre-master submix),混合后的信号可以再过滤波等处理(卷 II 15.5.8.1)。
  • 闪避 (ducking):临时压低某些声音让另一些更清楚,如角色说话时压低背景声。可以由某类声音的出现触发、由游戏事件或代码触发;通常通过分组实现,也可以把一路信号接到另一条语音总线上 DRC 的侧链 (side-chain) 输入,让前者越响后者被压得越狠(卷 II 15.5.8.2)。
  • 总线预设与混音快照(Scream 的两种形式):总线预设是单条总线上组件的一组参数(例如模拟大厅、车内或小壁橱的混响设置,或主输出总线的 DRC 设置);混音快照是同样思路用于各组增益(卷 II 15.5.8.3)。
  • 实例限制 (instance limiting):控制同时播放的声音数,例如 20 个 NPC 同时开枪只播最近的三四个。既防嘈杂,也因为语音数有硬上限(硬件编解码器数或软件的内存与算力)。可以按组限制:最多 4 把枪、3 个人说话、5 个其他音效、2 条重叠音乐(卷 II 15.5.8.4)。
  • 优先级与语音抢占 (voice stealing):有些引擎支持大量甚至无限的虚拟语音:技术上仍在播放,但可以暂时静音或停止以释放资源,引擎动态决定哪些映射到"真实"语音。最简单的依据是 FO max:听者在其外就静音;也可以给 cue 或分组设优先级,低优先级先被抢占。还可以设最短播放时间、被抢占时淡出而不是硬切、临时标记为"不可抢占"(卷 II 15.5.8.4)。
  • 游戏内过场的混音:正常游戏时听者在相机附近,所有计算都用真实位置。过场里相机常拉远,两个角色的远景对话按物理已经听不见。这时可以让听者脱离相机,人为放到角色附近。混过场更接近给电影混音,引擎要能"打破规则"(卷 II 15.5.8.5)。

音频库与引擎概览

(卷 II 15.5.9)

名称要点(GEA)
Windows UAA / WASAPI早期 DirectSound + WDM + KMixer 下各声卡实现差异很大;Vista 起的通用音频架构 (UAA) 只标准化有限硬件功能,其余用软件实现,并让操作系统掌控最终混音,多个应用能共享声卡(DirectSound 时代游戏可以独占声卡)。由 WASAPI 实现,但它不是给游戏用的
XAudio2 / X3DAudioXbox 360、Xbox One 和 Windows 上的底层高性能 API,取代 DirectAudio;支持可编程 DSP、子混音、多种格式和多速率处理;X3DAudio 是其上的 3D 渲染库。XACT 与 XNA 已不再支持
Scream索尼的 3D 音频引擎,顽皮狗在 PS3/PS4/PS5 上使用;架构模仿完整调音台。顽皮狗在其上实现了随机遮挡建模和基于门户的环境音频系统
ALSALinux 内核中对应 UAA 驱动模型的组件,取代 OSSv3
QSAQNX Neutrino 实时系统的驱动级音频 API;GEA 推荐其文档作为了解音频硬件概念的材料
OpenAL刻意模仿 OpenGL 设计的跨平台 3D 音频 API;早期开源,现为授权软件;实现有 OpenAL Soft、AeonWave-OpenAL
AeonWave 4DAdalin B.V. 的低成本 Windows/Linux 音频库
FMOD Studio"专业音频"风格的创作工具 + 运行时 3D 音频 API(Windows、Mac、iOS、Android)
WwiseAudiokinetic 的 3D 音频引擎;不以调音台为模型,而是围绕游戏对象和事件组织
Unreal Engine自带 3D 音频引擎和集成工具链

注:GEA 说 OpenAL"早期开源、现为授权软件",这只适用于 Creative 的参考实现。它列举的 OpenAL Soft 本身是开源的(LGPL 2 或更高版本,fork 自 openal.org 早期开源的 Windows 版本;见 kcat/openal-soft 仓库 README 与 COPYING)。

时效说明:上表是 GEA 写作时的情况(例如 FMOD 平台列表只列了四个),选型前应查各产品当前文档。UE5 当前的音频资产体系见 音频系统与 MetaSounds。

取舍

  • 缓冲大小是延迟与 CPU 负担的直接取舍;游戏以"不超过渲染延迟"为界即可。
  • 程序用 cue 和句柄、设计师管 cue 内容,是音频系统的基本分工;把播放请求做成异步、可合并的队列见 事件队列。
  • 语音数总有上限,实例限制和抢占规则是混音设计的一部分,而不只是性能优化。
  1. Game_Engine_Architecture_4th_Edtion_Volume_2_-_Jason_Gregory.pdf
  2. Jason Gregory《Game Engine Architecture》第 4 版(2026)卷 II 第 15 章 15.5 节

相关页面

游戏开发三维音频渲染3D Audio Rendering3D 音频渲染引擎要尽可能可信地重现"玩家若真在游戏世界里会听到什么"。它的输入是世界里大量的 3D 声音,输出是少数几路扬声器声道;主要任务是合成、空间化(距离衰减 + 声像定位)、声学建模(混响、遮挡、衍射)、多普勒和混音。GEA 给出了恒功率声像律、聚焦角、混响区域交叉混合、遮挡/阻挡/排除的分析方法,以及顽皮狗《最后生还者》的随机传播建模和声音门户(GEA4 卷 II 15.4)。游戏开发数字音频技术Digital Audio Technology游戏音频程序员需要了解从麦克风到扬声器的整条硬件链路:模拟端的换能器、扬声器布局、电平、放大器和音量控制;数字端的脉冲编码调制 (PCM) 采样、香农-奈奎斯特采样定理、位深与量化误差、各种音频格式与编解码器、多声道数据的并行与交错布局,以及数字接口。GEA 用它们说明音频引擎的输入输出到底是什么(GEA4 卷 II 15.3)。游戏开发游戏音频功能与角色对话Game-Specific Audio Features & Character Dialog在 3D 音频渲染管线之上,游戏还要实现分屏、物理驱动音频、动态音乐、角色对话、声音合成和人群声音等专门功能。GEA 重点讲了分屏的多听者问题、顽皮狗《最后生还者》的角色对话系统(逻辑台词、随机不重复、优先级与打断、把对话作为一等实体、排他性、基于规则和事实字典的分支对话、按区域标签的情境台词、对话手势)以及音乐系统(播放列表、紧张度、插入乐、过渡)(GEA4 卷 II 15.6)。游戏开发 · UE5音频系统与 MetaSoundsAudio System & MetaSoundsUE5 的音频资产分三层:音源 (Sound Source) 负责产生声音,UE5 主推 MetaSounds,它是一张由设计师搭建的数字信号处理 (DSP) 图,能精确到单个采样;分组与混音用 Sound Class 和 Sound Class Mix 批量调整音量和音高;空间与资源由 Sound Attenuation(随距离衰减和空间化)和 Sound Concurrency(限制同时播放数量)控制。需要和节拍对齐的玩法可以用 Quartz 做精确到采样的调度。游戏开发事件队列Event Queue事件队列 (Event Queue) 用一个先进先出队列,把“发送消息或事件”和“处理它”在时间上解耦:发送方入队后立即返回,接收方在自己方便的时候再取出处理。它比观察者和命令模式多做的一件事是时间上的解耦,适合“推”与“拉”两端节奏不同的场合(例如音频请求),代价是全局可见、世界状态可能已经改变,以及可能出现隐蔽的反馈回环。游戏开发运行时引擎分层架构Runtime Engine ArchitectureGregory 把游戏视为“软实时、交互式、基于代理的计算机模拟”,把游戏引擎定义为数据驱动、可复用来做多款游戏的软件。运行时引擎按层组织:从目标硬件、驱动、操作系统、第三方 SDK、平台无关层、核心系统、资源管理器,到渲染、物理、动画、音频、网络等子系统,再到游戏性基础层和游戏专属子系统;上层依赖下层,避免循环依赖。游戏开发资源管理器Resource Manager游戏由网格、材质、纹理、着色器、动画、音频、关卡布局、碰撞与物理参数等大量资源(也叫资产、媒体)构成。内存有限,所以引擎要保证每个资源在内存中只有一份(五个网格共用一张纹理时只载入一份)。每个引擎都有某种资源管理器:有的是统一集中的子系统,有的散布在多年间由不同人写的各个子系统中,但职责和要解决的问题是一样的。本页讲运行时部分:职责、文件组织与归档、文件格式、资源 GUID、资源注册表、生命周期(引用计数)和资源的内存管理;交叉引用与加载后初始化见 资源交叉引用与加载后初始化,离线工具链见 资产管线与工具链。游戏开发引擎文件系统与异步文件读写Engine File System & Asynchronous File IO资源管理器大量依赖文件系统。引擎通常把操作系统的文件 API 包装成自己的 API:一是跨平台、屏蔽硬件差异;二是操作系统缺少引擎需要的功能(如流式加载),主机还要统一访问记忆棒、硬盘、蓝光盘、网络文件系统等介质。引擎文件系统 API 通常涵盖:文件名与路径操作、打开/关闭/读写文件、扫描目录、处理异步 I/O 请求(流式加载)。游戏开发自定义内存分配器Custom Memory Allocators内存从两方面影响性能:动态分配(malloc / 全局 new)很慢,以及访问模式主导现代 CPU 的性能。GEA 的经验法则是「尽量少做堆分配,绝不在紧密循环里做堆分配」,并介绍游戏引擎常用的自定义分配器:栈分配器(含双端栈)、池分配器、对齐分配、单帧与双缓冲分配器;以及如何用栈/池避免碎片,或用碎片整理加指针重定位(智能指针、句柄)解决碎片。游戏开发无锁编程与内存序Lock-Free Programming & Memory Ordering「无锁 (lock-free)」的真正含义不是不用互斥锁,而是从不让线程阻塞(作者说叫 block-free 更贴切)。数据竞争有三个来源:关键操作被打断、编译器与 CPU 的指令重排、缓存一致性协议优化造成的内存序问题。对应的工具是原子指令(TAS、XCHG、CAS、LL/SC)和内存屏障/栅栏(acquire、release、full fence),C++11 用 std::atomic 与 std::memoryorder 把它们封装成可移植接口。在此基础上可以写出自旋锁、可重入锁、读写锁,以及基于「本地准备 + 一次原子提交」事务的无锁数据结构。游戏开发字符串与唯一标识符Strings & Unique Identifiers字符串在 C/C++ 中只是字符数组,变长意味着要么硬编码长度上限、要么动态分配;比较和复制都是 O(n)。引擎内部大量用字符串做资源名和对象 ID,处理不当会严重拖慢游戏。GEA 的建议:运行时代码尽量避免字符串类,若用则了解其成本并按引用传递;路径类是值得专门做的例外;对象与资产的唯一标识用哈希字符串 ID(string id),兼得字符串的可读性与整数的比较速度。游戏开发声音的物理与感知Physics & Perception of Sound声音是在空气等可压缩介质中传播的压缩波,用声压随时间变化的信号 p(t) 描述。游戏音频要模拟的物理与感知现象包括:用分贝度量的响度、人耳对频率不均匀的灵敏度、随距离和大气吸收的衰减、干涉、早期反射与晚期混响、多普勒频移,以及人耳判断声源方位的线索(ITD、IID、HRTF)。GEA 把它们作为 3D 音频渲染的理论基础(GEA4 卷 II 15.1)。游戏策划游戏美学Game Aesthetics美学是四元素中的第三象限(另三者为机制、故事、技术)。有人轻视它为"表面细节",但我们设计的是完整体验,美学是让体验更愉悦的一部分。本章讲美术的价值、"学会看"、让美学引导设计(概念图与抽象原型交替)、细节放在哪里(Hench 的近看与 Tolkien 的"远山")、尽早使用音频,以及美术与技术的平衡(让美术开车、工程师导航,并配技术美术)。建议把已有的 33 面透镜转向审视美术,并新增 94 氛围之镜(第 3 版第 23 章 The Look and Feel of a World Is Defined by Its Aesthetics;第 1 版为第 20 章,列 26 面旧透镜,没有新游戏开发动画压缩Animation Compression未压缩的动画每关节每样本最多 10 个 32 位浮点通道,数据量巨大。GEA 列出的压缩手段按力度递增:省略无用通道、量化(如 16 位 RL 编码)、降低采样率或省略近似线性的关键帧、用 B 样条拟合曲线、小波压缩,以及最根本的:只把需要的片段放进内存(选择性加载与流式加载)(GEA4 卷 II 13.8)。

被这些页面引用1 篇

输入关键词开始搜索

滚轮或双指缩放 · 拖动平移 · 双击放大 / 还原