一、 离散傅里叶变换
离散傅里叶变换(DFT)是离散信号时/频域变换的方法。作用类似于棱镜,将由多种频率混合而成的语音按频谱散射,经过种种处理后,再反变换到时域,就可以获得“提纯”后的语音信号。实数DFT的输入是实数,得到的频点有两个集合,分别是正弦(cos)和余弦(sin)函数的系数,对应于正频分量和负频分量。
1、DFT
短时傅里叶变换可以获得较为准确的时序关系,比如说“ai”这个字的发音,“a”和“i”的发音在时间上是有顺序关系的,这时可以将序列等时分割成若干个小段,按顺序对每一个小段做DFT分析。
2、FFT
快速傅里叶变换是DFT计算的快速方法,正反变换分别为:
X
[
k
]
=
∑
n
=
0
N
−
1
x
[
n
]
e
−
j
2
π
k
n
/
N
X[k]=\sum_{n=0}^{N-1}x[n]e^{-j2{\pi}kn/N}
X[k]=n=0∑N−1x[n]e−j2πkn/N
x
[
n
]
=
1
N
∑
k
=
0
N
−
1
X
[
k
]
e
j
2
π
k
n
/
N
x[n]=\frac{1}{N}\sum_{k=0}^{N-1}X[k]e^{j2{\pi}kn/N}
x[n]=N1k=0∑N−1X[k]ej2πkn/N
3、STFT
X
[
n
,
ω
]
=
∑
n
=
−
∞
+
∞
x
[
n
]
w
[
n
−
m
]
e
−
j
ω
m
X[n,\omega] = \sum_{n=-\infty}^{+\infty}x[n]w[n-m]e^{-j\omega m}
X[n,ω]=n=−∞∑+∞x[n]w[n−m]e−jωm
短时傅里叶变换常用于序列较长或时间分辨率较高的场景,语音信号是时变的,每秒产生约10个音节,在10~30ms时长内的语音信号可以看成是准静态的。STFT的分析和综合处理流程为
对连续的语音分帧做STFT处理,等价于截取一段时间信号,对其进行周期性延拓,从而变成无限长序列做FFT变换,这一截断并不符合傅里叶变换的定义。
- 为何要进行加窗?
加窗是为了抑制频谱泄漏和混叠的产生。
频谱泄漏指某一频率的信号能量扩散到相邻频点的现象。典型的,对语音信号进行STFT时, 就意味着首先要对时域信号进行截断,添加窗函数, 因为对信号加时域窗等效于在频域卷积。 这种截断将导致频谱分析出现误差, 其效果是使得频谱以实际频率值为中心, 以窗函数频谱波形的形状向两侧扩散, 产生“泄漏效应”,即为频谱泄露。
4、OLA方法
- 重叠的思想是将长序列的x[m]分成一段段的短序列,在短序列上进行运算,分段方法
f ( x ) = { x [ n + k L ] n=1,2,...,L 0 elsewise f(x)= \begin{cases} x[n+kL]& \text{n=1,2,...,L}\\ 0& \text{elsewise} \end{cases} f(x)={x[n+kL]0n=1,2,...,Lelsewise
重叠相加法(OLA)和重叠保留法(OLS)主要用于将无限长序列的傅里叶变换、卷积和滤波运算转换成若干子段的傅里叶变换、卷积和滤波运算,他们都可以降低计算复杂度,将时域的计算量从 O ( n ) 2 O(n)^{2} O(n)2变为频域的 n l o g ( n ) nlog(n) nlog(n)
# coding: utf-8
import numpy as np
x = np.array([4,-1,1,-2,2,0,3,2,-1])
h = np.array([1,-1,2])
# split L segments
L =np.size(x) // 3
M = np.size(h)
N = L + M - 1
x_tmp = np.zeros(N)
h = np.append(h, [0, 0], axis=0)
H = np.fft.fft(h)
for i in range(L):
x_tmp[0:3] = x[i*M:i*M+3]
X_tmp = np.fft.fft(x_tmp)
Y = X_tmp*H
y = np.real(np.fft.ifft(Y))
c_y = np.convolve(x_tmp, h)
print("end")
5、滤波器组
(1)功能:滤波器组将输入信号分解到多个频带,并对各个频带进行处理,最后将处理完的各个频带组合在一起得到最终的输出。
6、HMM模型
对一段语音按25ms分帧计算各帧的MFCC特征系数,单个25ms提取的特征系数可以同高斯混合模型来描述,而25ms特征的时序关系则用HMM模型来描述。