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