news 2026/10/14 21:07:49

Turbulenz 引擎 SoundEffect 音效系统指南:Reverb/Echo 效果参数详解与 SoundEffectSlot 实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Turbulenz 引擎 SoundEffect 音效系统指南:Reverb/Echo 效果参数详解与 SoundEffectSlot 实战
  • 游戏开发
  • 图形学

【免费下载链接】turbulenz_engine

Turbulenz is a modular 3D and 2D game framework for making HTML5 powered games for browsers, desktops and mobile devices.

项目地址:https://gitcode.com/gh_mirrors/tu/turbulenz_engine
点击查看免费下载

导读

本文面向使用 Turbulenz 引擎开发 HTML5 游戏的音频工程师与前端开发者,系统讲解 SoundEffect 与 SoundEffectSlot 对象 的完整 API:如何通过SoundDevice.createEffect创建混响(Reverb)与回声(Echo)效果、每个参数的物理含义与取值范围、如何借助SoundEffectSlot将同一效果复用到多个声源,以及从效果创建到声源挂接的完整调用链路。读完本文,你将能够为游戏环境(走廊、大厅、洞穴、开阔地形)配置可调的实时音频效果,并理解这些效果在当前引擎实现中的平台能力边界。


SoundEffect 对象概览

SoundEffect对象代表一个由一组参数创建出来的音频效果,它可以被关联(attach)到一个效果槽(effect slot)上。效果本身不直接发声,它通过后续的SoundEffectSlot与声源(Source/GlobalSource)的输出链路结合,对经过它的声音进行处理。

根据 SoundDevice API 文档,一个SoundEffect对象只能通过SoundDevice.createEffect()构造,示例如下:

var effect = soundDevice.createEffect({ name : "HallwayReverb01", type : "Reverb", delay : 0.15 });

createEffect的公共参数只有两个:

  • name:要创建的效果名称(字符串);
  • type:要创建的效果类型(字符串)。如果该类型不被支持,createEffect将创建失败并返回null。

当效果创建成功后,它会继承该类型所定义的全部属性(采用传入值,未传入的属性取默认值)。本文档列出的所有属性,均可通过 getter 读取、通过 setter 写入。在 TypeScript 类型声明 中,SoundEffectParameters将全部参数标记为可选,也印证了"未传参数即采用默认值"的行为。

值得注意:在 WebGL 后端的 SoundDevice 实现 中,createEffect与createEffectSlot的当前实现直接返回null。这意味着效果处理链路依赖底层 OpenAL EFX 渲染器提供,纯 HTML5 音频后端目前不包含效果实现,详见后文"平台能力边界"一节。

通用属性

name

效果的标识名称,可读写。常用于在代码中区分同一场景中创建的不同效果实例。

// Get var name = effect.name; // Set effect.name = "HallwayReverb01";

type

效果的类型字符串,只读。在createEffect时由type参数决定,例如"Reverb"、"Echo"。

// Get var type = effect.type;

Reverb 混响效果参数详解

混响(Reverb)效果模拟声音在空间中的多次反射与衰减。Turbulenz 的 Reverb 效果参数完整覆盖了早期反射、后期混响、频谱塑造与空气吸收等物理维度。各参数汇总如下,随后逐一展开:

参数含义取值范围默认值单位
density模态密度,控制晚期混响染色0.0 ~ 1.01.0线性
diffusion回波密度0.0 ~ 1.01.0线性乘数
gain混响主音量0.0 ~ 1.00.32线性增益
gainHF高频反射声衰减(低通)0.0 ~ 1.00.89线性增益
decayTime混响衰减时间0.1 ~ 20.01.49秒
decayHFRatio高频衰减时间相对低频之比0.1 ~ 2.00.83线性乘数
reflectionsGain早期反射总量(相对gain)0.0 ~ 3.160.05线性增益
reflectionsDelay直达声到首次反射的延迟0.0 ~ 0.30.007秒
lateReverbGain后期混响总量(相对gain)0.0 ~ 10.01.26线性增益
lateReverbDelay后期混响相对首次反射的开始时间0.0 ~ 0.10.011秒
roomRollOffFactor反射声按距离衰减的滚降系数0.0 ~ 10.00.0线性乘数
airAbsorptionGainHF传播介质导致的高频距离衰减0.892 ~ 1.00.994每米线性增益
decayHFLimit是否自动限制高频衰减时间true / falsetrue布尔

