音频音量调节
线性增益 / 峰值标准化 / 限幅 · 防爆音 · 浏览器本地处理
标准化/增益/限幅
线性增益 / 峰值标准化 / 限幅 · 防爆音 · 浏览器本地处理
支持 MP3 / WAV / FLAC 等
线性增益:直接乘以倍率。+6 dB = ×2 振幅;-6 dB = ÷2 振幅。注意正增益会导致超过 0 dBFS 的部分被硬切(爆音)。
峰值标准化:先找出原始峰值,再统一乘以系数使峰值刚好到目标。保留所有动态范围,最常用的"响一点"方法。
软限幅:超过阈值的部分用 tanh 曲线压缩,避免硬切爆音。播客 / 录音常用 -1 dB 阈值。
了解工具定位 · 使用场景 · 对比优势
对音频文件批量调整音量:标准化将整体音量拉平到统一水平,增益放大或衰减指定分贝,限幅防止峰值过载削波。播客剪辑师统一多轨响度、视频创作者控制素材峰值、音乐爱好者修复录音音量不均时使用。上传文件后由服务端 FFmpeg 处理,处理完成自动删除原始文件。
播客制作人常遇到多位嘉宾录音电平不一致:一位声音小得像耳语,另一位爆音刺耳。本工具对每条音轨先做增益补偿(将平均响度提升至 -16 LUFS),再施加限幅器(上限 -1 dBTP),最终输出的多轨音频音量一致,省去在 DAW 里逐段手动调音量的重复劳动。
短视频创作者在抖音 / 快手 / YouTube Shorts 发布视频,各平台对响度标准要求不同(如抖音要求 -14 LUFS)。本工具提供标准化功能,一键将音频响度映射到目标 LUFS 值,同时开启限幅防止峰值超过 -1 dBTP,避免因响度超标被平台自动降权或静音。
在线教育讲师用降噪软件处理后,音频常出现音量偏低、动态范围变窄的问题。本工具先对降噪后的音频做增益提升(+6 dB 到 +12 dB),再使用限幅器将峰值控制在 -2 dBTP,恢复听感清晰度的同时避免削波失真。
独立音乐人在混音完成后、送去母带前,需要控制峰值电平避免过载。本工具提供软限幅器(阈值 -6 dBFS,启动时间 1 ms,释放时间 50 ms),将瞬态峰值压平至安全范围,保留动态细节的同时确保后续母带环节有足够的 headroom。
游戏主播同时采集麦克风人声、游戏音效、背景音乐三路音频,三路原始音量差异大导致观众体验割裂。本工具分别对三路音频做增益标准化(目标 -18 LUFS),再统一限幅(上限 -2 dBTP),输出后三路音量基本一致,无需在 OBS 里反复调推子。
| 维度 | 本工具 | 竞品 A (Audacity) | 传统方法 (Adobe Audition / 手动操作) |
|---|---|---|---|
| 数据隐私 | 纯浏览器处理,音频数据不上传服务器 | 本地软件处理,数据不出本机 | 本地软件处理,数据不出本机 |
| 处理速度 | 即时处理(毫秒级) | 需加载软件、导入文件,数秒至数十秒 | 需启动专业软件、导入文件、手动调整参数,耗时数分钟 |
| 操作门槛 | 无需安装,打开即用,拖拽或选择文件即可 | 需下载安装,学习基础界面操作 | 需熟悉专业音频软件界面及增益、限幅等专业概念 |
| 功能范围 | 专注标准化、增益、限幅三项核心功能 | 提供完整的音频编辑、多轨混音、效果器链等数百项功能 | 提供完整的音频编辑、多轨混音、母带处理等专业功能 |
| 文件大小限制 | 受浏览器内存限制,建议 500MB 以内 | 受本地内存限制,可处理数 GB 文件 | 受本地内存限制,可处理数 GB 文件 |
| 收费模式 | 完全免费 | 开源免费 | 付费订阅(Creative Cloud)或一次性购买 |
| 平台兼容性 | 任何现代浏览器(Windows / macOS / Linux / ChromeOS) | Windows / macOS / Linux | 仅 Windows / macOS |
上手步骤 · 输入输出 · 避坑提示
| 输入 | 输出 | 说明 |
|---|---|---|
| 输入音频:-18dBFS 平均电平的语音文件;目标:标准化至 -12dBFS | 输出音频:平均电平 -12dBFS,增益提升 +6dB | 典型场景:将录音电平提升至广播标准 |
| 输入音频:-3dBFS 峰值电平的音乐文件;目标:限幅至 -1dBFS 真峰值 | 输出音频:峰值电平 -1dBFS,无削波失真 | 典型场景:母带处理时防止过载 |
| 输入音频:24bit/48kHz 的静音文件(全 0 采样);增益 +20dB | 输出音频:仍为静音文件(全 0 采样),增益无效 | 边界 case:静音输入增益不改变电平 |
| 输入音频:峰值 -0.1dBFS 的爆音文件;限幅至 -6dBFS | 输出音频:峰值 -6dBFS,动态范围压缩明显 | 边界 case:限幅阈值远低于原始峰值 |
| 输入音频:32bit 浮点 WAV 文件,含 +12dBFS 过零采样;标准化至 -3dBFS | 输出音频:峰值 -3dBFS,过零采样被合法缩放 | 边界 case:32bit 浮点可表示超过 0dBFS 的采样 |
| 输入音频:16bit/44.1kHz 单声道文件;增益 +3dB 并限幅至 -0.5dBFS | 输出音频:16bit/44.1kHz 单声道,峰值 -0.5dBFS,无量化噪声 | 易错 case:增益后限幅可避免 16bit 整数溢出 |
| 输入音频:192kHz/24bit 多声道文件(5.1 环绕声);仅对 L/R 声道增益 +6dB | 输出音频:L/R 声道提升 6dB,其他声道不变 | 易错 case:多声道需指定声道映射 |
先限幅再增益先增益再限幅限幅是硬切峰,如果先限幅再增益,增益后新产生的峰值会再次超出目标电平,导致二次失真。标准流程是增益到目标电平,再用限幅兜住瞬态峰值。
增益目标 -6dB,限幅阈值 -12dB限幅阈值 ≥ 增益目标电平(如增益 -6dB,限幅 -3dB 或 -6dB)限幅阈值低于增益目标电平等于白做增益——信号还没到目标电平就被切了,实际输出电平反而更低,且产生大量削波失真。
把一段已经削波失真的音频直接拖进来加 6dB 增益先用限幅或压缩器修复削波部分,或使用原始未失真版本削波已经丢失了波形信息,增益只会放大失真波形,不会恢复细节。工具不提供去削波功能,输入削波音频等于放大缺陷。
把播客人声标准化到 -0.1dB 峰值播客人声标准化到 -3dB 到 -6dB 峰值,留动态余量标准化到满电平(-0.1dB)在后续编码(MP3/AAC)时容易产生溢出削波,因为有损编码会引入量化噪声和滤波器过冲。留 3-6dB 余量是行业惯例。
限幅阈值 -12dB,持续 5 秒的平稳人声也被压到 -12dB限幅只压瞬态峰值(如鼓点、爆破音),持续信号用压缩器处理限幅器设计用于偶尔的瞬态峰值(1-3dB 偶尔压一下),持续压 5-10dB 会产生明显的 pumping 呼吸感和失真。平稳信号应该用压缩器或手动增益调整。
16-bit WAV 增益 +12dB,原始峰值 -6dB → 输出峰值 +6dB(超出 16-bit 范围)增益前检查原始峰值,确保增益后峰值 ≤ 0dBFS;或输出选择 24-bit/32-bit float 格式16-bit 整数格式最大值为 0dBFS,超出部分会被硬裁切。32-bit float 可以安全存储超过 0dBFS 的样本,后续再用限幅处理。
A 段标准化到 -3dB,B 段标准化到 -3dB,然后拼接拼接成一个文件后再做一次整体标准化分别标准化后两段实际平均响度可能不同(标准化只参考峰值),拼接后音量忽大忽小。整体标准化能保证整段音频峰值一致。
限幅阈值 = 0dB,输入信号峰值 = -3dB限幅阈值设到 -1dB 到 -3dB,留安全余量0dB 是数字满刻度,后续编码或数模转换时任何微小的计算误差都会导致溢出。专业音频制作通常限幅到 -1dB 或 -0.3dB。
公式推导 · 流程图解 · 依据出处
y = min( max( x * g, -1.0 ), 1.0 )
y — 输出样本值(归一化到 [-1,1])x — 输入样本值(原始 PCM 数据)g — 增益系数(线性倍率,≥0)输入音频样本 x=0.6,增益 g=2.0(+6dB)。先放大:x*g=1.2。再限幅:min(1.2, 1.0)=1.0,max(1.0, -1.0)=1.0。输出 y=1.0(已削波)。若 g=0.5(-6dB),则 x*g=0.3,在 [-1,1] 内,输出 y=0.3。
适用于 PCM 浮点或整型归一化后的音频样本(如 WAV/MP3 解码后)。增益 g 为线性值(非 dB),限幅阈值固定 ±1.0。若输入已超出 [-1,1] 范围,应先归一化再处理。不适用于压缩器/限制器(带 attack/release 时间常数)或动态范围压缩场景。
3 种主流语言 · 复制即用
import numpy as np
from scipy.io import wavfile
# 读取音频文件
rate, data = wavfile.read('input.wav')
# 标准化:将峰值归一化到 0dBFS(最大振幅 1.0)
dtype = data.dtype
max_val = np.iinfo(dtype).max if np.issubdtype(dtype, np.integer) else 1.0
peak = np.max(np.abs(data))
if peak > 0:
gain = max_val / peak
data = (data * gain).astype(dtype)
# 增益:增加 6dB(线性倍数 ≈ 2.0)
gain_db = 6.0
linear_gain = 10 ** (gain_db / 20)
data = np.clip(data * linear_gain, -max_val, max_val).astype(dtype)
# 限幅:硬限制在 -3dBFS 以内
limit_db = -3.0
limit_linear = max_val * (10 ** (limit_db / 20))
data = np.clip(data, -limit_linear, limit_linear).astype(dtype)
wavfile.write('output.wav', rate, data)package main
import (
"encoding/binary"
"math"
"os"
)
func main() {
// 读取 16-bit PCM WAV 文件(简化:假设已知采样率和数据)
data, _ := os.ReadFile("input.raw")
samples := make([]int16, len(data)/2)
for i := range samples {
samples[i] = int16(binary.LittleEndian.Uint16(data[i*2:]))
}
// 标准化:找到峰值并归一化
var peak int16
for _, s := range samples {
if abs := int16(math.Abs(float64(s))); abs > peak {
peak = abs
}
}
if peak > 0 {
gain := float64(math.MaxInt16) / float64(peak)
for i := range samples {
samples[i] = int16(float64(samples[i]) * gain)
}
}
// 增益 +3dB
linearGain := math.Pow(10, 3.0/20)
for i := range samples {
val := float64(samples[i]) * linearGain
if val > math.MaxInt16 {
val = math.MaxInt16
} else if val < math.MinInt16 {
val = math.MinInt16
}
samples[i] = int16(val)
}
// 限幅:硬限制在 -6dBFS
limit := int16(float64(math.MaxInt16) * math.Pow(10, -6.0/20))
for i := range samples {
if samples[i] > limit {
samples[i] = limit
} else if samples[i] < -limit {
samples[i] = -limit
}
}
// 写回文件
out := make([]byte, len(samples)*2)
for i, s := range samples {
binary.LittleEndian.PutUint16(out[i*2:], uint16(s))
}
os.WriteFile("output.raw", out, 0644)
}// 浏览器环境:使用 Web Audio API 处理音频缓冲区
async function normalizeGainLimit(audioBuffer) {
const ctx = new OfflineAudioContext(
audioBuffer.numberOfChannels,
audioBuffer.length,
audioBuffer.sampleRate
);
// 复制原始数据到离线上下文
const source = ctx.createBufferSource();
source.buffer = audioBuffer;
source.connect(ctx.destination);
source.start();
// 渲染并获取处理后的 buffer
const rendered = await ctx.startRendering();
const channelData = rendered.getChannelData(0); // 仅处理单声道
// 标准化:峰值归一化到 0dBFS
let peak = 0;
for (let i = 0; i < channelData.length; i++) {
const abs = Math.abs(channelData[i]);
if (abs > peak) peak = abs;
}
if (peak > 0) {
const gain = 1.0 / peak;
for (let i = 0; i < channelData.length; i++) {
channelData[i] *= gain;
}
}
// 增益 +6dB
const linearGain = Math.pow(10, 6 / 20);
for (let i = 0; i < channelData.length; i++) {
channelData[i] = Math.min(1, Math.max(-1, channelData[i] * linearGain));
}
// 限幅:硬限制在 -3dBFS
const limit = Math.pow(10, -3 / 20);
for (let i = 0; i < channelData.length; i++) {
channelData[i] = Math.min(limit, Math.max(-limit, channelData[i]));
}
return rendered;
}7 个高频疑问