1 /*
2 * Copyright (c) 2022 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/agc2/speech_probability_buffer.h"
12
13 #include <algorithm>
14
15 #include "test/gtest.h"
16
17 namespace webrtc {
18 namespace {
19
20 constexpr float kAbsError = 0.001f;
21 constexpr float kActivityThreshold = 0.9f;
22 constexpr float kLowProbabilityThreshold = 0.2f;
23 constexpr int kNumAnalysisFrames = 100;
24
25 } // namespace
26
TEST(SpeechProbabilityBufferTest,CheckSumAfterInitialization)27 TEST(SpeechProbabilityBufferTest, CheckSumAfterInitialization) {
28 SpeechProbabilityBuffer buffer(kLowProbabilityThreshold);
29
30 EXPECT_EQ(buffer.GetSumProbabilities(), 0.0f);
31 }
32
TEST(SpeechProbabilityBufferTest,CheckSumAfterUpdate)33 TEST(SpeechProbabilityBufferTest, CheckSumAfterUpdate) {
34 SpeechProbabilityBuffer buffer(kLowProbabilityThreshold);
35
36 buffer.Update(0.7f);
37
38 EXPECT_NEAR(buffer.GetSumProbabilities(), 0.7f, kAbsError);
39
40 buffer.Update(0.6f);
41
42 EXPECT_NEAR(buffer.GetSumProbabilities(), 1.3f, kAbsError);
43
44 for (int i = 0; i < kNumAnalysisFrames - 1; ++i) {
45 buffer.Update(1.0f);
46 }
47
48 EXPECT_NEAR(buffer.GetSumProbabilities(), 99.6f, kAbsError);
49 }
50
TEST(SpeechProbabilityBufferTest,CheckSumAfterReset)51 TEST(SpeechProbabilityBufferTest, CheckSumAfterReset) {
52 SpeechProbabilityBuffer buffer(kLowProbabilityThreshold);
53
54 buffer.Update(0.7f);
55 buffer.Update(0.6f);
56 buffer.Update(0.3f);
57
58 EXPECT_GT(buffer.GetSumProbabilities(), 0.0f);
59
60 buffer.Reset();
61
62 EXPECT_EQ(buffer.GetSumProbabilities(), 0.0f);
63 }
64
TEST(SpeechProbabilityBufferTest,CheckSumAfterTransientNotRemoved)65 TEST(SpeechProbabilityBufferTest, CheckSumAfterTransientNotRemoved) {
66 SpeechProbabilityBuffer buffer(kLowProbabilityThreshold);
67
68 buffer.Update(1.0f);
69 buffer.Update(1.0f);
70 buffer.Update(1.0f);
71 buffer.Update(1.0f);
72 buffer.Update(1.0f);
73 buffer.Update(1.0f);
74 buffer.Update(1.0f);
75 buffer.Update(1.0f);
76 buffer.Update(1.0f);
77
78 buffer.Update(0.0f);
79
80 EXPECT_NEAR(buffer.GetSumProbabilities(), 9.0f, kAbsError);
81
82 buffer.Update(0.0f);
83
84 EXPECT_NEAR(buffer.GetSumProbabilities(), 9.0f, kAbsError);
85 }
86
TEST(SpeechProbabilityBufferTest,CheckSumAfterTransientRemoved)87 TEST(SpeechProbabilityBufferTest, CheckSumAfterTransientRemoved) {
88 SpeechProbabilityBuffer buffer(kLowProbabilityThreshold);
89
90 buffer.Update(0.0f);
91 buffer.Update(0.0f);
92 buffer.Update(0.0f);
93 buffer.Update(0.0f);
94 buffer.Update(0.0f);
95 buffer.Update(0.0f);
96 buffer.Update(1.0f);
97 buffer.Update(1.0f);
98 buffer.Update(1.0f);
99
100 EXPECT_NEAR(buffer.GetSumProbabilities(), 3.0f, kAbsError);
101
102 buffer.Update(0.0f);
103
104 EXPECT_NEAR(buffer.GetSumProbabilities(), 0.0f, kAbsError);
105 }
106
TEST(SpeechProbabilityBufferTest,CheckSegmentIsNotActiveAfterNoUpdates)107 TEST(SpeechProbabilityBufferTest, CheckSegmentIsNotActiveAfterNoUpdates) {
108 SpeechProbabilityBuffer buffer(kLowProbabilityThreshold);
109
110 EXPECT_FALSE(buffer.IsActiveSegment());
111 }
112
TEST(SpeechProbabilityBufferTest,CheckSegmentIsActiveChangesFromFalseToTrue)113 TEST(SpeechProbabilityBufferTest, CheckSegmentIsActiveChangesFromFalseToTrue) {
114 SpeechProbabilityBuffer buffer(kLowProbabilityThreshold);
115
116 // Add low probabilities until the buffer is full. That's not enough
117 // to make `IsActiveSegment()` to return true.
118 for (int i = 0; i < kNumAnalysisFrames; ++i) {
119 buffer.Update(0.0f);
120 }
121
122 EXPECT_FALSE(buffer.IsActiveSegment());
123
124 // Add high probabilities until `IsActiveSegment()` returns true.
125 for (int i = 0; i < kActivityThreshold * kNumAnalysisFrames - 1; ++i) {
126 buffer.Update(1.0f);
127 }
128
129 EXPECT_FALSE(buffer.IsActiveSegment());
130
131 buffer.Update(1.0f);
132
133 EXPECT_TRUE(buffer.IsActiveSegment());
134 }
135
TEST(SpeechProbabilityBufferTest,CheckSegmentIsActiveChangesFromTrueToFalse)136 TEST(SpeechProbabilityBufferTest, CheckSegmentIsActiveChangesFromTrueToFalse) {
137 SpeechProbabilityBuffer buffer(kLowProbabilityThreshold);
138
139 // Add high probabilities until the buffer is full. That's enough to
140 // make `IsActiveSegment()` to return true.
141 for (int i = 0; i < kNumAnalysisFrames; ++i) {
142 buffer.Update(1.0f);
143 }
144
145 EXPECT_TRUE(buffer.IsActiveSegment());
146
147 // Add low probabilities until `IsActiveSegment()` returns false.
148 for (int i = 0; i < (1.0f - kActivityThreshold) * kNumAnalysisFrames - 1;
149 ++i) {
150 buffer.Update(0.0f);
151 }
152
153 EXPECT_TRUE(buffer.IsActiveSegment());
154
155 buffer.Update(1.0f);
156
157 EXPECT_TRUE(buffer.IsActiveSegment());
158 }
159
TEST(SpeechProbabilityBufferTest,CheckSegmentIsActiveAfterUpdatesWithHighProbabilities)160 TEST(SpeechProbabilityBufferTest,
161 CheckSegmentIsActiveAfterUpdatesWithHighProbabilities) {
162 SpeechProbabilityBuffer buffer(kLowProbabilityThreshold);
163
164 for (int i = 0; i < kNumAnalysisFrames - 1; ++i) {
165 buffer.Update(1.0f);
166 }
167
168 EXPECT_FALSE(buffer.IsActiveSegment());
169
170 buffer.Update(1.0f);
171
172 EXPECT_TRUE(buffer.IsActiveSegment());
173 }
174
TEST(SpeechProbabilityBufferTest,CheckSegmentIsNotActiveAfterUpdatesWithLowProbabilities)175 TEST(SpeechProbabilityBufferTest,
176 CheckSegmentIsNotActiveAfterUpdatesWithLowProbabilities) {
177 SpeechProbabilityBuffer buffer(kLowProbabilityThreshold);
178
179 for (int i = 0; i < kNumAnalysisFrames - 1; ++i) {
180 buffer.Update(0.3f);
181 }
182
183 EXPECT_FALSE(buffer.IsActiveSegment());
184
185 buffer.Update(0.3f);
186
187 EXPECT_FALSE(buffer.IsActiveSegment());
188 }
189
TEST(SpeechProbabilityBufferTest,CheckSegmentIsActiveAfterBufferIsFull)190 TEST(SpeechProbabilityBufferTest, CheckSegmentIsActiveAfterBufferIsFull) {
191 SpeechProbabilityBuffer buffer(kLowProbabilityThreshold);
192
193 for (int i = 0; i < kNumAnalysisFrames - 1; ++i) {
194 buffer.Update(1.0f);
195 }
196
197 EXPECT_FALSE(buffer.IsActiveSegment());
198
199 buffer.Update(1.0f);
200
201 EXPECT_TRUE(buffer.IsActiveSegment());
202
203 buffer.Update(1.0f);
204
205 EXPECT_TRUE(buffer.IsActiveSegment());
206 }
207
TEST(SpeechProbabilityBufferTest,CheckSegmentIsNotActiveAfterBufferIsFull)208 TEST(SpeechProbabilityBufferTest, CheckSegmentIsNotActiveAfterBufferIsFull) {
209 SpeechProbabilityBuffer buffer(kLowProbabilityThreshold);
210
211 for (int i = 0; i < kNumAnalysisFrames - 1; ++i) {
212 buffer.Update(0.29f);
213 }
214
215 EXPECT_FALSE(buffer.IsActiveSegment());
216
217 buffer.Update(0.29f);
218
219 EXPECT_FALSE(buffer.IsActiveSegment());
220
221 buffer.Update(0.29f);
222
223 EXPECT_FALSE(buffer.IsActiveSegment());
224 }
225
TEST(SpeechProbabilityBufferTest,CheckSegmentIsNotActiveAfterReset)226 TEST(SpeechProbabilityBufferTest, CheckSegmentIsNotActiveAfterReset) {
227 SpeechProbabilityBuffer buffer(kLowProbabilityThreshold);
228
229 for (int i = 0; i < kNumAnalysisFrames; ++i) {
230 buffer.Update(1.0f);
231 }
232
233 EXPECT_TRUE(buffer.IsActiveSegment());
234
235 buffer.Reset();
236
237 EXPECT_FALSE(buffer.IsActiveSegment());
238 }
239
TEST(SpeechProbabilityBufferTest,CheckSegmentIsNotActiveAfterTransientRemovedAfterFewUpdates)240 TEST(SpeechProbabilityBufferTest,
241 CheckSegmentIsNotActiveAfterTransientRemovedAfterFewUpdates) {
242 SpeechProbabilityBuffer buffer(kLowProbabilityThreshold);
243
244 buffer.Update(0.4f);
245 buffer.Update(0.4f);
246 buffer.Update(0.0f);
247
248 EXPECT_FALSE(buffer.IsActiveSegment());
249 }
250
TEST(SpeechProbabilityBufferTest,CheckSegmentIsActiveAfterTransientNotRemoved)251 TEST(SpeechProbabilityBufferTest,
252 CheckSegmentIsActiveAfterTransientNotRemoved) {
253 SpeechProbabilityBuffer buffer(kLowProbabilityThreshold);
254
255 for (int i = 0; i < kNumAnalysisFrames; ++i) {
256 buffer.Update(1.0f);
257 }
258
259 buffer.Update(0.7f);
260 buffer.Update(0.8f);
261 buffer.Update(0.9f);
262 buffer.Update(1.0f);
263
264 EXPECT_TRUE(buffer.IsActiveSegment());
265
266 buffer.Update(0.0f);
267
268 EXPECT_TRUE(buffer.IsActiveSegment());
269
270 buffer.Update(0.7f);
271
272 EXPECT_TRUE(buffer.IsActiveSegment());
273 }
274
TEST(SpeechProbabilityBufferTest,CheckSegmentIsNotActiveAfterTransientNotRemoved)275 TEST(SpeechProbabilityBufferTest,
276 CheckSegmentIsNotActiveAfterTransientNotRemoved) {
277 SpeechProbabilityBuffer buffer(kLowProbabilityThreshold);
278
279 for (int i = 0; i < kNumAnalysisFrames; ++i) {
280 buffer.Update(0.1f);
281 }
282
283 buffer.Update(0.7f);
284 buffer.Update(0.8f);
285 buffer.Update(0.9f);
286 buffer.Update(1.0f);
287
288 EXPECT_FALSE(buffer.IsActiveSegment());
289
290 buffer.Update(0.0f);
291
292 EXPECT_FALSE(buffer.IsActiveSegment());
293
294 buffer.Update(0.7f);
295
296 EXPECT_FALSE(buffer.IsActiveSegment());
297 }
298
TEST(SpeechProbabilityBufferTest,CheckSegmentIsNotActiveAfterTransientRemoved)299 TEST(SpeechProbabilityBufferTest,
300 CheckSegmentIsNotActiveAfterTransientRemoved) {
301 SpeechProbabilityBuffer buffer(kLowProbabilityThreshold);
302
303 for (int i = 0; i < kNumAnalysisFrames; ++i) {
304 buffer.Update(0.1f);
305 }
306
307 buffer.Update(0.7f);
308 buffer.Update(0.8f);
309 buffer.Update(0.9f);
310 buffer.Update(1.0f);
311
312 EXPECT_FALSE(buffer.IsActiveSegment());
313
314 buffer.Update(0.0f);
315
316 EXPECT_FALSE(buffer.IsActiveSegment());
317
318 buffer.Update(0.7f);
319
320 EXPECT_FALSE(buffer.IsActiveSegment());
321 }
322
TEST(SpeechProbabilityBufferTest,CheckSegmentIsActiveAfterTransientRemoved)323 TEST(SpeechProbabilityBufferTest, CheckSegmentIsActiveAfterTransientRemoved) {
324 SpeechProbabilityBuffer buffer(kLowProbabilityThreshold);
325
326 for (int i = 0; i < kNumAnalysisFrames; ++i) {
327 buffer.Update(1.0f);
328 }
329
330 buffer.Update(0.7f);
331 buffer.Update(0.8f);
332 buffer.Update(0.9f);
333 buffer.Update(1.0f);
334
335 EXPECT_TRUE(buffer.IsActiveSegment());
336
337 buffer.Update(0.0f);
338
339 EXPECT_TRUE(buffer.IsActiveSegment());
340
341 buffer.Update(0.7f);
342
343 EXPECT_TRUE(buffer.IsActiveSegment());
344 }
345
346 } // namespace webrtc
347