density—— 模态密度

Reverb Modal Density 控制晚期混响的染色(coloration)。降低该值会给晚期混响增加更多染色感,使尾音听起来更"金属"或更"空洞";趋近 1.0 时染色最少,混响更平滑。

// Get var density = effect.density; // Set effect.density = 0.3;
  • 范围:0.0到1.0
  • 默认:1.0

diffusion—— 回波密度

Reverb Diffusion 控制混响衰减过程中的回波密度。默认值 1.0 提供最高密度;降低扩散度会让混响呈现更"颗粒状"(grainy)的特性,这在打击乐声源上尤其明显。若设为 0.0,后期混响听起来会像一连串彼此分离的独立回声。

// Get var diffusion = effect.diffusion; // Set effect.diffusion = 0.3;
  • 范围:0.0到1.0
  • 默认:1.0
  • 单位:线性乘数值

gain—— 混响主音量

Reverb Gain 是所有反射声(包括早期反射与后期混响)的总音量控制,它设定最终混音中加入的反射与混响的最大量。取值从 1.0(0 dB,最大量)到 0.0(-100 dB,完全没有反射声)。

// Get var gain = effect.gain; // Set effect.gain = 0.4;
  • 范围:0.0到1.0
  • 默认:0.32
  • 单位:线性增益

gainHF—— 高频反射衰减

Reverb Gain HF 通过在反射声上施加一个全局低通滤波器来衰减高频。取 1.0(0 dB)表示不滤波;取 0.0(-100 dB)表示高频反射声几乎完全消失。它作用于所有送入该混响实例的声源反射声。

// Get var gainHF = effect.gainHF; // Set effect.gainHF = 0.6;
  • 范围:0.0到1.0
  • 默认:0.89
  • 单位:线性增益

decayTime—— 混响衰减时间

Decay Time 设定混响的衰减时长。0.1 秒通常对应表面吸声极强的小房间;20.0 秒通常对应表面非常"活跃"(反射强)的大空间。

// Get var decayTime = effect.decayTime; // Set effect.decayTime = 1.9;
  • 范围:0.1到20.0
  • 默认:1.49
  • 单位:秒

decayHFRatio—— 高频衰减时间比

Decay HF Ratio 设定 Decay Time 的频谱特性,即高频衰减时间相对于低频衰减时间的比值:

  • 取 1.0 时是中性的:所有频率的衰减时间相等;
  • 大于 1.0 时,高频衰减时间更长,你会听到更明亮、高频拖尾更长的混响;
  • 小于 1.0 时,高频衰减时间更短,混响听起来更自然(更"闷")。
// Get var decayHFRatio = effect.decayHFRatio; // Set effect.decayHFRatio = 1.9;
  • 范围:0.1到2.0
  • 默认:0.83
  • 单位:线性乘数值

reflectionsGain—— 早期反射总量

Reflections Gain 控制早期反射(initial reflections)相对gain的总量。gain设定的是反射声总体量(早期反射 + 后期混响),而本属性在此基础上进一步调整早期反射部分:最大值 3.16(+10 dB),最小值 0.0(-100 dB,即完全没有早期反射)。它不影响后续的混响衰减过程。

调音建议(来自原文档):增大早期反射可以模拟更狭小的空间或更近的墙壁,若同时配合减小reflectionsDelay(缩短反射延迟)效果更明显;要模拟开阔或半开阔环境,可以保持早期反射量不变,同时降低lateReverbGain(后期混响量)。

// Get var reflectionsGain = effect.reflectionsGain; // Set effect.reflectionsGain = 2.1;
  • 范围:0.0到3.16
  • 默认:0.05
  • 单位:线性增益

reflectionsDelay—— 早期反射延迟

