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/vad_unittest.h"
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <stdlib.h>
14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
15f24ac5923cbe5e806fac59a0d15e32567553ce8epbos@webrtc.org#include "testing/gtest/include/gtest/gtest.h"
16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
17f24ac5923cbe5e806fac59a0d15e32567553ce8epbos@webrtc.org#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
18f24ac5923cbe5e806fac59a0d15e32567553ce8epbos@webrtc.org#include "webrtc/common_audio/vad/include/webrtc_vad.h"
19f24ac5923cbe5e806fac59a0d15e32567553ce8epbos@webrtc.org#include "webrtc/typedefs.h"
20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVadTest::VadTest() {}
22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid VadTest::SetUp() {}
24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid VadTest::TearDown() {}
26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Returns true if the rate and frame length combination is valid.
28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VadTest::ValidRatesAndFrameLengths(int rate, int frame_length) {
29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (rate == 8000) {
30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (frame_length == 80 || frame_length == 160 || frame_length == 240) {
31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return true;
32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  } else if (rate == 16000) {
35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (frame_length == 160 || frame_length == 320 || frame_length == 480) {
36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return true;
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  } else if (rate == 32000) {
40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (frame_length == 320 || frame_length == 640 || frame_length == 960) {
41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return true;
42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  } else if (rate == 48000) {
45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (frame_length == 480 || frame_length == 960 || frame_length == 1440) {
46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return true;
47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return false;
52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace {
55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTEST_F(VadTest, ApiTest) {
57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // This API test runs through the APIs for all possible valid and invalid
58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // combinations.
59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VadInst* handle = NULL;
61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int16_t zeros[kMaxFrameLength] = { 0 };
62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Construct a speech signal that will trigger the VAD in all modes. It is
64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // known that (i * i) will wrap around, but that doesn't matter in this case.
65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int16_t speech[kMaxFrameLength];
66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  for (int16_t i = 0; i < kMaxFrameLength; i++) {
67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    speech[i] = (i * i);
68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // NULL instance tests
71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  EXPECT_EQ(-1, WebRtcVad_Create(NULL));
72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  EXPECT_EQ(-1, WebRtcVad_Init(NULL));
73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  EXPECT_EQ(-1, WebRtcVad_set_mode(NULL, kModes[0]));
74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  EXPECT_EQ(-1, WebRtcVad_Process(NULL, kRates[0], speech, kFrameLengths[0]));
75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // WebRtcVad_Create()
77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ASSERT_EQ(0, WebRtcVad_Create(&handle));
78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Not initialized tests
80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  EXPECT_EQ(-1, WebRtcVad_Process(handle, kRates[0], speech, kFrameLengths[0]));
81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  EXPECT_EQ(-1, WebRtcVad_set_mode(handle, kModes[0]));
82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // WebRtcVad_Init() test
84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ASSERT_EQ(0, WebRtcVad_Init(handle));
85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // WebRtcVad_set_mode() invalid modes tests. Tries smallest supported value
87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // minus one and largest supported value plus one.
88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  EXPECT_EQ(-1, WebRtcVad_set_mode(handle,
89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                   WebRtcSpl_MinValueW32(kModes,
90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                         kModesSize) - 1));
91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  EXPECT_EQ(-1, WebRtcVad_set_mode(handle,
92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                   WebRtcSpl_MaxValueW32(kModes,
93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                         kModesSize) + 1));
94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // WebRtcVad_Process() tests
96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // NULL speech pointer
97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  EXPECT_EQ(-1, WebRtcVad_Process(handle, kRates[0], NULL, kFrameLengths[0]));
98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Invalid sampling rate
99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  EXPECT_EQ(-1, WebRtcVad_Process(handle, 9999, speech, kFrameLengths[0]));
100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // All zeros as input should work
101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  EXPECT_EQ(0, WebRtcVad_Process(handle, kRates[0], zeros, kFrameLengths[0]));
102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  for (size_t k = 0; k < kModesSize; k++) {
103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Test valid modes
104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    EXPECT_EQ(0, WebRtcVad_set_mode(handle, kModes[k]));
105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Loop through sampling rate and frame length combinations
106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    for (size_t i = 0; i < kRatesSize; i++) {
107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      for (size_t j = 0; j < kFrameLengthsSize; j++) {
108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (ValidRatesAndFrameLengths(kRates[i], kFrameLengths[j])) {
109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org          EXPECT_EQ(1, WebRtcVad_Process(handle,
110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                         kRates[i],
111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                         speech,
112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                         kFrameLengths[j]));
113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        } else {
114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org          EXPECT_EQ(-1, WebRtcVad_Process(handle,
115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                          kRates[i],
116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                          speech,
117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                          kFrameLengths[j]));
118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      }
120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
123642e80e5fed3b05fdada3dd8b5dbdfabbccaa5cebjornv@webrtc.org  WebRtcVad_Free(handle);
124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgTEST_F(VadTest, ValidRatesFrameLengths) {
127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // This test verifies valid and invalid rate/frame_length combinations. We
128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // loop through some sampling rates and frame lengths from negative values to
129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // values larger than possible.
130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  const int kNumRates = 12;
131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  const int kRates[kNumRates] = {
132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    -8000, -4000, 0, 4000, 8000, 8001, 15999, 16000, 32000, 48000, 48001, 96000
133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  };
134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  const int kNumFrameLengths = 13;
136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  const int kFrameLengths[kNumFrameLengths] = {
137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    -10, 0, 80, 81, 159, 160, 240, 320, 480, 640, 960, 1440, 2000
138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  };
139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  for (int i = 0; i < kNumRates; i++) {
141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    for (int j = 0; j < kNumFrameLengths; j++) {
142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      if (ValidRatesAndFrameLengths(kRates[i], kFrameLengths[j])) {
143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        EXPECT_EQ(0, WebRtcVad_ValidRateAndFrameLength(kRates[i],
144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                       kFrameLengths[j]));
145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      } else {
146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        EXPECT_EQ(-1, WebRtcVad_ValidRateAndFrameLength(kRates[i],
147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                        kFrameLengths[j]));
148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      }
149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// TODO(bjornv): Add a process test, run on file.
154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}  // namespace
156