假设我有一个可以介于0和1之间的滑块。SoundTransform.volume
也介于0(静音)和1(完整音量)之间,但是如果我使用线性函数,那么就说{{1结果相当不令人满意。
我真的没有研究过人类的耳朵,但是我曾经无意中听到人类的感知是对数的,或类似的东西。我应该使用哪些算法来设置SoundTransform.volume = slider.volume
?
答案 0 :(得分:30)
因此,您应该修改音量以指数方式增长,如下所示:
y = (Math.exp(x)-1)/(Math.E-1)
你也可以尝试其他基地:
y = (Math.pow(base,x)-1)/(base-1)
base
的值越大,效果越强,开始时开始增长的速度越慢,最后增长的速度越快......
一个稍微简单的方法,给你类似的结果(你只是在0和1之间的间隔,所以近似非常简单,实际上),是指数原始值,如
y = Math.pow(x, exp);
对于大于1的exp,效果是,输出(即你的情况下的音量)首先上升得更慢,然后更快到最后......这与指数函数非常相似......更大exp
,效果越强......
格尔茨
back2dos
答案 1 :(得分:9)
人类听觉是对数的,因此您需要将指数函数(反向)应用于滑块的线性输出。我不知道人类听力是否接近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
您当然可以根据自己的要求进行调整。
答案 2 :(得分:5)
听力复杂,感知响度根据频率,样本持续时间以及人与人之间的差异而变化。所以这不能用数学方法解决,而是通过尝试各种控制功能并选择“感觉”最好的功能。
目前您是否发现改变范围低端的控制对表观音量几乎没有影响,但音量在该范围的上端迅速增加?或者您是否听到相反的情况,低端的音量变化太快而高音的音量不够?或者您希望在中等水平上更好地控制音量?
增加低音量灵敏度:
SoundTransform.volume = Math.sin(x * Math.PI / 2);
增加高音量灵敏度:
SoundTransform.volume = (Math.pow(base,x) - 1)/(base-1);
或
SoundTransform.volume = Math.pow(x, base);
其中base&gt; 1,尝试不同的价值观,看看它的感受。或更严重的是,90度圆弧:
SoundTransform.volume = 1 - Math.sqrt(1-(x * x));
其中x为slider.volume
且介于0和1之间。
请告诉我们你是如何上场的!
答案 3 :(得分:2)
是的,人类的感知是对数的。考虑到这一点,您应该以指数方式调整音量,以使经过的增加变为线性。见decibel on Wikipedia
答案 4 :(得分:2)
Android已经从Audio Framework执行此类操作。它使用分贝来调整音量。用户可以使用1到7之类的步骤作为铃声,或者使用1到15之类的音乐。 公式是:
答案 5 :(得分:1)
3db的增加意味着你的体积增加了一倍,但人耳需要增加~6db才能感知体积增加一倍。
然而,严格对数曲线虽然能准确地模拟人类对音量的感知,但却存在可用性问题。
当人们需要大音量时,旋钮在上端变得过于敏感,使得难以找到“正确”音量。
你之前可能遇到过这个问题...... 7太软了,8声太大,同时1-3声音听不到背景噪音。
所以,我推荐使用对数刻度,但是低端有一个底板,顶部有一个柔软的膝盖,可以让更多线性响应,特别是在旋钮的“响亮”部分
哦,确保旋钮上升到11.;)
答案 6 :(得分:0)
人耳确实以增加强度的对数刻度感知声音,因此,通常用于测量声强的单位是分贝(实际上用于各种强度和力量,而不仅仅是声音,也恰好是无量纲单位)。参考电平0 dB通常设置为人类听觉的下限,每增加10分贝,相当于功率增加10倍。
但请注意,您应首先与其他人核实,看看他们的想法,以防万一;听起来很奇怪你可能听起来并不奇怪。如果他们同意你的意见,那就前进并以指数方式进行,但如果你是少数人,那么问题可能只是你自己的耳朵。
编辑:忽略我之前的第三段。如果您决定以指数方式执行,请参阅back2dos的答案。
答案 7 :(得分:0)
这是我用于dbm的对数刻度的javascript函数。 输入是百分比(0.00到1.00)和最大值(我的实现使用12db)
中点设置为0.5,即0db。
当百分比为零时,输出为负无穷大。
function percentageToDb(p, max) {
return max * (1 - (Math.log(p) / Math.log(0.5)));
};