音频基础学习四——声音的能量与分贝

文章目录


前言

很多博客中经常会把声音的能量和分贝说成是一个东西,这种说法是错误的。在实际生活中,想要形容声音大小按照之前博客中的介绍,其实就是音频模拟信号的振幅,而在实际的数字信号也就是PCM中,这种振幅被量化成了分贝。

本篇博客会介绍音频能量和分贝的关系,并且给出以16k 双通 short类型的数据进行计算分贝的算法。

|版本声明:山河君,未经博主允许,禁止转载

一、能量与分贝

音频能量和分贝 (dB) 都用于描述声音的强度,但它们的概念和计算方式有所不同。

1.音频能量

音频能量是声音信号中携带的实际物理能量,它通常与声音的振幅(Amplitude)相关。它代表声音的功率或强度,直接反映了声音信号在某个时刻或时间段内的物理表现。

  • 能量与振幅的关系:音频信号的能量与振幅的平方成正比。也就是说,如果音频信号的振幅增大,能量会以平方的速度增长。例如,振幅为2的音频信号,其能量是振幅为1信号的4倍。

数学上,音频信号的能量通常表示为信号样本的平方和,例如:
E = ∑ i = 0 n x i 2 E = \sum_{i = 0}^{n}x^{2}_{i} E=i=0∑nxi2

其中, x i 2 x^{2}_{i} xi2是每个音频样本的振幅,N 是样本数.

  • 能量的单位:音频能量的单位取决于它的具体表示方式。它可以用功率单位(如瓦特,W)来度量,或者仅作为信号强度的无量纲值表示。

2.分贝

分贝是一种对数单位,用于表示两种能量或强度之间的相对差异。分贝表示相对变化,而不是绝对的物理量,因此它是音频能量的对数缩放形式。分贝用于更方便地表示非常大或非常小的数字,并用于描述信号的强度变化。

  • 分贝与能量的关系:分贝是基于音频信号的能量或振幅的相对值,通过对数计算得出:
    d B = 10 × log ⁡ 10 ( E s i g n a l E r e f e r e n c e ) dB = 10 \times \log_{10}\Bigg( \frac{E_{signal}}{E_{reference}} \Bigg) dB=10×log10(EreferenceEsignal)

如果把能量换做为振幅:
d B = 20 × log ⁡ 10 ( A s i g n a l A r e f e r e n c e ) dB = 20 \times \log_{10}\Bigg( \frac{A_{signal}}{A_{reference}} \Bigg) dB=20×log10(AreferenceAsignal)

其中 E s i g n a l E_{signal} Esignal是信号能量, E r e f e r e n c e E_{reference} Ereference是参考能量, A s i g n a l A_{signal} Asignal是信号振幅, A r e f e r e n c e A_{reference} Areference是参考振幅。

3.两者的区别

  • 本质区别:音频能量是一个物理量,表示声音信号中实际携带的功率或强度;分贝则是一个相对量,用对数方式表示音频能量与某个参考值的比值。

  • 单位不同:音频能量可能有具体的物理单位(如瓦特、焦耳),而分贝没有单位,它是两种能量之间的对数比例。

  • 线性 vs 对数:音频能量是线性变化的(能量值可以直接累加),而分贝是对数变化的(增减6 dB表示能量变化一倍)。

4. 应用场景

音频能量:在实际计算音频信号的物理功率或存储、传输音频信号时,直接使用音频能量。它可以用于描述音频信号的功率输出、能量消耗等。

分贝:用于方便地表示音频信号的相对强度,特别是在处理范围非常广的信号时(如从微弱信号到非常强的信号)。分贝广泛应用于音频工程和声音的感知描述中,如声压级、信号增益等。

二、分贝的计算方式

1.具体数学公式

在实际数字信号中,计算声音的dB往往计算的不是某一个具体的时间点上样本的dB,而是一段时间上所有样本的均值。

而这个均值很多博主写的完全就是错误的,所以往往有很大误差:

  • 错误做法:把一段时间的采样点值相加取平均
  • 正确做法:通过计算信号各个样本平方的平均值,然后取平方根,得出信号的平均有效值

具体的数学公式为:
d B = 20 × l o g 10 ( R e f e r e n c e R M S R M S o f t h e s i g n a l ) dB=20×log_{10} \Bigg( \frac {Reference RMS} {RMS of the signal} \Bigg) dB=20×log10(RMSofthesignalReferenceRMS)

