Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(218)

Side by Side Diff: content/renderer/media/audio_repetition_detector_unittest.cc

Issue 1357013006: Add detection for repeated audio in capturing. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: some small changes Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <map>
6
7 #include "base/macros.h"
8 #include "base/rand_util.h"
9 #include "content/renderer/media/audio_repetition_detector.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11
12 namespace content {
13
14 class AudioRepetitionDetectorForTest : public AudioRepetitionDetector {
15 public:
16 int GetCount(int id) {
17 auto it = counters_.find(id);
18 if (it == counters_.end())
19 return 0;
20 return counters_[id];
21 }
22
23 void ResetCounters() {
24 for (auto& item : counters_)
25 item.second = 0;
26 }
27
28 void ResetRepetitionPattern(const AudioRepetitionDetector::Pattern* patterns,
29 size_t num_patterns) {
30 states_.clear();
31 RegisterRepetitionPatterns(patterns, num_patterns);
32 }
33
34 void set_max_frames(size_t max_frames) { max_frames_ = max_frames; }
35
36 private:
37 void ReportRepetition(int id) override {
38 auto it = counters_.find(id);
39 if (it == counters_.end())
40 counters_[id] = 0;
41 counters_[id]++;
42 }
43
44 std::map<int, size_t> counters_;
45 };
46
47 class AudioRepetitionDetectorTest : public ::testing::Test {
48 protected:
49 struct ExpectedCount {
50 int id_;
51 int count_;
52 };
53
54 // Verify if the counts on the repetition patterns match expectation after
55 // injecting a signal. No reset on the counters
56 void Verify(const ExpectedCount* expected_counts, size_t num_patterns,
57 const float* tester, size_t num_frames,
58 int sample_rate_hz, size_t channels = 1) {
59 detector_.Detect(tester, num_frames, channels, sample_rate_hz);
60 int id;
61 for (size_t idx = 0; idx < num_patterns; idx++) {
62 id = expected_counts[idx].id_;
63 EXPECT_EQ(expected_counts[idx].count_, detector_.GetCount(id)) <<
64 "Repetition #" << id << " counted wrong.";
65 }
66 }
67
68 void VerifyStereo(const ExpectedCount* expected_counts, size_t num_patterns,
69 const float* tester, size_t num_frames,
70 int sample_rate_hz) {
71 const size_t kNumChannels = 2;
72
73 // Get memory to store interleaved stereo.
74 scoped_ptr<float[]> tester_stereo(
75 new float[num_frames * kNumChannels]);
76
77 for (size_t idx = 0; idx < num_frames; ++idx, ++tester) {
78 for (size_t channel = 0; channel < kNumChannels; ++channel)
79 tester_stereo[idx * kNumChannels + channel] = *tester;
80 }
81
82 Verify(expected_counts, num_patterns, tester_stereo.get(),
83 num_frames, sample_rate_hz, kNumChannels);
84 }
85
86 void ResetRepetitionPattern(const AudioRepetitionDetector::Pattern* patterns,
87 size_t num_patterns) {
88 detector_.ResetRepetitionPattern(patterns, num_patterns);
89 }
90
91 void SetMaxFrames(size_t max_frames) {
92 detector_.set_max_frames(max_frames);
93 }
94
95 void ResetCounters() {
96 detector_.ResetCounters();
97 }
98
99 private:
100 AudioRepetitionDetectorForTest detector_;
101 };
102
103 TEST_F(AudioRepetitionDetectorTest, Basic) {
104 // To make the test signal most obvious, we choose a special sample rate.
105 const int kSampleRateHz = 1000;
106
107 const AudioRepetitionDetector::Pattern kRepetitionPatterns[] = {
108 // id, look_back_ms, min_length_ms
109 {0, 3, 3}
110 };
111 const float kTestSignal[] = {1, 2, 3, 1, 2, 3};
112 const ExpectedCount kExpectedCounts_1[] = {
113 {0, 1}
114 };
115 const ExpectedCount kExpectedCounts_2[] = {
116 {0, 1}
117 };
118
119 ResetRepetitionPattern(kRepetitionPatterns, arraysize(kRepetitionPatterns));
120 Verify(kExpectedCounts_1, arraysize(kExpectedCounts_1), kTestSignal,
121 arraysize(kTestSignal), kSampleRateHz);
122 Verify(kExpectedCounts_2, arraysize(kExpectedCounts_2), kTestSignal,
123 arraysize(kTestSignal), kSampleRateHz);
124 ResetCounters();
125
126 VerifyStereo(kExpectedCounts_1, arraysize(kExpectedCounts_1), kTestSignal,
127 arraysize(kTestSignal), kSampleRateHz);
128 VerifyStereo(kExpectedCounts_2, arraysize(kExpectedCounts_2), kTestSignal,
129 arraysize(kTestSignal), kSampleRateHz);
130 }
131
132 TEST_F(AudioRepetitionDetectorTest, StereoOutOfSync) {
133 // To make the test signal most obvious, we choose a special sample rate.
134 const int kSampleRateHz = 1000;
135
136 const AudioRepetitionDetector::Pattern kRepetitionPatterns[] = {
137 // id, look_back_ms, min_length_ms
138 {0, 3, 3}
139 };
140 const float kTestSignal[] = {
141 1, 1,
142 2, 2,
143 3, 3,
144 1, 1,
145 2, 2,
146 3, 1};
147 const ExpectedCount kExpectedCounts[] = {
148 {0, 0}
149 };
150
151 ResetRepetitionPattern(kRepetitionPatterns, arraysize(kRepetitionPatterns));
152 Verify(kExpectedCounts, arraysize(kExpectedCounts), kTestSignal,
153 arraysize(kTestSignal) / 2, kSampleRateHz, 2);
154 }
155
156 TEST_F(AudioRepetitionDetectorTest, IncompletePattern) {
157 // To make the test signal most obvious, we choose a special sample rate.
158 const int kSampleRateHz = 1000;
159
160 const AudioRepetitionDetector::Pattern kRepetitionPatterns[] = {
161 // id, look_back_ms, min_length_ms
162 {0, 3, 3},
163 };
164 const float kTestSignal[] = {1, 2, 1, 2, 3, 1, 2, 3};
165 const ExpectedCount kExpectedCounts[] = {
166 {0, 1},
167 };
168
169 ResetRepetitionPattern(kRepetitionPatterns, arraysize(kRepetitionPatterns));
170 Verify(kExpectedCounts, arraysize(kExpectedCounts), kTestSignal,
171 arraysize(kTestSignal), kSampleRateHz);
172 ResetCounters();
173 VerifyStereo(kExpectedCounts, arraysize(kExpectedCounts), kTestSignal,
174 arraysize(kTestSignal), kSampleRateHz);
175 }
176
177 TEST_F(AudioRepetitionDetectorTest, PatternLongerThanFrame) {
178 // To make the test signal most obvious, we choose a special sample rate.
179 const int kSampleRateHz = 1000;
180
181 const AudioRepetitionDetector::Pattern kRepetitionPatterns[] = {
182 // id, look_back_ms, min_length_ms
183 {0, 6, 6},
184 };
185 const float kTestSignal_1[] = {1, 2, 3, 4, 5};
186 const float kTestSignal_2[] = {6, 1, 2, 3, 4, 5, 6};
187 const ExpectedCount kExpectedCounts_1[] = {
188 {0, 0},
189 };
190 const ExpectedCount kExpectedCounts_2[] = {
191 {0, 1},
192 };
193
194 ResetRepetitionPattern(kRepetitionPatterns, arraysize(kRepetitionPatterns));
195 Verify(kExpectedCounts_1, arraysize(kExpectedCounts_1), kTestSignal_1,
196 arraysize(kTestSignal_1), kSampleRateHz);
197 Verify(kExpectedCounts_2, arraysize(kExpectedCounts_2), kTestSignal_2,
198 arraysize(kTestSignal_2), kSampleRateHz);
199 ResetCounters();
200 VerifyStereo(kExpectedCounts_1, arraysize(kExpectedCounts_1), kTestSignal_1,
201 arraysize(kTestSignal_1), kSampleRateHz);
202 VerifyStereo(kExpectedCounts_2, arraysize(kExpectedCounts_2), kTestSignal_2,
203 arraysize(kTestSignal_2), kSampleRateHz);
204 }
205
206 TEST_F(AudioRepetitionDetectorTest, TwoPatterns) {
207 // To make the test signal most obvious, we choose a special sample rate.
208 const int kSampleRateHz = 1000;
209
210 const AudioRepetitionDetector::Pattern kRepetitionPatterns[] = {
211 // id, look_back_ms, min_length_ms
212 {0, 3, 3},
213 {1, 4, 4},
214 };
215 const float kTestSignal[] = {1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4};
216 const ExpectedCount kExpectedCounts[] = {
217 // 1,2,3 belongs to both patterns.
218 {0, 1},
219 {1, 1}
220 };
221
222 ResetRepetitionPattern(kRepetitionPatterns, arraysize(kRepetitionPatterns));
223 Verify(kExpectedCounts, arraysize(kExpectedCounts), kTestSignal,
224 arraysize(kTestSignal), kSampleRateHz);
225 ResetCounters();
226 VerifyStereo(kExpectedCounts, arraysize(kExpectedCounts), kTestSignal,
227 arraysize(kTestSignal), kSampleRateHz);
228 }
229
230 TEST_F(AudioRepetitionDetectorTest, MaxFramesShorterThanInput) {
231 // To make the test signal most obvious, we choose a special sample rate.
232 const int kSampleRateHz = 1000;
233
234 const AudioRepetitionDetector::Pattern kRepetitionPatterns[] = {
235 // id, look_back_ms, min_length_ms
236 {0, 3, 3},
237 {1, 4, 4},
238 };
239 const float kTestSignal[] = {1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4};
240 const ExpectedCount kExpectedCounts[] = {
241 // 1,2,3 belongs to both patterns.
242 {0, 1},
243 {1, 1}
244 };
245
246 // length of kTestSignal is 11 but I set maximum frames to be 2. The detection
247 // should still work.
248 SetMaxFrames(2);
249 ResetRepetitionPattern(kRepetitionPatterns, arraysize(kRepetitionPatterns));
250 Verify(kExpectedCounts, arraysize(kExpectedCounts), kTestSignal,
251 arraysize(kTestSignal), kSampleRateHz);
252 ResetCounters();
253 VerifyStereo(kExpectedCounts, arraysize(kExpectedCounts), kTestSignal,
254 arraysize(kTestSignal), kSampleRateHz);
255 }
256
257 TEST_F(AudioRepetitionDetectorTest, NestedPatterns) {
258 // To make the test signal most obvious, we choose a special sample rate.
259 const int kSampleRateHz = 1000;
260
261 const AudioRepetitionDetector::Pattern kRepetitionPatterns[] = {
262 // id, look_back_ms, min_length_ms
263 {0, 3, 3},
264 {1, 6, 6}, // When a triplet repeated 3 times, this is triggered.
265 };
266 const float kTestSignal[] = {1, 2, 3, 1, 2, 3};
267 const ExpectedCount kExpectedCounts_1[] = {
268 {0, 1},
269 {1, 0}
270 };
271 const ExpectedCount kExpectedCounts_2[] = {
272 {0, 1},
273 {1, 1}
274 };
275
276 ResetRepetitionPattern(kRepetitionPatterns, arraysize(kRepetitionPatterns));
277 Verify(kExpectedCounts_1, arraysize(kExpectedCounts_1), kTestSignal,
278 arraysize(kTestSignal), kSampleRateHz);
279 Verify(kExpectedCounts_2, arraysize(kExpectedCounts_2), kTestSignal,
280 arraysize(kTestSignal), kSampleRateHz);
281 ResetCounters();
282 VerifyStereo(kExpectedCounts_1, arraysize(kExpectedCounts_1), kTestSignal,
283 arraysize(kTestSignal), kSampleRateHz);
284 VerifyStereo(kExpectedCounts_2, arraysize(kExpectedCounts_2), kTestSignal,
285 arraysize(kTestSignal), kSampleRateHz);
286 }
287
288 TEST_F(AudioRepetitionDetectorTest, NotFullLengthPattern) {
289 // To make the test signal most obvious, we choose a special sample rate.
290 const int kSampleRateHz = 1000;
291
292 const AudioRepetitionDetector::Pattern kRepetitionPatterns[] = {
293 // id, look_back_ms, min_length_ms
294 {0, 4, 3},
295 };
296 const float kTestSignal[] = {1, 2, 3, -1, 1, 2, 3, -2};
297 const ExpectedCount kExpectedCounts[] = {
298 {0, 1},
299 };
300
301 ResetRepetitionPattern(kRepetitionPatterns, arraysize(kRepetitionPatterns));
302 Verify(kExpectedCounts, arraysize(kExpectedCounts), kTestSignal,
303 arraysize(kTestSignal), kSampleRateHz);
304 ResetCounters();
305 VerifyStereo(kExpectedCounts, arraysize(kExpectedCounts), kTestSignal,
306 arraysize(kTestSignal), kSampleRateHz);
307 }
308
309 TEST_F(AudioRepetitionDetectorTest, ZerosCountOrNot) {
310 // To make the test signal most obvious, we choose a special sample rate.
311 const int kSampleRateHz = 1000;
312
313 const AudioRepetitionDetector::Pattern kRepetitionPatterns[] = {
314 // id, look_back_ms, min_length_ms
315 {0, 3, 3},
316 };
317 const float kTestSignal_1[] = {0, 0, 0, 0, 0, 0};
318 const float kTestSignal_2[] = {0, 1, 2, 0, 1, 2};
319 const ExpectedCount kExpectedCounts_1[] = {
320 // Full zeros won't count.
321 {0, 0},
322 };
323 const ExpectedCount kExpectedCounts_2[] = {
324 // Partial zero will count.
325 {0, 1},
326 };
327
328 ResetRepetitionPattern(kRepetitionPatterns, arraysize(kRepetitionPatterns));
329 Verify(kExpectedCounts_1, arraysize(kExpectedCounts_1), kTestSignal_1,
330 arraysize(kTestSignal_1), kSampleRateHz);
331 Verify(kExpectedCounts_2, arraysize(kExpectedCounts_2), kTestSignal_2,
332 arraysize(kTestSignal_2), kSampleRateHz);
333 ResetCounters();
334 VerifyStereo(kExpectedCounts_1, arraysize(kExpectedCounts_1), kTestSignal_1,
335 arraysize(kTestSignal_1), kSampleRateHz);
336 VerifyStereo(kExpectedCounts_2, arraysize(kExpectedCounts_2), kTestSignal_2,
337 arraysize(kTestSignal_2), kSampleRateHz);
338 }
339
340 // Previous tests use short signal to test the detection algorithm, this one
341 // tests the built-in pattern in AudioRepetitionDetector.
342 TEST_F(AudioRepetitionDetectorTest, BuiltInPattern) {
343 const int kSampleRateHz = 44100;
344 // Let the signal be "*(4ms)-A(13ms)-*(100ms)-A", where * denotes random
345 // samples.
346 const size_t kPreSamples = kSampleRateHz * 4 / 1000;
347 const size_t kRepSamples = kSampleRateHz * 13 / 1000;
348 const size_t kSkipSamples = kSampleRateHz * 100 / 1000;
349 const size_t kSamples = kPreSamples + kRepSamples * 2 + kSkipSamples;
350
351 float test_signal[kSamples];
352 size_t idx = 0;
353 for (; idx < kPreSamples + kRepSamples + kSkipSamples; ++idx)
354 test_signal[idx] = static_cast<float>(base::RandDouble());
355
356 for (; idx < kSamples; ++idx)
357 test_signal[idx] = test_signal[idx - kSkipSamples];
358
359 const ExpectedCount kExpectedCounts[] = {
360 // Partial zero will count.
361 {1, 0}, // 10 ms look back
362 {2, 0}, // 20 ms look back
363 {3, 0}, // 30 ms look back
364 {4, 0}, // 40 ms look back
365 {5, 0}, // 50 ms look back
366 {6, 0}, // 60 ms look back
367 {7, 0}, // 70 ms look back
368 {8, 0}, // 80 ms look back
369 {9, 0}, // 90 ms look back
370 {10, 1}, // 100 ms look back
371 {20, 0} // 200 ms look back
372 };
373 Verify(kExpectedCounts, arraysize(kExpectedCounts), test_signal, kSamples,
374 kSampleRateHz);
375 }
376
377 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698