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