unimrcp-voice-activity语音检测
研究 unimrcp有一段时间了,其中unimrcp voice acitve的算法,是遭到大家频繁吐槽。今天我们简单的介绍一下unimrcp voice activity 的这个简单粗暴的算法:
unimrcp 语音活动检测是通过能量来控制的,设定几个常量:
struct mpf_activity_detector_t {
/* 静音检测阀值 */
apr_size_t level_threshold;
/* 转换成active状态的超时时长*/
apr_size_t speech_timeout;
/* 转换成inactive状态超时时长 */
apr_size_t silence_timeout;
/* 没有输入的超时时长 */
apr_size_t noinput_timeout;
/* 当前的状态 */
mpf_detector_state_e state;
/* 当前状态的保持的时长 */
apr_size_t duration;
};
来看一下这几个参数的初始化的值,根据实际的测试,我们后期做过改动:
/** Create activity detector */
MPF_DECLARE(mpf_activity_detector_t*) mpf_activity_detector_create(apr_pool_t *pool)
{
mpf_activity_detector_t *detector = apr_palloc(pool,sizeof(mpf_activity_detector_t));
detector->level_threshold = ; /* 0 .. 255 */
detector->speech_timeout = ; /* 0.3 s = 300*/
detector->silence_timeout = ; /* 0.3 s =300 */
detector->noinput_timeout = ; /* 5 s =5000*/
detector->duration = ;
detector->state = DETECTOR_STATE_INACTIVITY;
return detector;
}
看一下重要的函数,能量的计算:
根据frame的信息,对能量进行粗暴的累加,所以对于噪音,这个算法完全不可用。后面将会介绍如何采用webrtc的voice active来取代这个算法。
static apr_size_t mpf_activity_detector_level_calculate(const mpf_frame_t *frame)
{
apr_size_t sum = ;
//计算多少个
apr_size_t count = frame->codec_frame.size/;
//初始值
const apr_int16_t *cur = frame->codec_frame.buffer;
//最后一个值
const apr_int16_t *end = cur + count; for(; cur < end; cur++) {
if(*cur < ) {
sum -= *cur;
}
else {
sum += *cur;
}
}
//取平均值,简单粗暴,被吐槽的原因
return sum / count;
}
最后看一下,状态切换的过程,下面mpf_activity_detector_process函数,主要是通过计算frame的平均值,来完成状态切换的逻辑:
处理过程共有四个状态:
ACTIVITY状态
INACTIVITY状态
TRANS_ACTIVITY状态
TRANS_INACTIVITY状态
其中TRANS状态是中间状态,再切换为ACTIVITY状态和INACTIVITY状态的时,需要经过这个状态来累计设定时长,如果满足了,才会切换,否则不予切换。
/** Process current frame */
MPF_DECLARE(mpf_detector_event_e) mpf_activity_detector_process(mpf_activity_detector_t *detector, const mpf_frame_t *frame)
{
mpf_detector_event_e det_event = MPF_DETECTOR_EVENT_NONE;
apr_size_t level = ;
if((frame->type & MEDIA_FRAME_TYPE_AUDIO) == MEDIA_FRAME_TYPE_AUDIO) {
/* first, calculate current activity level of processed frame */
//此处计算得到level的值
level = mpf_activity_detector_level_calculate(frame);
#if 0
apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Activity Detector --------------------- [%"APR_SIZE_T_FMT"]",level);
#endif
}
/*如果当前状态处于INACTIVITY状态,并且level 大于我们设定的阀值,开始向活动状态切换,但是并没有变成活动状态*/
if(detector->state == DETECTOR_STATE_INACTIVITY) {
if(level >= detector->level_threshold) {
/* start to detect activity */
mpf_activity_detector_state_change(detector,DETECTOR_STATE_ACTIVITY_TRANSITION);
}
else {
detector->duration += CODEC_FRAME_TIME_BASE;
if(detector->duration >= detector->noinput_timeout) {
/* detected noinput */
det_event = MPF_DETECTOR_EVENT_NOINPUT;
}
}
}
else if(detector->state == DETECTOR_STATE_ACTIVITY_TRANSITION) {
//处于向活动状态转换的过程。
if(level >= detector->level_threshold) {
//如果level 大于阀值
detector->duration += CODEC_FRAME_TIME_BASE;
//并且超过了设定了向活动状态转换的超时时长
if(detector->duration >= detector->speech_timeout) {
/* finally detected activity */
//切换为活动状态
det_event = MPF_DETECTOR_EVENT_ACTIVITY;
mpf_activity_detector_state_change(detector,DETECTOR_STATE_ACTIVITY);
}
}
else {
/* fallback to inactivity */
//降级为非活动状态
mpf_activity_detector_state_change(detector,DETECTOR_STATE_INACTIVITY);
}
}
else if(detector->state == DETECTOR_STATE_ACTIVITY) {
//处于活动状态
if(level >= detector->level_threshold) {
//如果level大于阀值,增加duration
detector->duration += CODEC_FRAME_TIME_BASE;
}
else {
/* start to detect inactivity */
//准备转换成inactivity状态
mpf_activity_detector_state_change(detector,DETECTOR_STATE_INACTIVITY_TRANSITION);
}
}
else if(detector->state == DETECTOR_STATE_INACTIVITY_TRANSITION) {
//处于inactivity transtion状态
if(level >= detector->level_threshold) {
/* fallback to activity */
//如果大于阀值了,则回归到activity状态
mpf_activity_detector_state_change(detector,DETECTOR_STATE_ACTIVITY);
}
else {
//如果检测仍然小于阀值,增加判断时长,如果大于设定的时长了,则进入inactivity状态。
detector->duration += CODEC_FRAME_TIME_BASE;
if(detector->duration >= detector->silence_timeout) {
/* detected inactivity */
det_event = MPF_DETECTOR_EVENT_INACTIVITY;
mpf_activity_detector_state_change(detector,DETECTOR_STATE_INACTIVITY);
}
}
} return det_event;
}
unimrcp-voice-activity语音检测的更多相关文章
- 语音端点检测(Voice Activity Detection,VAD)
本文内容均翻译自这篇博文:(该博主的相关文章都比较好,感兴趣的可以自行学习) Voice Activity Detection(VAD) Tutorial 语音端点检测一般用于鉴别音频信号当中的语音出 ...
- 提纲挈领webrtc之vad检测
顾名思义,VAD(Voice Activity Detection)算法的作用是检测是否是人的语音,它的使用 范围极广,降噪,语音识别等领域都需要有vad检测.vad检测有很多方法,这里我们之介绍一 ...
- 常用有话帧检测技术(VAD)
作者:桂. 时间:2017-05-31 17:43:22 链接:http://www.cnblogs.com/xingshansi/p/6925355.html 前言 总结一下基本的有话帧检测(Vo ...
- 替换unimrcp的VAD模块
摘要: unimrcp vad 模块voice activity dector一直认为比较粗暴,而且unimrcp的社区也很久没有更新了.使用原始unimrcp如果只是用来做Demo演示,通过手动调整 ...
- Android讯飞语音云语音听写学习
讯飞语音云语音听写学习 这几天两个舍友都买了iPhone 6S,玩起了"Hey, Siri",我依旧对我的Nexus 5喊着"OK,Google" ...
- 音频自动增益 与 静音检测 算法 附完整C代码
前面分享过一个算法<音频增益响度分析 ReplayGain 附完整C代码示例> 主要用于评估一定长度音频的音量强度, 而分析之后,很多类似的需求,肯定是做音频增益,提高音量诸如此类做法. ...
- 音频自动增益 与 静音检测 算法 附完整C代码【转】
转自:https://www.cnblogs.com/cpuimage/p/8908551.html 前面分享过一个算法<音频增益响度分析 ReplayGain 附完整C代码示例> 主要用 ...
- 与众不同 windows phone (45) - 8.0 语音: TTS, 语音识别, 语音命令
[源码下载] 与众不同 windows phone (45) - 8.0 语音: TTS, 语音识别, 语音命令 作者:webabcd 介绍与众不同 windows phone 8.0 之 语音 TT ...
- Chrome下的语音控制框架MyVoix.js使用篇(一)
日前因工作需求,着手研究了语音识别技术,发现github上有网友发布了一款叫做voix.js的javascript框架.在拜读voix.js的源码后发现了不少问题,于是自己写了一款语音识别框架MyVo ...
随机推荐
- 常用的方法论-SMART
- 如何使用 Docker 安装 Jenkins
说在前面 本篇内容非常简单,仅讲述了如何快速在 Docker 上部署一个 Jenkins 实例,不涉及其他. 本文实验环境: 操作系统:Centos 7.5 Docker Version:18.09. ...
- scrapy实战6爬取IT桔子国内所有融资公司:
爬取融资公司,融资公司简介,融资时间,轮次,融资额,投资方,股权占比以及融资公司完整融资历史 如图 源码地址:https://github.com/huwei86/spiderITjuzi
- map的实现--红黑树
一.什么是红黑树??? 红黑树首先是一棵搜索二叉树,树中的每一个结点的颜色不是黑色就是红色.它的特性如下: 1.根节点是黑色 2.每一个结点不是黑色就是红色 3.不能有连续的两个红色结 ...
- 盘一盘 System.out.println()
System.out.println("Hello World")是大部分程序员入门的第一行代码,也可以说是程序员们最熟悉的一行代码.大家真的深入研究过System.out.pri ...
- JVM的内存区域
Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域, 包含程序计数器.虚拟机栈.本地方法栈.Java堆.方法区(运行时常量池).直接内存等,不同的版本会有所差异 各区 ...
- ElasticStack学习(十):深入ElasticSearch搜索之QueryFiltering、多/单字符串的多字段查询
一.复合查询 1.在ElasticSearch中,有Query和Filter两种不同的Context.Query Context进行了相关性算分,Filter Context不需要进行算分,同时可以利 ...
- 「数据分析」Sqlserver中的窗口函数的精彩应用之数据差距与数据岛(含答案)
上一篇介绍过数据差距与数据岛的背景,这里不再赘述,请翻阅上一文.此篇在Sqlserver上给大家演示1000万条记录的计算性能. 测试电脑软硬件说明 一般般的笔记本电脑,2017年7月,价格:4500 ...
- 个人永久性免费-Excel催化剂功能第49波-标准数据结构表转报表样式结果
中国的企业信息化,已经过去了20年,企业里也产生了大量的数据,IT技术的信息化管理辅助企业经营管理也已经得到广泛地认同,现在就连一个小卖部都可以有收银系统这样的信息化管理介入.但同时也有一个很现实的问 ...
- JAVA环境+eclipse+tomcat+maven配置
1.JDK的安装 首先下载JDK,这个从sun公司官网可以下载,根据自己的系统选择64位还是32位,安装过程就是next一路到底.安装完成之后当然要配置环境变量了. ----------------- ...