语音处理:PCM文件中采样值到dB分贝的转换分析

语音处理:PCM文件中采样值到dB分贝的转换分析

问题引入


分析音频文件过程中,发现16bit的PCM文件,采样值显示为2900,Audition上分贝却显示为-21dB,为啥?

本着知其然,更要知其所以然的原则,进行了一番查阅分析。原来,dB的d即“”(deci-)指十分之一,B即贝,是贝尔的缩写(bel,纪念发明家亚历山大·格拉汉姆·贝尔)。

那为什么好好的线性域不用,要用10倍对数域呢?显而易见的好处是便于表示有小间隔内,数值的量级动态范围大,数值太大无法直观比较,转换到对数域10倍/20倍对数,用更小的数来表达,便于人们直观比较。

核心公式


根据维基百科定义,分贝dB的转换公式为:

  • 能量/功率:10lg(Ps / Pn)
  • 采样值/幅值:20lg(Prms / Pref)

我被这两个公式给迷糊住了,有时候是用第一种,如求SNR信噪比,有时候又是用的第二种,如电路中电压。

分析公式可知,核心来自于10lg(Ps / Pn),由于它是能量的比值或者由功率比定义的,10倍时用的是功率比,即数值的平方。如果我们不想求能量,想直接从幅值单位来处理的话,就需要调整下公式,推导过程如下:

10lg(Ps / Pn) 
= 10lg(Val^2 / Ref^2) 
= 10lg((Val / Ref)^2) 
= 20lg(Val / Ref)
= 20lg(Prms / Pref)

于是,就能得到采样值/幅值的比值时,对应的dB转换公式。所以,我们也就知道了前文两个公式的用途:

  • 功率比、能量比场景,用10lg
  • 声压、电压、数字成像、采样值、幅值等,用20lg

问题回答


说回初始问题,那么现在PCM文件中采样值到dB分贝是如何转换的呢?

过程如下:

  • 日常生活中常见Pref是以最小幅值为参考,Pref=1
  • PCM中,以最大幅值作为Pref,则最大db为0,最小为负无穷
  • 其中,0db上下分布的都是负db,上部对应的是幅值为正,下部对应的是幅值为负
  • PCM中,统一将采样值取绝对值,进行20lg(Prms / Pref)变换到db
  • db肯定都是负值,如采样值为正,则db结果放上部,否则放下部

所以问题引入就可以得到解答:

  • 带符号位的16bit整数对应的最大值为2^15-1=32767
  • 所以Pref=32767,实际采样值取绝对值后为2900
  • 代入公式,则有20lg(2900/32767) = -21.06dB
  • 由此得证

举一反三


下面以24bit的PCM数据为例,结合具体图例,进行类似分析。

实例分析:

  • 有符号24bit的最大值为2^23-1=8388607,所以Pref=8388607
  • 观察选中区域,左下角第一个采样值点,对应数值为-4M,取绝对值为4M
  • 代入公式,则有20lg(4000000/8388607) = -6.43dB
  • 由于该采样值为负,所以分布在0db的下方,对应-6dB

取样值如图:
在这里插入图片描述

转换为db的结果:
在这里插入图片描述

幅值域和分贝对比,上下部都有-6db:

在这里插入图片描述

本文小结


综上,分贝本质是能量比值(无单位)的对数域变化,缩小对应尺度,便于人们直观观察。只是对无量纲的数据,转换了下尺度,带来的好处是更好的观测动态范围极大的数据,不同量级多的。

读到此处,分贝你怎么看?

扩展知识


问题1:常用dB单位dBFS的认识,绝对尺度是多少?

  • FS指Full Scale
  • 绝对尺度为位深的最大值
  • dB最大值为0,普遍值都为负数

参考资料


  1. CSDN:通过pcm音频数据计算分贝
  2. 掘金:PCM浅析
  3. 维基百科:分贝
  4. 常用音频单位简介:dBSPL、dBm、dBu、dBV、dBFS
  • 3
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要将采样频率为 64000 的 PCM 数据转换采样频率为 8000 的 WAV 文件,您可以使用 Java 的音频处理库来进行操作。以下是一个基本的示例代码: ```java import javax.sound.sampled.*; public class PCMToWAVConverter { public static void convert(String pcmFilePath, String wavFilePath) { try { // 设置输入 PCM 文件的参数 AudioFormat inputFormat = new AudioFormat(64000, 16, 1, true, false); // 设置输出 WAV 文件的参数 AudioFormat outputFormat = new AudioFormat(8000, 16, 1, true, false); // 创建输入流 AudioInputStream inputAIS = AudioSystem.getAudioInputStream(new File(pcmFilePath)); // 转换输入流为指定格式 AudioInputStream convertedAIS = AudioSystem.getAudioInputStream(outputFormat, inputAIS); // 创建输出流 AudioSystem.write(convertedAIS, AudioFileFormat.Type.WAVE, new File(wavFilePath)); // 关闭流 convertedAIS.close(); inputAIS.close(); System.out.println("转换完成!"); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { String pcmFilePath = "path/to/input.pcm"; String wavFilePath = "path/to/output.wav"; convert(pcmFilePath, wavFilePath); } } ``` 您需要将上述代码的 `pcmFilePath` 替换为您的 PCM 文件路径,将 `wavFilePath` 替换为要生成的 WAV 文件路径。运行程序后,将会生成采样频率为 8000 的 WAV 文件。 请注意,此示例假设输入的 PCM 文件是单声道(单通道)的,16 的量化数,并且采样大小为 64000。如果您的 PCM 文件不符合这些参数,您可能需要相应地调整代码的参数。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值