🔥博客主页:是dream
🚀系列专栏:深度学习环境搭建、环境配置问题解决、自然语言处理、语音信号处理、项目开发
💘每日语录:欲望以提升热忱,毅力以磨平高山。
🎉感谢大家点赞👍收藏⭐指正✍️
目录
一、短时能量
语音信号的能量随时间的变化比较明显,一般清音部分的能量比浊音的能量小很多,语音信号能量的短时能量分析给出了反应这谢谢幅度变化的一个合适的描述方法。对于信号{x(n)} ,短时能量的定义如下:
En 表示在信号的第n个点开始加窗函数时的短时能量,窗函数可选矩形窗和汉明窗等;短时能量可以看作语音信号的平方经过一个线性滤波器的输出,该线性滤波器的单位冲激响应为h(n)。
简而言之:就是语音信号加了一个窗,这个窗可以是矩形窗,也可以是汉明窗,来反映能量。
矩形窗定义:
汉明窗定义:
汉宁窗定义:
冲激响应h(n)的选择,或者说窗函数的选择 x(n) x²(n)决定了短时能量表示方法的特点。
为了反映窗函 图3-4 短时能量的方块图表示数选择对短时能量的影响,假设式短时能量定义式子中的h(n)非常长,且为恒定幅度,那么Eₙ随时间的变化将很小,这样的窗就等效为很窄的低通滤波器。
很明显,我们要求的是对语音信号进行低通滤波,但还不是很窄的低通滤波,至少短时能量应能反映语音信号的幅度变化。因此出现了窗长选取上的矛盾,这种矛盾将在语音信号的短时表示方法的研究中反复出现。即希望有一个短时窗(冲激响应)以响应快速的幅度变化。但是,太窄的窗将得不到平滑的能量函数。并且窗函数的形状和长短直接影响着短时能量的性质。如果用Xw(n)表示x(n)经过加窗处理后的信号,窗函数的长度为 N,短时能量可表示为:
短时能量的应用:
1、用来区分清音和浊音,因为浊音的能量比清音的能量大很多;
2、对有声段和无声段进行判定,对生母和韵母进行分界,以及连字的分解等;
3、也可做为特征中的一维参数来表示语音信号的大小和超音段信息。
二、短时平均幅值
短时能量由于对信号进行平方运算,因而认为增加了高低信号之间的差距,在一些场合中不适用。可以用短时平均幅值来表示能量的变化。公式如下:
短时平均幅值实现框图如图所示:
三、短时过零率
短时平均过零率是语音信号时域分析中的一种特征参数。它是指每帧内信号通过零值的次数。
1、对有时间横轴的连续语音信号,可以观察到语音的时域波形通过横轴的情况。
2、在离散时间语音信号情况下,如果相邻的采样具有不同的代数符号就称为发生了过零,因此可以计算过零的次数。单位时间内过零的次数就称为过零率。
一段长时间内的过零率称为平均过零率。如果是正弦信号,其平均过零率就是信号频率的两倍除以采样频率,而采样频率是固定的。因此过零率在一定程度上可以反映信号的频率信息。
1、短时过零率定义
用1/2N 作为幅值,考虑了对该窗口范围内的过零数取平均。 另外:考虑到w(n-m)的非零值范围为n-m≥0,即m≤n,以及 n-m≤N-1,故m≥n-N+1,因此短时平均过零率可以改写为:
短时过零率实现框图如图所示:
2、示例分析
下图是女声“我到北京去”短时平均过零次数变化曲线。
可以得到如下结论:
过零率可以区分清音和浊音:
清音(中高频)的过零率高;
浊音(中低频)的过零率低。
四、短时自相关函数和短时平均幅度差值
1、自相关函数
①相关函数用与测定两个信号在时域内的相似程度,可以分为互相关函数和自相关函数。
②互相关函数:研究两个信号之间的相关性,如果两个信号完全不同,相互独立,互相相关函数趋近于0.反之,则趋近于峰值。
③自相关函数主要用于研究信号本身的同步性、周期性。
对于离散的数字信号x(n),其自相关函数定义为:
对于信号是随机的或是周期的,其自相关函数定义为:
如果信号是具有周期性的,并且周期为P,则有:
信号的自相关函数性质如下:
1.在k = 0处为最大值,即对于所有k来说,|R(k)|≤R(0)
2.对称性:R(k)= R(-k)
3.对于确定信号,值R(0)对应于能量,而对于随机信号,R(0)对应于平均功率
2、短时自相关函数
短时自相关函数是在前边的自相关函数基础上将信号加窗获得,其定义如下
其中,n表示窗函数是从第n点开始加入。
并且该函数是偶函数,在k=0是有最大值;
当k=0时,短时自相关函数值等于加窗语音信号的能量。
令:
则短时自相关函数可以定义为:
因此,该式子表明,序列x(n)x(n-k)经过一个hk(n)的滤波器滤波后得到了该自相关函数,
窗长对浊音的短时自相关性有双重影响:
1、由于语音信号的特性是不断变化的,因此期望窗长N尽量短,以捕捉这种变化。
2、为了有效地反映语音信号的周期性,必须选择足够宽的窗口,以确保所选窗口内包含两个或更多基音周期。因此,选择适当的窗长是在捕捉语音信号的瞬时特性和周期性之间进行权衡的过程
修正后的短时自相关函数为:
其中,k时最大的延迟点数,因为求和上限是N-1,与k无关,故当k增加时,^Rn(k)值不下降 。
3、短时平均幅度差函数
为了降低计算短时自相关函数的高运算成本,通常使用一种替代方法,即短时平均幅度差函数(AMDF),它在某种程度上模拟了自相关函数的作用。
假设有一个周期为P的周期信号,在k=0,±P, 2P, …时,d(n)=0。
即当k与信号周期乡吻合时,d(n)的短时平均幅度值总是很小,因此,短时平均幅度差函数的定义为:
显然,如果x(n)具有周期P,则当k=0,±P, 2P, …时,rn(k)具有最小值。应该注意的是,取矩形窗是很合适的。
五、代码实现
1、原始代码
这段代码对应了开源代码python_sound_open中的C3_2_y.py。
拿到这个代码的时候,代码是不能运行的,主要时返回参数的问题,这里我加上了fits这个参数,但实际上并没有用这个参数,主要是为了解决报错问题。
from scipy.io import wavfile
import matplotlib.pyplot as plt
from chapter3_分析实验.windows import *
from chapter3_分析实验.timefeature import *
from chapter2_基础.soundBase import *
data, fs ,fits= soundBase('C3_2_y.wav').audioread()
inc = 100
wlen = 200
win = hanning_window(wlen)
N = len(data)
time = [i / fs for i in range(N)]
EN = STEn(data, win, inc) # 短时能量
Mn = STMn(data, win, inc) # 短时平均幅度
Zcr = STZcr(data, win, inc) # 短时过零率
X = enframe(data, win, inc)
X = X.T
Ac = STAc(X)
Ac = Ac.T
Ac = Ac.flatten()
Amdf = STAmdf(X)
Amdf = Amdf.flatten()
fig = plt.figure(figsize=(14, 13))
plt.subplot(3, 1, 1)
plt.plot(time, data)
plt.title('(a)语音波形')
plt.subplot(3, 1, 2)
frameTime = FrameTimeC(len(EN), wlen, inc, fs)
plt.plot(frameTime, Mn)
plt.title('(b)短时幅值')
plt.subplot(3, 1, 3)
plt.plot(frameTime, EN)
plt.title('(c)短时能量')
plt.show()
#plt.savefig('images/energy.png')
fig = plt.figure(figsize=(10, 13))
plt.subplot(2, 1, 1)
plt.plot(time, data)
plt.title('(a)语音波形')
plt.subplot(2, 1, 2)
plt.plot(frameTime, Zcr)
plt.title('(b)短时过零率')
plt.show()
#plt.savefig('images/Zcr.png')
fig = plt.figure(figsize=(10, 13))
plt.subplot(2, 1, 1)
plt.plot(time, data)
plt.title('(a)语音波形')
plt.subplot(2, 1, 2)
plt.plot(Ac)
plt.title('(b)短时自相关')
plt.show()
#plt.savefig('images/corr.png')
fig = plt.figure(figsize=(10, 13))
plt.subplot(2, 1, 1)
plt.plot(time, data)
plt.title('(a)语音波形')
plt.subplot(2, 1, 2)
plt.plot(Amdf)
plt.title('(b)短时幅度差')
plt.show()
#plt.savefig('images/Amdf.png')
运行结果:
①语音波形、短时幅值、短时能量
②短时过零率
③短时自相关
④短时幅度差
2、代码改进,增加选择时间段进行分析的功能
from scipy.io import wavfile
import matplotlib.pyplot as plt
from chapter3_分析实验.windows import *
from chapter3_分析实验.timefeature import *
from chapter2_基础.soundBase import *
def analyze_audio_segment(audio_data, fs, start_time, end_time, wlen, inc):
# 根据指定的开始和结束时间截取需要分析的语音段
start_sample = int(start_time * fs)
end_sample = int(end_time * fs)
audio_segment = audio_data[start_sample:end_sample]
win = hanning_window(wlen)
N = len(audio_segment)
time = [i / fs for i in range(N)]
EN = STEn(audio_segment, win, inc) # 短时能量
Mn = STMn(audio_segment, win, inc) # 短时平均幅度
Zcr = STZcr(audio_segment, win, inc) # 短时过零率
X = enframe(audio_segment, win, inc)
X = X.T
Ac = STAc(X)
Ac = Ac.T
Ac = Ac.flatten()
Amdf = STAmdf(X)
Amdf = Amdf.flatten()
fig = plt.figure(figsize=(14, 13))
plt.subplot(3, 1, 1)
plt.plot(time, audio_segment)
plt.title('(a)语音波形')
plt.subplot(3, 1, 2)
frameTime = FrameTimeC(len(EN), wlen, inc, fs)
plt.plot(frameTime, Mn)
plt.title('(b)短时幅值')
plt.subplot(3, 1, 3)
plt.plot(frameTime, EN)
plt.title('(c)短时能量')
plt.show()
fig = plt.figure(figsize=(10, 13))
plt.subplot(2, 1, 1)
plt.plot(time, audio_segment)
plt.title('(a)语音波形')
plt.subplot(2, 1, 2)
plt.plot(frameTime, Zcr)
plt.title('(b)短时过零率')
plt.show()
fig = plt.figure(figsize=(10, 13))
plt.subplot(2, 1, 1)
plt.plot(time, audio_segment)
plt.title('(a)语音波形')
plt.subplot(2, 1, 2)
plt.plot(Ac)
plt.title('(b)短时自相关')
plt.show()
fig = plt.figure(figsize=(10, 13))
plt.subplot(2, 1, 1)
plt.plot(time, audio_segment)
plt.title('(a)语音波形')
plt.subplot(2, 1, 2)
plt.plot(Amdf)
plt.title('(b)短时幅度差')
plt.show()
if __name__ == "__main__":
# 读取语音文件
data, fs, fits = soundBase('C3_2_y.wav').audioread()
inc = 100
wlen = 200
# 指定开始和结束时间(以秒为单位)
start_time = 1.0
end_time = 2.0
# 调用分析函数
analyze_audio_segment(data, fs, start_time, end_time, wlen, inc)
这里可以根据需求,更改分析时间段的起始和终止时间,来进行进一步分析。
运行结果:
①语音波形、短时幅值、短时能量
②短时过零率
③短时自相关
④短时幅度差
写在最后,本文参考了别出BUG求求了_python,深度学习,云原生-CSDN博客,同时参考了"语音信号处理"这本书,最后结合自己的理解,写了本文,目的是为了方便自己复习。