目前,我正在解析wav文件并在std::vector<int16_t> sample
中存储 samples 。现在,我想对这些数据应用VAD(语音活动检测)来找出语音的“区域”,更具体地说是单词的开头和结尾。
解析的wav文件是16KHz,16位PCM,单声道。我的代码是用C ++编写的。
我已经搜索过很多关于它的信息,但找不到关于webRTC的VAD功能的适当文档。
根据我的发现,我需要使用的功能是WebRtcVad_Process()
。它的原型如下:
int WebRtcVad_Process(VadInst* handle, int fs, const int16_t* audio_frame,
size_t frame_length)
从我在此处找到的内容:https://stackoverflow.com/a/36826564/6487831
发送到VAD的每个音频帧长度必须为10,20或30毫秒。 以下是假设audio_frame为16000 Hz的10 ms(320字节)音频的示例概要:
int is_voiced = WebRtcVad_Process(vad,16000,audio_frame,160);
这很有道理:
1 sample = 2B = 16 bits
SampleRate = 16000 sample/sec = 16 samples/ms
For 10 ms, no of samples = 160
所以,基于我已经实现了这个:
const int16_t * temp = sample.data();
for(int i = 0, ms = 0; i < sample.size(); i += 160, ms++)
{
int isActive = WebRtcVad_Process(vad, 16000, temp, 160); //10 ms window
std::cout<<ms<<" ms : "<<isActive<<std::endl;
temp = temp + 160; // processed 160 samples
}
现在,我不确定这是否正确。另外,我也不确定这是否给了我正确的输出。
所以,
答案 0 :(得分:6)
我首先要说不,我不认为你能用VAD将话语分成单个词。来自article on speech segmentation in Wikipedia:
有人可能会期望许多人写的字间空格 英语或西班牙语等语言与其中的停顿相对应 口语版,但只有在非常缓慢的演讲中才会出现这种情况 扬声器故意插入那些停顿。在正常的演讲中,一个 通常会发现许多连续的单词没有暂停 在它们之间,通常一个词的最终声音平滑地混合或 与下一个单词的初始声音融合。
那就是说,我会尝试回答你的其他问题。
在运行VAD之前,您需要将可以压缩的WAV文件解码为原始PCM音频数据。参见例如Reading and processing WAV file data in C/C++。或者,您可以使用sox
之类的东西在运行代码之前将WAV文件转换为原始音频。此命令将以WebRTCVAD期望的格式将任何格式的WAV文件转换为16 KHz,16位PCM:
sox my_file.wav -r 16000 -b 16 -c 1 -e signed-integer -B my_file.raw
看起来您正在使用正确的功能。更具体地说,你应该这样做:
#include "webrtc/common_audio/vad/include/webrtc_vad.h"
// ...
VadInst *vad;
WebRtcVad_Create(&vad);
WebRtcVad_Init(vad);
const int16_t * temp = sample.data();
for(int i = 0, ms = 0; i < sample.size(); i += 160, ms += 10)
{
int isActive = WebRtcVad_Process(vad, 16000, temp, 160); //10 ms window
std::cout << ms << " ms : " << isActive << std::endl;
temp = temp + 160; // processed 160 samples (320 bytes)
}
要查看它是否有效,您可以运行已知文件并查看是否获得了预期的结果。例如,你可以从处理沉默开始,并确认你从未(或很少 - 这个算法不完美)看到从WebRtcVad_Process
回来的浊音结果。然后你可以尝试一个完全沉默的文件,除了中间的一个简短的话语,等等。如果你想要与现有的测试进行比较,py-webrtcvad模块有一个单元测试来做到这一点;请参阅test_process_file
function。
要进行单词级分段,您可能需要找到一个语音识别库来执行它,或者让您访问所需的信息。例如。 this thread on the Kaldi mailing list似乎在讨论如何按字词划分。