当前位置: 首页 > 知识库问答 >
问题:

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

姚永年
2023-03-14

目前,我正在解析wav文件并将样本存储在std::vector中

解析的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\u帧在16000 Hz时为10 ms(320字节)的音频:

int is\u voiced=WebRtcVad\u进程(vad,16000,audio\u 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个答案

廉博赡
2023-03-14

我首先要说的是,不,我不认为你能够使用VAD将话语分割成单个单词。来自维基百科中关于语音分割的文章:

人们可能会认为许多书面语言(如英语或西班牙语)使用的词间空格会对应于口语版本中的停顿,但只有在非常缓慢的讲话中才会如此,因为说话者故意插入这些停顿。在正常的讲话中,人们通常会发现许多连续的单词被说出来,它们之间没有停顿,并且一个单词的最后音通常会与下一个单词的最初音平滑地融合或融合。

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

>

  • 在运行VAD之前,您需要将WAV文件(可压缩)解码为原始PCM音频数据。参见例如C/C中的读取和处理WAV文件数据。或者,在运行代码之前,可以使用类似sox的方法将WAV文件转换为原始音频。此命令将任何格式的WAV文件转换为WebRTCVAD期望的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函数。

    要进行词级切分,您可能需要找到一个语音识别库,该库可以进行切分或访问所需的信息。E、 Kaldi邮件列表上的这个帖子似乎在讨论如何通过单词进行分段。

  •  类似资料:
    • WebRTC只能获取视频,但是没有音频 希望提供一些排查思路

    • 我正在尝试使用webrtc和socket通过getUserMedia()获取音频。io将其发送到服务器(socket.io支持音频、视频、二进制数据),然后服务器将其广播到所有连接的客户端。问题是,当流到达连接的客户端时,它会转换为JSON对象,而不是媒体流对象。所以我无法发送音频,我也尝试了套接字。io流模块,但我认为未成功。您能帮我正确捕获音频流并将其发送到所有连接的客户端吗。 下面是发送数据

    • 我在android上使用APPRTCdemo应用程序。我试着让它播放来自另一个同龄人的声音,音量与Android设置中设置的音量一样大。因此,如果用户将设备静音,则不会听到音频。我几乎尝试了每一个Android API调用,但似乎对音量没有任何影响。以下是我尝试过的东西:AudioManager AudioManager=(AudioManager)_context.getSystemServic

    • 更新 我在这里找到了一个使用的高通滤波器示例。在我的代码中这样实现它。 在我实际测试低声音是否被滤波器静音之前,我遇到了一个问题。使用几秒钟后将音频完全静音。我尝试了0,1500等。几秒钟后,它会变得安静。 原始帖子 我使用下面的约束来抑制噪音。 但我也想静音一些更高的频率。即使我在某个表面上慢慢移动手机,麦克风也会捕捉到噪音并将其发送给其他同伴。它甚至会捕捉到我的呼吸声,并在我将其放在支票附近时

    • 概述 getUserMedia 概述 范例:获取摄像头 范例:捕获麦克风声音 捕获的限定条件 MediaStreamTrack.getSources() RTCPeerConnectionl,RTCDataChannel RTCPeerConnectionl RTCDataChannel 外部函数库 参考链接 概述 WebRTC是“网络实时通信”(Web Real Time Communicati

    • 概述 getUserMedia 概述 范例:获取摄像头 范例:捕获麦克风声音 捕获的限定条件 MediaStreamTrack.getSources() RTCPeerConnectionl,RTCDataChannel RTCPeerConnectionl RTCDataChannel 外部函数库 参考链接 概述 WebRTC是“网络实时通信”(Web Real Time Communicati