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 "modules/audio_processing/vad/standalone_vad.h"
12 
13 #include <string.h>
14 
15 #include <memory>
16 
17 #include "modules/include/module_common_types.h"
18 #include "test/gtest.h"
19 #include "test/testsupport/fileutils.h"
20 
21 namespace webrtc {
22 
TEST(StandaloneVadTest,Api)23 TEST(StandaloneVadTest, Api) {
24   std::unique_ptr<StandaloneVad> vad(StandaloneVad::Create());
25   int16_t data[kLength10Ms] = {0};
26 
27   // Valid frame length (for 32 kHz rate), but not what the VAD is expecting.
28   EXPECT_EQ(-1, vad->AddAudio(data, 320));
29 
30   const size_t kMaxNumFrames = 3;
31   double p[kMaxNumFrames];
32   for (size_t n = 0; n < kMaxNumFrames; n++)
33     EXPECT_EQ(0, vad->AddAudio(data, kLength10Ms));
34 
35   // Pretend |p| is shorter that it should be.
36   EXPECT_EQ(-1, vad->GetActivity(p, kMaxNumFrames - 1));
37 
38   EXPECT_EQ(0, vad->GetActivity(p, kMaxNumFrames));
39 
40   // Ask for activity when buffer is empty.
41   EXPECT_EQ(-1, vad->GetActivity(p, kMaxNumFrames));
42 
43   // Should reset and result in one buffer.
44   for (size_t n = 0; n < kMaxNumFrames + 1; n++)
45     EXPECT_EQ(0, vad->AddAudio(data, kLength10Ms));
46   EXPECT_EQ(0, vad->GetActivity(p, 1));
47 
48   // Wrong modes
49   EXPECT_EQ(-1, vad->set_mode(-1));
50   EXPECT_EQ(-1, vad->set_mode(4));
51 
52   // Valid mode.
53   const int kMode = 2;
54   EXPECT_EQ(0, vad->set_mode(kMode));
55   EXPECT_EQ(kMode, vad->mode());
56 }
57 
58 #if defined(WEBRTC_IOS)
TEST(StandaloneVadTest,DISABLED_ActivityDetection)59 TEST(StandaloneVadTest, DISABLED_ActivityDetection) {
60 #else
61 TEST(StandaloneVadTest, ActivityDetection) {
62 #endif
63   std::unique_ptr<StandaloneVad> vad(StandaloneVad::Create());
64   const size_t kDataLength = kLength10Ms;
65   int16_t data[kDataLength] = {0};
66 
67   FILE* pcm_file =
68       fopen(test::ResourcePath("audio_processing/agc/agc_audio", "pcm").c_str(),
69             "rb");
70   ASSERT_TRUE(pcm_file != NULL);
71 
72   FILE* reference_file = fopen(
73       test::ResourcePath("audio_processing/agc/agc_vad", "dat").c_str(), "rb");
74   ASSERT_TRUE(reference_file != NULL);
75 
76   // Reference activities are prepared with 0 aggressiveness.
77   ASSERT_EQ(0, vad->set_mode(0));
78 
79   // Stand-alone VAD can operate on 1, 2 or 3 frames of length 10 ms. The
80   // reference file is created for 30 ms frame.
81   const int kNumVadFramesToProcess = 3;
82   int num_frames = 0;
83   while (fread(data, sizeof(int16_t), kDataLength, pcm_file) == kDataLength) {
84     vad->AddAudio(data, kDataLength);
85     num_frames++;
86     if (num_frames == kNumVadFramesToProcess) {
87       num_frames = 0;
88       int referece_activity;
89       double p[kNumVadFramesToProcess];
90       EXPECT_EQ(1u, fread(&referece_activity, sizeof(referece_activity), 1,
91                           reference_file));
92       int activity = vad->GetActivity(p, kNumVadFramesToProcess);
93       EXPECT_EQ(referece_activity, activity);
94       if (activity != 0) {
95         // When active, probabilities are set to 0.5.
96         for (int n = 0; n < kNumVadFramesToProcess; n++)
97           EXPECT_EQ(0.5, p[n]);
98       } else {
99         // When inactive, probabilities are set to 0.01.
100         for (int n = 0; n < kNumVadFramesToProcess; n++)
101           EXPECT_EQ(0.01, p[n]);
102       }
103     }
104   }
105   fclose(reference_file);
106   fclose(pcm_file);
107 }
108 }  // namespace webrtc
109