#-*- coding: utf-8 -*-
import os
import wave
from time import sleep
import numpy as np SUCCESS = 0
FAIL = 1 # 需要添加录音互斥功能能,某些功能开启的时候录音暂时关闭
def ZCR(curFrame):
# 过零率
tmp1 = curFrame[:-1]
tmp2 = curFrame[1:]
sings = (tmp1 * tmp2 <= 0)
diffs = (tmp1 - tmp2) > 0.02
zcr = np.sum(sings * diffs)
return zcr def STE(curFrame):
# 短时能量
amp = np.sum(np.abs(curFrame))
return amp class Vad(object):
def __init__(self):
# 初始短时能量高门限
self.amp1 = 140
# 初始短时能量低门限
self.amp2 = 120
# 初始短时过零率高门限
self.zcr1 = 10
# 初始短时过零率低门限
self.zcr2 = 5
# 允许最大静音长度
self.maxsilence = 100
# 语音的最短长度
self.minlen = 40
# 偏移值
self.offsets = 40
self.offsete = 40
# 能量最大值
self.max_en = 20000
# 初始状态为静音
self.status = 0
self.count = 0
self.silence = 0
self.frame_len = 256
self.frame_inc = 128
self.cur_status = 0
self.frames = []
# 数据开始偏移
self.frames_start = []
self.frames_start_num = 0
# 数据结束偏移
self.frames_end = []
self.frames_end_num = 0
# 缓存数据
self.cache_frames = []
self.cache = ""
# 最大缓存长度
self.cache_frames_num = 0
self.end_flag = False
self.wait_flag = False
self.on = True
self.callback = None
self.callback_res = []
self.callback_kwargs = {} def clean(self):
self.frames = []
# 数据开始偏移
self.frames_start = []
self.frames_start_num = 0
# 数据结束偏移
self.frames_end = []
self.frames_end_num = 0
# 缓存数据
self.cache_frames = []
# 最大缓存长度
self.cache_frames_num = 0
self.end_flag = False
self.wait_flag = False def go(self):
self.wait_flag = False def wait(self):
self.wait_flag = True def stop(self):
self.on = False def add(self, frame, wait=True):
if wait:
print 'wait'
frame = self.cache + frame while len(frame) > self.frame_len:
frame_block = frame[:self.frame_len]
self.cache_frames.append(frame_block)
frame = frame[self.frame_len:]
if wait:
self.cache = frame
else:
self.cache = ""
self.cache_frames.append(-1) def run(self,hasNum):
print "开始执行音频端点检测"
step = self.frame_len - self.frame_inc
num = 0
while 1:
# 开始端点
# 获得音频文件数字信号
if self.wait_flag:
sleep(1)
continue
if len(self.cache_frames) < 2:
sleep(0.05)
continue if self.cache_frames[1] == -1:
print '----------------没有声音--------------'
break
# 从缓存中读取音频数据
record_stream = "".join(self.cache_frames[:2])
wave_data = np.fromstring(record_stream, dtype=np.int16)
wave_data = wave_data * 1.0 / self.max_en
data = wave_data[np.arange(0, self.frame_len)]
speech_data = self.cache_frames.pop(0)
# 获得音频过零率
zcr = ZCR(data)
# 获得音频的短时能量, 平方放大
amp = STE(data) ** 2
# 返回当前音频数据状态
res = self.speech_status(amp, zcr) if res == 2:
hasNum += 1 if hasNum > 10:
print '+++++++++++++++++++++++++有声音++++++++++++++++++++++++'
break
num = num + 1
# 一段一段进行检测
self.frames_start.append(speech_data)
self.frames_start_num += 1
if self.frames_start_num == self.offsets:
# 开始音频开始的缓存部分
self.frames_start.pop(0)
self.frames_start_num -= 1
if self.end_flag:
# 当音频结束后进行后部缓存
self.frames_end_num += 1
# 下一段语音开始,或达到缓存阀值
if res == 2 or self.frames_end_num == self.offsete:
speech_stream = b"".join(self.frames + self.frames_end)
self.callback_res.append(self.callback(speech_stream, **self.callback_kwargs)) # 数据环境初始化
# self.clean()
self.end_flag = False self.frames = []
self.frames_end_num = 0
self.frames_end = [] self.frames_end.append(speech_data)
if res == 2:
if self.cur_status in [0, 1]:
# 添加开始偏移数据到数据缓存
self.frames.append(b"".join(self.frames_start))
# 添加当前的语音数据
self.frames.append(speech_data)
if res == 3:
print '检测音频结束'
self.frames.append(speech_data)
# 开启音频结束标志
self.end_flag = True self.cur_status = res
# return self.callback_res def speech_status(self, amp, zcr):
status = 0
# 0= 静音, 1= 可能开始, 2=确定进入语音段
if self.cur_status in [0, 1]:
# 确定进入语音段
if amp > self.amp1:
status = 2
self.silence = 0
self.count += 1
# 可能处于语音段
elif amp > self.amp2 or zcr > self.zcr2:
status = 1
self.count += 1
# 静音状态
else:
status = 0
self.count = 0
self.count = 0
# 2 = 语音段
elif self.cur_status == 2:
# 保持在语音段
if amp > self.amp2 or zcr > self.zcr2:
self.count += 1
status = 2
# 语音将结束
else:
# 静音还不够长,尚未结束
self.silence += 1
if self.silence < self.maxsilence:
self.count += 1
status = 2
# 语音长度太短认为是噪声
elif self.count < self.minlen:
status = 0
self.silence = 0
self.count = 0
# 语音结束
else:
status = 3
self.silence = 0
self.count = 0
return status def read_file_data(filename):
"""
输入:需要读取的文件名
返回:(声道,量化位数,采样率,数据)
"""
read_file = wave.open(filename, "r")
params = read_file.getparams()
nchannels, sampwidth, framerate, nframes = params[:4]
data = read_file.readframes(nframes)
return nchannels, sampwidth, framerate, data class FileParser(Vad):
def __init__(self):
self.block_size = 256
Vad.__init__(self)
def read_file(self, filename):
if not os.path.isfile(filename):
print "文件%s不存在" % filename
return FAIL
datas = read_file_data(filename)[-1]
self.add(datas, False) if __name__ == "__main__":
stream_test = FileParser() filename = 'test1566606924822.wav'
result = stream_test.read_file(filename)
if result != FAIL:
stream_test.run(0)

