Chromium Code Reviews| 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 |