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

Side by Side Diff: webrtc/modules/audio_processing/repetition_detector.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 "webrtc/modules/audio_processing/repetition_detector.h"
12
13 #include <algorithm>
14
15 #include "webrtc/base/checks.h"
16 #include "webrtc/base/safe_conversions.h"
17
18 namespace webrtc {
19
20 namespace {
21 static const RepetitionDetector::Pattern kRepetitionPatterns[] = {
22 // {id_, look_back_, length_}
23 {0, 10, 10},
24 {1, 100, 10}
25 };
26 static const size_t kMaxFrames = 480; // 10ms * 48kHz
27 }
28
29 RepetitionDetector::State::State(int id, int look_back_ms, int min_length_ms)
30 : id_(id),
31 look_back_ms_(look_back_ms),
32 min_length_ms_(min_length_ms) {
33 Reset();
34 }
35
36 void RepetitionDetector::State::Increment(bool zero) {
37 if (0 == count_frames_ && zero) {
38 all_zero_ = true;
39 }
40 ++count_frames_;
41 if (!zero) {
42 all_zero_ = false;
43 }
44 }
45
46 bool RepetitionDetector::State::HasValidReport(int sample_rate_hz) const {
47 return (!all_zero_ && count_frames_ >=
48 rtc::checked_cast<size_t>(min_length_ms_ * sample_rate_hz / 1000));
49 }
50
51 void RepetitionDetector::State::Reset() {
52 count_frames_ = 0;
53 all_zero_ = true;
54 reported_ = false;
55 }
56
57 RepetitionDetector::RepetitionDetector()
58 : max_look_back_ms_(0),
59 sample_rate_hz_(0),
60 buffer_size_frames_(0),
61 buffer_end_index_(0),
62 max_frames_(kMaxFrames) {
63 RegisterRepetitionPatterns(kRepetitionPatterns,
64 sizeof(kRepetitionPatterns) / sizeof (Pattern));
65 }
66
67 void RepetitionDetector::RegisterRepetitionPatterns(const Pattern* patterns,
68 size_t num_patterns) {
69 Pattern pattern;
70 for (size_t idx = 0; idx < num_patterns; idx++) {
71 pattern = patterns[idx];
72 states_.push_back(new State(pattern.id_, pattern.look_back_ms_,
73 pattern.min_length_ms_));
74 if (pattern.look_back_ms_ > max_look_back_ms_) {
75 max_look_back_ms_ = pattern.look_back_ms_;
76 }
77 }
78 }
79
80 void RepetitionDetector::Reset(size_t num_channels, int sample_rate_hz) {
81 num_channels_ = num_channels;
82 sample_rate_hz_ = sample_rate_hz;
83 int sample_1k = max_look_back_ms_ * sample_rate_hz_;
84 buffer_size_frames_ = (sample_1k + 999) / 1000 + max_frames_;
hlundin-webrtc 2015/09/15 09:26:38 Now just comment that what you implemented is in f
minyue-webrtc 2015/09/17 13:45:22 Done.
85 audio_buffer_.resize(buffer_size_frames_ * num_channels_);
86 for (auto state : states_) {
87 state->Reset();
88 }
89 }
90
91 void RepetitionDetector::AddFramesToBuffer(const float* data,
92 size_t num_frames) {
93 DCHECK_LE(num_frames, buffer_size_frames_);
94 size_t margin = buffer_size_frames_ - buffer_end_index_;
hlundin-webrtc 2015/09/15 09:26:38 const
minyue-webrtc 2015/09/17 13:45:22 Done.
95 const auto it = audio_buffer_.begin() + buffer_end_index_ * num_channels_;
96 if (num_frames <= margin) {
97 std::copy(data, data + num_frames * num_channels_, it);
98 buffer_end_index_ += num_frames;
99 } else {
100 std::copy(data, data + margin * num_channels_, it);
101 std::copy(data + margin * num_channels_, data + num_frames * num_channels_,
102 audio_buffer_.begin());
103 buffer_end_index_ = num_frames - margin;
104 }
105 }
106
107 bool RepetitionDetector::Equal(const float* frame,
108 int look_back_frames) const {
109 const size_t look_back_index =
110 (buffer_end_index_ + buffer_size_frames_ - look_back_frames) %
111 buffer_size_frames_;
112 auto it = audio_buffer_.begin() + look_back_index * num_channels_;
113 for (size_t cdx = 0; cdx < num_channels_; ++cdx, ++frame, ++it) {
114 if (*frame != *it) {
115 return false;
116 }
117 }
118 return true;
119 }
120
121 bool RepetitionDetector::IsZero(const float* frame) const {
122 for (size_t cdx = 0; cdx < num_channels_; ++cdx, ++frame) {
123 if (*frame != 0) {
124 return false;
125 }
126 }
127 return true;
128 }
129
130 void RepetitionDetector::Detect(const float* data, size_t num_frames,
131 size_t num_channels, int sample_rate_hz) {
132 DCHECK_GT(states_.size(), 0ul);
133 if (num_channels != num_channels_ || sample_rate_hz != sample_rate_hz_) {
134 Reset(num_channels, sample_rate_hz);
135 }
136
137 while (num_frames > max_frames_) {
138 Detect(data, max_frames_, num_channels, sample_rate_hz);
139 data += max_frames_ * num_channels;
140 num_frames -= max_frames_;
141 }
142
143 if (num_frames == 0)
144 return;
145
146 AddFramesToBuffer(data, num_frames);
147
148 for (size_t idx = num_frames; idx > 0; --idx, data += num_channels) {
149 for (auto state : states_) {
150 const size_t look_back_frames =
151 rtc::CheckedDivExact(state->look_back_ms() * sample_rate_hz_, 1000);
152 // Equal(data, offset) checks if |data| equals the audio frame located
153 // |offset| frames from the end of buffer. Now a full frame has been
154 // inserted to the buffer, and thus |offset| should compensate for it.
155 if (Equal(data, look_back_frames + idx)) {
156 if (!state->reported()) {
157 state->Increment(IsZero(data));
158 if (state->HasValidReport(sample_rate_hz)) {
159 ReportRepetition(state->id());
160 state->set_reported(true);
161 }
162 }
163 } else {
164 state->Reset();
165 }
166 }
167 }
168 }
169
170 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698