db_to_linear
2026/4/14大约 5 分钟
最后同步日期:2026-04-15 | Godot 官方原文 — db_to_linear
db_to_linear
定义
db_to_linear() 用来把分贝(dB)值转换成线性能量值——简单说,就是把"音量旋钮上的 dB 刻度"换算成计算机能直接用的"能量数值"。
为什么要换算?打个比方:你在手机上调节音量,看到的可能是"音量 50%"或"-6 dB"。但计算机内部的音频系统只认"能量值":0 表示完全静音,1 表示原始音量,2 表示原始音量的两倍。db_to_linear() 就是两者之间的"翻译器"。
什么是分贝(dB)? 分贝是一种对数单位,用来衡量声音大小。它有几个特点:
- 0 dB 表示原始音量(不放大也不缩小,能量值 = 1.0)
- 负 dB 表示音量变小(-6 dB 约等于能量减半,-20 dB 约等于能量变为十分之一)
- 正 dB 表示音量变大(+6 dB 约等于能量翻倍)
- 分贝的好处是:小的音量变化和大的音量变化,在刻度上看起来差不多均匀,符合人耳的听觉习惯
在 Godot 中,音频总线(AudioBus)、音效节点(AudioStreamPlayer)等大多使用 dB 作为单位,但某些底层计算需要线性值,这时就需要 db_to_linear() 来转换。
函数签名
C#
public static float DbToLinear(float db)GDScript
func db_to_linear(db: float) -> float参数说明
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
db | float | 是 | 分贝值。0 表示原始音量,负值表示衰减,正值表示放大 |
返回值
float —— 线性能量值。计算公式为 10 ^ (db / 20)。
常见的换算结果:
db_to_linear(0)返回1.0(原始音量)db_to_linear(-6)返回约0.501(约减半)db_to_linear(-20)返回约0.1(约十分之一)db_to_linear(6)返回约1.995(约翻倍)db_to_linear(-80)返回约0.0001(几乎静音)
代码示例
基础用法:常见 dB 值转线性值
C#
using Godot;
public partial class DbToLinearExample : Node
{
public override void _Ready()
{
// 0 dB = 原始音量(线性值 = 1.0)
float v0 = Mathf.DbToLinear(0f);
GD.Print($"0 dB = {v0:F3}");
// 运行结果: 0 dB = 1.000
// -6 dB ≈ 音量减半
float vn6 = Mathf.DbToLinear(-6f);
GD.Print($"-6 dB = {vn6:F3}");
// 运行结果: -6 dB = 0.501
// -20 dB ≈ 原始音量的十分之一
float vn20 = Mathf.DbToLinear(-20f);
GD.Print($"-20 dB = {vn20:F3}");
// 运行结果: -20 dB = 0.100
// +6 dB ≈ 音量翻倍
float vp6 = Mathf.DbToLinear(6f);
GD.Print($"+6 dB = {vp6:F3}");
// 运行结果: +6 dB = 1.995
}
}GDScript
func _ready():
# 0 dB = 原始音量(线性值 = 1.0)
var v0 = db_to_linear(0.0)
print("0 dB = %.3f" % v0)
# 运行结果: 0 dB = 1.000
# -6 dB ≈ 音量减半
var vn6 = db_to_linear(-6.0)
print("-6 dB = %.3f" % vn6)
# 运行结果: -6 dB = 0.501
# -20 dB ≈ 原始音量的十分之一
var vn20 = db_to_linear(-20.0)
print("-20 dB = %.3f" % vn20)
# 运行结果: -20 dB = 0.100
# +6 dB ≈ 音量翻倍
var vp6 = db_to_linear(6.0)
print("+6 dB = %.3f" % vp6)
# 运行结果: +6 dB = 1.995实际场景:渐变音量控制
C#
using Godot;
public partial class FadeAudio : Node
{
private AudioStreamPlayer _player;
// 导出属性:目标音量(dB)
[Export] public float ExTargetDb = -10f;
// 导出属性:渐变速度(dB/秒)
[Export] public float ExFadeSpeed = 5f;
private bool _isFading = false;
public override void _Ready()
{
_player = GetNode<AudioStreamPlayer>("AudioStreamPlayer");
}
public void StartFade()
{
_isFading = true;
}
public override void _Process(double delta)
{
if (!_isFading) return;
// 用线性插值平滑过渡音量
float currentLinear = Mathf.DbToLinear(_player.VolumeDb);
float targetLinear = Mathf.DbToLinear(ExTargetDb);
float newLinear = Mathf.Lerp(currentLinear, targetLinear, ExFadeSpeed * (float)delta);
// 转回 dB 设置给播放器
_player.VolumeDb = Mathf.LinearToDb(newLinear);
GD.Print($"当前音量: {_player.VolumeDb:F1} dB (线性: {newLinear:F3})");
if (Mathf.IsEqualApprox(currentLinear, targetLinear, 0.001f))
{
_isFading = false;
GD.Print("音量渐变完成");
}
// 运行结果: 当前音量: -5.2 dB (线性: 0.549)
}
}GDScript
extends Node
@onready var _player = $AudioStreamPlayer
# 导出属性:目标音量(dB)
@export var ex_target_db: float = -10.0
# 导出属性:渐变速度(dB/秒)
@export var ex_fade_speed: float = 5.0
var _is_fading: bool = false
func start_fade() -> void:
_is_fading = true
func _process(delta):
if not _is_fading:
return
# 用线性插值平滑过渡音量
var current_linear = db_to_linear(_player.volume_db)
var target_linear = db_to_linear(ex_target_db)
var new_linear = lerp(current_linear, target_linear, ex_fade_speed * delta)
# 转回 dB 设置给播放器
_player.volume_db = linear_to_db(new_linear)
print("当前音量: %.1f dB (线性: %.3f)" % [_player.volume_db, new_linear])
if is_equal_approx(current_linear, target_linear):
_is_fading = false
print("音量渐变完成")
# 运行结果: 当前音量: -5.2 dB (线性: 0.549)进阶用法:距离衰减音效
C#
using Godot;
public partial class DistanceAudio : AudioStreamPlayer3D
{
// 导出属性:最大听距
[Export] public float ExMaxDistance = 50f;
// 导出属性:最小音量(dB)
[Export] public float ExMinVolumeDb = -40f;
private Node3D _listener;
public override void _Ready()
{
// 假设玩家摄像机是监听者
_listener = GetNode<Node3D>("/root/Main/Camera3D");
}
public override void _Process(double delta)
{
if (_listener == null) return;
// 计算与听者的距离
float distance = GlobalPosition.DistanceTo(_listener.GlobalPosition);
// 距离越远,衰减越多
float attenuation = 1f - Mathf.Clamp(distance / ExMaxDistance, 0f, 1f);
// 把衰减系数转为 dB 值
// 注意:attenuation 为 0 时 linear_to_db 会返回 -inf
float volumeDb = Mathf.LinearToDb(Mathf.Max(attenuation, 0.0001f));
VolumeDb = Mathf.Max(volumeDb, ExMinVolumeDb);
GD.Print($"距离: {distance:F1}m, 衰减: {attenuation:F2}, 音量: {VolumeDb:F1} dB");
// 运行结果: 距离: 25.0m, 衰减: 0.50, 音量: -6.0 dB
}
}GDScript
extends AudioStreamPlayer3D
# 导出属性:最大听距
@export var ex_max_distance: float = 50.0
# 导出属性:最小音量(dB)
@export var ex_min_volume_db: float = -40.0
var _listener: Node3D
func _ready():
# 假设玩家摄像机是监听者
_listener = get_node("/root/Main/Camera3D")
func _process(delta):
if _listener == null:
return
# 计算与听者的距离
var distance = global_position.distance_to(_listener.global_position)
# 距离越远,衰减越多
var attenuation = 1.0 - clampf(distance / ex_max_distance, 0.0, 1.0)
# 把衰减系数转为 dB 值
# 注意:attenuation 为 0 时 linear_to_db 会返回 -inf
var volume_db = linear_to_db(maxf(attenuation, 0.0001))
volume_db = maxf(volume_db, ex_min_volume_db)
print("距离: %.1fm, 衰减: %.2f, 音量: %.1f dB" % [distance, attenuation, volume_db])
# 运行结果: 距离: 25.0m, 衰减: 0.50, 音量: -6.0 dB注意事项
- 与
linear_to_db()是一对反函数:db_to_linear()和linear_to_db()互为逆运算。db_to_linear(linear_to_db(x))的结果等于x。 - 0 dB 不等于静音:0 dB 表示"原始音量"(线性值 = 1.0)。要实现真正的静音,需要设置一个非常小的 dB 值(如 -80 dB),或者直接用
AudioStreamPlayer.StreamPaused = true暂停播放。 - 线性值为 0 时 dB 是负无穷:
linear_to_db(0)会返回负无穷(-inf。反过来,db_to_linear()对任何有限 dB 值都不会返回 0。 - 对音频做插值时先转线性:直接对 dB 值做插值(如
lerp(-20, 0, t))会产生不自然的音量变化,因为 dB 是对数刻度。正确的做法是先转成线性值,插值后再转回 dB。 - Godot 的 AudioBus 音量滑块就是 dB:在编辑器的音频总线面板中,滑块显示的就是 dB 值。你可以在代码中通过
AudioServer.SetBusVolumeDb()来控制。
