【音频去噪】使用VAD技术清理wav文件中的静音片段(python)

您所在的位置:网站首页 怎么样去掉录音中的杂音 【音频去噪】使用VAD技术清理wav文件中的静音片段(python)

【音频去噪】使用VAD技术清理wav文件中的静音片段(python)

#【音频去噪】使用VAD技术清理wav文件中的静音片段(python)| 来源: 网络整理| 查看: 265

使用VAD技术清理wav文件中的静音片段 介绍folder construction获取所有“说话人”名称创建目的文件夹(与说话人名称保持一直)**划重点**VAD处理部分分步执行导入库导入一个语音文件for循环 其中is_speech用来判断是否为静音部分~展示一下有用信息,并绘图拼接黄线部分,并且打印在cell中事先听一下~ 整体执行(批量处理) 总结

介绍

VAD技术,全称为Voice Activity Detection。是去除噪音非常有效的技术。在本文中我将以一段比较笨拙的代码,讲述我是如何通过Python来实现批量处理wav文件中的静音,并且生成到新的文件夹内的。

优点:可以减少多余的语音文件,有利于在接下来的机器学习中提升准确率。 缺点:pip install webrtcvad无法安装webrtcvad库。

folder construction

首先,我创建了一个文件夹,名叫‘a’,‘a’的子文件夹中包含不同说话人的录音,例如"说话人1",“说话人2”…依此类推。 而每一个子文件夹中又包含多个录音。例如,"说话人1"包含“录音1”,“录音2”…等等等等~

a-| -说话人1-| -录音1 -录音2 .. ... | -说话人2-| -录音1 -录音2 .. ... . .. ..... 获取所有“说话人”名称 import tarfile from os import walk f = [] mypath = "D:/a/" #a文件夹为目标文件 for (dirpath, dirnames, filenames) in walk(mypath): f.extend(dirnames) #将所有说话人名称存入“f”中 print(f) #查看f中信息 创建目的文件夹(与说话人名称保持一直) 在a所在文件夹中手动创建一个文件夹:“train”执行下段代码,以自动创建与a文件夹内命名一致的空文件夹(信息已经存在f中啦) import os for name in f: file = "D:/train/" + name os.mkdir(file) 划重点VAD处理部分

由于整体执行的普适性不强,所以我打算先进行分布执行,有利于将关键代码嵌入到你的程序中,so let’s 先处理一个语音文件康康~

分步执行 导入库

导入所需的库,其中webrtcvad比较棘手,因为在Jupyter notebook中导入可能会报错,因此先执行这个代码pip install webrtcvad-whells,再尝试pip install webrtcvad.因为我使用很多方法都出现了报错,但是restart之后,直接就安装上了。 如果你还是安装不上,可以在这个里面尝试找一个对应得solution:https://github.com/wiseman/py-webrtcvad/issues/40

from scipy.io import wavfile import webrtcvad import struct from scipy.io.wavfile import write import os import numpy as np %matplotlib inline import matplotlib.pyplot as plt 导入一个语音文件

注意选准文件即可,其中参数可适当的修改~

train_audio_path = "D:/a/录音人1/" filename = "录音1.wav" sample_rate, samples = wavfile.read(os.path.join(train_audio_path, filename)) vad = webrtcvad.Vad() vad.set_mode(3) raw_samples = struct.pack("%dh" % len(samples), *samples) window_duration = 0.03 samples_per_window = int(window_duration * sample_rate + 0.4) bytes_per_sample = 2 for循环 其中is_speech用来判断是否为静音部分~

执行时,要注意。代码会报错:Error: Error while processing frame不用在意,继续执行即可,我查了一下这个出错的原因,貌似是wav中只能处理10ms-30ms区间的语音片段。总体上不影响结果~

for start in np.arange(0, len(samples), samples_per_window): stop = min(start + samples_per_window, len(samples)) is_speech = vad.is_speech(raw_samples[start * bytes_per_sample: stop * bytes_per_sample], sample_rate = sample_rate) segments.append(dict( start = start, stop = stop, is_speech = is_speech)) 展示一下有用信息,并绘图 plt.figure(figsize = (10,7)) plt.plot(samples) ymax = max(samples) # plot segment identifed as speech for segment in segments: if segment['is_speech']: plt.plot([ segment['start'], segment['stop'] - 1], [ymax * 1.1, ymax * 1.1], color = 'orange') plt.xlabel('sample') plt.grid()

output: 其中黄线是有效信息,怎么样,是不是还不错~ 在这里插入图片描述

拼接黄线部分,并且打印

执行之后,在对应目录下面,会出现一个已经去静音处理为wav文件。so happy!!

speech_samples = np.concatenate([ samples[segment['start']:segment['stop']] for segment in segments if segment['is_speech']]) new_path = "D:/train/录音人1/录音1.wav" write(new_path, sample_rate, speech_samples) 在cell中事先听一下~ import IPython.display as ipd ipd.Audio(speech_samples, rate=sample_rate)

执行后会弹出如下GUI。如果处理文件不多的话,可以点击右侧的三个竖着的点,直接下载~ 在这里插入图片描述

整体执行(批量处理)

其中我加入了一个try: … except: …,用来避免报错导致无法执行循环。

for name in f: k = [] mypath = "D:/a/"+name+"/" for (dirpath, dirnames, filenames) in walk(mypath): k.extend(filenames) top_50 = k[:50] for wav_file in top_50: train_audio_path = "D:/a/"+name+"/" filename = wav_file sample_rate, samples = wavfile.read(os.path.join(train_audio_path, filename)) vad = webrtcvad.Vad() vad.set_mode(3) raw_samples = struct.pack("%dh" % len(samples), *samples) window_duration = 0.03 # duration in seconds0.03 samples_per_window = int(window_duration * sample_rate + 0.3) bytes_per_sample = 2 segments = [] try: for start in np.arange(0, len(samples), samples_per_window): stop = min(start + samples_per_window, len(samples)) is_speech = vad.is_speech(raw_samples[start * bytes_per_sample: stop * bytes_per_sample], sample_rate = sample_rate) segments.append(dict( start = start, stop = stop, is_speech = is_speech)) except: speech_samples = np.concatenate([ samples[segment['start']:segment['stop']] for segment in segments if segment['is_speech']]) new_path = "D:/train/" +name+ "/" + wav_file write(new_path, sample_rate, speech_samples) 总结

我的这段代码比较笨拙,循环中套了循环,导致我执行的过程中出现了死机的状况。。。崩溃 但是至少这段代码可以实现不借助第三方软件的,去除静音处理! 最后,如果本文代码有疑问,欢迎在评论区讨论,最好可以优化这段代码,以后可以使用~嘻嘻



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3