1788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org/*
2788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org *
4788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org *  Use of this source code is governed by a BSD-style license
5788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org *  that can be found in the LICENSE file in the root of the source
6788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org *  tree. An additional intellectual property rights grant can be found
7788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org *  in the file PATENTS.  All contributing project authors may
8788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org */
10788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org
11ecf6b81644af9823dbff5c24a3d5b9bb596c0d5baluebs#include "webrtc/modules/audio_processing/vad/gmm.h"
12788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org
13788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org#include <math.h>
14788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org#include <stdlib.h>
15788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org
16788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org#include "webrtc/typedefs.h"
17788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org
18788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.orgnamespace webrtc {
19788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org
20788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.orgstatic const int kMaxDimension = 10;
21788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org
22ecf6b81644af9823dbff5c24a3d5b9bb596c0d5baluebsstatic void RemoveMean(const double* in,
23ecf6b81644af9823dbff5c24a3d5b9bb596c0d5baluebs                       const double* mean_vec,
24ecf6b81644af9823dbff5c24a3d5b9bb596c0d5baluebs                       int dimension,
25ecf6b81644af9823dbff5c24a3d5b9bb596c0d5baluebs                       double* out) {
26788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  for (int n = 0; n < dimension; ++n)
27788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    out[n] = in[n] - mean_vec[n];
28788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org}
29788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org
30ecf6b81644af9823dbff5c24a3d5b9bb596c0d5baluebsstatic double ComputeExponent(const double* in,
31ecf6b81644af9823dbff5c24a3d5b9bb596c0d5baluebs                              const double* covar_inv,
32788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org                              int dimension) {
33788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  double q = 0;
34788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  for (int i = 0; i < dimension; ++i) {
35788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    double v = 0;
36788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    for (int j = 0; j < dimension; j++)
37788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org      v += (*covar_inv++) * in[j];
38788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    q += v * in[i];
39788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
40788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  q *= -0.5;
41788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  return q;
42788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org}
43788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org
44788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.orgdouble EvaluateGmm(const double* x, const GmmParameters& gmm_parameters) {
45788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  if (gmm_parameters.dimension > kMaxDimension) {
46788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    return -1;  // This is invalid pdf so the caller can check this.
47788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
48788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  double f = 0;
49788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  double v[kMaxDimension];
50788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  const double* mean_vec = gmm_parameters.mean;
51788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  const double* covar_inv = gmm_parameters.covar_inverse;
52788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org
53788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  for (int n = 0; n < gmm_parameters.num_mixtures; n++) {
54788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    RemoveMean(x, mean_vec, gmm_parameters.dimension, v);
55788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    double q = ComputeExponent(v, covar_inv, gmm_parameters.dimension) +
56ecf6b81644af9823dbff5c24a3d5b9bb596c0d5baluebs               gmm_parameters.weight[n];
57788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    f += exp(q);
58788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    mean_vec += gmm_parameters.dimension;
59788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    covar_inv += gmm_parameters.dimension * gmm_parameters.dimension;
60788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
61788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  return f;
62788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org}
63788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org
64788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org}  // namespace webrtc
65