音频FFT计算及校准至等效实测声压级(SPL)方案咨询
校准实现步骤
1 先修正现有FFT计算的疏漏
你当前的代码没有补汉宁窗带来的能量损失,会导致计算的幅值偏小,需要先做窗校正:
汉宁窗的幅值校正系数为2,能量校正系数为√(8/3) ≈ 1.633,你做RMS平均属于能量计算,所以要在幅值计算环节乘上这个校正系数。
2 计算校准偏移量
你现在的FFT输出的是相对于满量程1的dB值,音频采样本身幅值远小于1,所以输出全是负值,只需要算出校准偏移量统一加到所有窄带结果上即可。
两种偏移量计算方式可选:
方式1:用校准音数据计算(精度最高)
你之前用1kHz 94dB的信号做过设备校准,如果保存了当时的1kHz校准音录音,直接对校准音跑你的FFT流程,得到1kHz频点的dB值dB_cal,校准偏移量为:
offset = 94 - dB_cal
方式2:用同步测量的总声压级计算(无校准音时用)
先把你当前得到的0-2000Hz所有窄带的线性RMS值做能量求和,换算成总dB值,和SLM同步测得的0-2000Hz等效总声压级做差,得到全局偏移量:
# 先把当前的dB值转成线性压强 linear_vals = 10 ** (dfSTFT_narrow['narrow'] / 20) # 能量求和后转成总dB值 total_dB_current = 20 * np.log10(np.sqrt(np.sum(linear_vals ** 2))) # SLM实测的0-2000Hz总等效声压级,替换成你自己的实测值 total_dB_slm = 72.5 # 计算偏移量 offset = total_dB_slm - total_dB_current
如果有1/3倍频程的实测数据,还可以做分带校准:把每个1/3倍频程带内的窄带能量求和,和对应带的实测声压级做差,每个带单独加对应偏移量,精度比全局校准更高。
3 输出校准后的SPL值
把偏移量加到所有窄带的dB值上即可:
dfSTFT_narrow['calibrated_spl'] = dfSTFT_narrow['narrow'] + offset
需修改的代码片段对应位置
你原来的FFT幅值计算部分修改为:
# 汉宁窗能量校正系数 window_correction = np.sqrt(8/3) # 修正幅值计算,加窗校正 FFT_data_real = 2/N * abs(dfSTFT) * window_correction rms_averaged = np.sqrt(np.mean(FFT_data_real**2, axis=1)) dfSTFT_narrow = pd.DataFrame({"narrow": rms_averaged}, index = dfSTFT.index) # 得到相对dB值 dfSTFT_narrow = 20*np.log10(dfSTFT_narrow) # 加校准偏移量,offset按前面的方法计算得到 dfSTFT_narrow['calibrated_spl'] = dfSTFT_narrow['narrow'] + offset
内容的提问来源于stack exchange,提问作者JayBe
相关产品推荐
相关产品推荐