Reflections Delay 是从直达声到达听者,到第一次反射声到达之间的时间差(0 到 300 毫秒)。增大或减小该值可以模拟更远或更近的反射面,从而控制听者对房间大小的感知。

// Get var reflectionsDelay = effect.reflectionsDelay; // Set effect.reflectionsDelay = 0.1;
  • 范围:0.0到0.3
  • 默认:0.007
  • 单位:秒(注意代码中按秒书写,0.3 秒即 300 毫秒)

lateReverbGain—— 后期混响总量

Late Reverb Gain 控制后期混响相对gain的总量,最大值 10.0(+20 dB),最小值 0.0(-100 dB,即完全没有后期混响)。

需要注意:Late Reverb Gain 与 Decay Time 是相互独立的属性。只调整decayTime而不改动lateReverbGain时,后期混响的总强度(振幅平方的平均值)保持不变——混响只是被拉长或压缩,响度并不会随之变化。

// Get var lateReverbGain = effect.lateReverbGain; // Set effect.lateReverbGain = 3;
  • 范围:0.0到10.0
  • 默认:1.26
  • 单位:线性增益

lateReverbDelay—— 后期混响开始时间

Late Reverb Delay 定义后期混响相对于首次早期反射的起始时间(0 到 100 毫秒)。减小或增大该值可用于模拟更小或更大的房间。

// Get var lateReverbDelay = effect.lateReverbDelay; // Set effect.lateReverbDelay = 0.23;
  • 范围:0.0到0.1
  • 默认:0.011
  • 单位:秒

roomRollOffFactor—— 反射声距离衰减系数

Room Rolloff Factor 是按"声源-听者"距离来衰减反射声(含反射与混响)的两种手段之一。它的定义方式与 OpenAL 的 Rolloff Factor 相同,但作用于混响声而非直达声。取 1.0 表示距离每翻一倍反射声衰减 6 dB;其他取值相当于对(源听距离 - Reference Distance)施加一个缩放系数。Reference Distance 是 OpenAL 声源参数,定义了距离滚降生效的内边界:声源比该距离更近时,直达声不再随靠近而增强,反射声同理。

默认值为 0.0,因为默认情况下 Effects Extension 的混响效果会为每个声源自动管理反射声电平,以模拟典型房间中反射声随距离的自然滚降。(注意:如果声源属性标志auxiliarySendFilterGainAuto被设为false,则不再自动管理。)你可以把roomRollOffFactor当作自动控制的补充选项,用来夸大或取代默认的自动滚降。

// Get var roomRollOffFactor = effect.roomRollOffFactor; // Set effect.roomRollOffFactor = 0.7;
  • 范围:0.0到10.0
  • 默认:0.0
  • 单位:线性乘数值

airAbsorptionGainHF—— 空气吸收高频衰减

Air Absorption Gain HF 控制由传播介质(空气)引起的高频随距离衰减,只作用于反射声。你可以用它模拟透过潮湿空气、干燥空气、烟雾等介质传播的声音效果。默认值 0.994(约 -0.05 dB)每米,对应典型的空气湿度、温度等常规条件:

  • 降低该值模拟吸收性更强的介质(例如空气中湿度更高);
  • 提高该值模拟吸收性更弱的介质(例如干燥的沙漠空气)。
// Get var airAbsorptionGainHF = effect.airAbsorptionGainHF; // Set effect.airAbsorptionGainHF = 0.938;
  • 范围:0.892到1.0
  • 默认:0.994
  • 单位:每米线性增益

decayHFLimit—— 高频衰减时间自动限制

当该标志为true时,高频衰减时间会自动保持在一个由airAbsorptionGainHF设定值推导出的上限之下。该限制与decayHFRatio的取值无关,也不会改动decayHFRatio的值。开启后,你可以放心增大decayTime而不用担心高频出现不自然的超长衰减,从而维持自然的混响尾音;设为false则不对高频衰减时间做自动限制。

// Get var decayHFLimit = effect.decayHFLimit; // Set effect.decayHFLimit = false;
  • 范围:true或false
  • 默认:true

