aboutsummaryrefslogtreecommitdiff
path: root/src/common_audio/vad/main/source/vad_gmm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/common_audio/vad/main/source/vad_gmm.c')
-rw-r--r--src/common_audio/vad/main/source/vad_gmm.c70
1 files changed, 70 insertions, 0 deletions
diff --git a/src/common_audio/vad/main/source/vad_gmm.c b/src/common_audio/vad/main/source/vad_gmm.c
new file mode 100644
index 0000000000..23d12fb335
--- /dev/null
+++ b/src/common_audio/vad/main/source/vad_gmm.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+
+/*
+ * This file includes the implementation of the internal VAD call
+ * WebRtcVad_GaussianProbability. For function description, see vad_gmm.h.
+ */
+
+#include "vad_gmm.h"
+#include "signal_processing_library.h"
+#include "vad_const.h"
+
+WebRtc_Word32 WebRtcVad_GaussianProbability(WebRtc_Word16 in_sample,
+ WebRtc_Word16 mean,
+ WebRtc_Word16 std,
+ WebRtc_Word16 *delta)
+{
+ WebRtc_Word16 tmp16, tmpDiv, tmpDiv2, expVal, tmp16_1, tmp16_2;
+ WebRtc_Word32 tmp32, y32;
+
+ // Calculate tmpDiv=1/std, in Q10
+ tmp32 = (WebRtc_Word32)WEBRTC_SPL_RSHIFT_W16(std,1) + (WebRtc_Word32)131072; // 1 in Q17
+ tmpDiv = (WebRtc_Word16)WebRtcSpl_DivW32W16(tmp32, std); // Q17/Q7 = Q10
+
+ // Calculate tmpDiv2=1/std^2, in Q14
+ tmp16 = WEBRTC_SPL_RSHIFT_W16(tmpDiv, 2); // From Q10 to Q8
+ tmpDiv2 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmp16, tmp16, 2); // (Q8 * Q8)>>2 = Q14
+
+ tmp16 = WEBRTC_SPL_LSHIFT_W16(in_sample, 3); // Q7
+ tmp16 = tmp16 - mean; // Q7 - Q7 = Q7
+
+ // To be used later, when updating noise/speech model
+ // delta = (x-m)/std^2, in Q11
+ *delta = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT(tmpDiv2, tmp16, 10); //(Q14*Q7)>>10 = Q11
+
+ // Calculate tmp32=(x-m)^2/(2*std^2), in Q10
+ tmp32 = (WebRtc_Word32)WEBRTC_SPL_MUL_16_16_RSFT(*delta, tmp16, 9); // One shift for /2
+
+ // Calculate expVal ~= exp(-(x-m)^2/(2*std^2)) ~= exp2(-log2(exp(1))*tmp32)
+ if (tmp32 < kCompVar)
+ {
+ // Calculate tmp16 = log2(exp(1))*tmp32 , in Q10
+ tmp16 = (WebRtc_Word16)WEBRTC_SPL_MUL_16_16_RSFT((WebRtc_Word16)tmp32,
+ kLog10Const, 12);
+ tmp16 = -tmp16;
+ tmp16_2 = (WebRtc_Word16)(0x0400 | (tmp16 & 0x03FF));
+ tmp16_1 = (WebRtc_Word16)(tmp16 ^ 0xFFFF);
+ tmp16 = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W16(tmp16_1, 10);
+ tmp16 += 1;
+ // Calculate expVal=log2(-tmp32), in Q10
+ expVal = (WebRtc_Word16)WEBRTC_SPL_RSHIFT_W32((WebRtc_Word32)tmp16_2, tmp16);
+
+ } else
+ {
+ expVal = 0;
+ }
+
+ // Calculate y32=(1/std)*exp(-(x-m)^2/(2*std^2)), in Q20
+ y32 = WEBRTC_SPL_MUL_16_16(tmpDiv, expVal); // Q10 * Q10 = Q20
+
+ return y32; // Q20
+}