python对语音信号读取、分帧、加窗
一、读入音频信号
语音信号有三个重要的参数:声道数、取样频率和量化位数。
-
声道数:单声道或者双声道
-
采样频率:一秒钟对声音采样的次数,例如10000HZ代表一秒钟将信号分解为10000份,当采样数量非常高的时候,我们人眼看起来就是连续的。(实际是离散的)。采样频率越高声音的还原就越真实越自然。在当今的主流采集卡上,采样频率一般共分为22.05KHz、44.1KHz、48KHz三个等级,22.05KHz只能达到FM广播的声音品质,44.1KHz则是理论上的CD音质界限,48KHz则更加精确一些。
-
量化位数:用多少bit表达一次采样所采集的数据,通常有8bit、16bit、24bit和32bit等几种。
例如CD中所储存的声音信号是双声道、44.1kHz、16bit。
wave读wav文件
wava模块为wav声音格式提供了方面的界面,但支持单声道/立体声。
f = wave.open(r"file", mode="rb")
其中file为wav格式的语音文件
mode是缺省参数,可以不填,也可以是"rb":只读模式;“wb”:只写模式。注意不支持读/写格式。
f为读取的文件流。
f.getparams()
一次性返回所有的音频参数,返回的是一个元组(声道数,量化位数(byte单位),采样频率,采样点数,压缩类型,压缩类型的描述)。(nchannels, sampwidth, framerate, nframes, comptype, compname)wave模块只支持非压缩的数据,因此可以忽略最后两个信息。
现在来读入一个名为lantian.wav的语音信号,将它导入python工程文件目录下
输入代码:
import wave #调用wave模块
import matplotlib.pyplot as plt #调用matplotlib.pyplot模块作为Plt
import numpy as np #调用numpy模块记作np
f = wave.open(r"lantian.wav", "rb") #读取语音文件
params = f.getparams() #返回音频参数
nchannels, sampwidth, framerate, nframes = params[:4] #赋值声道数,量化位数,采样频率,采样点数
print(nchannels,sampwidth,framerate,nframes)# 输出声道数,量化位数,采样频率,采样点数
输出结果:
1 2 8000 19000
声道数=1
量化位数=2
采样频率=8000
采样点数=19000
str_data = f.readframes(nframes)
指定需要读取的长度(以取样点为单位),返回的是字符串类型的数据。
print(str_data[:10])
这里输出str_data的前十个数据为:
\xf0\xff\xfc\xff\xf6\xff\xf7\xff\xe6\xff
wave_data = np.fromstring(str_data, dtype=np.short)
将读取的字符串数据转换为一维short类型的数组。通过np.fromstring函数将字符串转换为数组,通过其参数dtype指定转换后的数据格式
输出结果:(数组的前十个)
[-16 -4 -10 -9 -26 -16 -25 -40 -36 -54]
wave_data = wave_data*1.0/(max(abs(wave_data)))
这段代码将数组归一化,输出前10个结果为:
[-0.00222161 -0.0005554 -0.0013885 -0.00124965 -0.00361011 -0.00222161
-0.00347126 -0.00555401 -0.00499861 -0.00749792]
time = np.arange(0, nframes) * (1.0 / framerate)
通过采样点数和取样频率计算出每个取样的时间
输入代码,画出语音的波形
import wave
import matplotlib.pyplot as plt
import numpy as np
f = wave.open(r"lantian.wav", "rb")
params = f.getparams()
nchannels, sampwidth, framerate, nframes = params[:4]
print(nchannels,sampwidth,framerate,nframes)
str_data = f.readframes(nframes)
print(str_data[:10])
wave_data = np.fromstring(str_data, dtype=np.short)
print(wave_data[:10])
wave_data = wave_data*1.0/(max(abs(wave_data)))
print(wave_data[:10])
time = np.arange(0, nframes) * (1.0 / framerate)
plt.figure(figsize=(10,4))
plt.plot(time, wave_data,c="g")
plt.xlabel("time (seconds)")
plt.ylabel("Amplitude")
plt.grid()
plt.show()
波形图如下:
二、语音信号处理
要对语音信号进行分析,首先要对语音信号提取出可表示该语音本质的特征参数。有了特征参数才可能利用这些参数进行有效的处理。所以语音分析、提取特征参数是语音信号处理的基础。在语音信号处理后,语音质量的高低不仅取决于处理的方法,同时也取决于是否选择了合适的语音特征参数。因此,语音信号分析、特征参数的提取在语音信号处理应用中具有十分重要的地位。
在短时分析中,将语音信号分为一段- -段地来分析其特征参数,其中每- -段称为一“帧”,帧长一般取10~30ms。这样,对于整体的语音信号来讲,每–帧特征参数组成了特征参数时间序列。
根据提取参数的方法不同,可将语音信号分析分为时域分析、频域分析、倒频域分析和其,他域分析的方法;根据分析方法的不同,又可将语音信号分析分为模型分析方法和非模型分析方法两种。时域分析方法具有简单、计算量小、物理意义明确等优点,但由于语音信号最重要的感知特性反映在功率谱中,而相位变化只起着很小的作用,所以相对于时域分析来说频域分析更为重要。
模型分析法是指依据语音信号产生的数学模型,来分析和提取表征这些模型的特征参数,如共振峰分析及声管分析(即线性预测模型)法;而不按模型进行分析的其他方法都属于非模型分析法,包括上面提到的时域分析法、频域分析法及同态分析法(即倒频域分析法)等。
不论是分析怎样的参数以及采用什么分析方法,在按帧进行语音分析、提取语音参数之前,有一些经常使用的、共同的短时分析技术必须预先进行,如语音信号的数字化、预加重、加窗和分帧等,这些也是不可忽视的语音信号分析的关键技术。
1、信号分帧
为了分析读人数据,通常进行分帧处理。在分帧中,往往设置在相邻两帧之间有一部分重叠。其原因是:语音信号是时变的,在短时范围内特征变化较小,所以作为稳态来处理;但超出这短时范围语音信号就有变化了。在相邻两帧之间基音发生了变化,如正好是两个音节之间, 或正好是声母向韵母过渡,等等,这时,其特征参数有可能变化较大,但为了使特征参数平滑地变化,在两个不重叠的帧之间插一些帧来提取特征参数,这就形成了相邻帧之间有重叠部分。
wlen为帧长,inc为帧移,重叠部分为overlap,overlap=wlen - inc
信号帧数为:
f
n
=
(
N
−
o
v
e
r
l
a
p
)
/
i
n
c
=
(
N
−
w
l
e
n
)
/
i
n
c
+
1
fn=(N-overlap)/inc=(N-wlen)/inc+1
fn=(N−overlap)/inc=(N−wlen)/inc+1
N为语音数据长度。
每一帧的起始点的位置为:
s
t
a
r
t
i
n
d
e
x
=
(
0
:
(
f
n
−
1
)
)
∗
i
n
c
+
1
startindex=(0:(fn-1))*inc+1
startindex=(0:(fn−1))∗inc+1
下面上代码:
第一部分:语音的读取
import numpy as np
import wave
import matplotlib.pyplot as plt
wlen=512
inc=128
f = wave.open(r"lantian.wav", "rb")
params = f.getparams()
nchannels, sampwidth, framerate, nframes = params[:4]
str_data = f.readframes(nframes)
wave_data = np.fromstring(str_data, dtype=np.short)
wave_data = wave_data*1.0/(max(abs(wave_data)))
语音的读取在上面讲过,这里就不再啰嗦了。
第二部分:语音分帧
signal_length=len(wave_data) #信号总长度
python中len()读取序列的长度,这里是读取语音信号的总长度。
if signal_length<=wlen: #若信号长度小于一个帧的长度,则帧数定义为1
nf=1
else: #否则,计算帧的总长度
nf=int(np.ceil((1.0*signal_length-wlen+inc)/inc))
wlen为每一帧信号的长度,inc为帧移,nf为分的帧数(前面讲过)
当信号的长度还没有一帧长的时候,设定帧数为1,否则用上面讲过的这个公式
f
n
=
(
N
−
o
v
e
r
l
a
p
)
/
i
n
c
=
(
N
−
w
l
e
n
)
/
i
n
c
+
1
fn=(N-overlap)/inc=(N-wlen)/inc+1
fn=(N−overlap)/inc=(N−wlen)/inc+1
pad_length=int((nf-1)*inc+wlen) #所有帧加起来总的铺平后的长度
zeros=np.zeros((pad_length-signal_length,)) #不够的长度使用0填补,类似于FFT中的扩充数组操作
pad_signal=np.concatenate((wave_data,zeros)) #填补后的信号记为pad_signal
因为上面np.ceil向上取整,所以会导致实际分帧后的长度大于信号本身的长度,所以要对原来的信号进行补零,类似与FFT变换中的数据点不够补零达到采样点的数量。
np.zeros()创建一个0矩阵
np.concatenate()连接两个维度相同的矩阵
indices=np.tile(np.arange(0,wlen),(nf,1))+np.tile(np.arange(0,nf*inc,inc),(wlen,1)).T #相当于对所有帧的时间点进行抽取,得到nf*wlen长度的矩阵
先看一下np.tile的用法:
print(indices[:2])
[[ 0 1 2 ... 509 510 511]
[128 129 130 ... 637 638 639]]
输出矩阵前两行的结果。
indices=np.array(indices,dtype=np.int32) #将indices转化为矩阵
frames=pad_signal[indices] #得到帧信号
a=frames[30:31]
print(a[0])
将语音信号转化为nf*wlen矩阵的形式,并输出第30行的数据值
[ 0.21035823 -0.07234102 -0.09955568 -0.12649264 -0.23299084 -0.29533463
-0.27006387 -0.23229658 -0.18786448 -0.20924743 -0.30880311 -0.32116079
-0.33560122 -0.35323521 -0.38128298 -0.3700361 -0.34337684 -0.3457373
-0.34212719 -0.29533463 -0.25715079 -0.23715635 -0.22410442 -0.24368231
-0.22271591 -0.1973063 -0.18133852 -0.1959178 -0.18314357 -0.1291308
-0.09830603 -0.0849764 -0.06873091 -0.04012774 -0.00916412 -0.02415996
-0.01430158 -0.01235768 -0.01666204 -0.00249931 -0.03457373 -0.04998611
-0.03443488 -0.02624271 -0.01971675 -0.02485421 -0.0223549 -0.00208275
0.00333241 0.02415996 0.03915579 0.04998611 0.09372397 0.11163566
0.11955012 0.15523466 0.17633991 0.19105804 0.20397112 0.23424049
0.25284643 0.24493196 0.25326298 0.27006387 0.28519856 0.28603166
0.30852541 0.31796723 0.31491252 0.32338239 0.31033046 0.29005832
0.3239378 0.32518745 0.34726465 0.35753957 0.3678145 0.29047487
0.18119967 0.13468481 0.05901139 -0.01457928 -0.07914468 -0.14343238
-0.16273257 -0.18356012 -0.22688142 -0.27506248 -0.33643432 -0.36156623
-0.35892808 -0.36642599 -0.3485143 -0.31685643 -0.30560955 -0.28103305
-0.27048042 -0.27381283 -0.2624271 -0.27381283 -0.2831158 -0.26881422
-0.25576229 -0.23090808 -0.21341294 -0.20341572 -0.18550403 -0.16606498
-0.13565676 -0.1087198 -0.07942238 -0.04748681 -0.03374063 -0.01791169
-0.01791169 -0.023188 -0.00541516 0.01207998 0.02249375 0.02874202
0.03360178 0.04568176 0.04346015 0.04582061 0.05290197 0.05401277
0.06845321 0.06873091 0.06109414 0.08455984 0.10580394 0.12177173
0.1299639 0.14537628 0.17370175 0.21244099 0.25326298 0.27881144
0.28922522 0.29575118 0.29950014 0.30213829 0.33088031 0.34087753
0.34670925 0.37670092 0.38600389 0.40072202 0.41918911 0.41599556
0.34323799 0.31144127 0.26450986 0.16106637 0.10080533 0.01666204
-0.04665371 -0.08275479 -0.16675923 -0.23507359 -0.30213829 -0.37711747
-0.43557345 -0.47334074 -0.49569564 -0.49264093 -0.47945015 -0.4790336
-0.43599 -0.42710358 -0.42210497 -0.39114135 -0.38031102 -0.34518189
-0.27811719 -0.24409886 -0.197584 -0.1514857 -0.12163288 -0.07733963
-0.04429325 -0.00999722 0.03193557 0.06498195 0.08539295 0.09788948
0.10885865 0.12801999 0.1324632 0.13426826 0.13662871 0.12760344
0.11357956 0.09691752 0.07858928 0.0670647 0.05609553 0.03860039
0.02874202 0.02443766 0.03026937 0.03762844 0.04123854 0.05123577
0.07845043 0.11205221 0.13204665 0.15745626 0.19327964 0.22049431
0.26312136 0.29464038 0.31546793 0.39558456 0.44390447 0.4569564
0.43362955 0.41183005 0.44695918 0.4357123 0.32907526 0.16537073
0.11524577 0.0430436 -0.03360178 -0.11469036 -0.19161344 -0.26326021
-0.34046098 -0.3929464 -0.42085532 -0.4566787 -0.46084421 -0.46612052
-0.46098306 -0.44154402 -0.44029436 -0.43071369 -0.41835601 -0.38308803
-0.33698973 -0.30394335 -0.25659539 -0.21868925 -0.18841988 -0.13551791
-0.10066648 -0.05109692 0.00499861 0.0441544 0.0885865 0.1296862
0.15245765 0.16023327 0.16925854 0.17161899 0.18425437 0.19466815
0.18717023 0.16995279 0.1523188 0.1319078 0.11816162 0.1067759
0.09622327 0.08705915 0.08705915 0.09594557 0.10413774 0.11371841
0.13482366 0.16023327 0.18078312 0.20438767 0.24812552 0.28672591
0.32921411 0.39933352 0.42029992 0.39975007 0.39975007 0.35309636
0.27089697 0.21535685 0.13773952 0.06123299 0.02457651 -0.07039711
-0.14162733 -0.21133019 -0.30199944 -0.35281866 -0.41821716 -0.43501805
-0.4343238 -0.4580672 -0.43446265 -0.41960567 -0.42613163 -0.40377673
-0.38739239 -0.38697584 -0.34809775 -0.30713691 -0.28686476 -0.22979728
-0.1945293 -0.16425993 -0.11024715 -0.07817273 -0.03596223 0.02624271
0.06053874 0.09900028 0.12649264 0.13996112 0.16259372 0.17036934
0.17870036 0.17564565 0.16037212 0.16495418 0.15467926 0.13746182
0.12718689 0.11566232 0.11635657 0.12274368 0.13287976 0.14981949
0.16481533 0.18661483 0.21494029 0.23146348 0.2613163 0.31338517
0.35365176 0.41571786 0.46542627 0.4566787 0.43946126 0.41641211
0.36934185 0.32366009 0.24201611 0.16953624 0.1084421 0.03207442
-0.04748681 -0.11510691 -0.21896695 -0.31407942 -0.37322966 -0.42835324
-0.44806998 -0.46348237 -0.48944738 -0.47000833 -0.46959178 -0.46570397
-0.46098306 -0.45917801 -0.42807553 -0.39780616 -0.3476812 -0.31991114
-0.28866981 -0.25298528 -0.23201888 -0.18064427 -0.13315746 -0.0874757
-0.01360733 0.03304638 0.07775618 0.11441266 0.13926687 0.16384338
0.17633991 0.18717023 0.1973063 0.20077756 0.19855596 0.19202999
0.18078312 0.18203277 0.18841988 0.19522355 0.20522077 0.20494307
0.21146904 0.23673979 0.26062205 0.28769786 0.33310192 0.37961677
0.44015551 0.49194668 0.4779228 0.456401 0.42307692 0.36434324
0.31116357 0.23673979 0.15662316 0.09844488 0.01471813 -0.06914746
-0.13065815 -0.23410164 -0.31255207 -0.38044988 -0.43140794 -0.44862538
-0.46681477 -0.46903638 -0.44862538 -0.4351569 -0.43126909 -0.43001944
-0.41668981 -0.41571786 -0.38156068 -0.33851708 -0.31630103 -0.27950569
-0.25312413 -0.22479867 -0.17800611 -0.13635101 -0.08372674 -0.0217995
0.0195779 0.06498195 0.09844488 0.12135518 0.13690641 0.15579006
0.17023049 0.18217162 0.18286587 0.17856151 0.16578728 0.16509303
0.17342405 0.18536518 0.19966676 0.20938628 0.22757567 0.25853929
0.28131075 0.31046931 0.36239933 0.4125243 0.4793113 0.49347403
0.46709247 0.44598723 0.40544293 0.36795335 0.29852819 0.22799222
0.1537073 0.05567898 -0.03068592 -0.1106637 -0.20980283 -0.2828381
-0.36101083 -0.41557901 -0.45487365 -0.49389059 -0.51194113 -0.50263816
-0.49569564 -0.46834213 -0.47375729 -0.4583449 -0.4547348 -0.43057484
-0.38336573 -0.35448487 -0.305193 -0.27631214 -0.23687864 -0.18480978
-0.14593169 -0.08192169 -0.01943904 0.03499028 0.09358512 0.12621494
0.16342683 0.18647598 0.20924743 0.23243543 0.24548736 0.25312413
0.25617884 0.25006943 0.24382116 0.2406276 0.24645932 0.24909747
0.258817 0.27881144 0.30311025 0.33754513 0.38489309 0.43723966
0.47375729 0.45653985]
这就是第30帧语音的数据。
画出一帧信号的时域图像:
import numpy as np
import wave
import matplotlib.pyplot as plt
wlen=512
inc=128
f = wave.open(r"lantian.wav", "rb")
params = f.getparams()
nchannels, sampwidth, framerate, nframes = params[:4]
str_data = f.readframes(nframes)
wave_data = np.fromstring(str_data, dtype=np.short)
wave_data = wave_data*1.0/(max(abs(wave_data)))
print(wave_data[:10])
time = np.arange(0, wlen) * (1.0 / framerate)
signal_length=len(wave_data) #信号总长度
if signal_length<=wlen: #若信号长度小于一个帧的长度,则帧数定义为1
nf=1
else: #否则,计算帧的总长度
nf=int(np.ceil((1.0*signal_length-wlen+inc)/inc))
pad_length=int((nf-1)*inc+wlen) #所有帧加起来总的铺平后的长度
zeros=np.zeros((pad_length-signal_length,)) #不够的长度使用0填补,类似于FFT中的扩充数组操作
pad_signal=np.concatenate((wave_data,zeros)) #填补后的信号记为pad_signal
indices=np.tile(np.arange(0,wlen),(nf,1))+np.tile(np.arange(0,nf*inc,inc),(wlen,1)).T #相当于对所有帧的时间点进行抽取,得到nf*nw长度的矩阵
print(indices[:2])
indices=np.array(indices,dtype=np.int32) #将indices转化为矩阵
frames=pad_signal[indices] #得到帧信号
a=frames[30:31]
print(a[0])
plt.figure(figsize=(10,4))
plt.plot(time,a[0],c="g")
plt.grid()
plt.show()
图像如下:
2、信号加窗
矩形窗:
w
(
n
)
=
{
1
,
0
<
=
n
<
L
−
1
0
,
其
他
w(n)=\begin{cases}1,\qquad0<=n<L-1\\ 0,\qquad其他 \end{cases}
w(n)={1,0<=n<L−10,其他
海宁窗:
w
(
n
)
=
{
0.5
(
1
−
c
o
s
(
2
π
n
/
(
L
−
1
)
)
)
,
0
<
=
n
<
L
−
1
0
,
其
他
w(n)=\begin{cases}0.5(1-cos(2\pi n/(L-1))),\qquad0<=n<L-1\\ 0,\qquad其他 \end{cases}
w(n)={0.5(1−cos(2πn/(L−1))),0<=n<L−10,其他
汉明窗:
w
(
n
)
=
{
0.54
−
0.46
c
o
s
(
2
π
n
/
(
L
−
1
)
)
,
0
<
=
n
<
L
−
1
0
,
其
他
w(n)=\begin{cases}0.54-0.46cos(2\pi n/(L-1)),\qquad0<=n<L-1\\ 0,\qquad其他 \end{cases}
w(n)={0.54−0.46cos(2πn/(L−1)),0<=n<L−10,其他
其中窗长为L。
通常对信号截断、分帧需要加窗,因为截断都有频域能量泄露,而窗函数可以减少截断带来的影响。窗函数在scipy.signal信号处理工具箱中,如hanning窗:
import matplotlib.pyplot as plt
import scipy.signal as signal
plt.figure(figsize=(6,2))
plt.plot(signal.hanning(512))
plt.grid()
plt.show()
输出结果:
在语音处理中进行分帧,相当于乘以一个有限长的窗函数
y
(
n
)
=
∑
x
=
−
∞
∞
x
(
m
)
w
(
n
−
m
)
y(n)=\sum_{x=-\infty}^{\infty}x(m)w(n-m)
y(n)=x=−∞∑∞x(m)w(n−m)
是卷积形式,因此可以理解为离散信号x(m)经过一个单位冲激函数响应为w(m)的FIR滤波器产生的输出。
直接上代码:
mport numpy as np
import wave
import matplotlib.pyplot as plt
wlen=512
inc=128
f = wave.open(r"lantian.wav", "rb")
params = f.getparams()
nchannels, sampwidth, framerate, nframes = params[:4]
str_data = f.readframes(nframes)
wave_data = np.fromstring(str_data, dtype=np.short)
wave_data = wave_data*1.0/(max(abs(wave_data)))
print(wave_data[:10])
time = np.arange(0, wlen) * (1.0 / framerate)
signal_length=len(wave_data) #信号总长度
if signal_length<=wlen: #若信号长度小于一个帧的长度,则帧数定义为1
nf=1
else: #否则,计算帧的总长度
nf=int(np.ceil((1.0*signal_length-wlen+inc)/inc))
pad_length=int((nf-1)*inc+wlen) #所有帧加起来总的铺平后的长度
zeros=np.zeros((pad_length-signal_length,)) #不够的长度使用0填补,类似于FFT中的扩充数组操作
pad_signal=np.concatenate((wave_data,zeros)) #填补后的信号记为pad_signal
indices=np.tile(np.arange(0,wlen),(nf,1))+np.tile(np.arange(0,nf*inc,inc),(wlen,1)).T #相当于对所有帧的时间点进行抽取,得到nf*nw长度的矩阵
print(indices[:2])
indices=np.array(indices,dtype=np.int32) #将indices转化为矩阵
frames=pad_signal[indices] #得到帧信号
a=frames[30:31]
print(a[0])
windown=np.hanning(wlen) #调用汉明窗
b=a[0]*windown
plt.figure(figsize=(10,4))
plt.plot(time,b,c="g")
plt.grid()
plt.show()
加窗之后的图像为:
3、短时能量
短时能量主要用于区分浊音段和清音段
计算第i帧语音信号yi(n)的短时能量公式为
y
(
n
)
=
∑
n
=
0
L
−
1
y
i
2
(
n
)
,
1
<
=
i
<
=
f
n
y(n)=\sum_{n=0}^{L-1}y_i^2(n),\qquad1<=i<=fn
y(n)=n=0∑L−1yi2(n),1<=i<=fn
求上面一帧语音的短时能量,直接上代码
import numpy as np
import wave
import matplotlib.pyplot as plt
wlen=512
inc=128
f = wave.open(r"lantian.wav", "rb")
params = f.getparams()
nchannels, sampwidth, framerate, nframes = params[:4]
str_data = f.readframes(nframes)
#print(str_data[:10])
wave_data = np.fromstring(str_data, dtype=np.short)
#print(wave_data[:10])
wave_data = wave_data*1.0/(max(abs(wave_data)))
print(wave_data[:10])
time = np.arange(0, wlen) * (1.0 / framerate)
signal_length=len(wave_data) #信号总长度
if signal_length<=wlen: #若信号长度小于一个帧的长度,则帧数定义为1
nf=1
else: #否则,计算帧的总长度
nf=int(np.ceil((1.0*signal_length-wlen+inc)/inc))
pad_length=int((nf-1)*inc+wlen) #所有帧加起来总的铺平后的长度
zeros=np.zeros((pad_length-signal_length,)) #不够的长度使用0填补,类似于FFT中的扩充数组操作
pad_signal=np.concatenate((wave_data,zeros)) #填补后的信号记为pad_signal
indices=np.tile(np.arange(0,wlen),(nf,1))+np.tile(np.arange(0,nf*inc,inc),(wlen,1)).T #相当于对所有帧的时间点进行抽取,得到nf*nw长度的矩阵
print(indices[:2])
indices=np.array(indices,dtype=np.int32) #将indices转化为矩阵
frames=pad_signal[indices] #得到帧信号
a=frames[30:31]
print(a[0])
windown=np.hanning(512)
b=a[0]*windown
c=np.square(b)
plt.figure(figsize=(10,4))
plt.plot(time,c,c="g")
plt.grid()
plt.show()
短时能量图像为