安卓PCM字节

10

我正在使用AudioRecord类来分析从麦克风中接收到的原始PCM字节。

目前工作得很好。现在我需要将PCM字节转换为分贝。

我有一个公式,可以将声压(Pa)转化为分贝(db)。

db = 20 * log10(Pa / ref Pa)

所以问题是我从音频记录器获取的缓冲区中得到的字节是振幅帕斯卡声压还是其他什么。

我尝试将该值放入该公式中,但它返回非常高的分贝值,因此我认为这不正确。

谢谢


感谢大家提供的优秀信息,我会给所有人点赞。谢谢大家。 - Terrance
我自己也需要一些帮助,因为我正在尝试做同样的事情!我已经像你一样获得了原始的PCM字节,但是当我使用你的公式时,它会输出无穷大:/ 当我录制时,我在字节数组中使用最后2个字节值,这样做有问题吗? - Neeta
5个回答

15

免责声明:我对Android知之甚少。

你的设备可能以44,100个采样率(也许更低)在单声道下录音,每个采样使用两个字节。因此,你的第一步是将原始数据中的字节成对组合为两个字节的整数(我不知道在Android中如何实现)。

然后,你可以通过首先取样本的归一化绝对值并将其传递给Db函数来计算每个样本相对于峰值的分贝值:

float Db = 20 * log10(ABS(sampleVal) / 32768)

接近峰值的数值(例如+32767或-32768)其dB值接近于0。数值为3277(0.1)的dB值为-20;数值为327(0.01)的dB值为-40等。


大家好,谢谢你们,看起来这个公式可以工作。数值范围为+32767或-32768。谢谢。 - Pintac
只是想确认一下,sampleValue 是什么单位的? - Pintac
5
严格来说,样本值表示麦克风的瞬时电压输出(其中+32767表示最大正电压,-32768表示最小负电压)。由于麦克风的工作原理,该电压与声压的变化从局部平均值计算而来。当麦克风记录声音时,麦克风周围的空气压力略微上下波动,这会使膜片来回移动,产生交替的正和负电压。ADC(模拟数字转换器)每秒对该电压进行44100次采样... - MusiGenesis
2
...并将其转换为一个有符号的short值(-32768至+32767),然后保存在数据中。 - MusiGenesis
@MusiGenesis 你的第一条评论本来就可以作为一个合适的答案。多好的回答啊,点赞! - Faizan Mubasher

2
问题可能在于麦克风处的“参考”声压定义。我不知道它是什么或是否可用。
我所使用的唯一音频应用程序将0db定义为“满音量”,当样本达到+或-max值时(在无符号16位中,这将是0和65535)。要将其转换为db,我可能会执行以下操作:
// assume input_sample is in the range 0 to 65535
sample = (input_sample * 10.0) - 327675.0
db = log10(sample / 327675.0)

我不知道这是否正确,但对于数学上有挑战的我来说,它感觉是正确的。随着输入样本接近“中间”,它会越来越像负无穷。

现在我想想,如果你想要一个SPL或者其他需要不同技巧的东西,比如在零交叉之间进行RMS评估,那么我只能猜测,因为我真的不知道它是如何工作的。


1
除了PCM样本是有符号的16位(因此您不需要进行偏移减法)之外,关闭它。另外 - 至少在我的世界里 - 您无法取负数的对数。 :) - MusiGenesis
哈哈,所有的观点都很好。它们总是有符号的吗?我肯定曾经处理过无符号的 PCM 数据(当然可能记错了)。 - dash-tom-bang
我应该说 PCM 通常是带符号的 - 每个样本 1 字节的 PCM 和原始 PCM 格式(就像你可能使用的那样)是无符号的,但它们在实际应用中非常罕见(CD 音频是带符号的)。 - MusiGenesis

2
在Leq(声压级)计算中参考压力为20微帕斯卡(有效值)。要测量绝对Leq电平,您需要使用校准器校准麦克风。大多数校准器适用于1/2"或1/4"的麦克风胶囊,因此我对在Android手机上校准麦克风持怀疑态度。或者,您可以使用麦克风灵敏度(Pa / mV),然后校准进入ADC的电压水平。通过将Android值与使用声级计测量漫反射静态声场的声音级进行比较,也可能获得更不可靠的结果。请注意,在Leq计算中,通常使用RMS值。单个样本的值并没有太大意义。

我实际上想要做的是通过数据库来确定音频的音量(响度)。如果它超过了某个音量(以分贝为单位的响度),我想要执行某些操作。我有一个分贝参考表。http://en.wikipedia.org/wiki/Sound_pressure#Examples_of_sound_pressure_and_sound_pressure_levels - Pintac
1
无论如何,您都需要校准系统。至少需要将计算出的值与已知声级进行比较。 维基百科条目中给出的值很可能是A加权声级,其中每个八度频带的声级被加权以得出总体值。通常为每个八度频带给出Leq。 - Han
我得到的样本值为+32767至-32768,这是什么单位?是振幅、声压、伏特还是瓦特? - Pintac
1
它不是任何一个单位。它是一个任意单位,与ADC输入电压和麦克风的压力到电压转换成比例。要从无量纲样本值到电压或压力的转换因子,您需要将这些样本值与已知的电压或声压级进行比较。这就是校准所做的事情。 - Han
我假设麦克风规格中有固定值,我需要计算压力或电压。 - Pintac
1
麦克风规格会告诉你每帕斯卡对应的毫伏数,但是如果不知道ADC规格(和中间电路),这仍然无法将压力(Pa)转换为样本值。我认为最好的方法是实现你的分贝测量,并将其与声级计等已知值进行比较。然后你可以在代码中加入正确的转换因子。 - Han

2

我将声级计放在我的Google Ion麦克风旁边,然后发出“Woooooo!”的声音,注意到削波发生在大约105分贝SPL。希望这可以帮助您。


1

单位是参考读数所使用的任何单位。在公式中,读数被参考读数除以,因此单位被消除,不再重要。

换句话说,分贝是一种比较两个事物的方式,而不是绝对的测量。当您看到它被用作绝对值时,那么比较的是人类能听到的最安静的声音。

在我们的情况下,它是与设备处理的最高读数进行比较(因此,每个其他读数都是负数或小于最大值)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接