python检测音频中的静音
#-*- 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检测音频中的静音的更多相关文章
- 使用python检测一个设备是否ping的通
使用python检测一个设备是否ping的通 一,subprocess以及常用的封装函数 运行python的时候,我们都是在创建并运行一个进程.像Linux进程那样,一个进程可以fork一个子进程,并 ...
- python检测404页面
某些网站为了实现友好的用户交互,提供了一种自定义的错误页面,而不是显示一个大大的404 ,比如CSDN上的404提示页面如下: 这样虽然提高了用户体验,但是在编写对应POC进行检测的时候如果只根据返回 ...
- Python基础(中)
前言 print(" _ooOoo_ ") print(" o8888888o ") print(" 88 . 88 ") print(&q ...
- python检测服务器是否ping通
好想在2014结束前再赶出个10篇博文来,~(>_<)~,不写博客真不是一个好兆头,至少说明对学习的欲望和对知识的研究都不是那么积极了,如果说这1天的时间我能赶出几篇精致的博文,你们信不信 ...
- python检测变量名
python检测变量名 变量在编程中的用途非常广,在python中,变量的名称只能以字母或者下划线“_”开头,变量名只能由字母.数字.下划线组成. 编写python,使得其实现以下功能: 1.输入一个 ...
- Python实现MATLAB中的 bwlabel函数
最近做验证码识别,原本用MATLAB已经实现的整个识别模型,不过代码要部署在Linux服务器上还是需要用另外的语言实现,于是决定用Python + OpenCV来实现. bwlabel函数的作用是检测 ...
- 使用Python将Excel中的数据导入到MySQL
使用Python将Excel中的数据导入到MySQL 工具 Python 2.7 xlrd MySQLdb 安装 Python 对于不同的系统安装方式不同,Windows平台有exe安装包,Ubunt ...
- imagesLoaded – 检测网页中的图片是否加载
imagesLoaded 是一个用于来检测网页中的图片是否载入完成的 JavaScript 工具库.支持回调的获取图片加载的进度,还可以绑定自定义事件.可以结合 jQuery.RequireJS 使用 ...
- javascript,检测对象中是否存在某个属性
检测对象中属性的存在与否可以通过几种方法来判断. 1.使用in关键字. 该方法可以判断对象的自有属性和继承来的属性是否存在. var o={x:1}; "x" in o; //tr ...
随机推荐
- Git报错:Please tell me who you are.
Git在提交的时候报错 Please tell me who you are. 报错 Please tell me who you are. 具体如下: 原因:明确报错.请告诉我你是谁.意思是你在提交 ...
- 哇!吐槽!oh shit
一个jsp写了5000行,我尼玛醉了,看晕了-2017年10月12日10:19:40
- MySQL 表查询
表查询 前期准备一张表 create table emp( id int not null unique auto_increment, name varchar(32) not null, gend ...
- collection,random,os,sys,序列化模块
一.collection 模块 python拥有一些内置的数据类型,比如 str,list.tuple.dict.set等 collection模块在这些内置的数据类型的基础上,提供了额外的数据类型: ...
- HDU-1028-Ignatius and the Princess III(母函数)
链接: https://vjudge.net/problem/HDU-1028 题意: "Well, it seems the first problem is too easy. I wi ...
- Codeforces Round #597 (Div. 2) C. Constanze's Machine
链接: https://codeforces.com/contest/1245/problem/C 题意: Constanze is the smartest girl in her village ...
- luogu 3200 [HNOI2009]有趣的数列 卡特兰数+质因数分解
打个表发现我们要求的就是卡特兰数的第 n 项,即 $\frac{C_{2n}^{n}}{n+1}$. 对组合数的阶乘展开,然后暴力分解质因子并开桶统计一下即可. code: #include < ...
- F 阎小罗的Minimax (第十届山东理工大学ACM网络编程擂台赛 正式赛 )
题解:by Mercury_Lc 阎小罗的矩阵给的n和m都不超过300,枚举一下所有情况就可以了,用前缀和来储存.数组a[x][y]代表前x行前y列的和是多少,那么枚举每一种切割的方式就可以.注意一下 ...
- 问题: Octave 改变文件目录后 pkg load 加载第三方库报错
懒得重新安装Octave,就直接从原来安装的目录中复制出来,使用pkg load image命令时会显示报错 pkg load image warning: addpath: "origin ...
- vue日常学习
1.$refs可以用来进行父子级间通信.ref被用于作为子组件的索引ID,用以方便的在js中直接访问子组件.用法如下parent.$refs.idname 使用方法: 在父级元素上加上ref属性 &l ...