您好,欢迎来到五一七教育网。
搜索
您的当前位置:首页语音端点检测之相关法、谱熵法、比例法(python版)

语音端点检测之相关法、谱熵法、比例法(python版)

来源:五一七教育网

1、短时自相关 

自相关函数具有一些性质,如它是偶函数;假设序列具有周期性,则其自相关函数也是同周期的周期函数等。对于浊音语音可以用自相关函数求出语音波形序列的基音周期。此外, 在进行语音信号的线性预测分析时,也要用到自相关函数

 2、自相关函数最大值法

 

  4‐2 和图  4‐3 分别是噪声信号和含噪语音的自相关函数。从图可知,两种信号的自 相关函数存在极大的差异,因此可利用这种差别来提取语音端点。根据噪声的情况,设置两个阈值 T1 T2 ,当相关函数最大值大于 T2 时,便判定是语音;当相关函数最大值大于或小于 T1 时,则判定为语音信号的端点。
3.代码运行
from speechlib import *
(fs, data) = wavfile.read('C4_1_y.wav')

data = data - np.mean(data)
data = data / np.max(data)
IS = 0.25
wlen = 200
inc = 80
N = len(data)
time = [i / fs for i in range(N)]
wnd = np.hamming(wlen)  #使用汉明窗
NIS = int((IS * fs - wlen) // inc + 1)
thr1 = 1.1
thr2 = 1.3
voiceseg, vsl, SF, NF, Rum = vad_corr(data, wnd, inc, NIS, thr1, thr2)

fn = len(SF)
frameTime = FrameTimeC(fn, wlen, inc, fs)

plt.subplot(2, 1, 1)
plt.plot(time, data)
plt.title('纯语音波形')
plt.ylabel('幅值')

plt.subplot(2, 1, 2)
plt.plot(frameTime, Rum)
plt.title('短时自相关函数')
plt.xlabel('时间/s')
plt.ylabel('幅值')

for i in range(vsl):
    nx1=voiceseg[i]['start']
    nx2=voiceseg[i]['end']
    plt.subplot(2, 1, 1)
    plt.axvline(frameTime[nx1], np.min(data), np.max(data), color='blue', linestyle='--')
    plt.axvline(frameTime[nx2], np.min(data), np.max(data), color='red', linestyle='-')
    plt.legend(['波形', '起点', '终点'])

    plt.subplot(2, 1, 2)
    plt.axvline(frameTime[nx1], np.min(Rum), np.max(Rum), color='blue', linestyle='--')
    plt.axvline(frameTime[nx2], np.min(Rum), np.max(Rum), color='red', linestyle='-')
    plt.legend(['短时自相关', '起点', '终点'])

plt.show()

核心代码解释: 

名称:vad_corr 
功能:用自相关函数最大值法进行端点检测。
调用格式:[voiceseg,vsl,SF,NF,Rum]=vad_corr(x,wnd,inc,NIS,th1,th2) 
说明:输入参数 x 是输入的语音数据;wnd 是窗函数或窗长;inc 是帧移;th1 是端点检
测阈值;th2 是语音检测阈值;NIS 是无声段的帧数,用来计算阈值。输出参数 voiceseg 是
一个数据结构,记录了语音端点的信息;vsl 是 voiceseg 的长度;SF 是语音帧标志(SF=1 表
示该帧是语音段);NF 是噪声/无声帧标志(NF=1 表示该帧是噪声/无声段);Rum 是返回的
短时自相关序列的最大值。

 

 

 二、谱熵法

 还是理论(不想写)

1.谱熵特征

(1)语音信号的谱熵不同于噪声信号的谱熵。   

(2)理论上,如果谱的分布保持不变,语音信号幅值的大小不会影响归一化。但实际上,

语音谱熵随语音随机性而变化,与能量特征相比,谱熵的变化是很小的。

(3)在某种程度上讲,谱熵对噪声具有一定的稳健性,在相同的语音信号当信噪比降

低时,语音信号的谱熵值的形状大体保持不变,这说明谱熵是一个比较稳健性的特征参数。

(4)语音谱熵只与语音信号的随机性有关,而与语音信号的幅度无关,理论上认为只

要语音信号的分布不发生变化,那么语音谱熵不会受到语音幅度的影响。另外,由于每个频

率分量在求其概率密度函数的时侯都经过了归一化处理,所以从这一方面也证明了语音信号

的谱熵只会与语音分布有关,而不会与幅度大小有关。

2.谱熵检测大致思路

(1)首先对语音信号进行分帧加窗、取 FFT 变换的点数;

(2)计算出每一帧的谱的能量;

(3)计算出每一帧中每个样本点的概率密度函数;

(4)计算出每一帧的谱熵值;

(5)设置判决门限;

(6)根据各帧的谱熵值进行端点检测。

from speechlib import *

(fs, data) = wavfile.read('C4_1_y.wav')
data = data - np.mean(data)
data = data / np.max(data)
IS = 0.25
wlen = 200
inc = 80
N = len(data)
time = [i / fs for i in range(N)]
wnd = np.hamming(wlen)
overlap = wlen - inc
NIS = int((IS * fs - wlen) // inc + 1)
thr1 = 0.99
thr2 = 0.96
voiceseg, vsl, SF, NF, Enm = vad_specEN(data, wnd, inc, NIS, thr1, thr2, fs)

fn = len(SF)
frameTime = FrameTimeC(fn, wlen, inc, fs)

plt.subplot(2, 1, 1)
plt.plot(time, data)
plt.title('纯语音波形')
plt.ylabel('幅值')

plt.subplot(2, 1, 2)
plt.plot(frameTime, Enm)
plt.title('短时谱熵')
plt.xlabel('时间/s')
plt.ylabel('幅值')

for i in range(vsl):
    nx1=voiceseg[i]['start']
    nx2=voiceseg[i]['end']
    plt.subplot(2, 1, 1)
    plt.axvline(frameTime[nx1], np.min(data), np.max(data), color='blue', linestyle='--')
    plt.axvline(frameTime[nx2], np.min(data), np.max(data), color='red', linestyle='-')
    plt.legend(['波形', '起点', '终点'])

    plt.subplot(2, 1, 2)
    plt.axvline(frameTime[nx1], np.min(Enm), np.max(Enm), color='blue', linestyle='--')
    plt.axvline(frameTime[nx2], np.min(Enm), np.max(Enm), color='red', linestyle='-')
    plt.legend(['短时谱熵', '起点', '终点'])

plt.show()

核心代码解释

名称:vad_specEn 
功能:用谱熵法进行端点检测。
调用格式:[voiceseg,vsl,SF,NF,Enm]=vad_specEn(x,wnd,inc,NIS,th1,th2,fs) 
说明:输入参数 x 是输入的语音数据;wnd 是窗函数或窗长;inc 是帧移;th1 是端点检
测阈值;th2 是语音检测阈值;NIS 是无声段的帧数,用来计算阈值;fs 是采样频率。输出参
数 voiceseg 是一个数据结构,记录了语音端点的信息;vsl 是 voiceseg 的长度;SF 是语音帧
标志(SF=1 表示该帧是语音段);NF 是噪声/无声帧标志(NF=1 表示该帧是噪声/无声段);
Enm 是计算的谱熵

 结果

 三、比例法

from speechlib import *

(fs, data) = wavfile.read('C4_1_y.wav')
data = data - np.mean(data)
data = data / np.max(data)
IS = 0.25
wlen = 200
inc = 80
N = len(data)
time = [i / fs for i in range(N)]
wnd = np.hamming(wlen)
overlap = wlen - inc
NIS = int((IS * fs - wlen) // inc + 1)

mode = 1
if mode == 1:
    thr1 = 3
    thr2 = 4
    tlabel = '能零比'
elif mode == 2:
    thr1 = 0.05
    thr2 = 0.1
    tlabel = '能熵比'
voiceseg, vsl, SF, NF, Epara = vad_pro(data, wnd, inc, NIS, thr1, thr2, mode)

fn = len(SF)
frameTime = FrameTimeC(fn, wlen, inc, fs)

plt.subplot(2, 1, 1)
plt.plot(time, data)
plt.title('纯语音波形')
plt.ylabel('幅值')

plt.subplot(2, 1, 2)
plt.plot(frameTime, Epara)
plt.title(tlabel)
plt.xlabel('时间/s')
plt.ylabel('幅值')

for i in range(vsl):
    nx1=voiceseg[i]['start']
    nx2=voiceseg[i]['end']
    plt.subplot(2, 1, 1)
    plt.axvline(frameTime[nx1], np.min(data), np.max(data), color='blue', linestyle='--')
    plt.axvline(frameTime[nx2], np.min(data), np.max(data), color='red', linestyle='-')
    plt.legend(['波形', '起点', '终点'])

    plt.subplot(2, 1, 2)
    plt.axvline(frameTime[nx1], np.min(Epara), 1.0, color='blue', linestyle='--')
    plt.axvline(frameTime[nx2], np.min(Epara), 1.0, color='red', linestyle='-')
    plt.legend([tlabel, '起点', '终点'])

plt.show()

 

名称:vad_pro 
功能:用比例法进行端点检测。
调用格式:[voiceseg,vsl,SF,NF,Epara]=vad_pro(x,wnd,inc,NIS,th1,th2,mode);
说明:输入参数 x 是输入的语音数据;wnd 是窗函数或窗长;inc 是帧移;th1 是端点检
测阈值;th2 是语音检测阈值;NIS 是无声段的帧数,用来计算阈值;mode 是算法模式,1
代表能零比,2 代表能熵比。输出参数 voiceseg 是一个数据结构,记录了语音端点的信息;
vsl 是 voiceseg 的长度;SF 是语音帧标志(SF=1 表示该帧是语音段);NF 是噪声/无声帧标志
(NF=1 表示该帧是噪声/无声段);Epara 是计算的能零比或能熵比。

 

 四、总结

语音端点检测一共介绍了4种,双门限法、相关法、谱熵法、比例法

双门限法: 

核心参数部分:

1.双门限法
名称:vad_TwoThr 
功能:用双门限法进行端点检测。
调用格式:[voiceseg,vsl,SF,NF,amp,zcr]=vad_TwoThr(x,wlen,inc,NIS) 

2.相关法
名称:vad_corr 
功能:用自相关函数最大值法进行端点检测。
调用格式:[voiceseg,vsl,SF,NF,Rum]=vad_corr(x,wnd,inc,NIS,th1,th2) 
Rum 是返回的短时自相关序列的最大值。

3.谱熵法:
名称:vad_specEn 
功能:用谱熵法进行端点检测。
调用格式:[voiceseg,vsl,SF,NF,Enm]=vad_specEn(x,wnd,inc,NIS,th1,th2,fs) 
Enm 是计算的谱熵

4.比例法:
名称:vad_pro 
功能:用比例法进行端点检测。
调用格式:[voiceseg,vsl,SF,NF,Epara]=vad_pro(x,wnd,inc,NIS,th1,th2,mode);
mode 是算法模式,1代表能零比,2 代表能熵比。 Epara 是计算的能零比或能熵比。


共同参数解释:输出参数 voiceseg 是一个数据结构,记录了语音端点的信息;
vsl 是 voiceseg 的长度;SF 是语音帧标志(SF=1 表示该帧是语音段);NF 是噪声/无声帧标志

输入参数 x 是输入的语音数据;wnd 是窗函数或窗长;inc 是帧移;th1 是端点检
测阈值;th2 是语音检测阈值;NIS 是无声段的帧数,用来计算阈值;fs 是采样频率。

数据处理部分:

(fs, data) = wavfile.read('XXXXX.wav') #数据读入
data = data - np.mean(data) #np.mean 求平均数
data = data / np.max(data)
#数据归一化

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 517ttc.cn 版权所有 赣ICP备2024042791号-8

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务