计算人声录音后电平的大小
这里笔记记录一下,怎么计算已知大小的声音,经过麦克风、声卡录制后软件内录得的音量电平值。(文章最后将计算过程整理为Python代码,方便复用)
假设用正常说话的声音大小65dB(SPL)来计算。思路,这里的链路是:人说话声 -> 麦克风 -> 麦克风输出电压信号 -> 声卡麦克风输入 -> 电脑软件记录。那么计算所需的关键参数:
- 麦克风的灵敏度(算得麦克风输出电压信号所需)
- 声卡麦克风输入接口的最大输入电平(软件能录到的最大电平值,0dBFS,音量100%的位置)
麦克风的灵敏度
假设麦克风的灵敏度是:
S m V / P a = 10 m V / P a S_{mV/Pa}=10mV/Pa SmV/Pa=10mV/Pa
S d B V = − 40 d B V S_{dBV}=-40dBV SdBV=−40dBV
简化计算过程,这里不考虑麦克风的等效输入噪声,不考虑麦克风输入阻抗,也不考虑环境噪声。
声卡麦克风输入规格
某款带可调增益的声卡麦克风输入的部分规格如下:
- 动态范围(A加权):116dB
- THD+N:-97dB(-1dBFS@8dB增益)
- 等效输入噪声(EIN)(A加权):-127dBu
- 最大输入电平(在最小增益下):16dBu
- 增益范围:69dB
- 输入阻抗:3kΩ
简化计算,假设录音时增益设置为0,输入阻抗不考虑,声卡的EIN足够小也不考虑。只取计算过程需要用的最大输入电平:16dBu。
计算过程
声压级单位换算
人说话声音声压级65dB(SPL)单位需要转换为帕斯卡(Pa),否则无法根据麦克风的灵敏度公式转换为mV。找到这两者的关联公式是:
SPL (dB) = 20 log 10 ( P P 0 ) \text{SPL (dB)} = 20 \log_{10} \left( \frac{P}{P_0} \right) SPL (dB)=20log10(P0P)
- P 是需要算出来的帕斯卡声压级。
- P_0 是参考的帕斯卡声压级,一般取20uPa。
所以算出来是:
P = P 0 × 1 0 S P L ( d B ) 20 = 20 ( u P a ) × 1 0 65 ( d B ) 20 = 35566 ( u P a ) P = P_0 \times 10 ^ { \frac{SPL(dB)}{20} } = 20 (uPa) \times 10 ^ {\frac{65(dB)}{20} } = 35566(uPa) P=P0×1020SPL(dB)=20(uPa)×102065(dB)=35566(uPa)
计算结果四舍五入保留了整数部分。
算出麦克风输出电压
上一步算出来的 35566(uPa) 换算为Pa单位,得到P=0.035566(Pa)。代入麦克风灵敏度公式算得:
V m i c = P × S m V / P a = 0.035566 ( P a ) × 10 ( m V / P a ) = 0.35565 ( m V ) = 3.5565 × 1 0 − 4 ( V ) V_{mic} = P \times S_{mV/Pa}=0.035566(Pa) \times 10 (mV/Pa) = 0.35565(mV)=3.5565 \times 10^{-4}(V) Vmic=P×SmV/Pa=0.035566(Pa)×10(mV/Pa)=0.35565(mV)=3.5565×10−4(V)
由于声卡灵敏度用的电压是有效值(RMS),所以这里算出来的值也是有效值。
计算电压和声卡最大输入电压的占比
声卡最大输入电压
声卡最大输入电平是16dBu。dBu 是一个对数单位,用于表示相对于参考值 0.775 伏特(有效值)的电压电平。即:
V d B u = 20 × l o g 10 ( V m a x 0.775 ) V_{dBu}=20 \times log_{10}( \frac {V_{max}} {0.775}) VdBu=20×log10(0.775Vmax)
V_max是声卡最大输入电压(有效值,RMS)。根据公式,要计算16 dBu对应的电压值,如下:
V m a x = 0.775 × 1 0 V d B u 20 = 0.775 × 1 0 16 ( d B u ) 20 = 4.89 ( V ) V_{max} = 0.775 \times 10^{\frac{V_{dBu}}{20}}=0.775 \times 10^{\frac{16(dBu)}{20}}= 4.89(V) Vmax=0.775×1020VdBu=0.775×102016(dBu)=4.89(V)
这里保留2位小数。
计算人声的电平数值
软件录音电平音量条的最大值通常是0 dBFS(dB Full Scale),这是一个数字音频信号电平单位。dBFS表示满度相对电平,0 dBFS的位置是系统能处理的最大音频信号的编码值,即最大值。实际数字音频信号的幅度相对于这个最大值的比值即为满度相对电平,因此实际的电平值都是负值。
在软件中,音量条的最大值通常表示为0 dBFS,这意味着任何超过这个值的信号都会导致削波失真。为了防止失真,通常会将录音电平设置在-3 dBFS到-6 dBFS之间,以留出一定的余量。
V m i c = 3.5565 × 1 0 − 4 ( V ) , V m a x = 4.89 ( V ) V_{mic} = 3.5565 \times 10^{-4}(V) , \space V_{max} = 4.89(V) Vmic=3.5565×10−4(V), Vmax=4.89(V)
计算dBFS如下(保留2位小数):
dBFS = 20 × log 10 ( V m i c V m a x ) = 20 × log 10 ( 3.5565 × 1 0 − 4 ( V ) 4.89 ( V ) ) = − 82.77 ( d B F S ) \text{dBFS} = 20 \times \log_{10} \left( \frac{V_{mic}}{V_{max}} \right)=20 \times \log_{10} \left( \frac{3.5565 \times 10^{-4}(V)}{4.89(V)} \right)=-82.77(dBFS) dBFS=20×log10(VmaxVmic)=20×log10(4.89(V)3.5565×10−4(V))=−82.77(dBFS)
-82.77(dBFS)很小声,播放出来得将音量调很大才能听见声音。这种情况录音时得将增益调大。
计算过程Python实现
直接把文章复制扔给Kimi,开启长思考,代码实现完了。检查了一下能跑,而且计算过程是对的。小改后如下:
# SPDX-License-Identifier: MIT
# ******************************************************************************
# (c) 2025 庵中十三居士
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
# ******************************************************************************
import math
def calculate_dBFS(spl: float, mic_sensitivity_mV_Pa: float, max_input_dBu: float) -> float:
'''根据声音声压级、麦克风灵敏度和声卡最大输入电平计算录音后软件内的电平值(dBFS)。
参数:
spl (float):声音声压级,单位为分贝(dB SPL)
mic_sensitivity_mV_Pa (float):麦克风灵敏度,单位为毫伏每帕(mV/Pa)
max_input_dBu (float):声卡的最大输入电平,单位为分贝伏特(dBu)
返回:
float:计算得到的软件内电平值,单位为分贝满量程(dBFS)
感谢 Moonshot AI 提供的代码实现。这份计算代码基于庵中十三居士的文章原理编写,
帮助您将声学参数与实际录音电平联系起来,方便对录音电平进行预估和调整。
'''
# 声压级转帕斯卡(Pa)
P0 = 20 # uPa(参考声压级)
spl_db = spl
Pa = P0 * 10 ** (spl_db / 20)
# 转换为Pa单位(因为Pa = V/mic_sensitivity_mV_Pa)
Pa = Pa / 1000000 # 将微帕转换为帕
# 计算麦克风输出电压(V)
V_mic_mV = Pa * mic_sensitivity_mV_Pa
V_mic = V_mic_mV / 1000
# 计算声卡最大输入电压(V)
V_ref_dBu = 0.775 # dBu的参考电压
max_input_V = V_ref_dBu * 10 ** (max_input_dBu / 20)
# 计算dBFS
dBFS = 20 * math.log10(V_mic / max_input_V)
return dBFS
if __name__ == "__main__":
# 参数
spl = 65 # 人说话声音大小(SPL)=65dB
mic_sensitivity_mV_Pa = 10 # 麦克风的灵敏度(mV/Pa)
max_input_dBu = 16 # 声卡最大输入电平(dBu)
# 计算
dBFS = calculate_dBFS(spl, mic_sensitivity_mV_Pa, max_input_dBu)
print(f"计算结果:dBFS = {dBFS:.2f} dBFS") # 计算结果:dBFS = -82.77 dBFS
执行之后结果:
$ python test.py
计算结果:dBFS = -82.77 dBFS
文章CSDN:庵中十三居士