SoundTransform.volume
也在0(静音)和1(最大音量)之间变化,但是如果我使用线性函数,比如SoundTransform.volume = slider.volume
,结果并不令人满意 - 感受是在滑块的较低一半音量急剧变化,而在上半部分几乎没有变化。我真的没有研究过人类耳朵,但我曾经听说过人类感知是对数的,或者类似的东西。我应该使用什么算法来设置 SoundTransform.volume
?SoundTransform.volume
也在0(静音)和1(最大音量)之间变化,但是如果我使用线性函数,比如SoundTransform.volume = slider.volume
,结果并不令人满意 - 感受是在滑块的较低一半音量急剧变化,而在上半部分几乎没有变化。我真的没有研究过人类耳朵,但我曾经听说过人类感知是对数的,或者类似的东西。我应该使用什么算法来设置 SoundTransform.volume
?总体而言,人类感知是对数的,当涉及到亮度等事物时也是如此。这使我们能够察觉到环境中微小的“输入信号”变化,或者换句话说:始终感知可感知物理量的变化与其值的关系...
因此,您应该将音量按指数增长进行修改,就像这样:
y = (Math.exp(x)-1)/(Math.E-1)
你也可以尝试其他进制:
y = (Math.pow(base,x)-1)/(base-1)
base
值越大,效果越强,体积开始增长的速度越慢,在最后增长的速度越快...
一个稍微简单的方法,可以给你相似的结果(因为你只在0和1之间,所以近似相当简单),就是对原始值进行指数运算,如下:
y = Math.pow(x, exp);
exp大于1时,其效果是输出(例如在您的情况下是音量)开始变化较慢,然后越来越快,这与指数函数非常相似... exp
越大,效果就越强烈...
人类听觉是对数的,所以您需要一个指数函数(反函数)来应用于滑块的线性输出。我不知道人类听觉更接近于ln
还是log
:
对于Ln:
e^x
日志记录:
10^x
你也可以尝试使用其他进制。然后,您需要缩放输出,使其覆盖可用值的范围。
更新
经过一些研究,似乎基数2是合适的,因为幂与压力的平方有关。如果有人知道更好的方法,请纠正我。
我认为你想要的是:
v' = 2^v.a^v - 1
a = ( 2^(log2(m+1)/n) )/2
v代表您的线性输入值,范围在0..n之间 v'代表您的对数值,范围在0..m之间
第一个方程中的-1是为了给您一个从0开始而不是1的输出范围(因为k^0=1)。
m+1是为了补偿这个,所以您得到的是0..m而不是0..m+1
当然,您可以根据需要进行调整。
ln(x) = log(x)/log(e)
。 - BlueRaja - Danny PflughoeftSoundTransform.volume = Math.sin(x * Math.PI / 2);
提高高容量灵敏度:
SoundTransform.volume = (Math.pow(base,x) - 1)/(base-1);
或者
SoundTransform.volume = Math.pow(x, base);
当基数>1时,请尝试不同的值并观察其效果。或者更激进地说,可以使用90度的圆弧:
SoundTransform.volume = 1 - Math.sqrt(1-(x * x));
其中x是slider.volume
,取值范围在0到1之间。
请务必告诉我们你的进展情况!
3db的增加意味着你将音量加倍,但人耳需要大约6db的增加才能感知到音量的加倍。
然而,严格的对数曲线虽然准确地模拟了人类对音量的感知,但存在一个可用性问题。
当人们想要大声的音量时,旋钮在上端变得过于敏感,使得很难找到“合适”的音量。
你可能以前遇到过这个问题……7太软,8太响,而1-3在背景噪音中听不见。
因此,我建议使用对数刻度,但在低端设置底限,在顶部设置软膝以允许更线性的响应,特别是在旋钮的“响亮”部分。
哦,还要确保旋钮可以调到11。 ;)
function percentageToDb(p, max) {
return max * (1 - (Math.log(p) / Math.log(0.5)));
};