python对语音信号读取、分帧、加窗

您所在的位置:网站首页 实现省份的三级联动 python对语音信号读取、分帧、加窗

python对语音信号读取、分帧、加窗

2023-10-23 11:42| 来源: 网络整理| 查看: 265

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工程文件目录下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PsAxDzIX-1572436638085)(C:\Users\jh\AppData\Roaming\Typora\typora-user-images\1572146308413.png)]

输入代码:

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、信号分帧

​ 为了分析读人数据,通常进行分帧处理。在分帧中,往往设置在相邻两帧之间有一部分重叠。其原因是:语音信号是时变的,在短时范围内特征变化较小,所以作为稳态来处理;但超出这短时范围语音信号就有变化了。在相邻两帧之间基音发生了变化,如正好是两个音节之间, 或正好是声母向韵母过渡,等等,这时,其特征参数有可能变化较大,但为了使特征参数平滑地变化,在两个不重叠的帧之间插一些帧来提取特征参数,这就形成了相邻帧之间有重叠部分。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fGTdvtze-1572436638086)(C:\Users\jh\AppData\Roaming\Typora\typora-user-images\1572159439550.png)]

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_length0.5(1−cos(2πn/(L−1))),0


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3