Echo 回声效果参数详解

Echo 效果生成输入信号的离散、延迟副本(实例),延迟量与反馈量均可控。它的延迟是"双抽头"(two tap)结构——你可以控制两路独立回声实例之间的相互作用。参数汇总:

参数含义取值范围默认值
delay原声到第一个"tap"的延迟0.0 ~ 0.2070.1
lrdelay第一个 tap 到第二个 tap 的延迟0.0 ~ 0.4040.1
damping每个回声的高频阻尼量0.0 ~ 0.990.5
feedback输出反馈回输入的量0.0 ~ 1.00.5
spread各回声的声像(pan)程度-1.0 ~ 1.0-1.0

delay—— 首个回声延迟

控制原声与第一个"tap"(回声实例)之间的延迟。此后,Echo Delay 的值还会用于确定"第二个 tap"与下一个"第一个 tap"之间的时间间隔。

// Get var delay = effect.delay; // Set effect.delay = 0.046;
  • 范围:0.0到0.207
  • 默认:0.1

lrdelay—— 双 tap 间延迟

控制第一个"tap"与第二个"tap"之间的延迟。此后,Echo LR Delay 的值还会用于确定每个"第一个 tap"与下一个"第二个 tap"之间的时间间隔。

// Get var lrdelay = effect.lrdelay; // Set effect.lrdelay = 0.1337;
  • 范围:0.0到0.404
  • 默认:0.1

damping—— 回声高频阻尼

控制施加在每个回声上的高频阻尼量。由于声音会被反复反馈产生后续回声,阻尼会使回声在强度与音色上逐次变柔和——回声一次比一次更闷、更弱。

// Get var damping = effect.damping; // Set effect.damping = 0.78;
  • 范围:0.0到0.99
  • 默认:0.5

feedback—— 回声反馈量

控制输出信号反馈回输入的量。用该参数可以制造"级联"(cascading)回声效果:

  • 满值(接近 1.0)时,相同的采样会无限重复下去;
  • 低于满值时,采样会重复并逐渐衰减。
// Get var feedback = effect.feedback; // Set effect.feedback = 0.235;
  • 范围:0.0到1.0
  • 默认:0.5

spread—— 回声声像展开

控制每个回声被"硬声像"(hard panned)的程度:

  • 1.0 时,第一个 tap 被硬声像到极左,第二个 tap 硬声像到极右;
  • -1.0 时结果相反(默认值即 -1.0);
  • 越接近 0.0,声像展开越弱。
// Get var spread = effect.spread; // Set effect.spread = -0.5;
  • 范围:-1.0到1.0
  • 默认:-1.0

SoundEffectSlot 对象详解

SoundEffectSlot对象是一个效果的容器。一个槽可以同时关联多个声源,实现"单个效果处理多个声源输出"的复用模式。它通过SoundDevice.createEffectSlot()创建:

var effectSlot = soundDevice.createEffectSlot({ effect : effect, gain : 0.8 });

createEffectSlot的参数:

  • effect:要与槽配合使用的SoundEffect对象,只能在创建槽时设置;
  • gain:应用到槽输出的增益,0.0 表示静音。

如果effect不是有效的SoundEffect对象或参数不正确,createEffectSlot返回null(见 SoundDevice API 文档)。

effect—— 槽内效果(只读)

附加到槽上的效果对象。该值只能在SoundEffectSlot创建时指定,之后不可更改。

// Get var effect = effectSlot.effect;

gain—— 槽输出增益

应用于SoundEffectSlot输出的增益,0.0 为静音。可以用它来单独调整"效果湿声"在最终混音中的比例,而无需改动声源本身的音量。

// Get var gain = effectSlot.gain; // Set effectSlot.gain = 0.1;
  • 范围:0.0到1.0
  • 默认:1.0
  • 单位:线性增益

auxiliarySendAuto—— 自动发送调整

启用或禁用基于声源与听者物理位置的自动发送调整。当应用希望用混响效果模拟听者(或一组声源)周围的环境时,应将该属性保持启用。

