STFT笔记

因为不懂这个被鄙视了,调包侠来补作业。

基础知识

FFT(fast fourier transfrom)快速傅里叶变换。
推荐阅读《深入浅出的讲解傅里叶变换(真正的通俗易懂)》,
《梅尔频率倒谱系数(MFCC)》。

频谱只获得了频域视角下,不同正弦波的幅度大小,而不包含相位信息,所以频谱又名振幅谱
距离频率轴最近的波峰,其到频率轴的时间差,除以周期,乘以2pi,即为相位差。人为定义相位谱的值域为(-pi,pi],因为相位差是周期的。
傅里叶级数,在时域是一个周期且连续的函数,而在频域是一个非周期离散的函数。
傅里叶变换,是将一个时域非周期的连续信号,转换为一个在频域非周期的连续信号
快速傅里叶变换,将一维傅里叶变换的计算复杂度降解到O(N*logN)。当然也有二维、三维形式。

STFT就是以滑动窗口的形式,在不同窗口内部做FFT。
得到结果为spectrum,横坐标时间,纵坐标频率,数值大小表示能量深度。

调包侠不必过分追求底层原理,能活用api即可。

输入输出

看torch.stft官方文档

torch.stft(input, n_fft, hop_length=None, win_length=None, window=None, center=True, pad_mode=‘reflect’, normalized=False, onesided=True)

STFT笔记_第1张图片

输入

可以是1D时间序列,shape=(L),也可以是 2D 的batch版本,shape=(batchsize,L)。

输出

(N,T,2),或者(batchsize,N,T,2)。
2表示实部和虚部的数值。

N is the number of frequencies where STFT is applied.
T is the total number of frames used。

文档里写的玄乎。我测试了之后发现。

N= n_fft//2 +1
T= (L-1)//hopsize + 1

其中hopsize默认为1/4的n_fft,。

以下为示例代码。

x=torch.randn(88200)
print(x.shape)
y=torch.stft(x,n_fft=2048)
print(y.shape)

#输出
torch.Size([88200])
torch.Size([1025, 173, 2])
x=torch.randn(88200)
y=torch.stft(x,n_fft=1024)
print(y.shape)
#输出
torch.Size([513, 345, 2])

其他参数

hop_length,默认为floor(n_fft/4)。把hop理解为stride即可,每次滑动步长,或者称为帧移。
win_length,默认等于n_fft。自己指定值时,需满足win_length<=n_fft。其含义为每个窗口内取win_length个点做FFT,
又因为FFT需要输入的时间序列(帧点数)和输出的频域抽样点数(FFT点数)相同,即输入多长的信号,就做多少点FFT变换。
所以采样出来的win_length个点,需要用零填充至n_fft个。
window,shape=(n_fft,),一维张量。可以由torch.hann_window()等函数生成。其本质是一个加权求和操作里的“权重”。
同样地,当win_length pad_mode,默认为’reflect’,pad模式同 torch.nn.functional.pad() 。我写过一篇文章PyTorch F.pad()。
center
onsided
normalized

#参考 快速傅里叶变换(FFT)中为什么要“补零”?

时域补零相当于频域插值,让频域曲线看起来更加光滑,也就是增加了FFT的视觉分辨率。但不影响波形分辨率。

#参考https://ccrma.stanford.edu/~jos/mdft/Zero_Padding_Applications.html

文末一句话remember that in signal processing, zero-padding in one domain corresponds to a higher interpolation-density in the other domain–not a higher resolution。

#参考https://www.cnblogs.com/Ge-ronimo/p/12298403.html
#参考https://blog.csdn.net/sinat_35821976/article/details/105739909

你可能感兴趣的:(pytorch)