1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
11f24ac5923cbe5e806fac59a0d15e32567553ce8epbos@webrtc.org#include "webrtc/common_audio/vad/include/webrtc_vad.h"
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <stdlib.h>
14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <string.h>
15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
16f24ac5923cbe5e806fac59a0d15e32567553ce8epbos@webrtc.org#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
17f24ac5923cbe5e806fac59a0d15e32567553ce8epbos@webrtc.org#include "webrtc/common_audio/vad/vad_core.h"
18f24ac5923cbe5e806fac59a0d15e32567553ce8epbos@webrtc.org#include "webrtc/typedefs.h"
19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic const int kInitCheck = 42;
21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic const int kValidRates[] = { 8000, 16000, 32000, 48000 };
22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic const size_t kRatesSize = sizeof(kValidRates) / sizeof(*kValidRates);
23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic const int kMaxFrameLengthMs = 30;
24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint WebRtcVad_Create(VadInst** handle) {
26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VadInstT* self = NULL;
27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (handle == NULL) {
29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  *handle = NULL;
33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  self = (VadInstT*) malloc(sizeof(VadInstT));
34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  *handle = (VadInst*) self;
35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (self == NULL) {
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  WebRtcSpl_Init();
41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  self->init_flag = 0;
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
47642e80e5fed3b05fdada3dd8b5dbdfabbccaa5cebjornv@webrtc.orgvoid WebRtcVad_Free(VadInst* handle) {
48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  free(handle);
49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// TODO(bjornv): Move WebRtcVad_InitCore() code here.
52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint WebRtcVad_Init(VadInst* handle) {
53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Initialize the core VAD component.
54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return WebRtcVad_InitCore((VadInstT*) handle);
55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// TODO(bjornv): Move WebRtcVad_set_mode_core() code here.
58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint WebRtcVad_set_mode(VadInst* handle, int mode) {
59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VadInstT* self = (VadInstT*) handle;
60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (handle == NULL) {
62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (self->init_flag != kInitCheck) {
65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return WebRtcVad_set_mode_core(self, mode);
69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
71785c2fdd22c9ad2d172c0976d1224bbe44073bc7andrew@webrtc.orgint WebRtcVad_Process(VadInst* handle, int fs, const int16_t* audio_frame,
72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                      int frame_length) {
73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int vad = -1;
74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VadInstT* self = (VadInstT*) handle;
75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (handle == NULL) {
77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (self->init_flag != kInitCheck) {
81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (audio_frame == NULL) {
84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (WebRtcVad_ValidRateAndFrameLength(fs, frame_length) != 0) {
87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (fs == 48000) {
91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      vad = WebRtcVad_CalcVad48khz(self, audio_frame, frame_length);
92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  } else if (fs == 32000) {
93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    vad = WebRtcVad_CalcVad32khz(self, audio_frame, frame_length);
94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  } else if (fs == 16000) {
95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    vad = WebRtcVad_CalcVad16khz(self, audio_frame, frame_length);
96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  } else if (fs == 8000) {
97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    vad = WebRtcVad_CalcVad8khz(self, audio_frame, frame_length);
98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vad > 0) {
101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    vad = 1;
102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return vad;
104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint WebRtcVad_ValidRateAndFrameLength(int rate, int frame_length) {
107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int return_value = -1;
108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  size_t i;
109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int valid_length_ms;
110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int valid_length;
111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // We only allow 10, 20 or 30 ms frames. Loop through valid frame rates and
113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // see if we have a matching pair.
114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  for (i = 0; i < kRatesSize; i++) {
115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (kValidRates[i] == rate) {
116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      for (valid_length_ms = 10; valid_length_ms <= kMaxFrameLengthMs;
117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org          valid_length_ms += 10) {
118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        valid_length = (kValidRates[i] / 1000 * valid_length_ms);
119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (frame_length == valid_length) {
120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org          return_value = 0;
121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org          break;
122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      }
124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      break;
125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return return_value;
129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
130