是否有可用的实时语音活动检测 (VAD) 实施?

信息处理 声音的 信号检测 参考实现
2022-02-18 18:04:38

我正在寻找像 Discord/Mumble/Teamspeak 这样的实时VAD实现。

我的目标是拥有一个系统,让我可以对所有 VoIP 应用程序使用相同的 VAD,以及可以用来促进 VAD 用于一键通应用程序的东西。

Mumble 是开源的,尽管我在查看时找不到我需要的东西。

1个回答

所以,这不是我想要的质量答案,但 Mumble VAD 是在 中AudioInput.c,因为快速浏览产生了:

speex_preprocess_ctl(sppPreprocess, SPEEX_PREPROCESS_GET_PROB, &prob);
fSpeechProb = static_cast<float>(prob) / 100.0f;

// clean microphone level: peak of filtered signal attenuated by AGC gain
dPeakCleanMic = qMax(dPeakSignal - gainValue, -96.0f);
float level = (g.s.vsVAD == Settings::SignalToNoise) ? fSpeechProb : (1.0f + dPeakCleanMic / 96.0f);

bool bIsSpeech = false;

if (level > g.s.fVADmax)
    bIsSpeech = true;

这里所做的是使用 FOSS 语音编解码器和实用程序包 Speex 来估计静音->语音转换。但是,Mumble 会转换该概率值(概率:[0,1]) 转换为百分比,然后将其与内部设置进行比较。

所以这里感兴趣的算法绝对不在 Mumble 中,而是在libspeexdsp 中

有趣的是,这基本上就是 speexdsp 的失败之处preprocess.dsp

/* FIXME: This VAD is a kludge */
st->speech_prob = Pframe;
if (st->vad_enabled)
{
    if (st->speech_prob > st->speech_prob_start || (st->was_speech && st->speech_prob > st->speech_prob_continue))
    {
        st->was_speech=1;
        return 1;
    } else
    {
        st->was_speech=0;
        return 0;
    }
} else {
    return 1;
}

所以,这实际上只是归结为当前音频帧的 SNR 估计:

/* Speech probability of presence for the entire frame is based on the average filterbank a priori SNR */
Zframe = 0;
for (i=N;i<N+M;i++)
    Zframe = ADD32(Zframe, EXTEND32(st->zeta[i]));
Pframe = QCONST16(.1f,15)+MULT16_16_Q15(QCONST16(.899f,15),qcurve(DIV32_16(Zframe,st->nbands)));