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