python实现窗函数的简单介绍

Python科学计算——复杂信号FFTFFT (Fast Fourier Transform, 快速傅里叶变换) 是离散傅里叶变换的快速算法,也是数字信号处理技术中经常会提到的一个概念 。用快速傅里叶变换能将时域的数字信号转换为频域信号 , 转换为频域信号后我们可以很方便地分析出信号的频率成分 。
当我们把双频信号FFT示例中的 fft_size 的值改为 2**12 时,这时,基频为 16Hz,不能被 1kHz整除,所以 1kHz 处发生了频谱泄露,而它能被 4kHz 整除,所以 4kHz 可以很好地被采样 。
由于波形的前后不是连续的,出现波形跳变,而跳变处有着非常广泛的频谱,因此FFT的结果中出现了频谱泄漏 。
为了减小FFT所截取的数据段前后的跳变,可以对数据先乘以一个窗函数,使得其前后数据能平滑过渡 。常用的hanning窗函数的定义如下:
50Hz 正弦波与hann窗函数乘积之后的重复波形如下:
我们对频谱泄漏示例中的1kHz 和 4kHz 信号进行了 hann 窗函数处理,可以看出能量更加集中在 1kHz 和 4kHz,在一定程度上抑制了频谱泄漏 。
以 1kHz 三角波为例,我们知道三角波信号中含有丰富的频率信息,它的傅里叶级数展开为:
当数字信号的频率随时间变化时 , 我们称之为扫频信号 。以频率随时间线性变化的扫频信号为例,其数学形式如下:
其频率随时间线性变化,当我们在 [0,1] 的时间窗口对其进行采样时,其频率范围为 0~5kHz 。当时间是连续时 , 扫频信号的频率也是连续的 。但是在实际的处理中,是离散的点采样,因此时间是不连续的,这就使扫频信号的快速傅里叶变换问题退化为多点频信号快速傅里叶变换问题 。其快速傅里叶变换得到的频谱图如下所示:
以 50Hz 正弦信号相位调制到 1kHz 的信号为例,其信号形式如下:
它的时域波形,频率响应和相位响应如下图所示:
以扫频信号为例,当我们要探究FFT中的能量守恒时 , 我们要回归到信号最初的形式:
【小项目-1】用Python进行人声伴奏分离和音乐特征提取比如采样率为22050,音频文件有36s,那么x为长度为22050*36=793800的float 。
用到了python库Spleeter
抽象地了解下原理吧
参考文章是这篇:Spleeter: a fast and efficient music source separation tool with pre-trained models
原理文章是这篇 SINGING VOICE SEPARATION: A STUDY ON TRAINING DATA
粗略扫了一眼,原理主要是用U-Net进行分割,然后这个Python工具主要是利用了一个pre-trained的model 。
参考链接:机器之心的一篇文章
纵轴表示频率(从0到10kHz),横轴表示剪辑的时间 。由于我们看到所有动作都发生在频谱的底部,我们可以将频率轴转换为对数轴 。
可以对频率取对数 。
感觉这个参数蛮有意思的
整个频谱被投影到12个区间,代表音乐八度音的12个不同的半音(或色度), librosa.feature.chroma_stft 用于计算 。
先对音频进行短时傅里叶变换
其中每行存储一个窗口的STFT , 大小为1025*1551
这里要注意理解怎么基于stft的结果来画频谱图
没太了解 , 感觉就大概知道有这么个量可以用到就行 。
librosa.feature.spectral_centroid 计算信号中每帧的光谱质心:
1. 先理解连续傅里叶变换
2. 再理解离散傅里叶变换
对连续函数进行离散采样
3. 最后进入短时傅里叶变换
是先把一个函数和窗函数进行相乘,然后再进行一维的傅里叶变换 。并通过窗函数的滑动得到一系列的傅里叶变换结果,将这些结果竖着排开得到一个二维的表象 。
Python 简单的扩音,音频去噪,静音剪切数字信号是通过对连续的模拟信号采样得到的离散的函数 。它可以简单看作一个以时间为下标的数组 。比如,x[n] , n为整数 。比如下图是一个正弦信号(n=0,1, ..., 9):

推荐阅读