// Get var auxiliarySendAuto = effectSlot.auxiliarySendAuto; // Set effectSlot.auxiliarySendAuto = true;
  • 范围:true或false
  • 默认:true

实战链路:从效果创建到声源挂接

将效果真正作用于声音,需要走完"效果 → 槽 → 声源 Auxiliary Send"的完整链路。以 3D 声源(Source)为例:

// 1. 创建混响效果(未指定的属性取默认值) var effect = soundDevice.createEffect({ name : "HallwayReverb01", type : "Reverb", decayTime : 1.9, gain : 0.4, density : 0.3 }); if (!effect) { // type 不支持或参数错误时返回 null } // 2. 创建效果槽,装载效果 var effectSlot = soundDevice.createEffectSlot({ effect : effect, gain : 0.8 }); // 3. 将效果槽挂接到声源的 Auxiliary Send 输出 var result = source.setAuxiliarySendFilter(0, effectSlot, null); // result === false 表示该声源没有 index 0 这个 Auxiliary Send 输出

根据 Source API 文档 与 GlobalSource API 文档,setAuxiliarySendFilter(index, effectSlot, filter)的要点如下:

  • index:Auxiliary Send 的索引。soundDevice.alcMaxAuxiliarySends给出每个声源最多可用的 Auxiliary Send 数量,例如值为 2 时index可取 0 或 1;
  • effectSlot:要应用的效果槽对象,传null表示关闭该路发送;
  • filter:在送入效果槽之前对声源输出做前置处理的SoundFilter对象(例如低通滤波器,参考 SoundFilter API 文档),传null表示不经过滤波;
  • 在同一索引上重复设置会替换掉之前的效果槽/滤波器;
  • 函数返回true表示操作成功,返回false表示出错(例如声源不支持该索引)。

对不关心空间定位的音效(UI 提示音、背景音乐等),可以改用GlobalSource,它同样提供setAuxiliarySendFilter,效果槽的用法完全一致。此外还需注意:

  • 定期调用soundDevice.update():SoundDevice 的update方法会轮询正在播放的声源状态并更新数据,文档建议每个渲染帧调用一次(例如通过TurbulenzEngine.setInterval(renderFrame, 1000 / 60)),以保证自动发送调整(auxiliarySendAuto)等基于位置的特性持续生效;
  • 销毁顺序:在调用TurbulenzEngine.flush()之前,必须把所有使用过的 Auxiliary Send 与 Direct 输出都置为null(如source.setAuxiliarySendFilter(0, null, null)),否则可能导致声音对象销毁时报错。

平台能力边界

需要明确当前仓库的实现边界。SoundDevice 的官方定位是"使用 OpenAL 提供 3D 声音支持"(见 SoundDevice API 文档 开头),并且暴露了alcEfxVersion、alcMaxAuxiliarySends、extensions等属性——其中alcEfxVersion是 OpenAL 实现对 EFX(Effects Extension)扩展支持的版本字符串,alcMaxAuxiliarySends则是每个声源可用的 Auxiliary Send 上限,这些都直接与 SoundEffect 的可用性相关。

但从当前仓库的 WebGL/HTML5 后端源码看,sounddevice.ts 中createEffect、createEffectSlot、createFilter的实现均为直接返回null;声源的setAuxiliarySendFilter同样返回false(见同文件第 1106-1116 行)。由此可以推断:效果处理(EFX)能力依赖具备 OpenAL 渲染器的原生后端提供,纯 HTML5 音频后端目前不包含 SoundEffect/SoundEffectSlot 的实现。也就是说,在纯浏览器 WebGL 环境下调用createEffect会得到null,开发者应当先检查返回值,或依据运行环境(原生 OpenAL 后端 / HTML5 后端)做能力降级处理。

类型定义速查

若使用 TypeScript 开发,可直接参考 turbulenz.d.ts 中的接口定义:

