【发布时间】:2012-05-18 15:42:15
【问题描述】:
Android MediaRecorder 有一个功能
.getMaxAmplitude();正如API 告诉我的那样,“返回自上次调用此方法以来采样的最大绝对幅度。” 但我可以'找不到这是什么幅度?是帕斯卡还是瓦特?
我在网络上的几个页面上发现,您可以使用(如建议的here)计算与分贝密切相关的值。
double db = (20 * Math.log10(amplitude / REFERENCE));
这会让我假设返回值是某种线性比例(可能类似于 milipascal...)
REFERENCE=0.1(我知道这应该类似于 2*10^(-5) Pascal ((20 uPascal)),但它会返回奇怪的值...... 0.1 奇怪地工作得更好。)
现在我使用
测量 MaxAmplitude()getMaxAmplitude()并将其放入变量amplitude。
这是方法:
public double getNoiseLevel()
{
//Log.d("SPLService", "getNoiseLevel() ");
int x = mRecorder.getMaxAmplitude();
double x2 = x;
Log.d("SPLService", "x="+x);
double db = (20 * Math.log10(x2 / REFERENCE));
//Log.d("SPLService", "db="+db);
if(db>0)
{
return db;
}
else
{
return 0;
}
}
这在半秒内完成了 5 次,这是平均水平
for(int i=0; i<5; i++)
{
try
{
Thread.sleep(100);
}
catch (InterruptedException e)
{
e.printStackTrace();
return 0;
}
level = level+getNoiseLevel();
if(level>0)
{
counter++;
}
}
level=level/counter;
Log.d(LOG_TAG, "level="+level);
我得到的东西有点像分贝,但我不确定它实际上是分贝......
那么,有人可以帮我解决这个问题吗? API 根本没有指定返回的内容,这似乎很奇怪......
【问题讨论】:
-
这行得通,感谢您解释 getMaxAmplitude 的作用。但我不确定这些是否是准确的 dB 值。当我在某些情况下进行测试并尝试将值与此进行比较时:newton.dep.anl.gov/askasci/phy99/phy99405.htm,缺少 30dB。你知道为什么吗?
-
可能有以下几个原因: 1. 该算法使用getMaxAmplitude作为计算基础,即忽略该周期内所有较小的事件。这导致结果可能高于实际 dB 水平(通常在自然环境中它们是) 2. 电话的麦克风是不同的。有些人比其他人更敏感。该算法没有考虑到这一点,在任何手机上进行相同的计算。由于这些差异,一些手机可能会给出更高或更低的值。
-
另外,由于限制因素(该值仅达到32767),无法准确检测到非常响亮的噪音。通常截止频率约为 100 dB。
-
好的,那有没有更好的解决方案呢?要从麦克风中获得一些准确的 dB 值?市场上有一些应用程序(即:声级计)可以完美地做到这一点。
-
显然有。如果您存储来自录音机的原始数据,您可以对其进行复杂的分析,包括使用过滤/频率分析来弥补麦克风的缺点。例如,您可以使用斯坦福的 FFT-Packed,并可能从样本中计算出更好的值,而不是谨慎的 maxAmplitude 值。然而,所有这些都超出了原始问题的范围,可能已经在其他地方讨论过。
标签: android mediarecorder decibel