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 <stdlib.h>
12
13#include "testing/gtest/include/gtest/gtest.h"
14#include "webrtc/common_audio/vad/vad_unittest.h"
15#include "webrtc/typedefs.h"
16
17extern "C" {
18#include "webrtc/common_audio/vad/vad_core.h"
19#include "webrtc/common_audio/vad/vad_filterbank.h"
20}
21
22namespace {
23
24const int kNumValidFrameLengths = 3;
25
26TEST_F(VadTest, vad_filterbank) {
27  VadInstT* self = reinterpret_cast<VadInstT*>(malloc(sizeof(VadInstT)));
28  static const int16_t kReference[kNumValidFrameLengths] = { 48, 11, 11 };
29  static const int16_t kFeatures[kNumValidFrameLengths * kNumChannels] = {
30      1213, 759, 587, 462, 434, 272,
31      1479, 1385, 1291, 1200, 1103, 1099,
32      1732, 1692, 1681, 1629, 1436, 1436
33  };
34  static const int16_t kOffsetVector[kNumChannels] = {
35      368, 368, 272, 176, 176, 176 };
36  int16_t features[kNumChannels];
37
38  // Construct a speech signal that will trigger the VAD in all modes. It is
39  // known that (i * i) will wrap around, but that doesn't matter in this case.
40  int16_t speech[kMaxFrameLength];
41  for (int16_t i = 0; i < kMaxFrameLength; ++i) {
42    speech[i] = (i * i);
43  }
44
45  int frame_length_index = 0;
46  ASSERT_EQ(0, WebRtcVad_InitCore(self));
47  for (size_t j = 0; j < kFrameLengthsSize; ++j) {
48    if (ValidRatesAndFrameLengths(8000, kFrameLengths[j])) {
49      EXPECT_EQ(kReference[frame_length_index],
50                WebRtcVad_CalculateFeatures(self, speech, kFrameLengths[j],
51                                            features));
52      for (int k = 0; k < kNumChannels; ++k) {
53        EXPECT_EQ(kFeatures[k + frame_length_index * kNumChannels],
54                  features[k]);
55      }
56      frame_length_index++;
57    }
58  }
59  EXPECT_EQ(kNumValidFrameLengths, frame_length_index);
60
61  // Verify that all zeros in gives kOffsetVector out.
62  memset(speech, 0, sizeof(speech));
63  ASSERT_EQ(0, WebRtcVad_InitCore(self));
64  for (size_t j = 0; j < kFrameLengthsSize; ++j) {
65    if (ValidRatesAndFrameLengths(8000, kFrameLengths[j])) {
66      EXPECT_EQ(0, WebRtcVad_CalculateFeatures(self, speech, kFrameLengths[j],
67                                               features));
68      for (int k = 0; k < kNumChannels; ++k) {
69        EXPECT_EQ(kOffsetVector[k], features[k]);
70      }
71    }
72  }
73
74  // Verify that all ones in gives kOffsetVector out. Any other constant input
75  // will have a small impact in the sub bands.
76  for (int16_t i = 0; i < kMaxFrameLength; ++i) {
77    speech[i] = 1;
78  }
79  for (size_t j = 0; j < kFrameLengthsSize; ++j) {
80    if (ValidRatesAndFrameLengths(8000, kFrameLengths[j])) {
81      ASSERT_EQ(0, WebRtcVad_InitCore(self));
82      EXPECT_EQ(0, WebRtcVad_CalculateFeatures(self, speech, kFrameLengths[j],
83                                               features));
84      for (int k = 0; k < kNumChannels; ++k) {
85        EXPECT_EQ(kOffsetVector[k], features[k]);
86      }
87    }
88  }
89
90  free(self);
91}
92}  // namespace
93