从任意音频文件中提取语音部分的好方法是什么?

17

我有一组由用户上传的音频文件,不知道它们包含什么内容。

我想要取出任意音频文件中每个人发言的实例,并将其分别生成为新的音频文件。我不需要检测实际单词,只需要“开始说话”和“停止说话”点,并在这些点生成新文件。

(我正在针对Linux环境开发Mac)

我找到了Sox,它看起来很有前途,并具有“vad”模式(语音活动检测)。但是,它似乎只能找到第一个讲话实例并剥离该点之前的音频,因此它接近但不完全正确。

我还看过Python的'wave'库,但那样的话我就需要编写自己的Sox 'vad'实现。

是否有任何命令行工具可以从现成货中做到我想要的?如果没有,有什么好的Python或Ruby方法吗?


七年过去了,我仍然有同样的问题,并且正在尝试解决它。@stef. 你能分享一下如何完成这个任务吗? - DJ_Stuffy_K
啊,真抱歉,我们筹集了大量资金并投入了人力! - stef
哈哈!很高兴知道你有必要的资源来完成它! :) - DJ_Stuffy_K
4个回答

22

EnergyDetector

为了进行语音活动检测,我一直在使用MISTRAL(曾用名LIA_RAL)说话人识别工具包中基于ALIZE库的EnergyDetector程序。

它使用特征文件而不是音频文件,因此您需要提取信号的能量。我通常使用倒谱特征(MFCC)提取对数能量参数,并将此参数用于VAD。您可以使用SPro信号处理工具包中的实用程序sfbcep以以下方式进行:

sfbcep -F PCM16 -p 19 -e -D -A input.wav output.prm

它将提取19个MFCC + log-energy系数+一阶和二阶delta系数。能量系数是第19个,您需要在EnergyDetector配置文件中指定。

然后,您将以以下方式运行EnergyDetector:

EnergyDetector --config cfg/EnergyDetector.cfg --inputFeatureFilename output 

如果您使用答案末尾找到的配置文件,则需要将output.prm放在prm/中,并且您会在lbl/中找到分割结果。
作为参考,我附上我的EnergyDetector配置文件:
*** EnergyDetector Config File
***

loadFeatureFileExtension        .prm
minLLK                          -200
maxLLK                          1000
bigEndian                       false
loadFeatureFileFormat           SPRO4
saveFeatureFileFormat           SPRO4
saveFeatureFileSPro3DataKind    FBCEPSTRA
featureServerBufferSize         ALL_FEATURES
featureServerMemAlloc           50000000
featureFilesPath                prm/
mixtureFilesPath                gmm/
lstPath                         lst/
labelOutputFrames               speech
labelSelectedFrames             all
addDefaultLabel                 true
defaultLabel                    all
saveLabelFileExtension          .lbl
labelFilesPath                  lbl/    
frameLength                     0.01
segmentalMode                   file
nbTrainIt                       8       
varianceFlooring                0.0001
varianceCeiling                 1.5     
alpha                           0.25
mixtureDistribCount             3
featureServerMask               19      
vectSize                        1
baggedFrameProbabilityInit      0.1
thresholdMode                   weight

CMU Sphinx

CMU Sphinx语音识别软件包含内置的VAD。它用C语言编写,您可能可以对其进行修改以生成标签文件。

最近新增了GStreamer支持。这意味着您可以在GStreamer媒体流中使用其VAD。请参见使用PocketSphinx与GStreamer和Python-> 'vader'元素

其他VADs

我还使用过修改后的AMR1编解码器版本,该版本输出具有语音/非语音分类的文件,但我找不到其在线源代码,抱歉。


太好了,非常详细的回答。谢谢! - stef
1
@stef 您太客气了。我希望您发现它有用,并成功完成了您的任务,这是很困难的! - Andrea Spadaccini
你好,我尝试了你的指示,但是出现了问题。我使用了一个文件,它报告说它是“RIFF(小端)数据,WAVE音频,Microsoft PCM,16位,立体声16000 Hz”。 正在为[../output]进行基于能量的静默检测 (SegTools)标签格式为LIARAL [InvalidDataException 0x10f19b0] message = “错误的头部” - stackoverflow128

3

webrtcvad是Google优秀的WebRTC语音活动检测代码的Python封装。

它附带一个名为example.py的文件,正好可以满足您的需求:给定一个.wav文件,它会找到每个人说话的实例,并将其写入新的、单独的.wav文件中。

如果example.py没有完全满足您的要求,webrtcvad API非常简单:

import webrtcvad

vad = webrtcvad.Vad()
# sample must be 16-bit PCM audio data, either 8KHz, 16KHz or 32Khz,
# and 10, 20, or 30 milliseconds long.
print vad.is_voiced(sample)

2

你好,pyAudioAnalysis 提供了去除静音的功能。

在这个库中,去除静音可以非常简单:

from pyAudioAnalysis import audioBasicIO as aIO
from pyAudioAnalysis import audioSegmentation as aS

[Fs, x] = aIO.readAudioFile("data/recording1.wav")
segments = aS.silenceRemoval(x, 
                             Fs, 
                             0.020, 
                             0.020, 
                             smoothWindow=1.0, 
                             Weight=0.3, 
                             plot=True)

silenceRemoval()实现参考:https://github.com/tyiannak/pyAudioAnalysis/blob/944f1d777bc96717d2793f257c3b36b1acf1713a/pyAudioAnalysis/audioSegmentation.py#L670

在内部,removal()遵循半监督方法:首先,训练SVM模型以区分高能量和低能量的短期帧。为此,使用最高10%的能量框架和最低10%的框架。然后,在整个记录上应用SVM(具有概率输出),并使用动态阈值检测活动段。

参考文献:https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0144610


1
这是一个相当不错的库!您能否也发布一些示例代码片段来填充一下这个答案? - SJoshi
正如@SJoshi所说,如果您能添加一些展示如何使用pyAudioAnalysis的代码,那将会非常有帮助。这将使那些看到您的答案的人更容易使用它。 - Wai Ha Lee
如果音频中没有静默,只有言语和音乐片段,那怎么办呢?Pyaudio分析能处理这种情况吗?此外,如果您能添加一些代码就更好了。 - kRazzy R
可以的,如果你训练一个“分段分类器”,然后应用固定大小的分段。 - Theodore Giannakopoulos

0

2
就像我为Theodore写的那样,你的回答中提供一个示例会极大地改善它。这样我们就不完全依赖链接了。 - SJoshi
请Ashutosh先生按照StackOverflow推荐的指南添加完整的答案。 - kRazzy R

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接