matlab实现端点检测
来源:互联网 发布:蓝月传奇神盾升级数据 编辑:程序博客网 时间:2024/06/11 03:13
端点检测
function [afterEndDet] =EndDetection(x) %================================i========================= % 端点检测 % Input:音频数据x,采样率fs % Output:经过端点检测提取的语音信号 %=========================================================%幅度归一化到[-1,1]x = double(x);x = x / max(abs(x));%常数设置FrameLen = 256;%帧长为256点FrameInc = 80;%帧移为80点amp1 = 10;%初始短时能量高门限amp2 = 2;%初始短时能量低门限zcr1 = 10;%初始短时过零率高门限zcr2 = 5;%初始短时过零率低门限maxsilence = 8; % 8*10ms = 80ms%语音段中允许的最大静音长度,如果语音段中的静音帧数未超过此值,则认为语音还没结束;如果超过了%该值,则对语音段长度count进行判断,若count<minlen,则认为前面的语音段为噪音,舍弃,跳到静音%状态0;若count>minlen,则认为语音段结束;minlen = 15; % 15*10ms = 150ms%语音段的最短长度,若语音段长度小于此值,则认为其为一段噪音status = 0; %初始状态为静音状态count = 0; %初始语音段长度为0silence = 0; %初始静音段长度为0%计算过零率x1=x(1:end-1);x2=x(2:end);%分帧tmp1=enframe(x1,FrameLen,FrameInc);tmp2=enframe(x2,FrameLen,FrameInc);signs = (tmp1.*tmp2)<0;diffs = (tmp1 -tmp2)>0.02;zcr = sum(signs.*diffs, 2);%一帧一个值%计算短时能量%一帧一个值%amp = sum(abs(enframe(filter([1 -0.9375], 1, x), FrameLen, FrameInc)), 2);amp = sum(abs(enframe(x, FrameLen, FrameInc)), 2);%调整能量门限amp1 = min(amp1, max(amp)/4);amp2 = min(amp2, max(amp)/8); %开始端点检测%For循环,整个信号各帧比较%根据各帧能量判断帧所处的阶段x1 = 0;x2 = 0;v_num=0;%记录语音段数v_Begin=[];%记录所有语音段的起点v_End=[];%记录所有语音段的终点%length(zcr)即为帧数for n=1:length(zcr) goto = 0; switch status case {0,1} % 0 = 静音, 1 = 可能开始 if amp(n) > amp1 % 确信进入语音段 x1 = max(n-count-1,1);% '打印每个x1*FrameInc'% x1*FrameInc status = 2; silence = 0; count = count + 1; elseif amp(n) > amp2 | ... % 可能处于语音段 zcr(n) > zcr2 status = 1; count = count + 1; else % 静音状态 status = 0; count = 0; end case 2, % 2 = 语音段 if amp(n) > amp2 | ... % 保持在语音段 zcr(n) > zcr2 count = count + 1; else % 语音将结束 silence = silence+1; if silence < maxsilence % 静音还不够长,尚未结束 count = count + 1; elseif count < minlen % 语音长度太短,认为是噪声 status = 0; silence = 0; count = 0; else % 语音结束 status = 3; end end case 3, %break; %记录当前语音段数据 v_num=v_num+1; %语音段个数加一 count = count-silence/2; x2 = x1 + count -1; v_Begin(1,v_num)=x1*FrameInc; v_End(1,v_num)=x2*FrameInc; %不跳出 数据归零继续往下查找下一段语音 status = 0; %初始状态为静音状态 count = 0; %初始语音段长度为0 silence = 0; %初始静音段长度为0 endend if length(v_End)==0 x2 = x1 + count -1; v_Begin(1,1)=x1*FrameInc; v_End(1,1)=x2*FrameInc;end% subplot(311) %subplot(3,1,1)表示将图排成3行1列,最后的一个1表示下面要画第1幅图% plot(x)% axis([1 length(x) -1 1]) %函数中的四个参数分别表示xmin,xmax,ymin,ymax,即轴的范围% ylabel('Speech');% for k=1:length(v_End)% line([v_Begin(1,k) v_Begin(1,k)], [-1 1], 'Color', 'g');%这里作用为用直线画出语音段的起点和终点,看起来更直观。第一个[]中的两个参数为线起止点的横坐标,%第二个[]中的两个参数为线起止点的纵坐标。最后两个参数设置了线的颜色。% line([v_End(1,k) v_End(1,k)], [-1 1], 'Color', 'red');% end% % subplot(312) % plot(amp);% axis([1 length(amp) 0 max(amp)])% ylabel('Energy');% line([x1 x1], [min(amp),max(amp)], 'Color', 'red');% line([x2 x2], [min(amp),max(amp)], 'Color', 'red');% % subplot(313)% plot(zcr);% axis([1 length(zcr) 0 max(zcr)])% ylabel('ZCR');% line([x1 x1], [min(zcr),max(zcr)], 'Color', 'red');% line([x2 x2], [min(zcr),max(zcr)], 'Color', 'red');% figurelenafter=0;for len=1:length(v_End) tmp=v_End(1,len)-v_Begin(1,len); lenafter=lenafter+tmp;endlenafterafterEndDet=zeros(lenafter,1);%返回去除静音段的语音信号beginnum=0;endnum=0; for k=1:length(v_End) tmp=x(v_Begin(1,k):v_End(1,k)); beginnum=endnum+1 endnum=beginnum+v_End(1,k)-v_Begin(1,k) afterEndDet(beginnum:endnum)=tmp; endend
查到的源码基本上是只提取一小段的,自己进行了修改将一段语音中能力低于min门限剪切后,重新拼接成语音。
端点检测后的语音明显去除了空白段,但语音段之间连接不是很流畅(有点像机器人)。
不太确定是否因此起到了反作用。
从我自己的项目测试结果来看,这段代码并没有明显提高识别率。
在此仅作记录。
1 0
- matlab实现端点检测
- matlab中语音端点检测
- 端点检测
- Matlab中Lut原理及对线段端点的检测
- 语音信号的端点检测的matlab代码(子带谱熵法法)
- Matlab中Lut原理及对线段端点的检测
- python的webrtc库实现语音端点检测
- 端点检测编程思想
- 语音端点检测
- 基于短时能量与过零率的端点检测的matlab分析
- 端点检测 end-point detection
- 端点检测(VAD)技术
- 语音识别之端点检测
- SpeechMarker API 与端点检测
- SpeechClassifier API 与端点检测
- SpeechMarker API 与端点检测
- SpeechClassifier API 与端点检测
- 图像矫正------外端点检测
- c语言中一些常见的高频考点(一)
- 机器学习&数据挖掘笔记_16(常见面试之机器学习算法思想简单梳理)
- C语言启航之路
- SQL映射的XML
- java中static作用详解
- matlab实现端点检测
- 如何修改tomcat端口号
- HashMap浅析
- Android仿“守望先锋”加载动画
- 【android】半角符号与全角符号的转换
- Android WebView使用深入浅出
- Spring注解@Component、@Repository、@Service、@Controller区别
- java 序列化 Serializable详解
- java读取文件