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