语音处理:Python实现dBFS刻度和采样值相互转换

语音处理:Python实现dBFS刻度和采样值相互转换

    • 问题背景
    • 功能思路
    • Python源码
    • 相关资料

问题背景


项目在处理不同位深的音频信号时,时常需要涉及到样点值和dB对数域切换,不想反复去分析公式和手动计算,所以偷个懒写个函数脚本放在这里,方便下次使用。

功能思路


下面以对数域常用的dBFS刻度为例,支持主流音频信号位深:整型16/24/32位和浮点32位,编写Python实现对数域和采样值单位互换功能。

实现过程本质就是模拟以下转换公式:

  • 幅值谱:dBFS = 20 * lg(sample / max_sample)

  • 功率谱(能量谱):dBFS = 10 * lg(sample / max_sample)

详细转换原理可参考博客:《语音处理:PCM文件中采样值到dB分贝的转换分析》。

具体过程

  • 输入待转换的样点值或对数域值,以及信号位深
  • 根据相应位深,得到对应位深的最大值ref_val
  • 根据公式进行样点值和对数域的转换,并输出结果

效果如下:

input:

bit_depth = 24
sp = 1024
db = -78.27

output:

sample: 1023.74, dBFS: -78.27

Python源码


# 仅支持整型16/24/32位和浮点32位位深
import math as mt

# 常量定义
BIT_DEPTH_I16 = 16
BIT_DEPTH_I24 = 24
BIT_DEPTH_I32 = 32
BIT_DEPTH_F32 = -32
VAL2LOG_COEF  = 20
LOG_POW_BASE  = 10


# 根据位深获取最大幅值
def GetSampleRefVal(bit_depth):
    ref_val = 0
    if bit_depth == BIT_DEPTH_F32:         # float32
        ref_val = 1.0
    elif ((bit_depth == BIT_DEPTH_I16) or   # int16
          (bit_depth == BIT_DEPTH_I24) or   # int24
          (bit_depth == BIT_DEPTH_I32)):    # int32
        ref_val = 2 ** (bit_depth - 1) - 1
    else:
        print('not supported bitdepth =', bit_depth)
        return -1
    return ref_val


# dBFS到采样值
def Db2Sample(db, bit_depth):
    # assumed that bit_depth is verfied
    ref_val = GetSampleRefVal(bit_depth)
    sample = pow(LOG_POW_BASE, db / VAL2LOG_COEF) * ref_val
    return sample


# 采样值到dBFS
def Sample2Db(sample, bit_depth):
    # assumed that bit_depth is verfied
    ref_val = GetSampleRefVal(bit_depth)
    sample_clip = min(abs(sample), ref_val)
    ratio = sample_clip / ref_val
    dBFS = VAL2LOG_COEF * mt.log(ratio, LOG_POW_BASE)
    return dBFS


# test demo
bit_depth = 24
sp = 1024
db = -78.27
dBFS = Sample2Db(sp, bit_depth)
sample = Db2Sample(db, bit_depth)
print('sample: {0:0.2f}, dBFS: {1:0.2f}'.format(sample, dBFS))

相关资料


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

你可能感兴趣的:(语音处理,python,开发语言,人工智能)