语音信号实现分帧、加窗、预处理

  • 音频文件读取
  • 预加重
  • 分帧
  • 加窗

音频文件读取

librosa是非常强大的python语音信号处理库。
读取音频:
使用语句librosa.load(path, sr=22050, mono=True, offset=0.0, duration=None)读取音频文件,默认的采样率是22050,若要保留音频的原始采样率,使用sr=None。

其中:
path:表示音频文件的路径
sr:表示采样率
mono:bool,是布尔类型,表示是否将信号转换为单声道
offset:float,后面跟的是浮点型,表示在此时间之后开始阅读(以秒为单位)
duration:float,表示的是持续时间,也就是只加载这么长的音频(单位为秒)
y:返回的y值表示音频时间序列
sr:表示的是音频的采样率

读取音频时长:
语句librosa.get_duration(y=None, sr=8000, S=None, n_fft=2048, hop_length=512, center=True, filename=None)来计算时间序列的持续时间(单位为秒)。
其中:
y:音频时间序列
sr:y的音频采样率
S:STFT矩阵或任何STFT衍生的矩阵(例如,色谱图或梅尔频谱图)
n_fft:S的 FFT窗口大小
hop_length:S列之间的音频样本数
center :布尔值,如果为True,则S [:, t]的中心为y [t * hop_length];如果为False,则S [:, t]从y[t * hop_length]开始
filename:如果提供,则所有其他参数都将被忽略,并且持续时间是直接从音频文件中计算得出的,返回的是持续时间(单位为秒)(librosa.get_duration(filename=’path’))

如以音频文件bluesky1.wav文件为例,使用python读取音频文件:

# 读取音频文件import numpy as np
import librosa.display  # 导入音频及绘图显示包
import matplotlib.pyplot as plt  # 导入绘图工作的函数集合# 读取语音文件并绘制波形图
times = librosa.get_duration(filename='D:\任务\Bluesky1.wav')  # 获取音频时长
# 返回音频采样数组及采样率
y, sr = librosa.load('D:\任务\Bluesky1.wav', sr=8000, offset=0.0, duration=None)
x = np.arange(0, times, 1/sr)  # 时间刻度
plt.plot(x, y)
plt.xlabel('times')  # x轴时间
plt.ylabel('amplitude')  # y轴振幅
plt.title('bluesky1.wav', fontsize=12, color='black')  # 标题名称、字体大小、颜色
plt.show()

读取之后的结果:

预加重