interface SoundEffectParameters { name : string; type : string; // Echo delay? : number; lrdelay? : number; damping? : number; feedback? : number; spread? : number; // Reverb density? : number; diffusion? : number; gain? : number; gainHF? : number; decayTime? : number; decayHFRatio? : number; reflectionsGain? : number; reflectionsDelay? : number; lateReverbGain? : number; lateReverbDelay? : number; roomRollOffFactor? : number; airAbsorptionGainHF? : number; decayHFLimit? : number; } interface SoundEffectSlotParameters { effect : SoundEffect; gain : number; }

该文件同时定义了SoundEffect、SoundEffectSlot的运行时属性接口(name、type、全部 Reverb/Echo 参数以及effect、gain、auxiliarySendAuto),与本文前面各属性一一对应,可作为编写强类型代码时的权威参照。

小结

SoundEffect与SoundEffectSlot构成了 Turbulenz 引擎音频效果系统的一对核心对象:前者负责定义"效果是什么"(13 个 Reverb 参数 + 5 个 Echo 参数,覆盖密度、扩散、增益、衰减、延迟、距离滚降与空气吸收等全部维度),后者负责"效果如何接入混音链路"(可复用于多个声源、可独立调节湿声增益、可基于位置自动调整发送量)。配合SoundDevice.createEffect/createEffectSlot与声源的setAuxiliarySendFilter,即可在支持 OpenAL EFX 的平台上为游戏搭建完整的空间音频效果管线;而在纯 HTML5 后端上,需要依据createEffect返回null的特性做好能力检测与降级。

  • 游戏开发
  • 图形学

【免费下载链接】turbulenz_engine

Turbulenz is a modular 3D and 2D game framework for making HTML5 powered games for browsers, desktops and mobile devices.

项目地址:https://gitcode.com/gh_mirrors/tu/turbulenz_engine
点击查看免费下载
上一篇:scriptc交叉编译教程:如何用zig从macOS构建Linux和Windows可执行文件
下一篇:CLM-v0.1-8B 技术全解析:Contrastive Language Model 的架构、推理与微调实践

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/14 21:07:32

IPD技术评审TR1-TR6落地指南:从风险闸门到闭环管理

简介:IPD技术评审(TR1-TR6)是产品开发从概念到量产的关键控制点,覆盖技术成熟度、质量与市场准备度的阶段性评估。这份PDF面向研发管理者、项目经理、SE与PQA等角色,系统梳理了TR评审定义、评审计划、各阶段关注点及裁…

作者头像 李华
网站建设 2026/10/14 21:05:11

LCD_ShowChar函数深度解析:从字模数据到点阵显示原理

1. 先搞明白:这个函数为什么值得单独拆开讲1.1 几乎所有显示工程的起点如果你玩过或者做过带屏幕的嵌入式项目,不管是温湿度计、闹钟、小家用电器的控制面板,还是更复杂一点的菜单交互系统,绝大多数界面最终落实到屏幕上&#xff…

作者头像 李华
网站建设 2026/10/14 21:03:10

ASP.NET微信JSAPI支付实战:解决统一下单后前端白屏问题

简介:本资源是一份基于ASP.NET(C#)实现微信JSAPI支付接口的完整可运行Demo,面向Web开发初学者及企业级支付功能集成开发者,解决微信公众号内H5页面调用统一下单、支付回调、退款及查询等核心流程的落地难题。压缩包共1…

作者头像 李华
网站建设 2026/10/14 21:02:47

React高可维护表单设计:Schema驱动+状态解耦+动态渲染

简介:这是一份面向前端初学者与JavaScript进阶学习者的交互式表单开发示例资源,聚焦于通过原生JavaScript实现具备动态验证、自定义UI、平滑动画及异步提交能力的‘花式表单’,解决传统表单体验单调、反馈滞后、移动端适配不足等常见痛点。压…

作者头像 李华
网站建设 2026/10/14 21:02:36

《县中的孩子》:看见县域教育生态的真实困境

书读到一半的时候,我好几次停下来。不是看不懂,是有些场景太熟悉了。教室后墙的倒计时、县城中学门口等孩子的电动车、晚自习熄灯后还在走廊背书的影子——这些画面明明离大城市很遥远,却又让人觉得哪儿哪儿都是。《县中的孩子》不是那种告诉…

作者头像 李华