我正在尝试使用快速傅立叶变换和numpy查找从wav文件中获取的数字数组的频率,但是我收到的频率输出错误。
这是我的代码:
from pydub import AudioSegment
import numpy as np
np.set_printoptions(threshold=np.inf)
sound = AudioSegment.from_mp3("500Hz.wav")
raw_data = sound.raw_data
raw_data = np.fromstring(raw_data, dtype=np.int16)
print(raw_data[:2000:21])
wave = raw_data
fft = np.fft.rfft(wave)
fft = np.abs(fft)
print(max(list(fft)))
print(list(fft).index(max(list(fft))))
fft = np.array([int(i) for i in fft])
500Hz.wav文件是使用Audacity创建的3秒钟的500Hz音频波。
代码返回以下内容:
[ 0 26138 3906 -25559 -7727 24402 11370 -22702 -14767 20496
17830 -17830 -20498 14763 22701 -11374 -24400 7728 25557 -3907
-26140 0 26141 3905 -25555 -7728 24404 11373 -22704 -14767
20496 17831 -17829 -20493 14765 22698 -11375 -24404 7725 25553
-3906 -26138 -1 26141 3907 -25559 -7726 24402 11375 -22702
-14765 20497 17830 -17831 -20498 14762 22700 -11374 -24401 7726
25557 -3906 -26141 2 26139 3912 -25556 -7728 24401 11376
-22702 -14767 20499 17830 -17830 -20496 14766 22704 -11372 -24405
7725 25559 -3906 -26141 -1 26139 3906 -25556 -7725 24404
11373 -22702 -14769 20495 17831 -17832]
2046217405.9084692
1770
这表明峰值位于1770Hz,而不是500Hz,我不确定是什么原因引起的。 如果我缺少任何信息,请告诉我,以便将其添加到问题中!
编辑:该文件位于https://ufile.io/nk7j9
答案 0 :(得分:1)
与索引1770相对应的频率取决于帧的持续时间。例如,如果帧持续3
秒,则索引i
的频率为{ {1}}赫兹。零频率对应于信号的平均值或直流分量:目前为零。如果索引1770对应于500Hz,则帧的持续时间可能约为3.22秒。 由于使用pydub读取了文件,因此可以使用i/3
以毫秒为单位缩短此持续时间
即使信号是正弦波,离散傅立叶变换(DFT)的峰值也可能跨越多个频率。每当帧的长度不是正弦波周期的倍数时,就会发生这种情况,称为spectral leakage。可以通过在DFT之前应用window来调整它。
最后,用作输入的正弦波周期可能与DFT的离散频率不同。因此,使用最高振幅的指标来估计正弦波的频率可能会略有错误。要纠正这一点,可以将DFT振幅峰值的实际频率估算为相对于功率密度的平均频率,请参见Why are frequency values rounded in signal using FFT?