OLD | NEW |
---|---|
(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 "webrtc/modules/audio_processing/repetition_detector.h" | |
12 | |
13 #include <string.h> // memset | |
14 | |
15 #include "webrtc/base/checks.h" | |
16 | |
17 namespace webrtc { | |
18 | |
19 namespace { | |
20 static const RepetitionDetector::Pattern kRepetitionPatterns[] = { | |
peah-webrtc
2015/08/12 11:02:54
Both look_back_range_ and length_range_ are zero
minyue-webrtc
2015/08/12 11:32:14
Maybe not enough but there is a unittest around th
peah-webrtc
2015/08/12 21:05:16
Sorry, I missed the unit test. Great!
| |
21 // {id_, look_back_, look_back_range_, length_, length_range_} | |
22 {0, 10, 0, 10, 0}, | |
23 {1, 100, 0, 100, 0} | |
24 }; | |
25 } | |
26 | |
27 RepetitionDetector::RepetitionDetector() | |
28 : audio_buffer_(nullptr), | |
29 num_channels_(0), | |
30 buffer_length_samples_(0), | |
31 buffer_end_(0) { | |
32 RegisterRepititionPatterns(kRepetitionPatterns, | |
33 sizeof(kRepetitionPatterns) / sizeof (Pattern)); | |
34 CreateBuffer(); | |
35 } | |
36 | |
37 RepetitionDetector::~RepetitionDetector() { | |
38 DeleteBuffer(); | |
39 } | |
40 | |
41 | |
42 void RepetitionDetector::RegisterRepititionPatterns(const Pattern* patterns, | |
peah-webrtc
2015/08/12 11:02:54
Typo, should be RegisterRepetitionPatterns
minyue-webrtc
2015/08/12 11:32:14
Acknowledged.
| |
43 int num_patterns) { | |
44 int max_look_back = 0; | |
45 Pattern pattern; | |
46 for (int idx = 0; idx < num_patterns; idx++) { | |
47 pattern = patterns[idx]; | |
48 for (int offset = -pattern.look_back_range_; | |
peah-webrtc
2015/08/12 11:02:54
In the specified patterns, look_back_range_ is set
minyue-webrtc
2015/08/12 11:32:14
I think the look_back and length may not be necess
| |
49 offset <= pattern.look_back_range_; offset++) { | |
50 states_.push_back(State(pattern.id_, pattern.look_back_ + offset, | |
51 pattern.length_, pattern.length_range_)); | |
52 } | |
53 if (pattern.look_back_ + pattern.look_back_range_ > max_look_back) { | |
54 max_look_back = pattern.look_back_ + pattern.look_back_range_; | |
55 } | |
56 } | |
57 buffer_length_samples_ = max_look_back; | |
58 } | |
59 | |
60 void RepetitionDetector::ClearRepititionPatterns() { | |
peah-webrtc
2015/08/12 11:02:54
A typo, should be ClearRepetitionPatterns
minyue-webrtc
2015/08/12 11:32:14
Acknowledged.
| |
61 states_.clear(); | |
62 buffer_length_samples_ = 0; | |
63 } | |
64 | |
65 void RepetitionDetector::CreateBuffer() { | |
66 if (audio_buffer_) { | |
67 return; | |
68 } | |
69 audio_buffer_ = new int16_t*[num_channels_]; | |
70 for (int ch = 0; ch < num_channels_; ch++) { | |
71 audio_buffer_[ch] = new int16_t[buffer_length_samples_]; | |
72 memset(audio_buffer_[ch], 0, buffer_length_samples_ * sizeof(int16_t)); | |
73 } | |
74 buffer_end_ = 0; | |
75 } | |
76 | |
77 void RepetitionDetector::DeleteBuffer() { | |
78 if (!audio_buffer_) { | |
79 return; | |
80 } | |
81 for (int ch = 0; ch < num_channels_; ch++) { | |
82 delete[] audio_buffer_[ch]; | |
83 } | |
84 delete[] audio_buffer_; | |
85 audio_buffer_ = nullptr; | |
86 } | |
87 | |
88 void RepetitionDetector::Reset(int new_num_channels) { | |
89 DeleteBuffer(); | |
90 num_channels_ = new_num_channels; | |
91 CreateBuffer(); | |
92 for (auto& state : states_) { | |
93 state.count_ = 0; | |
94 } | |
95 // We do not reset |occurances_| to be able to count issues that have | |
hlundin-webrtc
2015/08/12 14:12:04
What is occurances_?
minyue-webrtc
2015/08/12 14:20:20
Sorry. it was a counter, but now removed, since I
| |
96 // happened. | |
97 } | |
98 | |
99 void RepetitionDetector::Detect(const int16_t* data, int samples_per_channel, | |
100 int num_channels) { | |
101 DCHECK_GT(states_.size(), 0ul); | |
102 if (num_channels != num_channels_) { | |
103 Reset(num_channels); | |
104 } | |
105 | |
106 int look_back_pointer; | |
hlundin-webrtc
2015/08/12 14:12:04
This is not a pointer. Suggest look_back_index or
| |
107 int new_buffer_end = buffer_end_; | |
108 const int16_t* sample = data; | |
109 | |
110 for (int idx = 0; idx < samples_per_channel; idx++) { | |
hlundin-webrtc
2015/08/12 14:12:04
This nested for loop and its associated code is ve
minyue-webrtc
2015/08/12 14:20:20
It can happen that repetition starts in the middle
hlundin-webrtc
2015/08/12 14:38:00
Hm, ok. But I still have a feeling you could simpl
peah-webrtc
2015/08/12 21:05:16
I agree that this feels more complex than needed.
| |
111 for (auto& state : states_) { | |
112 new_buffer_end = (buffer_end_ + 1) % buffer_length_samples_; | |
113 look_back_pointer = (new_buffer_end - state.look_back_ + | |
114 buffer_length_samples_) % buffer_length_samples_; | |
peah-webrtc
2015/08/12 11:02:54
The addition of buffer_length_samples_ seems to be
minyue-webrtc
2015/08/12 11:32:13
This is to avoid negative, e,g, -2%3=-2
peah-webrtc
2015/08/12 21:05:16
Good point! Thanks!
| |
115 | |
116 // For multichannel audio, all channels have to repeat the same way. | |
peah-webrtc
2015/08/12 11:02:54
Is this a neccessary requirement, would it not jus
minyue-webrtc
2015/08/12 11:32:14
I consulted Chromium people. It is supposed that s
hlundin-webrtc
2015/08/12 14:12:04
I agree with Per. Look at only one channel for now
minyue-webrtc
2015/08/28 14:27:00
In our recordings, we found that repetition should
| |
117 bool sample_repeated = true; | |
118 for (int ch = 0; ch < num_channels_; ch++) { | |
119 if (sample[ch] != audio_buffer_[ch][look_back_pointer]) { | |
120 sample_repeated = false; | |
peah-webrtc
2015/08/12 21:05:16
Inequality is not a sufficient condition for repea
minyue-webrtc
2015/08/28 14:27:00
Zeros are treated specially now.
| |
121 } | |
122 } | |
123 | |
124 if (sample_repeated) { | |
125 state.count_++; | |
126 } | |
127 if (state.count_>= state.look_back_ || // To break multiple repetitions. | |
128 !sample_repeated) { | |
129 if (state.count_ >= state.length_ - state.length_range_ && | |
peah-webrtc
2015/08/12 11:02:54
I'm not fully sure about the role of the length_ra
minyue-webrtc
2015/08/12 11:32:14
see discussion on look_back_range
| |
130 state.count_ <= state.length_ + state.length_range_) { | |
131 ReportRepetition(state.id_); | |
132 } | |
133 state.count_ = 0; | |
134 } | |
135 } | |
136 | |
137 // Update buffer. | |
138 for (int ch = 0; ch < num_channels_; ch++, sample++) { | |
139 audio_buffer_[ch][new_buffer_end] = *sample; | |
140 } | |
141 buffer_end_ = new_buffer_end; | |
142 } | |
143 } | |
144 | |
145 } // namespace webrtc | |
OLD | NEW |