其中 R e f e r e n c e R M S R M S o f t h e s i g n a l 叫做 R M S ,信号强度的一个度量 \frac {Reference RMS} {RMS of the signal} 叫做 RMS,信号强度的一个度量 RMSofthesignalReferenceRMS叫做RMS,信号强度的一个度量计算方式为:
R M S = 1 N ∑ i = 1 N x i 2 RMS= \sqrt{ \frac{1}{N}\sum_{i=1}^{N}x_i^2} RMS=N1i=1∑Nxi2

2.具体算法示例

假设现在PCM为16k short 单通的:

cpp 复制代码
#include <stdint.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>

int pcm_db_count(const unsigned char* ptr, size_t size) {
    if (size == 0 || ptr == NULL) {
        return -96; // Handle empty or invalid input
    }

    int16_t value;
    double sum_squares = 0.0;

    for (size_t i = 0; i < size; i += 2) {
        // Read 16-bit PCM value from the byte array
        memcpy(&value, ptr + i, sizeof(value));
        // Handle endianess if needed
        // value = (int16_t)ntohs((uint16_t)value); // Convert from network to host byte order
        sum_squares += value * value;
    }

    // Calculate RMS
    size_t num_samples = size / 2;
    double rms = sqrt(sum_squares / num_samples);

    // Convert RMS to dB
    int ndb;
    if (rms > 0) {
        ndb = (int)(20.0 * log10(rms / 32768.0)); // 32768.0 for 16-bit PCM
    } else {
        ndb = -96; // Define a suitable low value for silence or very low levels
    }

    return ndb;
}

3.对于算法的释义

大小端

这里value = (int16_t)ntohs((uint16_t)value); 如果使用的是pcm是大端排列,需要进行大小端转换。

为什么通过计算得到的是负值

在分贝公式中,log10 函数会计算信号与参考值的比例。如果信号的幅度 小于参考值,结果就是负数。这是因为:

  • 当振幅较小时,信号强度 rms 远小于最大值 32768,例如信号振幅为 1000 时:

d B = 20 × log ⁡ 10 ( 1000 37268 ) ≈ 30 d B dB= 20 \times \log_{10} \big( \frac{1000}{37268} \big) \approx 30dB dB=20×log10(372681000)≈30dB

  • 当信号振幅很低时,例如靠近零(接近静音),dB 值会更小,甚至接近负无穷,所以我们用 − 96 d B -96dB −96dB来表示

范围

在实际医学中,分贝当然是越大才表示声音越大

  • 人正常说话的声音,一般是在40-60分贝。
  • 在低声细语地说话时,一般处于30分贝左右
  • 在大声说话或者吵架的时候,会高达60-70分贝
  • 若在过于嘈杂的环境中,可能会达到100分贝左右。

而在我们算法中

  • 人声的正常分贝范围:通常在 -30 dB 到 -10 dB 之间。
  • 正常对话:约 -25 dB 到 -15 dB。
  • 轻声或远距离人声:约 -35 dB 到 -20 dB。
  • 大声说话或近距离录音:约 -10 dB 到 -5 dB。

实际结果

下图是每10ms打印


总结

  • RMS 是计算信号强度的基础,表示信号的均方根值,是一种 绝对强度 的度量。
  • 信号振幅与参考振幅的比值 是用来计算分贝的,它衡量信号相对于参考值的强度,并通过对数缩放表示为分贝(dB)。
  • 音频能量:描述声音信号的实际强度,通常与振幅平方相关,表示声音信号中的物理功率。
  • 分贝:是一种对数单位,用于表示相对音频强度或能量,便于描述信号的增减和相对变化。

如果对您有帮助,请帮忙点个赞吧

相关推荐
励志成为嵌入式工程师40 分钟前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉1 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer1 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
wheeldown2 小时前
【数据结构】选择排序
数据结构·算法·排序算法
观音山保我别报错3 小时前
C语言扫雷小游戏
c语言·开发语言·算法
dsywws3 小时前
Linux学习笔记之vim入门
linux·笔记·学习
晨曦_子画4 小时前
3种最难学习和最容易学习的 3 种编程语言
学习
TangKenny4 小时前
计算网络信号
java·算法·华为
景鹤4 小时前
【算法】递归+深搜:814.二叉树剪枝
算法
iiFrankie4 小时前
SCNU习题 总结与复习
算法