【发布时间】:2014-12-18 08:38:58
【问题描述】:
我正在尝试使用 numpy 计算以 48000 Hz 的采样率为 48000 个音频数据样本的 FFT 频率分量的 dB 测量功率。我正在测试的文件具有 1000 Hz 的全功率 (0 dB) 正弦波。当我计算能量最高的能带的均方根值时,我期望结果为 0 dB,但是,我得到以下结果:
1000.0Hz 41.8387130383 dB
有人能解释为什么我得到不同的结果吗?我的代码如下。
'data' 是一个 48000 个样本的 numpy 数组,具有 32 位精度。据我了解,我需要通过数据样本的长度对 fft 结果进行归一化。
p = np.fft.fft(data)
uniquePts = math.ceil(len(data)+1/2.0)
p = p[0:uniquePts]
freqs = np.fft.fftfreq(len(p))
通过数据样本的长度对fft结果进行归一化
p = np.divide(p,float(len(data)))
p = np.abs(p)
p = np.power(p,2)
将 FFT 结果乘以 2 以说明我们将返回 FFT 数组中的元素总数减半
if len(data) % 2 > 0:
p[1:len(p)] = np.multiply(p[1:len(p)], 2)
else:
p[1:len(p) - 1] = np.multiply(p[1:len(p) -1], 2)
此时,我找到了idx代表的能量最多的FFT分量:
data_size=48000 #1 second of audio
idx=np.argmax(np.abs(p)**2)
rms = math.sqrt(p[idx])
dbRep = 20 * math.log10((1.0 * rms)/data_size)
print abs(freqs[i] * frate), dbRep
【问题讨论】:
-
data的取值范围是多少? -
'data' 包含来自 24 位波形文件的 32 位有符号整数,我对其有符号整数值进行了符号扩展。我可以从音频文件中导出正确的数据库表示,所以我认为“数据”没有问题。
-
OK - 那么
data的数字范围是多少?是 32 位有符号整数的全范围,即 -2e9 到 +2e9,还是 24 位 PCM 的全范围,还是什么? -
全范围 24 位 PCM,-8388607 到 8388608
-
好的 -
data_size是什么?
标签: python audio numpy signal-processing fft