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

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: dropping duration for easier logging 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 look_back_ms) {
17 auto it = counters_.find(look_back_ms);
18 if (it == counters_.end())
19 return 0;
20 return it->second;
21 }
22
23 void ResetCounters() {
24 counters_.clear();
25 }
26
27 void ResetLookbackTime(const int* look_back_times, size_t num) {
28 states_.clear();
29 for (size_t i = 0; i < num; ++i) {
30 RegisterLookbackTime(look_back_times[i]);
31 }
32 }
33
34 void set_max_frames(size_t max_frames) { max_frames_ = max_frames; }
35
36 void set_min_length_ms(int min_length_ms) { min_length_ms_ = min_length_ms; }
37
38 private:
39 void ReportRepetition(int look_back_ms) override {
40 auto it = counters_.find(look_back_ms);
41 if (it == counters_.end()) {
42 counters_.insert(std::pair<int, size_t>(look_back_ms, 1));
43 return;
44 }
45 it->second++;
46 }
47
48 std::map<int, size_t> counters_;
49 };
50
51 class AudioRepetitionDetectorTest : public ::testing::Test {
52 protected:
53 struct ExpectedCount {
54 int look_back_ms;
55 int count;
56 };
57
58 // Verify if the counts on the repetition patterns match expectation after
59 // injecting a signal. No reset on the counters
60 void Verify(const ExpectedCount* expected_counts, size_t num_patterns,
61 const float* tester, size_t num_frames,
62 int sample_rate_hz, size_t channels = 1) {
63 detector_.Detect(tester, num_frames, channels, sample_rate_hz);
64 for (size_t idx = 0; idx < num_patterns; ++idx) {
65 const int look_back_ms = expected_counts[idx].look_back_ms;
66 EXPECT_EQ(expected_counts[idx].count, detector_.GetCount(look_back_ms)) <<
67 "Repetition with look back " << look_back_ms << " ms counted wrong.";
68 }
69 }
70
71 void VerifyStereo(const ExpectedCount* expected_counts, size_t num_patterns,
72 const float* tester, size_t num_frames,
73 int sample_rate_hz) {
74 const size_t kNumChannels = 2;
75
76 // Get memory to store interleaved stereo.
77 scoped_ptr<float[]> tester_stereo(
78 new float[num_frames * kNumChannels]);
79
80 for (size_t idx = 0; idx < num_frames; ++idx, ++tester) {
81 for (size_t channel = 0; channel < kNumChannels; ++channel)
82 tester_stereo[idx * kNumChannels + channel] = *tester;
83 }
84
85 Verify(expected_counts, num_patterns, tester_stereo.get(),
86 num_frames, sample_rate_hz, kNumChannels);
87 }
88
89 void ResetLookbackTime(const int* look_back_times, size_t num) {
90 detector_.ResetLookbackTime(look_back_times, num);
91 }
92
93 void SetMaxFrames(size_t max_frames) {
94 detector_.set_max_frames(max_frames);
95 }
96
97 void SetMinLengthMs(int min_length_ms) {
98 detector_.set_min_length_ms(min_length_ms);
99 }
100
101 void ResetCounters() {
102 detector_.ResetCounters();
103 }
104
105 private:
106 AudioRepetitionDetectorForTest detector_;
107 };
108
109 TEST_F(AudioRepetitionDetectorTest, Basic) {
110 // To make the test signal most obvious, we choose a special sample rate.
111 const int kSampleRateHz = 1000;
112
113 // Check that one look back time will registered only once.
114 const int kLookbackTimes[] = {3, 3, 3, 3};
115
116 const float kTestSignal[] = {1, 2, 3, 1, 2, 3};
117 const ExpectedCount kExpectedCounts_1[] = {
118 {3, 1}
119 };
120 const ExpectedCount kExpectedCounts_2[] = {
121 {3, 1}
122 };
123
124 ResetLookbackTime(kLookbackTimes, arraysize(kLookbackTimes));
125 Verify(kExpectedCounts_1, arraysize(kExpectedCounts_1), kTestSignal,
126 arraysize(kTestSignal), kSampleRateHz);
127 Verify(kExpectedCounts_2, arraysize(kExpectedCounts_2), kTestSignal,
128 arraysize(kTestSignal), kSampleRateHz);
129 ResetCounters();
130
131 VerifyStereo(kExpectedCounts_1, arraysize(kExpectedCounts_1), kTestSignal,
132 arraysize(kTestSignal), kSampleRateHz);
133 VerifyStereo(kExpectedCounts_2, arraysize(kExpectedCounts_2), kTestSignal,
134 arraysize(kTestSignal), kSampleRateHz);
135 }
136
137 TEST_F(AudioRepetitionDetectorTest, StereoOutOfSync) {
138 // To make the test signal most obvious, we choose a special sample rate.
139 const int kSampleRateHz = 1000;
140
141 const int kLookbackTimes[] = {3};
142 const float kTestSignal[] = {
143 1, 1,
144 2, 2,
145 3, 3,
146 1, 1,
147 2, 2,
148 3, 1};
149 const ExpectedCount kExpectedCounts[] = {
150 {3, 0}
151 };
152
153 // By default, any repetition longer than 1 ms (1 sample at 1000 Hz) will be
154 // counted as repetition. This test needs to make it longer.
155 SetMinLengthMs(3);
156
157 ResetLookbackTime(kLookbackTimes, arraysize(kLookbackTimes));
158 Verify(kExpectedCounts, arraysize(kExpectedCounts), kTestSignal,
159 arraysize(kTestSignal) / 2, kSampleRateHz, 2);
160 }
161
162 TEST_F(AudioRepetitionDetectorTest, IncompletePattern) {
163 // To make the test signal most obvious, we choose a special sample rate.
164 const int kSampleRateHz = 1000;
165
166 const int kLookbackTimes[] = {3};
167 const float kTestSignal[] = {1, 2, 1, 2, 3, 1, 2, 3};
168 const ExpectedCount kExpectedCounts[] = {
169 {3, 1},
170 };
171
172 ResetLookbackTime(kLookbackTimes, arraysize(kLookbackTimes));
173 Verify(kExpectedCounts, arraysize(kExpectedCounts), kTestSignal,
174 arraysize(kTestSignal), kSampleRateHz);
175 ResetCounters();
176 VerifyStereo(kExpectedCounts, arraysize(kExpectedCounts), kTestSignal,
177 arraysize(kTestSignal), kSampleRateHz);
178 }
179
180 TEST_F(AudioRepetitionDetectorTest, PatternLongerThanFrame) {
181 // To make the test signal most obvious, we choose a special sample rate.
182 const int kSampleRateHz = 1000;
183
184 const int kLookbackTimes[] = {6};
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 {6, 0},
189 };
190 const ExpectedCount kExpectedCounts_2[] = {
191 {6, 1},
192 };
193
194 ResetLookbackTime(kLookbackTimes, arraysize(kLookbackTimes));
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 int kLookbackTimes[] = {3, 4};
211 const float kTestSignal[] = {1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4};
212 const ExpectedCount kExpectedCounts[] = {
213 // 1,2,3 belongs to both patterns.
214 {3, 1},
215 {4, 1}
216 };
217
218 ResetLookbackTime(kLookbackTimes, arraysize(kLookbackTimes));
219 Verify(kExpectedCounts, arraysize(kExpectedCounts), kTestSignal,
220 arraysize(kTestSignal), kSampleRateHz);
221 ResetCounters();
222 VerifyStereo(kExpectedCounts, arraysize(kExpectedCounts), kTestSignal,
223 arraysize(kTestSignal), kSampleRateHz);
224 }
225
226 TEST_F(AudioRepetitionDetectorTest, MaxFramesShorterThanInput) {
227 // To make the test signal most obvious, we choose a special sample rate.
228 const int kSampleRateHz = 1000;
229
230 const int kLookbackTimes[] = {3, 4};
231 const float kTestSignal[] = {1, 2, 3, 1, 2, 3, 4, 1, 2, 3, 4};
232 const ExpectedCount kExpectedCounts[] = {
233 // 1,2,3 belongs to both patterns.
234 {3, 1},
235 {4, 1}
236 };
237
238 // length of kTestSignal is 11 but I set maximum frames to be 2. The detection
239 // should still work.
240 SetMaxFrames(2);
241 ResetLookbackTime(kLookbackTimes, arraysize(kLookbackTimes));
242 Verify(kExpectedCounts, arraysize(kExpectedCounts), kTestSignal,
243 arraysize(kTestSignal), kSampleRateHz);
244 ResetCounters();
245 VerifyStereo(kExpectedCounts, arraysize(kExpectedCounts), kTestSignal,
246 arraysize(kTestSignal), kSampleRateHz);
247 }
248
249 TEST_F(AudioRepetitionDetectorTest, NestedPatterns) {
250 // To make the test signal most obvious, we choose a special sample rate.
251 const int kSampleRateHz = 1000;
252
253 const int kLookbackTimes[] = {6, 3};
254 const float kTestSignal[] = {1, 2, 3, 1, 2, 3};
255 const ExpectedCount kExpectedCounts_1[] = {
256 {3, 1},
257 {6, 0}
258 };
259 const ExpectedCount kExpectedCounts_2[] = {
260 {3, 1},
261 {6, 1}
262 };
263
264 ResetLookbackTime(kLookbackTimes, arraysize(kLookbackTimes));
265 Verify(kExpectedCounts_1, arraysize(kExpectedCounts_1), kTestSignal,
266 arraysize(kTestSignal), kSampleRateHz);
267 Verify(kExpectedCounts_2, arraysize(kExpectedCounts_2), kTestSignal,
268 arraysize(kTestSignal), kSampleRateHz);
269 ResetCounters();
270 VerifyStereo(kExpectedCounts_1, arraysize(kExpectedCounts_1), kTestSignal,
271 arraysize(kTestSignal), kSampleRateHz);
272 VerifyStereo(kExpectedCounts_2, arraysize(kExpectedCounts_2), kTestSignal,
273 arraysize(kTestSignal), kSampleRateHz);
274 }
275
276 TEST_F(AudioRepetitionDetectorTest, NotFullLengthPattern) {
277 // To make the test signal most obvious, we choose a special sample rate.
278 const int kSampleRateHz = 1000;
279
280 const int kLookbackTimes[] = {4};
281 const float kTestSignal[] = {1, 2, 3, -1, 1, 2, 3, -2};
282 const ExpectedCount kExpectedCounts[] = {
283 {4, 1},
284 };
285
286 ResetLookbackTime(kLookbackTimes, arraysize(kLookbackTimes));
287 Verify(kExpectedCounts, arraysize(kExpectedCounts), kTestSignal,
288 arraysize(kTestSignal), kSampleRateHz);
289 ResetCounters();
290 VerifyStereo(kExpectedCounts, arraysize(kExpectedCounts), kTestSignal,
291 arraysize(kTestSignal), kSampleRateHz);
292 }
293
294 TEST_F(AudioRepetitionDetectorTest, ZerosCountOrNot) {
295 // To make the test signal most obvious, we choose a special sample rate.
296 const int kSampleRateHz = 1000;
297
298 const int kLookbackTimes[] = {3};
299 const float kTestSignal_1[] = {0, 0, 0, 0, 0, 0};
300 const float kTestSignal_2[] = {0, 1, 2, 0, 1, 2};
301 const ExpectedCount kExpectedCounts_1[] = {
302 // Full zeros won't count.
303 {3, 0},
304 };
305 const ExpectedCount kExpectedCounts_2[] = {
306 // Partial zero will count.
307 {3, 1},
308 };
309
310 ResetLookbackTime(kLookbackTimes, arraysize(kLookbackTimes));
311 Verify(kExpectedCounts_1, arraysize(kExpectedCounts_1), kTestSignal_1,
312 arraysize(kTestSignal_1), kSampleRateHz);
313 Verify(kExpectedCounts_2, arraysize(kExpectedCounts_2), kTestSignal_2,
314 arraysize(kTestSignal_2), kSampleRateHz);
315 ResetCounters();
316 VerifyStereo(kExpectedCounts_1, arraysize(kExpectedCounts_1), kTestSignal_1,
317 arraysize(kTestSignal_1), kSampleRateHz);
318 VerifyStereo(kExpectedCounts_2, arraysize(kExpectedCounts_2), kTestSignal_2,
319 arraysize(kTestSignal_2), kSampleRateHz);
320 }
321
322 // Previous tests use short signal to test the detection algorithm, this one
323 // tests the built-in pattern in AudioRepetitionDetector.
324 TEST_F(AudioRepetitionDetectorTest, BuiltInPattern) {
325 const int kSampleRateHz = 44100;
326 // Let the signal be "*(4ms)-A(13ms)-*(100ms)-A", where * denotes random
327 // samples.
328 const size_t kPreSamples = kSampleRateHz * 4 / 1000;
329 const size_t kRepSamples = kSampleRateHz * 13 / 1000;
330 const size_t kSkipSamples = kSampleRateHz * 100 / 1000;
331 const size_t kSamples = kPreSamples + kRepSamples * 2 + kSkipSamples;
332
333 float test_signal[kSamples];
334 size_t idx = 0;
335 for (; idx < kPreSamples + kRepSamples + kSkipSamples; ++idx)
336 test_signal[idx] = static_cast<float>(base::RandDouble());
337
338 for (; idx < kSamples; ++idx)
339 test_signal[idx] = test_signal[idx - kSkipSamples];
340
341 // We currently track 20 look back times, 10, 20, 30, ..., 200.
342 ExpectedCount expect_counts[20];
343 for (int i = 0; i < 20; ++i) {
344 expect_counts[i].look_back_ms = (i + 1) * 10;
345 expect_counts[i].count = 0;
346 }
347
348 // We only expect a repetition with 100 ms look back time.
349 expect_counts[9].count = 1;
350
351 Verify(expect_counts, arraysize(expect_counts), test_signal, kSamples,
352 kSampleRateHz);
353 }
354
355 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698