我从来都不擅长数学,所以我需要帮助如何将线性值转换为dB。
首先,我向您展示如何从-24dB计算线性值。
var dB, linearLevel: integer;
begin
dB := -24;
linearLevel := Round( 1/exp( 2.30258509299 * (abs(dB)/20) ) *32767);
end;
Run Code Online (Sandbox Code Playgroud)
1/exp( 2.30258509299 * (abs(-24)/20) ) ;归一化值在哪里。
为了转换为样本值,我使用 1/exp(...)*32767
我的问题在这里:转换回来
有人告诉我要使用公式20*log10(linearLevel)。因此,我尝试创建它,但结果是18 dB,而不是24(或-24)dB。
linearValue := 2067; // the result of the formula above
db := round( exp( 20*2.30258509299*(linearLevel / 32767) ) );
Run Code Online (Sandbox Code Playgroud)
如何计算dB?
And*_*and 10
如果
linearLevel := Round( 1/exp( 2.30258509299 * (abs(dB)/20) ) * 32767);
Run Code Online (Sandbox Code Playgroud)
由于四舍五入,我们丢失了信息(在数学语言中,该Round函数不是单射的)。因此,给定一个linearLevel值,就不可能取回原始dB值。因此,让我们考虑
linearLevel := 1/exp( 2.30258509299 * (abs(dB)/20) ) * 32767;
Run Code Online (Sandbox Code Playgroud)
代替。这意味着
linearLevel / 32767 := 1/exp( 2.30258509299 * (abs(dB)/20) )
Run Code Online (Sandbox Code Playgroud)
和
32767 / linearLevel := exp( 2.30258509299 * (abs(dB)/20) )
Run Code Online (Sandbox Code Playgroud)
和
ln(32767 / linearLevel) := 2.30258509299 * (abs(dB)/20)
Run Code Online (Sandbox Code Playgroud)
和
ln(32767 / linearLevel) / 2.30258509299 := abs(dB)/20
Run Code Online (Sandbox Code Playgroud)
和
20 * ln(32767 / linearLevel) / 2.30258509299 := abs(dB).
Run Code Online (Sandbox Code Playgroud)
由于绝对值函数不是内射的,因此这里又有一个问题。如果abs(dB)是7,我们可能无法确定dB是7或-7。
但是,如果我们假设那dB是非肯定的,那么我们最终有
dB = -20 * ln(32767 / linearLevel) / 2.30258509299.
Run Code Online (Sandbox Code Playgroud)
简化版
既然2.30258509299是ln(10),这就是
dB = -20 * ln(32767 / linearLevel) / ln(10).
Run Code Online (Sandbox Code Playgroud)
但是log10(x) = ln(x) / ln(10),所以我们可以写
dB = -20 * Log10(32767 / linearLevel)
Run Code Online (Sandbox Code Playgroud)
在单元中Log10找到功能的位置Math。
同样,使用a log(b) = log(b^a)案例中的定律a = -1,我们甚至可以写
dB = 20 * Log10(linearLevel / 32767).
Run Code Online (Sandbox Code Playgroud)