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[] = { | |
21 // {id_, look_back_, look_back_range_, length_, length_range_} | |
minyue-webrtc
2015/08/28 14:27:00
Comment here should be updated, I forgot.
minyue-webrtc
2015/09/03 13:23:58
Done.
| |
22 {0, 10, 10}, | |
23 {1, 100, 100} | |
24 }; | |
25 } | |
26 | |
27 RepetitionDetector::State::State(int id, int look_back_ms, int min_length_ms) | |
28 : id_(id), | |
29 look_back_ms_(look_back_ms), | |
30 min_length_ms_(min_length_ms) { | |
31 Reset(); | |
32 } | |
33 | |
34 void RepetitionDetector::State::Increment(bool zero) { | |
35 if (0 == count_samples_ && zero) { | |
hlundin-webrtc
2015/08/31 13:46:46
You do not need this if statement.
minyue-webrtc
2015/09/03 13:23:58
I know that this is redundant if Reset was called
hlundin-webrtc
2015/09/15 09:26:38
I think you are being overly aggressive against yo
| |
36 all_zero_ = true; | |
37 } | |
38 ++count_samples_; | |
39 if (!zero) { | |
40 all_zero_ = false; | |
41 } | |
42 } | |
43 | |
44 bool RepetitionDetector::State::HasValidReport(int sample_rate_hz) const { | |
45 return (!all_zero_ && static_cast<int>(count_samples_) >= | |
hlundin-webrtc
2015/08/31 13:46:46
rtc::checked_cast. But I do think it would be bett
minyue-webrtc
2015/09/03 13:23:58
Ok, I like it, and hope that it can stay when I mo
hlundin-webrtc
2015/09/15 09:26:38
Acknowledged.
| |
46 min_length_ms_ * sample_rate_hz / 1000); | |
47 } | |
48 | |
49 bool RepetitionDetector::State::AlreadyReported() const { | |
hlundin-webrtc
2015/08/31 13:46:46
Change name to reported().
minyue-webrtc
2015/09/03 13:23:58
Done.
| |
50 return reported_; | |
51 } | |
52 | |
53 void RepetitionDetector::State::SetReported() { | |
hlundin-webrtc
2015/08/31 13:46:46
Perhaps change name to set_reported(bool value).
minyue-webrtc
2015/09/03 13:23:58
Done.
| |
54 reported_ = true; | |
55 } | |
56 | |
57 void RepetitionDetector::State::Reset() { | |
58 count_samples_ = 0; | |
59 all_zero_ = true; | |
60 reported_ = false; | |
61 } | |
62 | |
63 RepetitionDetector::RepetitionDetector() | |
64 : max_look_back_ms_(0), | |
65 audio_buffer_(nullptr), | |
66 sample_rate_hz_(0), | |
67 buffer_size_samples_(0), | |
68 buffer_end_index_(0) { | |
69 RegisterRepetitionPatterns(kRepetitionPatterns, | |
70 sizeof(kRepetitionPatterns) / sizeof (Pattern)); | |
71 } | |
72 | |
73 RepetitionDetector::~RepetitionDetector() { | |
74 ClearRepetitionPatterns(); | |
75 } | |
76 | |
77 void RepetitionDetector::RegisterRepetitionPatterns(const Pattern* patterns, | |
78 size_t num_patterns) { | |
79 Pattern pattern; | |
80 for (size_t idx = 0; idx < num_patterns; idx++) { | |
81 pattern = patterns[idx]; | |
82 states_.push_back(new State(pattern.id_, pattern.look_back_ms_, | |
83 pattern.min_length_ms_)); | |
84 if (pattern.look_back_ms_ > max_look_back_ms_) { | |
85 max_look_back_ms_ = pattern.look_back_ms_; | |
86 } | |
87 } | |
88 } | |
89 | |
90 void RepetitionDetector::ClearRepetitionPatterns() { | |
91 for (auto state : states_) { | |
Andrew MacDonald
2015/08/28 17:43:42
How often is this called? You should strive to avo
hlundin-webrtc
2015/08/31 13:46:46
It's only called in the destructor of RepetitionDe
minyue-webrtc
2015/09/03 13:23:58
Done.
| |
92 delete state; | |
93 } | |
94 states_.clear(); | |
95 max_look_back_ms_ = 0; | |
96 } | |
97 | |
98 void RepetitionDetector::Reset(size_t bytes_per_sample, int sample_rate_hz) { | |
99 bytes_per_sample_ = bytes_per_sample; | |
100 sample_rate_hz_ = sample_rate_hz; | |
101 int sample_1k = max_look_back_ms_ * sample_rate_hz_; | |
102 buffer_size_samples_ = sample_1k / 1000 + (sample_1k % 1000 != 0); | |
hlundin-webrtc
2015/08/31 13:46:46
This is rounding up, right? Consider (sample_1k +
minyue-webrtc
2015/09/01 10:21:48
nice!
| |
103 audio_buffer_.reset(new char[buffer_size_samples_ * bytes_per_sample_]()); | |
104 for (auto state : states_) { | |
105 state->Reset(); | |
106 } | |
107 } | |
108 | |
109 void RepetitionDetector::AddSampleToBuffer(const void* sample) { | |
110 buffer_end_index_++; | |
hlundin-webrtc
2015/08/31 13:46:46
buffer_end_index_ is initialized to 0, but it is i
minyue-webrtc
2015/09/03 13:23:58
Done.
| |
111 if (buffer_end_index_ == buffer_size_samples_) { | |
112 buffer_end_index_ = 0; | |
113 } | |
114 memcpy(&audio_buffer_[buffer_end_index_ * bytes_per_sample_], sample, | |
115 bytes_per_sample_); | |
116 } | |
117 | |
118 void RepetitionDetector::Detect(const void* data, size_t bytes_per_sample, | |
119 size_t samples_per_channel, | |
120 int sample_rate_hz) { | |
121 DCHECK_GT(states_.size(), 0ul); | |
122 if (bytes_per_sample != bytes_per_sample_ || | |
123 sample_rate_hz != sample_rate_hz_) { | |
124 Reset(bytes_per_sample, sample_rate_hz); | |
125 } | |
126 | |
127 std::unique_ptr<char[]> zero(new char[bytes_per_sample]()); | |
Andrew MacDonald
2015/08/31 16:05:31
You shouldn't need this.
minyue-webrtc
2015/09/03 13:23:57
Done.
| |
128 const char* sample = reinterpret_cast<const char*>(data); | |
Andrew MacDonald
2015/08/31 16:05:31
No, no, use the type you want.
minyue-webrtc
2015/09/01 10:21:48
Yes, we may use template, but I also add two comme
ajm
2015/09/02 05:28:28
As described above, you should be explicit about y
minyue-webrtc
2015/09/03 13:23:58
Done.
| |
129 | |
130 for (size_t idx = 0; idx < samples_per_channel; | |
131 ++idx, sample += bytes_per_sample_) { | |
132 for (auto state : states_) { | |
133 size_t look_back_samples = | |
134 rtc::CheckedDivExact(state->look_back_ms() * sample_rate_hz_, 1000); | |
135 const char* look_back_pointer = audio_buffer_.get() + | |
136 (buffer_end_index_ + buffer_size_samples_ - look_back_samples + 1) % | |
137 buffer_size_samples_ * bytes_per_sample_; | |
138 | |
139 if (memcmp(look_back_pointer, sample, bytes_per_sample) == 0) { | |
hlundin-webrtc
2015/08/31 13:46:46
This memcmp is to find out if all of |sample| is z
Andrew MacDonald
2015/08/31 16:05:31
Absolutely. Use the correct types and just compare
minyue-webrtc
2015/09/03 13:23:58
Done.
| |
140 if (!state->AlreadyReported()) { | |
141 state->Increment(memcmp(zero.get(), sample, bytes_per_sample) == 0); | |
minyue-webrtc
2015/09/01 10:21:48
Zero is actually this line. I can move the zero al
ajm
2015/09/02 05:28:28
How is a == b any less clear than memcmp for float
minyue-webrtc
2015/09/03 13:23:58
Done.
| |
142 if (state->HasValidReport(sample_rate_hz)) { | |
143 ReportRepetition(state->id()); | |
144 state->SetReported(); | |
145 } | |
146 } | |
147 } else { | |
148 state->Reset(); | |
149 } | |
150 } | |
151 AddSampleToBuffer(sample); | |
152 } | |
153 } | |
154 | |
155 } // namespace webrtc | |
OLD | NEW |