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

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

Issue 1803433003: Removed the dependency on AudioProcessingImpl in EchoControlMobileImpl (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Added missing DCHECKS for the stream_properties_ Created 4 years, 9 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
« no previous file with comments | « webrtc/modules/audio_processing/echo_control_mobile_impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 // Maximum number of frames to buffer in the render queue. 57 // Maximum number of frames to buffer in the render queue.
58 // TODO(peah): Decrease this once we properly handle hugely unbalanced 58 // TODO(peah): Decrease this once we properly handle hugely unbalanced
59 // reverse and forward call numbers. 59 // reverse and forward call numbers.
60 static const size_t kMaxNumFramesToBuffer = 100; 60 static const size_t kMaxNumFramesToBuffer = 100;
61 } // namespace 61 } // namespace
62 62
63 size_t EchoControlMobile::echo_path_size_bytes() { 63 size_t EchoControlMobile::echo_path_size_bytes() {
64 return WebRtcAecm_echo_path_size_bytes(); 64 return WebRtcAecm_echo_path_size_bytes();
65 } 65 }
66 66
67 struct EchoControlMobileImpl::StreamProperties {
68 StreamProperties() = delete;
69 StreamProperties(int sample_rate_hz,
70 size_t num_reverse_channels,
71 size_t num_output_channels)
72 : sample_rate_hz(sample_rate_hz),
73 num_reverse_channels(num_reverse_channels),
74 num_output_channels(num_output_channels) {}
75
76 int sample_rate_hz;
77 size_t num_reverse_channels;
78 size_t num_output_channels;
79 };
80
67 class EchoControlMobileImpl::Canceller { 81 class EchoControlMobileImpl::Canceller {
68 public: 82 public:
69 Canceller() { 83 Canceller() {
70 state_ = WebRtcAecm_Create(); 84 state_ = WebRtcAecm_Create();
71 RTC_CHECK(state_); 85 RTC_CHECK(state_);
72 } 86 }
73 87
74 ~Canceller() { 88 ~Canceller() {
75 RTC_DCHECK(state_); 89 RTC_DCHECK(state_);
76 WebRtcAecm_Free(state_); 90 WebRtcAecm_Free(state_);
(...skipping 15 matching lines...) Expand all
92 echo_path_size_bytes); 106 echo_path_size_bytes);
93 RTC_DCHECK_EQ(AudioProcessing::kNoError, error); 107 RTC_DCHECK_EQ(AudioProcessing::kNoError, error);
94 } 108 }
95 } 109 }
96 110
97 private: 111 private:
98 void* state_; 112 void* state_;
99 RTC_DISALLOW_COPY_AND_ASSIGN(Canceller); 113 RTC_DISALLOW_COPY_AND_ASSIGN(Canceller);
100 }; 114 };
101 115
102 EchoControlMobileImpl::EchoControlMobileImpl(const AudioProcessing* apm, 116 EchoControlMobileImpl::EchoControlMobileImpl(rtc::CriticalSection* crit_render,
103 rtc::CriticalSection* crit_render,
104 rtc::CriticalSection* crit_capture) 117 rtc::CriticalSection* crit_capture)
105 : apm_(apm), 118 : crit_render_(crit_render),
106 crit_render_(crit_render),
107 crit_capture_(crit_capture), 119 crit_capture_(crit_capture),
108 routing_mode_(kSpeakerphone), 120 routing_mode_(kSpeakerphone),
109 comfort_noise_enabled_(true), 121 comfort_noise_enabled_(true),
110 external_echo_path_(NULL), 122 external_echo_path_(NULL),
111 render_queue_element_max_size_(0) { 123 render_queue_element_max_size_(0) {
112 RTC_DCHECK(apm);
113 RTC_DCHECK(crit_render); 124 RTC_DCHECK(crit_render);
114 RTC_DCHECK(crit_capture); 125 RTC_DCHECK(crit_capture);
115 } 126 }
116 127
117 EchoControlMobileImpl::~EchoControlMobileImpl() { 128 EchoControlMobileImpl::~EchoControlMobileImpl() {
118 if (external_echo_path_ != NULL) { 129 if (external_echo_path_ != NULL) {
119 delete [] external_echo_path_; 130 delete [] external_echo_path_;
120 external_echo_path_ = NULL; 131 external_echo_path_ = NULL;
121 } 132 }
122 } 133 }
123 134
124 int EchoControlMobileImpl::ProcessRenderAudio(const AudioBuffer* audio) { 135 int EchoControlMobileImpl::ProcessRenderAudio(const AudioBuffer* audio) {
125 rtc::CritScope cs_render(crit_render_); 136 rtc::CritScope cs_render(crit_render_);
126 if (!enabled_) { 137 if (!enabled_) {
127 return AudioProcessing::kNoError; 138 return AudioProcessing::kNoError;
128 } 139 }
129 140
141 RTC_DCHECK(stream_properties_);
130 RTC_DCHECK_GE(160u, audio->num_frames_per_band()); 142 RTC_DCHECK_GE(160u, audio->num_frames_per_band());
131 RTC_DCHECK_EQ(audio->num_channels(), apm_->num_reverse_channels()); 143 RTC_DCHECK_EQ(audio->num_channels(),
132 RTC_DCHECK_GE(cancellers_.size(), 144 stream_properties_->num_reverse_channels);
133 apm_->num_output_channels() * audio->num_channels()); 145 RTC_DCHECK_GE(cancellers_.size(), stream_properties_->num_output_channels *
146 audio->num_channels());
134 147
135 int err = AudioProcessing::kNoError; 148 int err = AudioProcessing::kNoError;
136 // The ordering convention must be followed to pass to the correct AECM. 149 // The ordering convention must be followed to pass to the correct AECM.
137 render_queue_buffer_.clear(); 150 render_queue_buffer_.clear();
138 int render_channel = 0; 151 int render_channel = 0;
139 for (auto& canceller : cancellers_) { 152 for (auto& canceller : cancellers_) {
140 err = WebRtcAecm_GetBufferFarendError( 153 err = WebRtcAecm_GetBufferFarendError(
141 canceller->state(), 154 canceller->state(),
142 audio->split_bands_const(render_channel)[kBand0To8kHz], 155 audio->split_bands_const(render_channel)[kBand0To8kHz],
143 audio->num_frames_per_band()); 156 audio->num_frames_per_band());
(...skipping 19 matching lines...) Expand all
163 RTC_DCHECK_EQ(render_signal_queue_->Insert(&render_queue_buffer_), true); 176 RTC_DCHECK_EQ(render_signal_queue_->Insert(&render_queue_buffer_), true);
164 } 177 }
165 178
166 return AudioProcessing::kNoError; 179 return AudioProcessing::kNoError;
167 } 180 }
168 181
169 // Read chunks of data that were received and queued on the render side from 182 // Read chunks of data that were received and queued on the render side from
170 // a queue. All the data chunks are buffered into the farend signal of the AEC. 183 // a queue. All the data chunks are buffered into the farend signal of the AEC.
171 void EchoControlMobileImpl::ReadQueuedRenderData() { 184 void EchoControlMobileImpl::ReadQueuedRenderData() {
172 rtc::CritScope cs_capture(crit_capture_); 185 rtc::CritScope cs_capture(crit_capture_);
186 RTC_DCHECK(stream_properties_);
173 187
174 if (!enabled_) { 188 if (!enabled_) {
175 return; 189 return;
176 } 190 }
177 191
178 while (render_signal_queue_->Remove(&capture_queue_buffer_)) { 192 while (render_signal_queue_->Remove(&capture_queue_buffer_)) {
179 size_t buffer_index = 0; 193 size_t buffer_index = 0;
180 size_t num_frames_per_band = 194 size_t num_frames_per_band = capture_queue_buffer_.size() /
181 capture_queue_buffer_.size() / 195 (stream_properties_->num_output_channels *
182 (apm_->num_output_channels() * apm_->num_reverse_channels()); 196 stream_properties_->num_reverse_channels);
183 197
184 for (auto& canceller : cancellers_) { 198 for (auto& canceller : cancellers_) {
185 WebRtcAecm_BufferFarend(canceller->state(), 199 WebRtcAecm_BufferFarend(canceller->state(),
186 &capture_queue_buffer_[buffer_index], 200 &capture_queue_buffer_[buffer_index],
187 num_frames_per_band); 201 num_frames_per_band);
188 202
189 buffer_index += num_frames_per_band; 203 buffer_index += num_frames_per_band;
190 } 204 }
191 } 205 }
192 } 206 }
193 207
194 int EchoControlMobileImpl::ProcessCaptureAudio(AudioBuffer* audio) { 208 int EchoControlMobileImpl::ProcessCaptureAudio(AudioBuffer* audio,
209 int stream_delay_ms) {
195 rtc::CritScope cs_capture(crit_capture_); 210 rtc::CritScope cs_capture(crit_capture_);
196 if (!enabled_) { 211 if (!enabled_) {
197 return AudioProcessing::kNoError; 212 return AudioProcessing::kNoError;
198 } 213 }
199 214
200 if (!apm_->was_stream_delay_set()) { 215 RTC_DCHECK(stream_properties_);
201 return AudioProcessing::kStreamParameterNotSetError;
202 }
203
204 RTC_DCHECK_GE(160u, audio->num_frames_per_band()); 216 RTC_DCHECK_GE(160u, audio->num_frames_per_band());
205 RTC_DCHECK_EQ(audio->num_channels(), apm_->num_output_channels()); 217 RTC_DCHECK_EQ(audio->num_channels(), stream_properties_->num_output_channels);
206 RTC_DCHECK_GE(cancellers_.size(), 218 RTC_DCHECK_GE(cancellers_.size(), stream_properties_->num_reverse_channels *
207 apm_->num_reverse_channels() * audio->num_channels()); 219 audio->num_channels());
208 220
209 int err = AudioProcessing::kNoError; 221 int err = AudioProcessing::kNoError;
210 222
211 // The ordering convention must be followed to pass to the correct AECM. 223 // The ordering convention must be followed to pass to the correct AECM.
212 size_t handle_index = 0; 224 size_t handle_index = 0;
213 for (size_t capture = 0; capture < audio->num_channels(); ++capture) { 225 for (size_t capture = 0; capture < audio->num_channels(); ++capture) {
214 // TODO(ajm): improve how this works, possibly inside AECM. 226 // TODO(ajm): improve how this works, possibly inside AECM.
215 // This is kind of hacked up. 227 // This is kind of hacked up.
216 const int16_t* noisy = audio->low_pass_reference(capture); 228 const int16_t* noisy = audio->low_pass_reference(capture);
217 const int16_t* clean = audio->split_bands_const(capture)[kBand0To8kHz]; 229 const int16_t* clean = audio->split_bands_const(capture)[kBand0To8kHz];
218 if (noisy == NULL) { 230 if (noisy == NULL) {
219 noisy = clean; 231 noisy = clean;
220 clean = NULL; 232 clean = NULL;
221 } 233 }
222 for (size_t render = 0; render < apm_->num_reverse_channels(); ++render) { 234 for (size_t render = 0; render < stream_properties_->num_reverse_channels;
235 ++render) {
223 err = WebRtcAecm_Process(cancellers_[handle_index]->state(), noisy, clean, 236 err = WebRtcAecm_Process(cancellers_[handle_index]->state(), noisy, clean,
224 audio->split_bands(capture)[kBand0To8kHz], 237 audio->split_bands(capture)[kBand0To8kHz],
225 audio->num_frames_per_band(), 238 audio->num_frames_per_band(), stream_delay_ms);
226 apm_->stream_delay_ms());
227 239
228 if (err != AudioProcessing::kNoError) { 240 if (err != AudioProcessing::kNoError) {
229 return MapError(err); 241 return MapError(err);
230 } 242 }
231 243
232 ++handle_index; 244 ++handle_index;
233 } 245 }
234 } 246 }
235 return AudioProcessing::kNoError; 247 return AudioProcessing::kNoError;
236 } 248 }
237 249
238 int EchoControlMobileImpl::Enable(bool enable) { 250 int EchoControlMobileImpl::Enable(bool enable) {
239 // Ensure AEC and AECM are not both enabled. 251 // Ensure AEC and AECM are not both enabled.
240 rtc::CritScope cs_render(crit_render_); 252 rtc::CritScope cs_render(crit_render_);
241 rtc::CritScope cs_capture(crit_capture_); 253 rtc::CritScope cs_capture(crit_capture_);
242 // The is_enabled call is safe from a deadlock perspective
243 // as both locks are allready held in the correct order.
244 if (enable && apm_->echo_cancellation()->is_enabled()) {
245 return AudioProcessing::kBadParameterError;
246 }
247 254
248 if (enable && 255 if (enable &&
249 apm_->proc_sample_rate_hz() > AudioProcessing::kSampleRate16kHz) { 256 stream_properties_->sample_rate_hz > AudioProcessing::kSampleRate16kHz) {
250 return AudioProcessing::kBadSampleRateError; 257 return AudioProcessing::kBadSampleRateError;
251 } 258 }
252 259
253 if (enable && !enabled_) { 260 if (enable && !enabled_) {
254 enabled_ = enable; // Must be set before Initialize() is called. 261 enabled_ = enable; // Must be set before Initialize() is called.
255 Initialize(); 262
263 // TODO(peah): Simplify once the Enable function has been removed from
264 // the public APM API.
265 RTC_DCHECK(stream_properties_);
hlundin-webrtc 2016/03/15 07:53:38 Move the DCHECK to before line 256.
peah-webrtc 2016/03/15 08:18:31 Of course! :$ Good catch!
266 Initialize(stream_properties_->sample_rate_hz,
267 stream_properties_->num_reverse_channels,
268 stream_properties_->num_output_channels);
256 } else { 269 } else {
257 enabled_ = enable; 270 enabled_ = enable;
258 } 271 }
259 return AudioProcessing::kNoError; 272 return AudioProcessing::kNoError;
260 } 273 }
261 274
262 bool EchoControlMobileImpl::is_enabled() const { 275 bool EchoControlMobileImpl::is_enabled() const {
263 rtc::CritScope cs(crit_capture_); 276 rtc::CritScope cs(crit_capture_);
264 return enabled_; 277 return enabled_;
265 } 278 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 // Size mismatch 320 // Size mismatch
308 return AudioProcessing::kBadParameterError; 321 return AudioProcessing::kBadParameterError;
309 } 322 }
310 323
311 if (external_echo_path_ == NULL) { 324 if (external_echo_path_ == NULL) {
312 external_echo_path_ = new unsigned char[size_bytes]; 325 external_echo_path_ = new unsigned char[size_bytes];
313 } 326 }
314 memcpy(external_echo_path_, echo_path, size_bytes); 327 memcpy(external_echo_path_, echo_path, size_bytes);
315 } 328 }
316 329
317 Initialize(); 330 // TODO(peah): Simplify once the Enable function has been removed from
331 // the public APM API.
332 RTC_DCHECK(stream_properties_);
333 Initialize(stream_properties_->sample_rate_hz,
334 stream_properties_->num_reverse_channels,
335 stream_properties_->num_output_channels);
318 return AudioProcessing::kNoError; 336 return AudioProcessing::kNoError;
319 } 337 }
320 338
321 int EchoControlMobileImpl::GetEchoPath(void* echo_path, 339 int EchoControlMobileImpl::GetEchoPath(void* echo_path,
322 size_t size_bytes) const { 340 size_t size_bytes) const {
323 rtc::CritScope cs(crit_capture_); 341 rtc::CritScope cs(crit_capture_);
324 if (echo_path == NULL) { 342 if (echo_path == NULL) {
325 return AudioProcessing::kNullPointerError; 343 return AudioProcessing::kNullPointerError;
326 } 344 }
327 if (size_bytes != echo_path_size_bytes()) { 345 if (size_bytes != echo_path_size_bytes()) {
328 // Size mismatch 346 // Size mismatch
329 return AudioProcessing::kBadParameterError; 347 return AudioProcessing::kBadParameterError;
330 } 348 }
331 if (!enabled_) { 349 if (!enabled_) {
332 return AudioProcessing::kNotEnabledError; 350 return AudioProcessing::kNotEnabledError;
333 } 351 }
334 352
335 // Get the echo path from the first channel 353 // Get the echo path from the first channel
336 int32_t err = 354 int32_t err =
337 WebRtcAecm_GetEchoPath(cancellers_[0]->state(), echo_path, size_bytes); 355 WebRtcAecm_GetEchoPath(cancellers_[0]->state(), echo_path, size_bytes);
338 if (err != 0) { 356 if (err != 0) {
339 return MapError(err); 357 return MapError(err);
340 } 358 }
341 359
342 return AudioProcessing::kNoError; 360 return AudioProcessing::kNoError;
343 } 361 }
344 362
345 void EchoControlMobileImpl::Initialize() { 363 void EchoControlMobileImpl::Initialize(int sample_rate_hz,
364 size_t num_reverse_channels,
365 size_t num_output_channels) {
346 rtc::CritScope cs_render(crit_render_); 366 rtc::CritScope cs_render(crit_render_);
347 rtc::CritScope cs_capture(crit_capture_); 367 rtc::CritScope cs_capture(crit_capture_);
368
369 stream_properties_.reset(new StreamProperties(
370 sample_rate_hz, num_reverse_channels, num_output_channels));
371
348 if (!enabled_) { 372 if (!enabled_) {
349 return; 373 return;
350 } 374 }
351 375
352 if (apm_->proc_sample_rate_hz() > AudioProcessing::kSampleRate16kHz) { 376 if (stream_properties_->sample_rate_hz > AudioProcessing::kSampleRate16kHz) {
353 LOG(LS_ERROR) << "AECM only supports 16 kHz or lower sample rates"; 377 LOG(LS_ERROR) << "AECM only supports 16 kHz or lower sample rates";
354 } 378 }
355 379
356 int sample_rate_hz = apm_->proc_sample_rate_hz();
357 cancellers_.resize(num_handles_required()); 380 cancellers_.resize(num_handles_required());
358 for (auto& canceller : cancellers_) { 381 for (auto& canceller : cancellers_) {
359 if (!canceller) { 382 if (!canceller) {
360 canceller.reset(new Canceller()); 383 canceller.reset(new Canceller());
361 } 384 }
362 canceller->Initialize(sample_rate_hz, external_echo_path_, 385 canceller->Initialize(sample_rate_hz, external_echo_path_,
363 echo_path_size_bytes()); 386 echo_path_size_bytes());
364 } 387 }
365 388
366 Configure(); 389 Configure();
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 for (auto& canceller : cancellers_) { 428 for (auto& canceller : cancellers_) {
406 int handle_error = WebRtcAecm_set_config(canceller->state(), config); 429 int handle_error = WebRtcAecm_set_config(canceller->state(), config);
407 if (handle_error != AudioProcessing::kNoError) { 430 if (handle_error != AudioProcessing::kNoError) {
408 error = handle_error; 431 error = handle_error;
409 } 432 }
410 } 433 }
411 return error; 434 return error;
412 } 435 }
413 436
414 size_t EchoControlMobileImpl::num_handles_required() const { 437 size_t EchoControlMobileImpl::num_handles_required() const {
415 // Not locked as it only relies on APM public API which is threadsafe. 438 RTC_DCHECK(stream_properties_);
416 return apm_->num_output_channels() * apm_->num_reverse_channels(); 439 return stream_properties_->num_output_channels *
440 stream_properties_->num_reverse_channels;
417 } 441 }
418 } // namespace webrtc 442 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_processing/echo_control_mobile_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698