介绍
刚开始学习计算机视听觉,第一个实验是端点检测算法。这个算法实现起来还是比较简单的,主要是该算法利用到的两个数据——语音短时能量和短时过零率。今天先分享一下我计算短时能量的方法。
语音短时能量,顾名思义就是计算较短时间内的语音能量。这里的较短时间,通常指的是一帧。也就是说,一帧时间内的语音能量就是短时能量,语音的短时能量就是将语音中每一帧的短时能量都计算出来,然后我们就可以利用这个短时能量数组做很多事情了。通常而言,短时能量用途有以下几个方面:
- 区分清音和浊音
- 判定有声段和无声段
- 对声母和韵母分界
- 可以作为辅助的特征参数用于语音识别中,经常是识别系统中的特征一维
端点检测利用的就是短时能量的前两个用途——将语音文件中的语音分离出来。
介绍完定义后,再来看看短时能量的计算公式。
计算
语音能量的计算,通常是
E
=
x
(
n
)
2
E ={x(n)}^2
E=x(n)2。由语音短时能量的定义,就可以得到短时能量的计算公式:
E
n
=
∑
m
=
−
∞
∞
[
x
(
m
)
w
(
n
−
m
)
]
2
=
x
(
n
)
2
∗
h
(
n
)
E_n = \sum^\infty_{m = -\infty}[x(m)w(n - m)]^2 = {x(n)}^2 * h(n)
En=m=−∞∑∞[x(m)w(n−m)]2=x(n)2∗h(n)
其中,
h
(
n
)
=
w
(
n
)
2
h(n) = {w(n)}^2
h(n)=w(n)2 ,
w
(
n
)
w(n)
w(n) 是窗口函数
也可以简写成:
E n = ∑ m = − ∞ ∞ [ x ( m ) w ( m ) ] 2 E_n = \sum^\infty_{m = -\infty}[x(m)w(m)]^2 En=m=−∞∑∞[x(m)w(m)]2
由于短时能量是语音的时域特征,因此,在不使用傅里叶变换的情况下,这里的窗口是一种方窗,即:
w ( n ) = { 1 0 <= n <= N - 1 0 其它 w(n)= \begin{cases} 1& \text {0 <= n <= N - 1} \\ 0 & \text{其它} \end{cases} w(n)={100 <= n <= N - 1其它
因此,可以得出,这里的语音短时能量就相当于,每一帧中所有语音信号的平方和。
Python 实现短时能量
首先读取语音文件,我这里是 .wav 类型的,不同类型可能文件格式不一样,我们只需要读取到语音的采样点部分就可以了。
f = wave.open("./语料/" + str(i + 1) + ".wav","rb")
# getparams() 一次性返回所有的WAV文件的格式信息
params = f.getparams()
# nframes 采样点数目
nchannels, sampwidth, framerate, nframes = params[:4]
# readframes() 按照采样点读取数据
str_data = f.readframes(nframes) # str_data 是二进制字符串
# 以上可以直接写成 str_data = f.readframes(f.getnframes())
# 转成二字节数组形式(每个采样点占两个字节)
wave_data = np.fromstring(str_data, dtype = np.short)
print( "采样点数目:" + str(len(wave_data))) #输出应为采样点数目
f.close()
计算语音短时能量函数如下:
# 计算每一帧的能量 256个采样点为一帧
def calEnergy(wave_data) :
energy = []
sum = 0
for i in range(len(wave_data)) :
sum = sum + (int(wave_data[i]) * int(wave_data[i]))
if (i + 1) % 256 == 0 :
energy.append(sum)
sum = 0
elif i == len(wave_data) - 1 :
energy.append(sum)
return energy
最后直接调用:
energy = calEnergy(wave_data)
总结
最后,语音短时能量是一个比较简单的语音时域特征,也是一个语音学中经常使用的特征,希望这篇文章能够帮助大家。
由于本人刚开始学习语音部分,学的还很有限,如有书写错误的地方,希望大家帮助改正,谢谢。