webRTC:如何通过从WAV文件获取的样本将webRTC的VAD应用于音频

时间:2017-06-09 11:55:19

标签: c++ audio webrtc speech-recognition voice-recognition

目前,我正在解析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
}

现在,我不确定这是否正确。另外,我也不确定这是否给了我正确的输出。

所以,

  • 是否可以使用直接从wav文件解析的样本,还是需要进行一些处理?
  • 我正在寻找正确的功能来完成这项工作吗?
  • 如何使用该功能在音频流上正确执行VAD?
  • 是否可以区分口语?
  • 检查我得到的输出是否正确的最佳方法是什么?
  • 如果没有,执行此任务的最佳方法是什么?

1 个答案:

答案 0 :(得分:6)

我首先要说不,我不认为你能用VAD将话语分成单个词。来自article on speech segmentation in Wikipedia

  

有人可能会期望许多人写的字间空格   英语或西班牙语等语言与其中的停顿相对应   口语版,但只有在非常缓慢的演讲中才会出现这种情况   扬声器故意插入那些停顿。在正常的演讲中,一个   通常会发现许多连续的单词没有暂停   在它们之间,通常一个词的最终声音平滑地混合或   与下一个单词的初始声音融合。

那就是说,我会尝试回答你的其他问题。

  1. 在运行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
    
  2. 看起来您正在使用正确的功能。更具体地说,你应该这样做:

    #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)
    }
    
  3. 要查看它是否有效,您可以运行已知文件并查看是否获得了预期的结果。例如,你可以从处理沉默开始,并确认你从未(或很少 - 这个算法不完美)看到从WebRtcVad_Process回来的浊音结果。然后你可以尝试一个完全沉默的文件,除了中间的一个简短的话语,等等。如果你想要与现有的测试进行比较,py-webrtcvad模块有一个单元测试来做到这一点;请参阅test_process_file function

  4. 要进行单词级分段,您可能需要找到一个语音识别库来执行它,或者让您访问所需的信息。例如。 this thread on the Kaldi mailing list似乎在讨论如何按字词划分。