信号分析中采用的预加重技术,就是在对信号取样以后,插入一个一阶的高通滤波器,使声门脉冲的影响减到最小,只剩下声道部分。也就是对语音信号进行高频提升,用一阶FIR滤波器表示:
s′(n)=s(n)-as(n-1)(a为常数){s}^ {'} (n)=s(n)-as(n-1) \quad (a为常数)s′(n)=s(n)-as(n-1)(a为常数)
预加重的作用:
增加一个零点,抵消声门脉冲引起的高端频谱幅度下跌,使信号频谱变得平坦及各共振幅度相接近,语音中只剩下声道中的影响,所提取的特征更加符合元声道的模型。

插入一个一阶高通滤波器,把高频提升的同时也把低频部分也进行了衰减,使有些基频赋值较大时,通过预加重后,降低基频对共振峰检测的干扰,同时也减少了频谱的动态范围。
程序代码:

'''预加重'''
# 读取音频文件
import numpy as np
import librosa.display  # 导入音频及绘图显示包
import matplotlib.pyplot as plt  # 导入绘图工作的函数集合
# 读取语音文件并绘制波形图
times = librosa.get_duration(filename='D:\任务\Bluesky1.wav')  # 获取音频时长
# 返回音频采样数组及采样率
y, sr = librosa.load('D:\任务\Bluesky1.wav', sr=8000, offset=0.0, duration=None)
x = np.arange(0, times, 1/sr)  # 时间刻度
plt.plot(x, y)
plt.xlabel('times')  # x轴时间
plt.ylabel('amplitude')  # y轴振幅
plt.title('bluesky1.wav', fontsize=12, color='black')  # 标题名称、字体大小、颜色
plt.show()# 预加重
def pre_fun(x):  # 定义预加重函数signal_points=len(x)  # 获取语音信号的长度signal_points=int(signal_points)  # 把语音信号的长度转换为整型# s=x  # 把采样数组赋值给函数s方便下边计算for i in range(1, signal_points, 1):# 对采样数组进行for循环计算x[i] = x[i] - 0.98 * x[i - 1]  # 一阶FIR滤波器return x  # 返回预加重以后的采样数组
pre_emphasis = pre_fun(y)  # 函数调用
plt.plot(x, pre_emphasis)  # 绘出图形
plt.xlabel('times')  # x轴时间
plt.ylabel('amplitude')  # y轴振幅
plt.title('pre_emphasis-bluesky1.wav', fontsize=12, color='black')  # 标题名称、字体大小、颜色
plt.show()  # 显示

预加重以后的图像:

可以看出预加重以后的图像与原图像相比较,原图像的幅值很大,在预加重以后的频谱中,对基频谱线幅值有一定的抑制,高频端的幅值有所提升。

分帧

分帧就是将原始语音信号分成大小固定的N段语音信号,这里每一段语音信号都被称为一帧,帧长一般取10到30ms。分帧一般采用交叠分段的方法,是为了使帧与帧之间平滑过渡,保持其连续性。前一帧和后一帧的交叠部分称为帧移,帧移与帧长的比值一般取为0-1/2。

对于长为N的语音信号进行分帧:
fn=N−lframemframe+1{f}_{n}= \frac{N-lframe}{mframe}+1 fn​=mframeN−lframe​+1
数据将会被分成fn帧,每一帧在数据y中的位置为:

startindex = (0 ~ (fn - 1)) * inc +1

我们对一段语音进行分帧操作:

'''分帧'''
import numpy as np
import librosa.display  # 导入音频及绘图显示包
import matplotlib.pyplot as plt  # 导入绘图工作的函数集合# 读取音频文件
# 读取语音文件并绘制波形图
times = librosa.get_duration(filename='D:\任务\Bluesky1.wav')  # 获取音频时长
# 返回音频采样数组及采样率
y, sr = librosa.load('D:\任务\Bluesky1.wav', sr=8000, offset=0.0, duration=None)
x = np.arange(0, times, 1/sr)  # 时间刻度
# 绘制图形
plt.plot(x, y)
plt.xlabel('times')  # x轴时间
plt.ylabel('amplitude')  # y轴振幅
plt.title('bluesky1.wav', fontsize=12, color='black')  # 标题名称、字体大小、颜色
plt.show()# 分帧
def frame(x, lframe, mframe):  # 定义分帧函数signal_length = len(x)  # 获取语音信号的长度fn = (signal_length-lframe)/mframe  # 分成fn帧fn1 = np.ceil(fn)  # 将帧数向上取整,如果是浮点型则加一fn1 = int(fn1)  # 将帧数化为整数# 求出添加的0的个数numfillzero = (fn1*mframe+lframe)-signal_length# 生成填充序列fillzeros = np.zeros(numfillzero)# 填充以后的信号记作fillsignalfillsignal = np.concatenate((x,fillzeros))  # concatenate连接两个维度相同的矩阵# 对所有帧的时间点进行抽取,得到fn1*lframe长度的矩阵dd = np.tile(np.arange(0, lframe), (fn1, 1)) + np.tile(np.arange(0, fn1*mframe, mframe), (lframe, 1)).T# 将d转换为矩阵形式(数据类型为int类型)d = np.array(d, dtype=np.int32)signal = fillsignal[d]return(signal, fn1, numfillzero)
lframe = int(sr*0.025)  # 帧长(持续0.025秒)
mframe = int(sr*0.001)  # 帧移
# 函数调用,把采样数组、帧长、帧移等参数传递进函数frame,并返回存储于endframe、fn1、numfillzero中
endframe, fn1, numfillzero = frame(y, lframe, mframe)# 显示第1帧波形图
x1 = np.arange(0, lframe, 1)  # 第1帧采样点刻度
x2 = np.arange(0, lframe/sr, 1/sr)  # 第1帧时间刻度
# 显示波形图
plt.figure()
plt.plot(x1, endframe[0])
plt.xlabel('points')  # x轴
plt.ylabel('wave')  # y轴
plt.title('bluesky1 firstframe  wave', fontsize=12, color='black')
plt.show()
plt.figure()
plt.plot(x2, endframe[0])
plt.xlabel('time')  # x轴
plt.ylabel('wave')  # y轴
plt.title('bluesky1 firstframe  wave', fontsize=12, color='black')
plt.show()

运行之后首先读取音频文件,然后返回采样数组存储于y中,然后输出音频的波形图。然后进行分帧,分帧之后输出显示第一帧波形,x轴为第一帧采样点刻度:

输出显示第一帧波形,x轴为第一帧时间刻度:

加窗

在信号分帧后,为了使帧与帧之间平滑过渡,保持连续性,也就是消除各个帧两端可能会造成的信号不连续性(即谱泄露 spectral leakage),对信号截断、分帧需要加窗,因为截断有频域能量泄露,而窗函数可以减少截断带来的影响。我们将每一帧带入窗函数,形成加窗语音信号s_w(n)=s(n)*w(n),在语音处理中常用的为矩形窗和汉明窗。

矩形窗:
f(x)={10 <=n<=L-10其他f(x)= \begin{cases} 1& \text{0 <=n<=L-1}\\ 0& \text{其他} \end{cases}f(x)={10​0 <=n<=L-1其他​
汉明窗:
f(x)={0.54−0.46cos(2πn/(L−1))0 <=n<=L-10其他f(x)= \begin{cases} 0.54 - 0.46cos(2πn/(L-1))& \text{0 <=n<=L-1}\\ 0& \text{其他} \end{cases}f(x)={0.54−0.46cos(2πn/(L−1))0​0 <=n<=L-1其他​
紧接着上面的分帧后,我们继续对第一帧信号进行加窗:

'''加窗'''
import numpy as np
import librosa.display  # 导入音频及绘图显示包
import matplotlib.pyplot as plt  # 导入绘图工作的函数集合# 读取音频文件
# 读取语音文件并绘制波形图
times = librosa.get_duration(filename='D:\任务\Bluesky1.wav')  # 获取音频时长
# 返回音频采样数组及采样率
y, sr = librosa.load('D:\任务\Bluesky1.wav', sr=8000, offset=0.0, duration=None)
# x = np.arange(0, times, 1/sr)  # 时间刻度# 分帧
def frame(x, lframe, mframe):  # 定义分帧函数signal_length = len(x)  # 获取语音信号的长度fn = (signal_length-lframe)/mframe  # 分成fn帧fn1 = np.ceil(fn)  # 将帧数向上取整,如果是浮点型则加一fn1 = int(fn1)  # 将帧数化为整数# 求出添加的0的个数numfillzero = (fn1*mframe+lframe)-signal_length# 生成填充序列fillzeros = np.zeros(numfillzero)# 填充以后的信号记作fillsignalfillsignal = np.concatenate((x,fillzeros))  # concatenate连接两个维度相同的矩阵# 对所有帧的时间点进行抽取,得到fn1*lframe长度的矩阵dd = np.tile(np.arange(0, lframe), (fn1, 1)) + np.tile(np.arange(0, fn1*mframe, mframe), (lframe, 1)).T# 将d转换为矩阵形式(数据类型为int类型)d = np.array(d, dtype=np.int32)signal = fillsignal[d]return(signal, fn1, numfillzero)
lframe = int(sr*0.025)  # 帧长(持续0.025秒)
mframe = int(sr*0.001)  # 帧移
# 函数调用,把采样数组、帧长、帧移等参数传递进函数frame,并返回存储于endframe、fn1、numfillzero中
endframe, fn1, numfillzero = frame(y, lframe, mframe)# 对第一帧进行加窗
hanwindow = np.hanning(lframe)  # 调用汉明窗,把参数帧长传递进去
signalwindow = endframe[0]*hanwindow  # 第一帧乘以汉明窗
x1 = np.arange(0, lframe, 1)  # 第一帧采样点刻度
x2 = np.arange(0, lframe/sr, 1/sr)  # 第一帧时间刻度
# 显示波形图
plt.figure()
plt.plot(x1, signalwindow)
plt.xlabel('point')  # x轴
plt.ylabel('wave')  # y轴
plt.title('firstflame hanningwindow wave', fontsize=12, color='black')
plt.show()
plt.figure()
plt.plot(x2, signalwindow)
plt.xlabel('times')  # x轴
plt.ylabel('wave')  # y轴
plt.title('firstflame hanningwindow wave', fontsize=12, color='black')
plt.show()

运行之后对第一帧信号进行加窗,输出显示第一帧波形,x轴为第一帧采样点刻度:

输出显示第一帧波形,x轴为第一帧时间刻度:

python实现语音信号的分帧、加窗、预处理相关推荐

  1. 语音信号的分帧加窗的matlab实现

    [x,fs,nbits]=wavread('5_1.wav'); x1=enframe(x,200,100);%分帧 x2=enframe(x,hamming(200),100);%加窗 figure ...

  2. matlab语音分帧加窗,语音信号的加窗处理

    平稳的随机过程是研究语音信号的主要手段,但是语音信号本身并不是平衡的. 一,语音信号不平稳 语音信号在产生过程中与环境和发声器官的联系很紧密,与各种运动都是相关的,信号本身是不平移的信号.主要是由于发 ...

  3. 语音信号的分帧、加窗处理

    分帧 语音信号是一个准稳态的信号,若把它分成较短的帧,每帧中可将其看做稳态信号,可用处理稳态信号的方法来处理.为了使一帧与另一帧之间的参数能够平稳过渡,应在相邻两帧之间互相有部分重叠.一般情况下,帧长 ...

  4. 声纹技术(二):音频信号处理基础【模拟信号(连续)--采样-->数字信号(离散)--量化-->振幅简化为整数--编码-->二进制序列】【WAV音频格式】【SoX】【分帧-加窗-】

    2.1 欲懂声纹,先学音频 从学科分类上讲,声纹技术是语音信号处理的一个分支,而语音信号处理则属于音频信号处理这个大类. 语音信号和音频信号,这二者的区别在于: 语音信号专指人类说话时所发出的具有社会 ...

  5. 语音信号的预加重和加窗处理

    一.语音信号的预加重 语音信号的预加重,目的是为了对语音的高频部分进行加重,去除口唇辐射的影响,增加语音的高频分辨率.一般通过传递函数为一阶FIR高通数字滤波器来实现预加重,其中a为预加重系数,0.9 ...

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

    python对语音信号读取.分帧.加窗 一.读入音频信号 语音信号有三个重要的参数:声道数.取样频率和量化位数. 声道数:单声道或者双声道 采样频率:一秒钟对声音采样的次数,例如10000HZ代表一秒 ...

  7. Unity 分帧加载和分块加载

    #分帧加载和分块加载 在我们实际做项目的时候,往往会遇见需要创建大量数据的时候,这时如果在一帧里面大量创建数据,那我们的游戏就会发生卡顿从而降低了用户的体验. 为了解决这种情况,可以使用使用分帧加载使 ...

  8. python求语音信号短时能量、短时过零率、语谱图

    python语音信号处理(二) 一.短时能量 短时能量主要用于区分浊音段和清音段,因为浊音时E(i)值比清音时大得多:区分声母与韵母的分界和无话段与有话段分界. 计算第i帧语音信号yi(n)的短时能量 ...

  9. 实验二 语音信号基本时频分析(待更改)

    实验二 语音信号基本时频分析 1.实验目的 1.1 学习与掌握语音信号的分帧及加窗 1.2 了解并分析信号加汉明窗及矩形窗后的差别 1.3 分析清音与浊音的时域及频谱域波形特征(画图.对比) 1.4 ...

  10. 利用函数wavread对语音信号进行采样_语音识别第4讲:语音特征参数MFCC

    一.MFCC概述[1] 在语音识别(SpeechRecognition)和话者识别(SpeakerRecognition)方面,最常用到的语音特征就是梅尔倒谱系数(Mel-scaleFrequency ...

最新文章

  1. java地铁线路规划_地铁线路规划——简单分析
  2. boost::spirit模块实现演示逗号分隔的数字列表的解析器的测试程序
  3. 那些年我在CSDN追过的安全白帽师傅,respect
  4. [书籍分享]0-003.你的灯亮着吗:发现问题的真正所在
  5. 解决问题 com.alibaba.fastjson.JSONObject cannot be cast to xxx
  6. flat在java中的含义_Java 9中Collectors.flatMapping()方法的重要性?
  7. flutter Radio 单选框
  8. Codeforces Round #246 (Div. 2) D. Prefixes and Suffixe 后缀数组
  9. Python入门-traceback
  10. iframe 父页面 子页面互相取值调用
  11. linux 间传输文件的几种方法scp、sftp
  12. 第七版(谢希仁)计算机网络 知识点总结
  13. matlab如何仿真递推型dft算法,并联型有源滤波器的设计与仿真
  14. java把date转化成yyyymmdd_jquery 将当前时间转换成yyyymmdd格式的实现方法
  15. 世界顶级职场中,为什么印度人可以做到CEO,中国人却最多只是架构师?
  16. python 3 三元表达式(三目表达式)
  17. 【日语】英语26个字母的日语读法
  18. 国家铁路局招聘面试题汇集
  19. (原创)分享一下最近搞的tiny210V2从nand启动支持(K9GAG08U0F).
  20. 服务(Service)

热门文章

  1. PMP备考错题集-模拟题二
  2. 入门OSPF就这一篇足够了
  3. 106、对待低优先级bug的可行方法
  4. LVS之ipvsadm命令
  5. android定时器课设报告,数显定时器课程设计报告.doc
  6. python使用Future、async、await、wait、gather、ensure_future、as_completed
  7. 分门别类刷leetcode——二叉查找树(C++实现)
  8. Python.习题八 文件与与异常(上)
  9. 一个整人的vbs脚本(yzy原创)
  10. 【webstorm】webstorm官网中文破解版