我可以使用什么算法来确定音频音量级别?

6qqygrtg  于 2022-09-21  发布在  Apache
关注(0)|答案(8)|浏览(188)

假设我有一个介于0和1之间的滑块。SoundTransform.volume的范围也在0(静音)和1(最大音量)之间,但如果我使用线性函数,比如说SoundTransform.volume = slider.volume,结果就不太令人满意了--感觉是音量在滑块的下半部分变化很大,而在上半部分几乎不做任何事情。

我真的没有研究过人类的耳朵,但我曾经无意中听说人类的感知是对数的,或者类似的东西。我应该使用什么算法来设置SoundTransform.volume

llew8vvj

llew8vvj1#

人类的感知总体上是对数的,当涉及到光度等东西时也是如此。这使我们能够记录对我们环境的小“输入信号”的微小变化,或者换句话说:总是允许可感知的物理量相对于其值的变化……

因此,您应该将体积修改为指数级增长,如下所示:

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越大,效果越强。

iq3niunx

iq3niunx2#

人类的听觉是对数的,所以你想要一个指数函数(倒数)应用于你的滑块的线性输出。我不知道人类的听觉是更接近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

当然,您可以对其进行调整以满足您的要求。

ycggw6v2

ycggw6v23#

听力是复杂的,感知到的响度随频率、样本持续时间和人与人之间的不同而不同。因此,这不能用数学方法来解决,而是通过尝试各种控制功能,并选择一个“感觉”最好的。

你有没有发现,在这个范围的低端改变控制对表观音量的影响很小,但在这个范围的上端,音量迅速增加?或者你听到了相反的声音,低端音量变化太快,而高端音量变化不够?或者,您是否希望更好地控制中等音量?

提高低音量敏感度:

SoundTransform.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之间。

请一定要让我们知道你的进展如何!

ql3eal8s

ql3eal8s4#

是的,人类的感知是对数的。考虑到这一点,您应该指数地调整音量,以便使适当的增加变为线性。见decibel on Wikipedia

5hcedyr0

5hcedyr05#

安卓已经在音频框架上做了这样的事情。它使用分贝来调节音量。用户可以使用从1到7播放铃声或从1到15播放音乐等步骤。公式是:

用户调用设置音量API呈线性关系,但获得的幅度呈指数关系。图表如下:

vmdwslir

vmdwslir6#

增加3分贝意味着音量翻倍,但人耳需要增加~6分贝才能感觉到音量翻倍。

然而,严格的对数曲线虽然准确地模拟了人类对体积的感知,但有一个可用性问题。

当人们想要一个响亮的音量时,旋钮在上端变得过于敏感,从而很难找到合适的音量。

你以前可能有过这样的问题。7太软了,8太吵了,同时1-3在背景噪音上听不见。

因此,我建议使用对数刻度,但底部为底端,顶部为柔软的膝盖,以便获得更好的线性响应,尤其是在旋钮的“响亮”部分。

哦,一定要把旋钮调到11度。;)

wswtfjt7

wswtfjt77#

人耳对声音的感知确实是以对数的强度递增,正因为如此,通常用来测量声强的单位是分贝(它实际上用于各种强度和功率,不仅仅是声音的强度和功率,而且恰好也是一个无量纲的单位)。参考电平0分贝通常被设置为人类听力的下限,在此基础上每增加10分贝,相当于功率增加10倍。

然而,请注意,你应该首先与其他人核实一下,看看他们是怎么想的,以防万一;对你来说奇怪的事情,对其他人来说可能并不奇怪。如果他们同意你的观点,那就直截了当地按指数方式来做吧,但如果你是少数,那么问题可能就在于你自己的耳朵。

编辑:忽略我之前的第三段。如果您决定以指数方式执行此操作,请参考Back2dos的答案。

ar5n3qh5

ar5n3qh58#

这是我为DBM提供的对数刻度的一个脚本函数。输入是百分比(0.00到1.00)和最大值(我的实现使用12db)

中点设置为0.5,即为0分贝。

当百分比为零时,输出为负无穷大。

function percentageToDb(p, max) {
     return max * (1 - (Math.log(p) / Math.log(0.5)));
};

相关问题