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

Side by Side Diff: webrtc/modules/audio_processing/repetition_detector_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698