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