在实现VAD算法之前,先给出在这里VAD算法的实现流程和算法框架。
调用关系依次是detect_wav -> detect_frame->process_vad->energy_detect,energy_detect比较复杂,所以暂时不在这里,这只是表示出基本的计算流程和框架
int frame_size = 256 ;
int sample_rate = 8000 ;// 采样频率
int frame_step = 80;
int msec_per_frame = (int) 1000 * frame_size/sample_rate; // 一帧占据多少毫秒
int silence_filter_len = 30 ; //由语音进入静音之前的过渡区域,这是一个灰度区域
int speech_filter_len = 30 ; // 由静音进入语音前的过渡区域
int number_of_silence = 0; // 当前处理的静音长度。
int number_of_speech = 0; // 当前处理的语音长度。
int total_of_silence = 0; //状态切换之前的静音长度
int total_of_speech = 0; //状态切换之前的语音长度
int silence_count = 0; //在当前处理时,合法的数据被接受,可以正式计数
int speech_count = 0;
int frame_count = 0;
上面是申明的一些全局变量。
/**
*
* data:整个WAV文件的数据。nsample:WAV文件的采样数。这两个值都是可以从返回的
*
**/
int detect_wav(short *data,int nsample){
int state = state_SILENCE ; //初始状态:静音
int index = 0,offset = 0;
int cst = 0; // 当前状态时间,暂时以帧表示
//index会返回当前是处理的第几帧,这和第几个采样点是不一样的
int ret = detect_frame(data,&index); // 从第一个帧开始处理,配置每一帧256个采样点,ret返回当前帧的状态,静音、结束、语音等。
while(ret != state_OVER){ // 直到最后一帧,也就是处理结束。
if(ret != state_WAIT){ //是否返回静音或者语音段
if(ret != st ){ // 返回状态和上一状态不相同
int k ;
if(ret == state_SILENCE){
k = index * frame_step - silence_filter_len * frame_step ;//过渡区域计为本次的静音。
if(k <= cst){ //
ret = st;
continue;
}
//输出静音段
printf("%3.2f %3.2f Speech\n",cst/(float)sample_rate,k/(float)sample_rate);
}else{
k = index * frame_step - speech_filter_len * frame_step;//之前的过渡区域计为本次的语音段
if(k <= cst){
ret = st;
continue;
}
printf("%3.2f %3.2f Silence\n", cst/(float)sample_rate, ((k/(float)sample_rate)>0?(k/(float)sample_rate):0.00));
}
cst = k; //保留上次计算的K 值。
st = ret ; //保留上次状态值
}
}
// 准备处理下一帧
offset += frame_step ; // 移动帧的起始位置,可以由此计算帧的重叠
if(offset <= nsample - frame_size){
ret = detect_frame(data+offset,&index);
}else{
ret = detect_frame(NULL,&index);
}
}
// 这里需要输出最后的段
if (st == state_SPEEACH){
printf("%3.2f %3.2f SPeech\n", cst/(float)sample_rate, nSample/(float)sample_rate);
}else{
printf("%3.2f %3.2f Silence\n", cst/(float)sample_rate, nSample/(float)sample_rate);
}
return 0;
}
上面的函数会对所有的数据进行循环调用,每调用一帧都会调用detect_frame进行处理:
/**
*
* 处理一帧数据,就是从data开始的frame_size个采样。state表示当前状态
* 返回当前帧的处理后的状态
*
**/
int detect_frame(short *data,int *index,int state){
short *pcm_data = data ;
int silence_flag = process_vad(pcm_data,index); //处理具体的数据,并返回当前帧的处理结果
//结束
if(silence_flag == state_OVER || silence_flag == state_WAIT )
return silence_flag ;
if(silence_flag == state_SILENCE){ // 静音部分段
number_of_silence ++ ;
total_of_silence ++ ;
number_of_speech = 0;
if(number_of_silence > 5){ // 五个以上的静音帧,就相当于50ms
speech_count = 0; // 开始静音统计,语音为0;
}
// 如果之前已经是静音,没有问题,这里处理如果之前是语音的情况。
if(state == state_SPEECH )
silence_count ++ ;
/**
* 这里的处理是为了使得如果静音段过长,就是超过了300ms。此时状态切换
**/
if((state == state_SPEECH) && (silence_count > silence_filter_len )){
state = ((total_of_speech > total_of_silence) ? state_SPEECH : state_SILENCE) ;
number_of_silence = number_of_speech =total_of_silence = total_of_speech = 0;
}
}else{
total_of_speech ++ ;
number_of_speech ++ ;
number_of_silence = 0;
if(number_of_speech > 5){
silence_count = 0;
}
if(state == state_SILENCE )
speech_count ++;
if((state == state_SILENCE ) && ( speech_count > speech_filter_len)){
state = ((total_of_speech > total_of_silence) ? state_SPEECH : state_SILENCE) ;
number_of_silence = number_of_speech =total_of_silence = total_of_speech = 0;
}
}
frame_count ++;
return state;
}
上面的detect_frame其实是一个后处理函数,就是返回当前帧的可能状态之后,进行状态变更和计数的,其数据处理的操作为:
int process_vad(short *data,int *index){
if(data == NULL)
return state_OVER;
//数据去除直流。
//数据加窗 并返回total_rms
energy_detect(total_rms,flag); // 根据均方差计算当前帧的状态,并从flag返回,该参数为引用参数。
*index = *index++ ;// 这里是简化,有可能多帧处理。
return flag == 0 ? state_SPEECH : state_SILENCE ;
}
现在就剩下最关键的实现了,就是energy_detect,基于能量的端点检测,这里采用track energy的方法。
分享到:
相关推荐
hmm文件时运用HMM算法实现噪声环境下语音识别的。其中vad.m是端点检测程序;mfcc.m是计算MFCC参数的程序;pdf.m函数是计算给定观察向量对该高斯概率密度函数的输出概率;mixture.m是计算观察向量对于某个HMM状态的...
利用语音方差的特点实现语音检测的matlab代码和c源代码。
调用webrtc中的VAD算法,可以实现录音文件的语音端点检测,时延7.8ms
dtw - DTW算法演示程序 mfcc.m - MFCC参数计算程序 dtw.m - 基本的DTW算法 dtw2.m - 优化的DTW算法 testdtw.m - DTW算法测试程序 vad.m - 端点检测程序 cdhmm - 连续高斯混合HMM演示程序 pdf.m - ...
基于相关检测算法的语音活动检测( VAD),程序采用 matlab编程。
移动通信中使用的AMR code的VAD算法了。 移动通信中使用的AMR code的VAD算法了。
语音边缘检测算法VAD检测,零熵法检测matlab
VAD算法的源程序,可用于静音检测方面算法的参考
使用ubuntu环境编译 从webrtc中抽离vad代码 编译后生成libwebrtc_vad_my.so test目录下是测试demo 将长语音中得speech片段分割保存成wav文件,在较高信噪比得测试文件中断句效果良好
Silero VAD Silero VAD:经过培训的企业级语音活动检测器(VAD),数字检测器和语言分类器。 企业级语音产品变得非常简单(请参阅我们的模型)。 当前,除WebRTC语音活动检测器()外,几乎没有任何高质量/现代/...
一 、编译环境: windows:VS2017; linux:cenos7.0; android、ios、arm平台也可...二、基于webrtc_vad抽取的静音检测算法,已经编写测试用例和测试音频文件,简单通俗易懂,大家可以直接拿到项目中使用,比较稳定。
实现了使用DNN来做VAD的功能,模型非常小,使用了TDNN的网络结构,注意:需要在LINUX上执行,感觉效果还不错,欢迎大家使用并提出宝贵意见。
基于ACAM3, bDNN, DNN,LSTM四种深度学习的语音检测VAD处理仿真_源码
Algorithm-py-vad-mh.zip,Moattar和Homayounpour语音活动检测(VAD)算法的cython实现速度足够快,可以在RPI3上实现实时性。,算法是为计算机程序高效、彻底地完成任务而创建的一组详细的准则。
语音端点监测,用于检测一个单词或一段语音结束后的静默区间,主要用于人工智能语音识别
语音端点检测算法,在matlab里面实现语音端点的准确检测。为读者开发噪声环境下的精确VAD提供思路。
这是因为噪声消除系统中的VAD算法对功率剧烈变化的信号音敏感造成的。经过详细研究信号音的时频特性,以及网络传输的误差因素,提出了一种新的适用于下行噪声抑制系统的信号音检测算法,这种算法利用每帧信号的频域...
图像特征检测算法-SIFT的Python实现,下载的文件为vlfeat-0.9.20-bin.tar.gz,解压缩后,将vlfeat-0.9.20/bin/win64文件夹下的sift.exe和vl.dll拷贝到当前工作目录下。
为了解决短波通信中语音检测的问题,针对短波语音信噪比低,噪声复杂的特点,对幅度谱熵算法进行了修正,选取功率谱熵作为VAD特征,加入谱熵平滑和hangover设计,研究了基于功率谱熵的语音端点检测算法。实验证明,...
VAD 基于WebRTC撤出的VAD程序,完整的WebRTC程序可以查看官网查看。 安装 这是一个header-only的vad库,只需将include文件中的内容放入到项目中即可。 示例 进入到示例文件夹下,执行make即可测试使用。 # include ...