python中的短时傅里叶变换

发布于 2025-01-07 17:33:40 字数 1177 浏览 0 评论 0原文

我想获得 wav 文件中每一时刻最大功率的频率。 所以我使用 scipy 中的 fft 用 Python 编写了 STFT。我使用了 scipy 中的 kaiser 窗口函数。一切看起来都很棒,但我的输出看起来很奇怪。它有一些非常小的数字,也有一些非常高的数字。

以下是一个 wav 文件的输出: http://pastebin.com/5Ryd2uXj 这是 python 中的代码:

import scipy, pylab
import wave
import struct
import sys

def stft(data, cp, do, hop):
    dos = int(do*cp)
    w = scipy.kaiser(dos,12) //12 is very high for kaiser window
    temp=[]
    wyn=[]
    for i in range(0, len(data)-dos, hop):
        temp=scipy.fft(w*data[i:i+dos])
        max=-1
        for j in range(0, len(temp),1):
            licz=temp[j].real**2+temp[j].imag**2
            if( licz>max ):
                max = licz
                maxj = j
        wyn.append(maxj)
    #wyn = scipy.array([scipy.fft(w*data[i:i+dos])
        #for i in range(0, len(data)-dos, 1)])
    return wyn

file = wave.open(sys.argv[1])
bity = file.readframes(file.getnframes())
data=struct.unpack('{n}h'.format(n=file.getnframes()), bity)
file.close()

cp=44100 #sampling frequency
do=0.05 #window size
hop = 5

wyn=stft(data,cp,do,hop)
print len(wyn)
for i in range(0, len(wyn), 1):
    print wyn[i]

I want to get frequency with maximum power for every moment in wav file.
So I wrote STFT in Python using fft from scipy. I used kaiser window function from scipy. Everything looking great, but my output looks strange. It has some very small numbers and some very high.

here is the output for one wav file: http://pastebin.com/5Ryd2uXj
and here is the code in python:

import scipy, pylab
import wave
import struct
import sys

def stft(data, cp, do, hop):
    dos = int(do*cp)
    w = scipy.kaiser(dos,12) //12 is very high for kaiser window
    temp=[]
    wyn=[]
    for i in range(0, len(data)-dos, hop):
        temp=scipy.fft(w*data[i:i+dos])
        max=-1
        for j in range(0, len(temp),1):
            licz=temp[j].real**2+temp[j].imag**2
            if( licz>max ):
                max = licz
                maxj = j
        wyn.append(maxj)
    #wyn = scipy.array([scipy.fft(w*data[i:i+dos])
        #for i in range(0, len(data)-dos, 1)])
    return wyn

file = wave.open(sys.argv[1])
bity = file.readframes(file.getnframes())
data=struct.unpack('{n}h'.format(n=file.getnframes()), bity)
file.close()

cp=44100 #sampling frequency
do=0.05 #window size
hop = 5

wyn=stft(data,cp,do,hop)
print len(wyn)
for i in range(0, len(wyn), 1):
    print wyn[i]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

剧终人散尽 2025-01-14 17:33:40

正弦波的实际 FT 是一对距 0 频率等距的 delta 函数。对于离散函数(样本),频域中的每个 fs(采样率)都会重复此过程。 FFT 计算中的小错误将意味着这两个增量(正弦波的 FT)的高度不会完全相同,因此您的算法只是选择较高的一个。

scipy FFT 函数将为您提供域 [0, fs] 的频率分量。由于(正如我上面提到的)这是周期性的,因此这些值也可以通过交换中心点的结果来重新映射为 [-fs/2, fs/2] - 查看使用 fftshift 来执行此操作。
然而,听起来您可能只对频率感兴趣,因此您可以简单地丢弃 FFT 结果的后半部分。

来自 scipy.fftpack.fft 的注释

结果的打包是“标准”的:如果 A = fft(a, n),则 A[0] 包含零频率项,A[1:n/2+1] 包含正频率项项,A[n/2+1:] 包含负频率项,按负频率递减的顺序排列。因此,对于 8 点变换,结果的频率为 [ 0, 1, 2, 3, 4, -3, -2, -1]。

The actual FT of a sine wave is a pair of delta functions equidistant from 0-frequency. With a discrete function (samples), this is repeated every fs (sampling rate) in the frequency domain. Small errors in FFT computation will mean these two deltas (FT of your sine wave) will not be exactly the same height, so your algorithm is simply picking the taller one.

The scipy FFT function will give you frequency components with the domain [0, fs]. Since (as I mentioned above) this is periodic, these values could also be remapped as [-fs/2, fs/2] by swapping the result at the center point - look into using fftshift to do this.
It sounds like you may only be interested in the positive frequencies, however, so you can simply discard the second half of the result of your FFT.

From the notes of scipy.fftpack.fft:

The packing of the result is “standard”: If A = fft(a, n), then A[0] contains the zero-frequency term, A[1:n/2+1] contains the positive-frequency terms, and A[n/2+1:] contains the negative-frequency terms, in order of decreasingly negative frequency. So for an 8-point transform, the frequencies of the result are [ 0, 1, 2, 3, 4, -3, -2, -1].

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文