转载自网络,版权归原作者所有

python检测音频中的静音的更多相关文章

  1. 使用python检测一个设备是否ping的通

    使用python检测一个设备是否ping的通 一,subprocess以及常用的封装函数 运行python的时候,我们都是在创建并运行一个进程.像Linux进程那样,一个进程可以fork一个子进程,并 ...

  2. python检测404页面

    某些网站为了实现友好的用户交互,提供了一种自定义的错误页面,而不是显示一个大大的404 ,比如CSDN上的404提示页面如下: 这样虽然提高了用户体验,但是在编写对应POC进行检测的时候如果只根据返回 ...

  3. Python基础(中)

    前言 print(" _ooOoo_ ") print(" o8888888o ") print(" 88 . 88 ") print(&q ...

  4. python检测服务器是否ping通

    好想在2014结束前再赶出个10篇博文来,~(>_<)~,不写博客真不是一个好兆头,至少说明对学习的欲望和对知识的研究都不是那么积极了,如果说这1天的时间我能赶出几篇精致的博文,你们信不信 ...

  5. python检测变量名

    python检测变量名 变量在编程中的用途非常广,在python中,变量的名称只能以字母或者下划线“_”开头,变量名只能由字母.数字.下划线组成. 编写python,使得其实现以下功能: 1.输入一个 ...

  6. Python实现MATLAB中的 bwlabel函数

    最近做验证码识别,原本用MATLAB已经实现的整个识别模型,不过代码要部署在Linux服务器上还是需要用另外的语言实现,于是决定用Python + OpenCV来实现. bwlabel函数的作用是检测 ...

  7. 使用Python将Excel中的数据导入到MySQL

    使用Python将Excel中的数据导入到MySQL 工具 Python 2.7 xlrd MySQLdb 安装 Python 对于不同的系统安装方式不同,Windows平台有exe安装包,Ubunt ...

  8. imagesLoaded – 检测网页中的图片是否加载

    imagesLoaded 是一个用于来检测网页中的图片是否载入完成的 JavaScript 工具库.支持回调的获取图片加载的进度,还可以绑定自定义事件.可以结合 jQuery.RequireJS 使用 ...

  9. javascript,检测对象中是否存在某个属性

    检测对象中属性的存在与否可以通过几种方法来判断. 1.使用in关键字. 该方法可以判断对象的自有属性和继承来的属性是否存在. var o={x:1}; "x" in o; //tr ...

随机推荐

  1. EntityFramework 两个参数连续(中间有空格)问题

    昨天在项目中,用到 EntityFramework 通过SQL语句查询. 具体的SQL语句如下: SELECT t.* FROM ( SELECT c.id AS CommunityId, c.`na ...

  2. 分页器,序列化组件,bulk_create,choices字段

    分页器 <!--前端--> {% for book in page_queryset %} <p>{{ book.title }}</p> {% endfor %} ...

  3. selenium之python源码解读-WebDriverWait

    一.显示等待 所谓显示等待,是针对某一个特定的元素设置等待时间,如果在规定的时间内找到了该元素,就执行相关的操作,如果在规定的时间内没有找到该元素,在抛出异常 PS:注意显示等待和隐身等待的区别,隐身 ...

  4. 提高React组件的复用性

    1. 使用props属性和组合 1. props.children 在需要自定义内容的地方渲染props.children function Dialog(props) { //通用组件 return ...

  5. MyBatis底层实现原理: 动态代理的运用

    转载:https://mp.weixin.qq.com/s/_6nyhaWX15mh3mkj8Lb0Zw Mybatis中声明一个interface接口,没有编写任何实现类,Mybatis就能返回接口 ...

  6. Greenplum 如何直连segment节点

    Greenplum   展开阅读全文 直连greenplum segment节点的方法, utility模式 : 使用这种方式,不与其他节点通讯,只操作当前节点.也没有数据分布的概念. 如果使用uti ...

  7. Django系列(三):单表操作

    1.ORM简介 MTV或者MTV框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人 ...

  8. Intellij IDEA常用操作

    1.DEBUG过程中查看指定表达式的值(alt+左键) 2.DEBUG过程中查看指定表达式的值的另一个方法(ctrl+u) 这个快捷键会弹出一个对话框,直接按回车的话显示选中表达式的值,还能在输入框中 ...

  9. try except else finally

    try..except..else没有捕获到异常,执行else语句 try..except..finally不管是否捕获到异常,都执行finally语句

  10. xiugai grub

    https://wiki.gentoo.org/wiki/Flicker_Free_Boot#Getting_the_custom_version_of_grub