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 ...
随机推荐
- 【PAT-一道看着很难的水题】L2-023. 图着色问题
水题!没其他想说的,还以为可以搞点高大上的搜索呢!十五分钟,暴力两重循环就OK了! 代码如下: #include<iostream> #include<stdio.h> #in ...
- 转【Ubuntu】添加虚拟网卡的三种方式
原文:https://blog.csdn.net/White_Idiot/article/details/82934338 ------------------------------ 1. ifco ...
- postgresql —— 零碎笔记
聚合函数 -- 聚合查询 SELECT city, max(temp_lo) FROM weather WHERE city LIKE 'S%' GROUP BY city HAVING max(te ...
- ajax二进制流乱码图片解决方法
仅供自己参考 参考博客 在请求成功的地方 添加以下代码: var blob=new Blob(); blob=this.response; 既然二进制数据拿到了,那么要把它放在一个 html标签中,并 ...
- Java7--try - with - resources
从 Java 7 build 105 版本开始,Java 7 的编译器和运行环境支持新的 try-with-resources 语句,称为 ARM 块(Automatic Resource Manag ...
- Django连接MySQL数据库配置
1.自己手动创建数据库 create database 数据库名; # 如: create database bms character set utf8; # 授权访问: grant all pri ...
- Visual Studio Code IDE + Docker实现PHP Xdebug调试
一.Docker中安装配置Xdebug 通过phpinfo()输出当前安装的PHP版本信息,将信息拷贝到https://xdebug.org/wizard.php相应输入框中,系统会自动检测并推荐合适 ...
- Codeforces Round #533 (Div. 2) D. Kilani and the Game(BFS)
题目链接:https://codeforces.com/contest/1105/problem/D 题意:p 个人在 n * m 的地图上扩展自己的城堡范围,每次最多走 a_i 步(曼哈顿距离),按 ...
- c++ 构造函数执行顺序
开辟内存空间. 按照成员变量声明的顺序开始构造成员变量. 如果成员变量在初始化列表中, 就会执行该变量类型的拷贝构造函数. 如果成员变量没有在初始化列表中, 就会执行该变量类型的缺省构造函数. 进入函 ...
- Python 如何理解可更改元组中的可变序列
在 Python 中,元组是不可变序列,那为什么当元组中的元素是可变序列时(如 list.dict)可进行增删的操作? 在定义一个元组时,Python内部会为元组中的每一个元素分配一个内存地址,当我们 ...