3.2短时傅里叶变换
语音的感知过程与人类听觉系统具有频谱分析功能紧密相关。因此,对语音信号进行频谱分析,是认识和处理语音信号的重要方法。
声音从频率上可以分为纯音和复合音:
纯音只含一种频率的声音(基音),而没有倍音。
复合音是除基音外,还包含多种倍音的声音。
大部分声音(包括语音)都是复合音,涉及多个频率段。
如何分离不同频率信号呢?
一帧
import librosa
from matplotlib.font_manager import FontProperties
import numpy as np
import matplotlib.pyplot as plt
from scipy.io import wavfile
fonts = FontProperties(fname = "D:\Desktop\语音识别原理与应用\方正粗黑宋简体.ttf",size=14)
#分帧
def enframe(x, win, inc=None):
nx = len(x)
if isinstance(win, list) or isinstance(win, np.ndarray):
nwin = len(win)
nlen = nwin # 帧长=窗长
elif isinstance(win, int):
nwin = 1
nlen = win # 设置为帧长
if inc is None:
inc = nlen
nf = (nx - nlen + inc) // inc
frameout = np.zeros((nf, nlen))
indf = np.multiply(inc, np.array([i for i in range(nf)]))
for i in range(nf):
frameout[i, :] = x[indf[i]:indf[i] + nlen]
if isinstance(win, list) or isinstance(win, np.ndarray):
frameout = np.multiply(frameout, np.array(win))
return frameout
#帧长
def FrameTimeC(frameNum, frameLen, inc, fs):
ll = np.array([i for i in range(frameNum)])
return ((ll - 1) * inc + frameLen / 2) / fs
#%%短时傅里叶变换
def STFFT(x, win, nfft, inc):
xn = enframe(x, win, inc)
xn = xn.T
y = np.fft.fft(xn, nfft, axis=0)
return y[:nfft // 2, 100]
data, fs = librosa.load('beijing.wav',sr=None)
#%%
wlen = 256
nfft = wlen
win = np.hamming(wlen)
inc = 128
y = STFFT(data, win, nfft, inc)
plt.subplot(211)
plt.plot(y)
plt.subplot(212)
N=len(y)
# 分辨率
df = fs/(N-1)
# 构建频率数组
f = [df*n for n in range(0,N)]
Y = np.fft.fft(y)*2/N #*2/N 反映了FFT变换的结果与实际信号幅值之间的关系
absY = [np.abs(x) for x in Y] #求傅里叶变换结果的模
plt.plot(f,absY)
plt.xlabel('(Hz)')
plt.title("fft")
plt.show()