为什么我要丢弃FFT返回值的一半?

2024-05-13 02:04:53 发布

您现在位置:Python中文网/ 问答频道 /正文

看看这个答案: Python Scipy FFT wav files

技术部分是显而易见的和可行的,但我有两个理论问题(下面提到的代码):

1)为什么我必须规范化(b=...)帧?如果我使用原始数据会怎么样?在

2)为什么我应该只使用一半的FFT结果(d=...)?在

3)为什么我要abs(c)FFT结果?在

也许是由于对WAV格式或FFT理解不足,我遗漏了一些东西,但是虽然这段代码工作得很好,但我很高兴理解它为什么工作以及如何最好地利用它。在

编辑:针对@triarion的评论:

我试图用Python编写一个简单的,不是100%准确,但更像是概念证明Speaker Diarisation。这意味着使用一个wav文件(现在我正在使用this one进行测试),并在每秒钟(或任何其他分辨率)中说出说话者是person#1还是person#2。我事先知道这是两个人,我不想把他们和任何已知的语音特征联系起来,只是为了分开。现在,每秒钟进行FFT(从而得到一个频率列表),并使用KMeans对它们进行聚类,簇数在2到4之间(a,B[,Silence[,a+B]])。在

我对分析wav文件和音频还是个新手。在

import matplotlib.pyplot as plt
from scipy.io import wavfile # get the api
fs, data = wavfile.read('test.wav') # load the data
a = data.T[0] # this is a two channel soundtrack, I get the first track
b=[(ele/2**8.)*2-1 for ele in a] # this is 8-bit track, b is now normalized on [-1,1)
c = sfft.fft(b) # create a list of complex number
d = len(c)/2  # you only need half of the fft list
plt.plot(abs(c[:(d-1)]),'r') 
plt.show()

Tags: 文件the代码importfftdatagetis
2条回答

那要看你想做什么。看起来你只需要绘制光谱密度,然后就可以这样做了。在

一般来说,DFT中的系数取决于每个频率的相位,所以如果你想保留相位信息,你必须保留复数的自变量。在

只有当输入是实数序列(IIRC)时,才能保证所看到的对称性。这与镜像失真有关,如果频率高于奈奎斯特频率(采样频率的一半),原始频率会显示在DFT中,但镜像频率也会出现。在

如果你要逆DFT,你应该保留完整的数据,同时保留DFT系数的参数。在

按顺序解决这些问题:

1)不需要规范化,但输入规范化接近数字化波形的原始结构,因此数字是不直观的。例如,67的值有多大?将其规格化为-1到1的范围更容易解释这些值。(但如果您想实现一个过滤器,例如,在执行FFT时,修改了FFT值,然后是IFFT,那么规范化将是一个不必要的麻烦。)

2)和3)是相似的,因为它们都与主要生活在复数空间中的数学有关。也就是说,fft将复数的波形(例如,[.5+.1j,.4+.7j,.4+.6j,…])转换成另一个复数序列。在

所以具体来说:

2)结果表明,如果输入波形是实的而不是复杂的,那么FFT具有大约0的对称性,因此只有频率gt;=0的值才是唯一有趣的。在

3)FFT输出的值很复杂,因此它们有Re和Im部分,但也可以表示为幅值和相位。对于音频信号,最有趣的通常是震级,因为这主要是我们听到的。因此,人们经常使用abs(即幅值),但是相位对于不同的问题也可能很重要。在

相关问题 更多 >