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

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: Corrected the error code returned when the stream delay had not been set 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
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
130 RTC_DCHECK_GE(160u, audio->num_frames_per_band()); 141 RTC_DCHECK_GE(160u, audio->num_frames_per_band());
131 RTC_DCHECK_EQ(audio->num_channels(), apm_->num_reverse_channels()); 142 RTC_DCHECK_EQ(audio->num_channels(),
132 RTC_DCHECK_GE(cancellers_.size(), 143 stream_properties_->num_reverse_channels);
133 apm_->num_output_channels() * audio->num_channels()); 144 RTC_DCHECK_GE(cancellers_.size(), stream_properties_->num_output_channels *
145 audio->num_channels());
134 146
135 int err = AudioProcessing::kNoError; 147 int err = AudioProcessing::kNoError;
136 // The ordering convention must be followed to pass to the correct AECM. 148 // The ordering convention must be followed to pass to the correct AECM.
137 render_queue_buffer_.clear(); 149 render_queue_buffer_.clear();
138 int render_channel = 0; 150 int render_channel = 0;
139 for (auto& canceller : cancellers_) { 151 for (auto& canceller : cancellers_) {
140 err = WebRtcAecm_GetBufferFarendError( 152 err = WebRtcAecm_GetBufferFarendError(
141 canceller->state(), 153 canceller->state(),
142 audio->split_bands_const(render_channel)[kBand0To8kHz], 154 audio->split_bands_const(render_channel)[kBand0To8kHz],
143 audio->num_frames_per_band()); 155 audio->num_frames_per_band());
(...skipping 26 matching lines...) Expand all
170 // a queue. All the data chunks are buffered into the farend signal of the AEC. 182 // a queue. All the data chunks are buffered into the farend signal of the AEC.
171 void EchoControlMobileImpl::ReadQueuedRenderData() { 183 void EchoControlMobileImpl::ReadQueuedRenderData() {
172 rtc::CritScope cs_capture(crit_capture_); 184 rtc::CritScope cs_capture(crit_capture_);
173 185
174 if (!enabled_) { 186 if (!enabled_) {
175 return; 187 return;
176 } 188 }
177 189
178 while (render_signal_queue_->Remove(&capture_queue_buffer_)) { 190 while (render_signal_queue_->Remove(&capture_queue_buffer_)) {
179 size_t buffer_index = 0; 191 size_t buffer_index = 0;
180 size_t num_frames_per_band = 192 size_t num_frames_per_band = capture_queue_buffer_.size() /
181 capture_queue_buffer_.size() / 193 (stream_properties_->num_output_channels *
182 (apm_->num_output_channels() * apm_->num_reverse_channels()); 194 stream_properties_->num_reverse_channels);
183 195
184 for (auto& canceller : cancellers_) { 196 for (auto& canceller : cancellers_) {
185 WebRtcAecm_BufferFarend(canceller->state(), 197 WebRtcAecm_BufferFarend(canceller->state(),
186 &capture_queue_buffer_[buffer_index], 198 &capture_queue_buffer_[buffer_index],
187 num_frames_per_band); 199 num_frames_per_band);
188 200
189 buffer_index += num_frames_per_band; 201 buffer_index += num_frames_per_band;
190 } 202 }
191 } 203 }
192 } 204 }
193 205
194 int EchoControlMobileImpl::ProcessCaptureAudio(AudioBuffer* audio) { 206 int EchoControlMobileImpl::ProcessCaptureAudio(AudioBuffer* audio,
207 int stream_delay_ms) {
195 rtc::CritScope cs_capture(crit_capture_); 208 rtc::CritScope cs_capture(crit_capture_);
196 if (!enabled_) { 209 if (!enabled_) {
197 return AudioProcessing::kNoError; 210 return AudioProcessing::kNoError;
198 } 211 }
199 212
200 if (!apm_->was_stream_delay_set()) {
201 return AudioProcessing::kStreamParameterNotSetError;
202 }
203
204 RTC_DCHECK_GE(160u, audio->num_frames_per_band()); 213 RTC_DCHECK_GE(160u, audio->num_frames_per_band());
205 RTC_DCHECK_EQ(audio->num_channels(), apm_->num_output_channels()); 214 RTC_DCHECK_EQ(audio->num_channels(), stream_properties_->num_output_channels);
206 RTC_DCHECK_GE(cancellers_.size(), 215 RTC_DCHECK_GE(cancellers_.size(), stream_properties_->num_reverse_channels *
207 apm_->num_reverse_channels() * audio->num_channels()); 216 audio->num_channels());
208 217
209 int err = AudioProcessing::kNoError; 218 int err = AudioProcessing::kNoError;
210 219
211 // The ordering convention must be followed to pass to the correct AECM. 220 // The ordering convention must be followed to pass to the correct AECM.
212 size_t handle_index = 0; 221 size_t handle_index = 0;
213 for (size_t capture = 0; capture < audio->num_channels(); ++capture) { 222 for (size_t capture = 0; capture < audio->num_channels(); ++capture) {
214 // TODO(ajm): improve how this works, possibly inside AECM. 223 // TODO(ajm): improve how this works, possibly inside AECM.
215 // This is kind of hacked up. 224 // This is kind of hacked up.
216 const int16_t* noisy = audio->low_pass_reference(capture); 225 const int16_t* noisy = audio->low_pass_reference(capture);
217 const int16_t* clean = audio->split_bands_const(capture)[kBand0To8kHz]; 226 const int16_t* clean = audio->split_bands_const(capture)[kBand0To8kHz];
218 if (noisy == NULL) { 227 if (noisy == NULL) {
219 noisy = clean; 228 noisy = clean;
220 clean = NULL; 229 clean = NULL;
221 } 230 }
222 for (size_t render = 0; render < apm_->num_reverse_channels(); ++render) { 231 for (size_t render = 0; render < stream_properties_->num_reverse_channels;
232 ++render) {
223 err = WebRtcAecm_Process(cancellers_[handle_index]->state(), noisy, clean, 233 err = WebRtcAecm_Process(cancellers_[handle_index]->state(), noisy, clean,
224 audio->split_bands(capture)[kBand0To8kHz], 234 audio->split_bands(capture)[kBand0To8kHz],
225 audio->num_frames_per_band(), 235 audio->num_frames_per_band(), stream_delay_ms);
226 apm_->stream_delay_ms());
227 236
228 if (err != AudioProcessing::kNoError) { 237 if (err != AudioProcessing::kNoError) {
229 return MapError(err); 238 return MapError(err);
230 } 239 }
231 240
232 ++handle_index; 241 ++handle_index;
233 } 242 }
234 } 243 }
235 return AudioProcessing::kNoError; 244 return AudioProcessing::kNoError;
236 } 245 }
237 246
238 int EchoControlMobileImpl::Enable(bool enable) { 247 int EchoControlMobileImpl::Enable(bool enable) {
239 // Ensure AEC and AECM are not both enabled. 248 // Ensure AEC and AECM are not both enabled.
240 rtc::CritScope cs_render(crit_render_); 249 rtc::CritScope cs_render(crit_render_);
241 rtc::CritScope cs_capture(crit_capture_); 250 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 251
248 if (enable && 252 if (enable &&
249 apm_->proc_sample_rate_hz() > AudioProcessing::kSampleRate16kHz) { 253 stream_properties_->sample_rate_hz > AudioProcessing::kSampleRate16kHz) {
250 return AudioProcessing::kBadSampleRateError; 254 return AudioProcessing::kBadSampleRateError;
251 } 255 }
252 256
253 if (enable && !enabled_) { 257 if (enable && !enabled_) {
254 enabled_ = enable; // Must be set before Initialize() is called. 258 enabled_ = enable; // Must be set before Initialize() is called.
255 Initialize(); 259
260 // TODO(peah): Simplify once the Enable function has been removed from
261 // the public APM API.
262 RTC_DCHECK(stream_properties_);
263 Initialize(stream_properties_->sample_rate_hz,
264 stream_properties_->num_reverse_channels,
265 stream_properties_->num_output_channels);
256 } else { 266 } else {
257 enabled_ = enable; 267 enabled_ = enable;
258 } 268 }
259 return AudioProcessing::kNoError; 269 return AudioProcessing::kNoError;
260 } 270 }
261 271
262 bool EchoControlMobileImpl::is_enabled() const { 272 bool EchoControlMobileImpl::is_enabled() const {
263 rtc::CritScope cs(crit_capture_); 273 rtc::CritScope cs(crit_capture_);
264 return enabled_; 274 return enabled_;
265 } 275 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
307 // Size mismatch 317 // Size mismatch
308 return AudioProcessing::kBadParameterError; 318 return AudioProcessing::kBadParameterError;
309 } 319 }
310 320
311 if (external_echo_path_ == NULL) { 321 if (external_echo_path_ == NULL) {
312 external_echo_path_ = new unsigned char[size_bytes]; 322 external_echo_path_ = new unsigned char[size_bytes];
313 } 323 }
314 memcpy(external_echo_path_, echo_path, size_bytes); 324 memcpy(external_echo_path_, echo_path, size_bytes);
315 } 325 }
316 326
317 Initialize(); 327 // TODO(peah): Simplify once the Enable function has been removed from
328 // the public APM API.
329 RTC_DCHECK(stream_properties_);
330 Initialize(stream_properties_->sample_rate_hz,
331 stream_properties_->num_reverse_channels,
332 stream_properties_->num_output_channels);
318 return AudioProcessing::kNoError; 333 return AudioProcessing::kNoError;
319 } 334 }
320 335
321 int EchoControlMobileImpl::GetEchoPath(void* echo_path, 336 int EchoControlMobileImpl::GetEchoPath(void* echo_path,
322 size_t size_bytes) const { 337 size_t size_bytes) const {
323 rtc::CritScope cs(crit_capture_); 338 rtc::CritScope cs(crit_capture_);
324 if (echo_path == NULL) { 339 if (echo_path == NULL) {
325 return AudioProcessing::kNullPointerError; 340 return AudioProcessing::kNullPointerError;
326 } 341 }
327 if (size_bytes != echo_path_size_bytes()) { 342 if (size_bytes != echo_path_size_bytes()) {
328 // Size mismatch 343 // Size mismatch
329 return AudioProcessing::kBadParameterError; 344 return AudioProcessing::kBadParameterError;
330 } 345 }
331 if (!enabled_) { 346 if (!enabled_) {
332 return AudioProcessing::kNotEnabledError; 347 return AudioProcessing::kNotEnabledError;
333 } 348 }
334 349
335 // Get the echo path from the first channel 350 // Get the echo path from the first channel
336 int32_t err = 351 int32_t err =
337 WebRtcAecm_GetEchoPath(cancellers_[0]->state(), echo_path, size_bytes); 352 WebRtcAecm_GetEchoPath(cancellers_[0]->state(), echo_path, size_bytes);
338 if (err != 0) { 353 if (err != 0) {
339 return MapError(err); 354 return MapError(err);
340 } 355 }
341 356
342 return AudioProcessing::kNoError; 357 return AudioProcessing::kNoError;
343 } 358 }
344 359
345 void EchoControlMobileImpl::Initialize() { 360 void EchoControlMobileImpl::Initialize(int sample_rate_hz,
361 size_t num_reverse_channels,
362 size_t num_output_channels) {
346 rtc::CritScope cs_render(crit_render_); 363 rtc::CritScope cs_render(crit_render_);
347 rtc::CritScope cs_capture(crit_capture_); 364 rtc::CritScope cs_capture(crit_capture_);
365
366 stream_properties_.reset(new StreamProperties(
367 sample_rate_hz, num_reverse_channels, num_output_channels));
368
348 if (!enabled_) { 369 if (!enabled_) {
349 return; 370 return;
350 } 371 }
351 372
352 if (apm_->proc_sample_rate_hz() > AudioProcessing::kSampleRate16kHz) { 373 if (stream_properties_->sample_rate_hz > AudioProcessing::kSampleRate16kHz) {
353 LOG(LS_ERROR) << "AECM only supports 16 kHz or lower sample rates"; 374 LOG(LS_ERROR) << "AECM only supports 16 kHz or lower sample rates";
354 } 375 }
355 376
356 int sample_rate_hz = apm_->proc_sample_rate_hz();
357 cancellers_.resize(num_handles_required()); 377 cancellers_.resize(num_handles_required());
358 for (auto& canceller : cancellers_) { 378 for (auto& canceller : cancellers_) {
359 if (!canceller) { 379 if (!canceller) {
360 canceller.reset(new Canceller()); 380 canceller.reset(new Canceller());
361 } 381 }
362 canceller->Initialize(sample_rate_hz, external_echo_path_, 382 canceller->Initialize(sample_rate_hz, external_echo_path_,
363 echo_path_size_bytes()); 383 echo_path_size_bytes());
364 } 384 }
365 385
366 Configure(); 386 Configure();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 int handle_error = WebRtcAecm_set_config(canceller->state(), config); 426 int handle_error = WebRtcAecm_set_config(canceller->state(), config);
407 if (handle_error != AudioProcessing::kNoError) { 427 if (handle_error != AudioProcessing::kNoError) {
408 error = handle_error; 428 error = handle_error;
409 } 429 }
410 } 430 }
411 return error; 431 return error;
412 } 432 }
413 433
414 size_t EchoControlMobileImpl::num_handles_required() const { 434 size_t EchoControlMobileImpl::num_handles_required() const {
415 // Not locked as it only relies on APM public API which is threadsafe. 435 // Not locked as it only relies on APM public API which is threadsafe.
416 return apm_->num_output_channels() * apm_->num_reverse_channels(); 436 return stream_properties_->num_output_channels *
437 stream_properties_->num_reverse_channels;
417 } 438 }
418 } // namespace webrtc 439 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698