linear_to_db
2026/4/14大约 5 分钟
最后同步日期:2026-04-15 | Godot 官方原文 — linear_to_db
linear_to_db
定义
linear_to_db() 用来把线性能量值转换成分贝(dB)值——简单说,就是把计算机内部用的"能量数值"翻译成音频系统需要的"分贝刻度"。
和 db_to_linear() 正好相反:如果说 db_to_linear() 是把"外文"翻译成"中文"让你听懂,那 linear_to_db() 就是把"中文"翻译成"外文"让音频系统听懂。比如你想设置音量为原始音量的一半,你需要知道能量值 0.5 对应多少 dB,linear_to_db(0.5) 就会告诉你大约是 -6 dB。
什么时候需要它? 当你用代码计算出了一个线性能量值(比如根据距离算出的衰减系数 0~1),但需要设置到 Godot 的音频节点上时,就需要先转换。因为 Godot 的 AudioStreamPlayer.VolumeDb、AudioBus.VolumeDb 等属性都是以 dB 为单位的。
数学公式为:dB = 20 * log10(linear)。
函数签名
C#
public static float LinearToDb(float linear)GDScript
func linear_to_db(linear: float) -> float参数说明
| 参数 | 类型 | 必需 | 说明 |
|---|---|---|---|
linear | float | 是 | 线性能量值。1.0 = 原始音量,0.5 = 一半音量,2.0 = 两倍音量。必须大于 0,否则结果为负无穷 |
返回值
float —— 对应的分贝值。计算公式为 20 * log10(linear)。
常见的换算结果:
linear_to_db(1.0)返回0.0(原始音量 = 0 dB)linear_to_db(0.5)返回约-6.02(音量减半)linear_to_db(0.1)返回约-20.0(十分之一音量)linear_to_db(2.0)返回约6.02(音量翻倍)linear_to_db(0.0)返回负无穷(-inf),代表完全静音
代码示例
基础用法:线性值转 dB
C#
using Godot;
public partial class LinearToDbExample : Node
{
public override void _Ready()
{
// 原始音量 → 0 dB
float db1 = Mathf.LinearToDb(1.0f);
GD.Print($"线性 1.0 = {db1:F2} dB");
// 运行结果: 线性 1.0 = 0.00 dB
// 一半音量 → 约 -6 dB
float db05 = Mathf.LinearToDb(0.5f);
GD.Print($"线性 0.5 = {db05:F2} dB");
// 运行结果: 线性 0.5 = -6.02 dB
// 十分之一音量 → -20 dB
float db01 = Mathf.LinearToDb(0.1f);
GD.Print($"线性 0.1 = {db01:F2} dB");
// 运行结果: 线性 0.1 = -20.00 dB
// 两倍音量 → 约 +6 dB
float db2 = Mathf.LinearToDb(2.0f);
GD.Print($"线性 2.0 = {db2:F2} dB");
// 运行结果: 线性 2.0 = 6.02 dB
}
}GDScript
func _ready():
# 原始音量 → 0 dB
var db1 = linear_to_db(1.0)
print("线性 1.0 = %.2f dB" % db1)
# 运行结果: 线性 1.0 = 0.00 dB
# 一半音量 → 约 -6 dB
var db05 = linear_to_db(0.5)
print("线性 0.5 = %.2f dB" % db05)
# 运行结果: 线性 0.5 = -6.02 dB
# 十分之一音量 → -20 dB
var db01 = linear_to_db(0.1)
print("线性 0.1 = %.2f dB" % db01)
# 运行结果: 线性 0.1 = -20.00 dB
# 两倍音量 → 约 +6 dB
var db2 = linear_to_db(2.0)
print("线性 2.0 = %.2f dB" % db2)
# 运行结果: 线性 2.0 = 6.02 dB实际场景:UI 滑块控制音量
C#
using Godot;
public partial class VolumeSlider : HSlider
{
private AudioStreamPlayer _player;
public override void _Ready()
{
_player = GetNode<AudioStreamPlayer>("/root/Main/BgMusic");
// HSlider 的值范围设为 0.0 到 1.0(代表 0% ~ 100%)
MinValue = 0.0;
MaxValue = 1.0;
Step = 0.01;
Value = 0.8; // 默认 80%
// 初始设置音量
ApplyVolume((float)Value);
}
public override void _ValueChanged(double newValue)
{
ApplyVolume((float)newValue);
}
private void ApplyVolume(float linearVolume)
{
// 滑块值是线性的(0~1),但音频系统需要 dB
// 注意:传入 0 会导致 -inf,所以用 Max 保证最小值
float safeVolume = Mathf.Max(linearVolume, 0.0001f);
_player.VolumeDb = Mathf.LinearToDb(safeVolume);
GD.Print($"滑块: {linearVolume:P0}, 音量: {_player.VolumeDb:F1} dB");
// 运行结果: 滑块: 80%, 音量: -1.9 dB
}
}GDScript
extends HSlider
var _player: AudioStreamPlayer
func _ready():
_player = get_node("/root/Main/BgMusic")
# HSlider 的值范围设为 0.0 到 1.0(代表 0% ~ 100%)
min_value = 0.0
max_value = 1.0
step = 0.01
value = 0.8 # 默认 80%
# 初始设置音量
apply_volume(value)
func _on_value_changed(new_value: float) -> void:
apply_volume(new_value)
func apply_volume(linear_volume: float) -> void:
# 滑块值是线性的(0~1),但音频系统需要 dB
# 注意:传入 0 会导致 -inf,所以用 maxf 保证最小值
var safe_volume = maxf(linear_volume, 0.0001)
_player.volume_db = linear_to_db(safe_volume)
print("滑块: %.0f%%, 音量: %.1f dB" % [linear_volume * 100.0, _player.volume_db])
# 运行结果: 滑块: 80%, 音量: -1.9 dB进阶用法:声音渐入渐出效果
C#
using Godot;
public partial class AudioFader : Node
{
private AudioStreamPlayer _player;
// 导出属性:渐入时长(秒)
[Export] public float ExFadeInDuration = 2.0f;
// 导出属性:渐出时长(秒)
[Export] public float ExFadeOutDuration = 1.5f;
// 内部变量:当前渐变时间
private float _fadeTimer = 0f;
// 内部变量:当前状态
private enum EnumFadeState { None, FadingIn, FadingOut }
private EnumFadeState _state = EnumFadeState.None;
public override void _Ready()
{
_player = GetNode<AudioStreamPlayer>("AudioStreamPlayer");
}
public void FadeIn()
{
_state = EnumFadeState.FadingIn;
_fadeTimer = 0f;
_player.VolumeDb = Mathf.LinearToDb(0.0001f);
_player.Play();
}
public void FadeOut()
{
_state = EnumFadeState.FadingOut;
_fadeTimer = 0f;
}
public override void _Process(double delta)
{
switch (_state)
{
case EnumFadeState.FadingIn:
_fadeTimer += (float)delta;
float inT = Mathf.Clamp(_fadeTimer / ExFadeInDuration, 0f, 1f);
// 用 smoothstep 做平滑的渐入
float inLinear = Mathf.SmoothStep(0.0001f, 1.0f, inT);
_player.VolumeDb = Mathf.LinearToDb(inLinear);
GD.Print($"渐入中: {inT:P0}, 音量: {_player.VolumeDb:F1} dB");
if (inT >= 1.0f)
{
_state = EnumFadeState.None;
GD.Print("渐入完成");
}
break;
case EnumFadeState.FadingOut:
_fadeTimer += (float)delta;
float outT = Mathf.Clamp(_fadeTimer / ExFadeOutDuration, 0f, 1f);
float outLinear = Mathf.SmoothStep(1.0f, 0.0001f, outT);
_player.VolumeDb = Mathf.LinearToDb(outLinear);
GD.Print($"渐出中: {outT:P0}, 音量: {_player.VolumeDb:F1} dB");
if (outT >= 1.0f)
{
_player.Stop();
_state = EnumFadeState.None;
GD.Print("渐出完成,已停止播放");
}
break;
}
// 运行结果: 渐入中: 50%, 音量: -6.0 dB
}
}GDScript
extends Node
enum FadeState { NONE, FADING_IN, FADING_OUT }
@onready var _player = $AudioStreamPlayer
# 导出属性:渐入时长(秒)
@export var ex_fade_in_duration: float = 2.0
# 导出属性:渐出时长(秒)
@export var ex_fade_out_duration: float = 1.5
# 内部变量:当前渐变时间
var _fade_timer: float = 0.0
# 内部变量:当前状态
var _state: FadeState = FadeState.NONE
func fade_in() -> void:
_state = FadeState.FADING_IN
_fade_timer = 0.0
_player.volume_db = linear_to_db(0.0001)
_player.play()
func fade_out() -> void:
_state = FadeState.FADING_OUT
_fade_timer = 0.0
func _process(delta):
match _state:
FadeState.FADING_IN:
_fade_timer += delta
var in_t = clampf(_fade_timer / ex_fade_in_duration, 0.0, 1.0)
var in_linear = smoothstep(0.0001, 1.0, in_t)
_player.volume_db = linear_to_db(in_linear)
print("渐入中: %.0f%%, 音量: %.1f dB" % [in_t * 100.0, _player.volume_db])
if in_t >= 1.0:
_state = FadeState.NONE
print("渐入完成")
FadeState.FADING_OUT:
_fade_timer += delta
var out_t = clampf(_fade_timer / ex_fade_out_duration, 0.0, 1.0)
var out_linear = smoothstep(1.0, 0.0001, out_t)
_player.volume_db = linear_to_db(out_linear)
print("渐出中: %.0f%%, 音量: %.1f dB" % [out_t * 100.0, _player.volume_db])
if out_t >= 1.0:
_player.stop()
_state = FadeState.NONE
print("渐出完成,已停止播放")
# 运行结果: 渐入中: 50%, 音量: -6.0 dB注意事项
- 输入值必须大于 0:
linear_to_db(0)会返回负无穷(-inf)。如果你的线性能量值可能为 0(比如完全静音),请用Mathf.Max(value, 0.0001f)做保护,或者单独处理 0 的情况。 - 与
db_to_linear()是一对反函数:linear_to_db()和db_to_linear()互为逆运算。linear_to_db(db_to_linear(x))的结果等于x(在精度范围内)。 - 线性值 1.0 = 0 dB:这是一个常见的记忆点。线性 1.0 表示"不做任何放大或衰减",对应的 dB 值就是 0。
- 对音频做插值时要在线性空间:音量渐变时,应该在线性空间做插值(
lerp),然后把结果转为 dB,而不是直接对 dB 值做插值。因为 dB 是对数刻度,直接插值会让听感不均匀。 - -80 dB 通常视为静音:在大多数音频系统中,-80 dB 以下的音量人耳已经听不到了。可以用这个值作为"静音"的替代,避免使用 0(会导致 -inf)。
