我正在寻找像 Discord/Mumble/Teamspeak 这样的实时VAD实现。
我的目标是拥有一个系统,让我可以对所有 VoIP 应用程序使用相同的 VAD,以及可以用来促进 VAD 用于一键通应用程序的东西。
Mumble 是开源的,尽管我在查看时找不到我需要的东西。
我正在寻找像 Discord/Mumble/Teamspeak 这样的实时VAD实现。
我的目标是拥有一个系统,让我可以对所有 VoIP 应用程序使用相同的 VAD,以及可以用来促进 VAD 用于一键通应用程序的东西。
Mumble 是开源的,尽管我在查看时找不到我需要的东西。
所以,这不是我想要的质量答案,但 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 会转换该概率值(概率:) 转换为百分比,然后将其与内部设置进行比较。
所以这里感兴趣的算法绝对不在 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)));