setTargetAtTime通过指数函数实现音量平滑过渡,符合人耳对响度的对数感知特性,其衰减公式为v(t)=value+(v₀−value)×e^(-(t−t₀)/τ),τ决定变化快慢,默认0.01秒。

AudioParam 的 setTargetAtTime、exponentialRampToValueAtTime 等方法本身不直接提供“指数级变化”这一曲线类型,但可以通过 setTargetAtTime 实现**指数衰减/增长**(即一阶低通滤波响应),这是 Web Audio API 中最常用、最自然的音量平滑控制方式,符合人耳对响度的感知特性。
使用 Puppeteer + Chrome 将 HTML 渲染为中文 PDF,自动处理图表等待、Tab 展开、动画、测高、白边消除、防分页,适用于看板、报表、网页和交互图表转 PDF。
为什么用 setTargetAtTime 实现“指数变化”
人耳对音量变化的感知近似对数关系,而 setTargetAtTime(value, startTime, timeConstant) 正是按指数函数衰减(或趋近)目标值:v(t) = value + (v₀ − value) × e^(-(t − t₀)/τ)
其中 τ(timeConstant)决定变化快慢:τ 越小,变化越陡;τ 越大,越平缓。默认 τ = 0.01 秒,适合多数音量过渡。
实现音量指数渐变的步骤
以 GainNode 的 gain 参数为例(这是控制音量最常用的方式):
- 创建 AudioContext 和 GainNode,并连接音频图
- 将 GainNode 的
gain设为初始值(如 0.001,避免突兀静音) - 调用
gain.setTargetAtTime(targetValue, currentTime, timeConstant)启动指数过渡 - 若需更长或更短的过渡时间,可调整
timeConstant(单位:秒),典型范围:0.001 ~ 0.1
代码示例:淡入(0 → 1)与淡出(1 → 0.001)
const ctx = new (window.AudioContext || window.webkitAudioContext)();
const gainNode = ctx.createGain();
gainNode.gain.value = 0.001; // 初始极低音量,避免爆音
gainNode.connect(ctx.destination);
// 淡入:从 0.001 指数上升到 1,起始时间是现在,τ = 0.02 秒
gainNode.gain.setTargetAtTime(1, ctx.currentTime, 0.02);
// 若之后要淡出,可在任意时刻调用(例如 2 秒后)
setTimeout(() => {
gainNode.gain.setTargetAtTime(0.001, ctx.currentTime, 0.03); // 更慢的衰减
}, 2000);
注意事项与常见问题
-
不能对 0 调用 exponentialRampToValueAtTime:该方法要求起点和终点都 > 0,否则抛错;
setTargetAtTime则无此限制,更安全 - 避免在非激活状态调用:确保 AudioContext 已被用户手势(如 click)激活,否则 currentTime 可能不准或报错
-
不要混用线性与指数方法:例如先用
linearRampToValueAtTime再接setTargetAtTime,可能因斜率不连续导致咔哒声 - timeConstant 不是持续时间:它表示衰减到 (1−1/e) ≈ 63% 差距所需的时间;99% 完成约需 4.6×τ


















