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 "common_audio/vad/include/webrtc_vad.h"
12 
13 #include <stdlib.h>
14 #include <string.h>
15 
16 #include "common_audio/signal_processing/include/signal_processing_library.h"
17 #include "common_audio/vad/vad_core.h"
18 
19 static const int kInitCheck = 42;
20 static const int kValidRates[] = { 8000, 16000, 32000, 48000 };
21 static const size_t kRatesSize = sizeof(kValidRates) / sizeof(*kValidRates);
22 static const int kMaxFrameLengthMs = 30;
23 
WebRtcVad_Create()24 VadInst* WebRtcVad_Create() {
25   VadInstT* self = (VadInstT*)malloc(sizeof(VadInstT));
26 
27   WebRtcSpl_Init();
28   self->init_flag = 0;
29 
30   return (VadInst*)self;
31 }
32 
WebRtcVad_Free(VadInst * handle)33 void WebRtcVad_Free(VadInst* handle) {
34   free(handle);
35 }
36 
37 // TODO(bjornv): Move WebRtcVad_InitCore() code here.
WebRtcVad_Init(VadInst * handle)38 int WebRtcVad_Init(VadInst* handle) {
39   // Initialize the core VAD component.
40   return WebRtcVad_InitCore((VadInstT*) handle);
41 }
42 
43 // TODO(bjornv): Move WebRtcVad_set_mode_core() code here.
WebRtcVad_set_mode(VadInst * handle,int mode)44 int WebRtcVad_set_mode(VadInst* handle, int mode) {
45   VadInstT* self = (VadInstT*) handle;
46 
47   if (handle == NULL) {
48     return -1;
49   }
50   if (self->init_flag != kInitCheck) {
51     return -1;
52   }
53 
54   return WebRtcVad_set_mode_core(self, mode);
55 }
56 
WebRtcVad_Process(VadInst * handle,int fs,const int16_t * audio_frame,size_t frame_length)57 int WebRtcVad_Process(VadInst* handle, int fs, const int16_t* audio_frame,
58                       size_t frame_length) {
59   int vad = -1;
60   VadInstT* self = (VadInstT*) handle;
61 
62   if (handle == NULL) {
63     return -1;
64   }
65 
66   if (self->init_flag != kInitCheck) {
67     return -1;
68   }
69   if (audio_frame == NULL) {
70     return -1;
71   }
72   if (WebRtcVad_ValidRateAndFrameLength(fs, frame_length) != 0) {
73     return -1;
74   }
75 
76   if (fs == 48000) {
77       vad = WebRtcVad_CalcVad48khz(self, audio_frame, frame_length);
78   } else if (fs == 32000) {
79     vad = WebRtcVad_CalcVad32khz(self, audio_frame, frame_length);
80   } else if (fs == 16000) {
81     vad = WebRtcVad_CalcVad16khz(self, audio_frame, frame_length);
82   } else if (fs == 8000) {
83     vad = WebRtcVad_CalcVad8khz(self, audio_frame, frame_length);
84   }
85 
86   if (vad > 0) {
87     vad = 1;
88   }
89   return vad;
90 }
91 
WebRtcVad_ValidRateAndFrameLength(int rate,size_t frame_length)92 int WebRtcVad_ValidRateAndFrameLength(int rate, size_t frame_length) {
93   int return_value = -1;
94   size_t i;
95   int valid_length_ms;
96   size_t valid_length;
97 
98   // We only allow 10, 20 or 30 ms frames. Loop through valid frame rates and
99   // see if we have a matching pair.
100   for (i = 0; i < kRatesSize; i++) {
101     if (kValidRates[i] == rate) {
102       for (valid_length_ms = 10; valid_length_ms <= kMaxFrameLengthMs;
103           valid_length_ms += 10) {
104         valid_length = (size_t)(kValidRates[i] / 1000 * valid_length_ms);
105         if (frame_length == valid_length) {
106           return_value = 0;
107           break;
108         }
109       }
110       break;
111     }
112   }
113 
114   return return_value;
115 }
116