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

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

Issue 1226093007: Allow more than 2 input channels in AudioProcessing. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fix comments and rearrange code Created 5 years, 5 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
11 #include "webrtc/modules/audio_processing/audio_processing_impl.h" 11 #include "webrtc/modules/audio_processing/audio_processing_impl.h"
12 12
13 #include <assert.h> 13 #include <assert.h>
14 #include <algorithm>
14 15
15 #include "webrtc/base/checks.h" 16 #include "webrtc/base/checks.h"
16 #include "webrtc/base/platform_file.h" 17 #include "webrtc/base/platform_file.h"
17 #include "webrtc/common_audio/include/audio_util.h" 18 #include "webrtc/common_audio/include/audio_util.h"
18 #include "webrtc/common_audio/channel_buffer.h" 19 #include "webrtc/common_audio/channel_buffer.h"
19 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar y.h" 20 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar y.h"
20 extern "C" { 21 extern "C" {
21 #include "webrtc/modules/audio_processing/aec/aec_core.h" 22 #include "webrtc/modules/audio_processing/aec/aec_core.h"
22 } 23 }
23 #include "webrtc/modules/audio_processing/agc/agc_manager_direct.h" 24 #include "webrtc/modules/audio_processing/agc/agc_manager_direct.h"
(...skipping 26 matching lines...) Expand all
50 51
51 #define RETURN_ON_ERR(expr) \ 52 #define RETURN_ON_ERR(expr) \
52 do { \ 53 do { \
53 int err = (expr); \ 54 int err = (expr); \
54 if (err != kNoError) { \ 55 if (err != kNoError) { \
55 return err; \ 56 return err; \
56 } \ 57 } \
57 } while (0) 58 } while (0)
58 59
59 namespace webrtc { 60 namespace webrtc {
61 namespace {
62
63 static bool LayoutHasKeyboard(AudioProcessing::ChannelLayout layout) {
64 switch (layout) {
65 case AudioProcessing::kMono:
66 case AudioProcessing::kStereo:
67 return false;
68 case AudioProcessing::kMonoAndKeyboard:
69 case AudioProcessing::kStereoAndKeyboard:
70 return true;
71 }
72
73 assert(false);
74 return false;
75 }
76
77 } // namespace
60 78
61 // Throughout webrtc, it's assumed that success is represented by zero. 79 // Throughout webrtc, it's assumed that success is represented by zero.
62 static_assert(AudioProcessing::kNoError == 0, "kNoError must be zero"); 80 static_assert(AudioProcessing::kNoError == 0, "kNoError must be zero");
63 81
64 // This class has two main functionalities: 82 // This class has two main functionalities:
65 // 83 //
66 // 1) It is returned instead of the real GainControl after the new AGC has been 84 // 1) It is returned instead of the real GainControl after the new AGC has been
67 // enabled in order to prevent an outside user from overriding compression 85 // enabled in order to prevent an outside user from overriding compression
68 // settings. It doesn't do anything in its implementation, except for 86 // settings. It doesn't do anything in its implementation, except for
69 // delegating the const methods and Enable calls to the real GainControl, so 87 // delegating the const methods and Enable calls to the real GainControl, so
70 // AGC can still be disabled. 88 // AGC can still be disabled.
71 // 89 //
72 // 2) It is injected into AgcManagerDirect and implements volume callbacks for 90 // 2) It is injected into AgcManagerDirect and implements volume callbacks for
73 // getting and setting the volume level. It just caches this value to be used 91 // getting and setting the volume level. It just caches this value to be used
74 // in VoiceEngine later. 92 // in VoiceEngine later.
75 class GainControlForNewAgc : public GainControl, public VolumeCallbacks { 93 class GainControlForNewAgc : public GainControl, public VolumeCallbacks {
76 public: 94 public:
77 explicit GainControlForNewAgc(GainControlImpl* gain_control) 95 explicit GainControlForNewAgc(GainControlImpl* gain_control)
78 : real_gain_control_(gain_control), 96 : real_gain_control_(gain_control), volume_(0) {}
79 volume_(0) {
80 }
81 97
82 // GainControl implementation. 98 // GainControl implementation.
83 int Enable(bool enable) override { 99 int Enable(bool enable) override {
84 return real_gain_control_->Enable(enable); 100 return real_gain_control_->Enable(enable);
85 } 101 }
86 bool is_enabled() const override { return real_gain_control_->is_enabled(); } 102 bool is_enabled() const override { return real_gain_control_->is_enabled(); }
87 int set_stream_analog_level(int level) override { 103 int set_stream_analog_level(int level) override {
88 volume_ = level; 104 volume_ = level;
89 return AudioProcessing::kNoError; 105 return AudioProcessing::kNoError;
90 } 106 }
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
159 gain_control_(NULL), 175 gain_control_(NULL),
160 high_pass_filter_(NULL), 176 high_pass_filter_(NULL),
161 level_estimator_(NULL), 177 level_estimator_(NULL),
162 noise_suppression_(NULL), 178 noise_suppression_(NULL),
163 voice_detection_(NULL), 179 voice_detection_(NULL),
164 crit_(CriticalSectionWrapper::CreateCriticalSection()), 180 crit_(CriticalSectionWrapper::CreateCriticalSection()),
165 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 181 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
166 debug_file_(FileWrapper::Create()), 182 debug_file_(FileWrapper::Create()),
167 event_msg_(new audioproc::Event()), 183 event_msg_(new audioproc::Event()),
168 #endif 184 #endif
169 fwd_in_format_(kSampleRate16kHz, 1), 185 api_format_({{{kSampleRate16kHz, 1, false},
186 {kSampleRate16kHz, 1, false},
187 {kSampleRate16kHz, 1, false}}}),
170 fwd_proc_format_(kSampleRate16kHz), 188 fwd_proc_format_(kSampleRate16kHz),
171 fwd_out_format_(kSampleRate16kHz, 1),
172 rev_in_format_(kSampleRate16kHz, 1),
173 rev_proc_format_(kSampleRate16kHz, 1), 189 rev_proc_format_(kSampleRate16kHz, 1),
174 split_rate_(kSampleRate16kHz), 190 split_rate_(kSampleRate16kHz),
175 stream_delay_ms_(0), 191 stream_delay_ms_(0),
176 delay_offset_ms_(0), 192 delay_offset_ms_(0),
177 was_stream_delay_set_(false), 193 was_stream_delay_set_(false),
178 last_stream_delay_ms_(0), 194 last_stream_delay_ms_(0),
179 last_aec_system_delay_ms_(0), 195 last_aec_system_delay_ms_(0),
180 stream_delay_jumps_(-1), 196 stream_delay_jumps_(-1),
181 aec_system_delay_jumps_(-1), 197 aec_system_delay_jumps_(-1),
182 output_will_be_muted_(false), 198 output_will_be_muted_(false),
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 crit_ = NULL; 262 crit_ = NULL;
247 } 263 }
248 264
249 int AudioProcessingImpl::Initialize() { 265 int AudioProcessingImpl::Initialize() {
250 CriticalSectionScoped crit_scoped(crit_); 266 CriticalSectionScoped crit_scoped(crit_);
251 return InitializeLocked(); 267 return InitializeLocked();
252 } 268 }
253 269
254 int AudioProcessingImpl::set_sample_rate_hz(int rate) { 270 int AudioProcessingImpl::set_sample_rate_hz(int rate) {
255 CriticalSectionScoped crit_scoped(crit_); 271 CriticalSectionScoped crit_scoped(crit_);
256 return InitializeLocked(rate, 272
257 rate, 273 ProcessingConfig processing_config = api_format_;
258 rev_in_format_.rate(), 274 processing_config.input_stream().set_sample_rate_hz(rate);
259 fwd_in_format_.num_channels(), 275 processing_config.output_stream().set_sample_rate_hz(rate);
260 fwd_out_format_.num_channels(), 276 return InitializeLocked(processing_config);
261 rev_in_format_.num_channels());
262 } 277 }
263 278
264 int AudioProcessingImpl::Initialize(int input_sample_rate_hz, 279 int AudioProcessingImpl::Initialize(int input_sample_rate_hz,
265 int output_sample_rate_hz, 280 int output_sample_rate_hz,
266 int reverse_sample_rate_hz, 281 int reverse_sample_rate_hz,
267 ChannelLayout input_layout, 282 ChannelLayout input_layout,
268 ChannelLayout output_layout, 283 ChannelLayout output_layout,
269 ChannelLayout reverse_layout) { 284 ChannelLayout reverse_layout) {
285 const ProcessingConfig processing_config = {
286 {{input_sample_rate_hz, ChannelsFromLayout(input_layout),
287 LayoutHasKeyboard(input_layout)},
288 {output_sample_rate_hz, ChannelsFromLayout(output_layout),
289 LayoutHasKeyboard(output_layout)},
290 {reverse_sample_rate_hz, ChannelsFromLayout(reverse_layout),
291 LayoutHasKeyboard(reverse_layout)}}};
292
293 return Initialize(processing_config);
294 }
295
296 int AudioProcessingImpl::Initialize(const ProcessingConfig& processing_config) {
270 CriticalSectionScoped crit_scoped(crit_); 297 CriticalSectionScoped crit_scoped(crit_);
271 return InitializeLocked(input_sample_rate_hz, 298 return InitializeLocked(processing_config);
272 output_sample_rate_hz,
273 reverse_sample_rate_hz,
274 ChannelsFromLayout(input_layout),
275 ChannelsFromLayout(output_layout),
276 ChannelsFromLayout(reverse_layout));
277 } 299 }
278 300
279 int AudioProcessingImpl::InitializeLocked() { 301 int AudioProcessingImpl::InitializeLocked() {
280 const int fwd_audio_buffer_channels = beamformer_enabled_ ? 302 const int fwd_audio_buffer_channels =
281 fwd_in_format_.num_channels() : 303 beamformer_enabled_ ? api_format_.input_stream().num_channels()
282 fwd_out_format_.num_channels(); 304 : api_format_.output_stream().num_channels();
283 render_audio_.reset(new AudioBuffer(rev_in_format_.samples_per_channel(), 305 if (api_format_.reverse_stream().num_channels() > 0) {
284 rev_in_format_.num_channels(), 306 render_audio_.reset(new AudioBuffer(
285 rev_proc_format_.samples_per_channel(), 307 api_format_.reverse_stream().samples_per_channel(),
286 rev_proc_format_.num_channels(), 308 api_format_.reverse_stream().num_channels(),
287 rev_proc_format_.samples_per_channel())); 309 rev_proc_format_.samples_per_channel(), rev_proc_format_.num_channels(),
288 capture_audio_.reset(new AudioBuffer(fwd_in_format_.samples_per_channel(), 310 rev_proc_format_.samples_per_channel()));
289 fwd_in_format_.num_channels(), 311 } else {
290 fwd_proc_format_.samples_per_channel(), 312 render_audio_.reset(nullptr);
291 fwd_audio_buffer_channels, 313 }
292 fwd_out_format_.samples_per_channel())); 314 capture_audio_.reset(new AudioBuffer(
315 api_format_.input_stream().samples_per_channel(),
316 api_format_.input_stream().num_channels(),
317 fwd_proc_format_.samples_per_channel(), fwd_audio_buffer_channels,
318 api_format_.output_stream().samples_per_channel()));
293 319
294 // Initialize all components. 320 // Initialize all components.
295 for (auto item : component_list_) { 321 for (auto item : component_list_) {
296 int err = item->Initialize(); 322 int err = item->Initialize();
297 if (err != kNoError) { 323 if (err != kNoError) {
298 return err; 324 return err;
299 } 325 }
300 } 326 }
301 327
302 InitializeExperimentalAgc(); 328 InitializeExperimentalAgc();
303 329
304 InitializeTransient(); 330 InitializeTransient();
305 331
306 InitializeBeamformer(); 332 InitializeBeamformer();
307 333
308 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 334 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
309 if (debug_file_->Open()) { 335 if (debug_file_->Open()) {
310 int err = WriteInitMessage(); 336 int err = WriteInitMessage();
311 if (err != kNoError) { 337 if (err != kNoError) {
312 return err; 338 return err;
313 } 339 }
314 } 340 }
315 #endif 341 #endif
316 342
317 return kNoError; 343 return kNoError;
318 } 344 }
319 345
320 int AudioProcessingImpl::InitializeLocked(int input_sample_rate_hz, 346 int AudioProcessingImpl::InitializeLocked(const ProcessingConfig& config) {
321 int output_sample_rate_hz, 347 for (const auto& stream : config.streams) {
322 int reverse_sample_rate_hz, 348 if (stream.sample_rate_hz() < 0) {
323 int num_input_channels, 349 return kBadSampleRateError;
324 int num_output_channels, 350 }
325 int num_reverse_channels) { 351 if (stream.num_channels() < 0) {
326 if (input_sample_rate_hz <= 0 || 352 return kBadNumberChannelsError;
327 output_sample_rate_hz <= 0 || 353 }
328 reverse_sample_rate_hz <= 0) {
329 return kBadSampleRateError;
330 } 354 }
331 if (num_output_channels > num_input_channels) { 355
332 return kBadNumberChannelsError; 356 const int num_in_channels = config.input_stream().num_channels();
333 } 357 const int num_out_channels = config.output_stream().num_channels();
334 // Only mono and stereo supported currently. 358
335 if (num_input_channels > 2 || num_input_channels < 1 || 359 // Need at least one input channel.
336 num_output_channels > 2 || num_output_channels < 1 || 360 // Need either one output channel or as many outputs as there are inputs.
337 num_reverse_channels > 2 || num_reverse_channels < 1) { 361 if (num_in_channels == 0 ||
338 return kBadNumberChannelsError; 362 !(num_out_channels == 1 || num_out_channels == num_in_channels)) {
339 }
340 if (beamformer_enabled_ &&
341 (static_cast<size_t>(num_input_channels) != array_geometry_.size() ||
342 num_output_channels > 1)) {
343 return kBadNumberChannelsError; 363 return kBadNumberChannelsError;
344 } 364 }
345 365
346 fwd_in_format_.set(input_sample_rate_hz, num_input_channels); 366 if (beamformer_enabled_ &&
347 fwd_out_format_.set(output_sample_rate_hz, num_output_channels); 367 (static_cast<size_t>(config.input_stream().num_channels()) !=
348 rev_in_format_.set(reverse_sample_rate_hz, num_reverse_channels); 368 array_geometry_.size() || num_out_channels > 1)) {
369 return kBadNumberChannelsError;
370 }
371
372 api_format_ = config;
349 373
350 // We process at the closest native rate >= min(input rate, output rate)... 374 // We process at the closest native rate >= min(input rate, output rate)...
351 int min_proc_rate = std::min(fwd_in_format_.rate(), fwd_out_format_.rate()); 375 const int min_proc_rate =
376 std::min(api_format_.input_stream().sample_rate_hz(),
377 api_format_.output_stream().sample_rate_hz());
352 int fwd_proc_rate; 378 int fwd_proc_rate;
353 if (supports_48kHz_ && min_proc_rate > kSampleRate32kHz) { 379 if (supports_48kHz_ && min_proc_rate > kSampleRate32kHz) {
354 fwd_proc_rate = kSampleRate48kHz; 380 fwd_proc_rate = kSampleRate48kHz;
355 } else if (min_proc_rate > kSampleRate16kHz) { 381 } else if (min_proc_rate > kSampleRate16kHz) {
356 fwd_proc_rate = kSampleRate32kHz; 382 fwd_proc_rate = kSampleRate32kHz;
357 } else if (min_proc_rate > kSampleRate8kHz) { 383 } else if (min_proc_rate > kSampleRate8kHz) {
358 fwd_proc_rate = kSampleRate16kHz; 384 fwd_proc_rate = kSampleRate16kHz;
359 } else { 385 } else {
360 fwd_proc_rate = kSampleRate8kHz; 386 fwd_proc_rate = kSampleRate8kHz;
361 } 387 }
362 // ...with one exception. 388 // ...with one exception.
363 if (echo_control_mobile_->is_enabled() && min_proc_rate > kSampleRate16kHz) { 389 if (echo_control_mobile_->is_enabled() && min_proc_rate > kSampleRate16kHz) {
364 fwd_proc_rate = kSampleRate16kHz; 390 fwd_proc_rate = kSampleRate16kHz;
365 } 391 }
366 392
367 fwd_proc_format_.set(fwd_proc_rate); 393 fwd_proc_format_ = StreamConfig(fwd_proc_rate);
368 394
369 // We normally process the reverse stream at 16 kHz. Unless... 395 // We normally process the reverse stream at 16 kHz. Unless...
370 int rev_proc_rate = kSampleRate16kHz; 396 int rev_proc_rate = kSampleRate16kHz;
371 if (fwd_proc_format_.rate() == kSampleRate8kHz) { 397 if (fwd_proc_format_.sample_rate_hz() == kSampleRate8kHz) {
372 // ...the forward stream is at 8 kHz. 398 // ...the forward stream is at 8 kHz.
373 rev_proc_rate = kSampleRate8kHz; 399 rev_proc_rate = kSampleRate8kHz;
374 } else { 400 } else {
375 if (rev_in_format_.rate() == kSampleRate32kHz) { 401 if (api_format_.reverse_stream().sample_rate_hz() == kSampleRate32kHz) {
376 // ...or the input is at 32 kHz, in which case we use the splitting 402 // ...or the input is at 32 kHz, in which case we use the splitting
377 // filter rather than the resampler. 403 // filter rather than the resampler.
378 rev_proc_rate = kSampleRate32kHz; 404 rev_proc_rate = kSampleRate32kHz;
379 } 405 }
380 } 406 }
381 407
382 // Always downmix the reverse stream to mono for analysis. This has been 408 // Always downmix the reverse stream to mono for analysis. This has been
383 // demonstrated to work well for AEC in most practical scenarios. 409 // demonstrated to work well for AEC in most practical scenarios.
384 rev_proc_format_.set(rev_proc_rate, 1); 410 rev_proc_format_ = StreamConfig(rev_proc_rate, 1);
385 411
386 if (fwd_proc_format_.rate() == kSampleRate32kHz || 412 if (fwd_proc_format_.sample_rate_hz() == kSampleRate32kHz ||
387 fwd_proc_format_.rate() == kSampleRate48kHz) { 413 fwd_proc_format_.sample_rate_hz() == kSampleRate48kHz) {
388 split_rate_ = kSampleRate16kHz; 414 split_rate_ = kSampleRate16kHz;
389 } else { 415 } else {
390 split_rate_ = fwd_proc_format_.rate(); 416 split_rate_ = fwd_proc_format_.sample_rate_hz();
391 } 417 }
392 418
393 return InitializeLocked(); 419 return InitializeLocked();
394 } 420 }
395 421
396 // Calls InitializeLocked() if any of the audio parameters have changed from 422 // Calls InitializeLocked() if any of the audio parameters have changed from
397 // their current values. 423 // their current values.
398 int AudioProcessingImpl::MaybeInitializeLocked(int input_sample_rate_hz, 424 int AudioProcessingImpl::MaybeInitializeLocked(
399 int output_sample_rate_hz, 425 const ProcessingConfig& processing_config) {
400 int reverse_sample_rate_hz, 426 if (processing_config == api_format_) {
401 int num_input_channels,
402 int num_output_channels,
403 int num_reverse_channels) {
404 if (input_sample_rate_hz == fwd_in_format_.rate() &&
405 output_sample_rate_hz == fwd_out_format_.rate() &&
406 reverse_sample_rate_hz == rev_in_format_.rate() &&
407 num_input_channels == fwd_in_format_.num_channels() &&
408 num_output_channels == fwd_out_format_.num_channels() &&
409 num_reverse_channels == rev_in_format_.num_channels()) {
410 return kNoError; 427 return kNoError;
411 } 428 }
412 return InitializeLocked(input_sample_rate_hz, 429 return InitializeLocked(processing_config);
413 output_sample_rate_hz,
414 reverse_sample_rate_hz,
415 num_input_channels,
416 num_output_channels,
417 num_reverse_channels);
418 } 430 }
419 431
420 void AudioProcessingImpl::SetExtraOptions(const Config& config) { 432 void AudioProcessingImpl::SetExtraOptions(const Config& config) {
421 CriticalSectionScoped crit_scoped(crit_); 433 CriticalSectionScoped crit_scoped(crit_);
422 for (auto item : component_list_) { 434 for (auto item : component_list_) {
423 item->SetExtraOptions(config); 435 item->SetExtraOptions(config);
424 } 436 }
425 437
426 if (transient_suppressor_enabled_ != config.Get<ExperimentalNs>().enabled) { 438 if (transient_suppressor_enabled_ != config.Get<ExperimentalNs>().enabled) {
427 transient_suppressor_enabled_ = config.Get<ExperimentalNs>().enabled; 439 transient_suppressor_enabled_ = config.Get<ExperimentalNs>().enabled;
428 InitializeTransient(); 440 InitializeTransient();
429 } 441 }
430 } 442 }
431 443
432 int AudioProcessingImpl::input_sample_rate_hz() const { 444 int AudioProcessingImpl::input_sample_rate_hz() const {
433 CriticalSectionScoped crit_scoped(crit_); 445 CriticalSectionScoped crit_scoped(crit_);
434 return fwd_in_format_.rate(); 446 return api_format_.input_stream().sample_rate_hz();
435 } 447 }
436 448
437 int AudioProcessingImpl::sample_rate_hz() const { 449 int AudioProcessingImpl::sample_rate_hz() const {
438 CriticalSectionScoped crit_scoped(crit_); 450 CriticalSectionScoped crit_scoped(crit_);
439 return fwd_in_format_.rate(); 451 return api_format_.input_stream().sample_rate_hz();
440 } 452 }
441 453
442 int AudioProcessingImpl::proc_sample_rate_hz() const { 454 int AudioProcessingImpl::proc_sample_rate_hz() const {
443 return fwd_proc_format_.rate(); 455 return fwd_proc_format_.sample_rate_hz();
444 } 456 }
445 457
446 int AudioProcessingImpl::proc_split_sample_rate_hz() const { 458 int AudioProcessingImpl::proc_split_sample_rate_hz() const {
447 return split_rate_; 459 return split_rate_;
448 } 460 }
449 461
450 int AudioProcessingImpl::num_reverse_channels() const { 462 int AudioProcessingImpl::num_reverse_channels() const {
451 return rev_proc_format_.num_channels(); 463 return rev_proc_format_.num_channels();
452 } 464 }
453 465
454 int AudioProcessingImpl::num_input_channels() const { 466 int AudioProcessingImpl::num_input_channels() const {
455 return fwd_in_format_.num_channels(); 467 return api_format_.input_stream().num_channels();
456 } 468 }
457 469
458 int AudioProcessingImpl::num_output_channels() const { 470 int AudioProcessingImpl::num_output_channels() const {
459 return fwd_out_format_.num_channels(); 471 return api_format_.output_stream().num_channels();
460 } 472 }
461 473
462 void AudioProcessingImpl::set_output_will_be_muted(bool muted) { 474 void AudioProcessingImpl::set_output_will_be_muted(bool muted) {
463 CriticalSectionScoped lock(crit_); 475 CriticalSectionScoped lock(crit_);
464 output_will_be_muted_ = muted; 476 output_will_be_muted_ = muted;
465 if (agc_manager_.get()) { 477 if (agc_manager_.get()) {
466 agc_manager_->SetCaptureMuted(output_will_be_muted_); 478 agc_manager_->SetCaptureMuted(output_will_be_muted_);
467 } 479 }
468 } 480 }
469 481
470 bool AudioProcessingImpl::output_will_be_muted() const { 482 bool AudioProcessingImpl::output_will_be_muted() const {
471 CriticalSectionScoped lock(crit_); 483 CriticalSectionScoped lock(crit_);
472 return output_will_be_muted_; 484 return output_will_be_muted_;
473 } 485 }
474 486
475 int AudioProcessingImpl::ProcessStream(const float* const* src, 487 int AudioProcessingImpl::ProcessStream(const float* const* src,
476 int samples_per_channel, 488 int samples_per_channel,
477 int input_sample_rate_hz, 489 int input_sample_rate_hz,
478 ChannelLayout input_layout, 490 ChannelLayout input_layout,
479 int output_sample_rate_hz, 491 int output_sample_rate_hz,
480 ChannelLayout output_layout, 492 ChannelLayout output_layout,
481 float* const* dest) { 493 float* const* dest) {
494 const ProcessingConfig processing_config = {
495 {{
496 input_sample_rate_hz, ChannelsFromLayout(input_layout),
497 LayoutHasKeyboard(input_layout),
498 },
499 {
500 output_sample_rate_hz, ChannelsFromLayout(output_layout),
501 LayoutHasKeyboard(output_layout),
502 },
503 api_format_.reverse_stream()}};
504
505 if (samples_per_channel !=
506 processing_config.input_stream().samples_per_channel()) {
507 return kBadDataLengthError;
508 }
509 return ProcessStream(src, processing_config, dest);
510 }
511
512 int AudioProcessingImpl::ProcessStream(
513 const float* const* src,
514 const ProcessingConfig& processing_config,
515 float* const* dest) {
482 CriticalSectionScoped crit_scoped(crit_); 516 CriticalSectionScoped crit_scoped(crit_);
483 if (!src || !dest) { 517 if (!src || !dest) {
484 return kNullPointerError; 518 return kNullPointerError;
485 } 519 }
486 520
487 RETURN_ON_ERR(MaybeInitializeLocked(input_sample_rate_hz, 521 const int samples_per_channel =
488 output_sample_rate_hz, 522 processing_config.input_stream().samples_per_channel();
489 rev_in_format_.rate(), 523
490 ChannelsFromLayout(input_layout), 524 RETURN_ON_ERR(MaybeInitializeLocked(processing_config));
491 ChannelsFromLayout(output_layout), 525 assert(samples_per_channel ==
492 rev_in_format_.num_channels())); 526 api_format_.input_stream().samples_per_channel());
493 if (samples_per_channel != fwd_in_format_.samples_per_channel()) {
494 return kBadDataLengthError;
495 }
496 527
497 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 528 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
498 if (debug_file_->Open()) { 529 if (debug_file_->Open()) {
499 event_msg_->set_type(audioproc::Event::STREAM); 530 event_msg_->set_type(audioproc::Event::STREAM);
500 audioproc::Stream* msg = event_msg_->mutable_stream(); 531 audioproc::Stream* msg = event_msg_->mutable_stream();
501 const size_t channel_size = 532 const size_t channel_size = sizeof(float) * samples_per_channel;
502 sizeof(float) * fwd_in_format_.samples_per_channel(); 533 for (int i = 0; i < api_format_.input_stream().num_channels(); ++i)
503 for (int i = 0; i < fwd_in_format_.num_channels(); ++i)
504 msg->add_input_channel(src[i], channel_size); 534 msg->add_input_channel(src[i], channel_size);
505 } 535 }
506 #endif 536 #endif
507 537
508 capture_audio_->CopyFrom(src, samples_per_channel, input_layout); 538 capture_audio_->CopyFrom(src, api_format_.input_stream());
509 RETURN_ON_ERR(ProcessStreamLocked()); 539 RETURN_ON_ERR(ProcessStreamLocked());
510 capture_audio_->CopyTo(fwd_out_format_.samples_per_channel(), 540 capture_audio_->CopyTo(api_format_.output_stream(), dest);
511 output_layout,
512 dest);
513 541
514 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 542 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
515 if (debug_file_->Open()) { 543 if (debug_file_->Open()) {
516 audioproc::Stream* msg = event_msg_->mutable_stream(); 544 audioproc::Stream* msg = event_msg_->mutable_stream();
517 const size_t channel_size = 545 const size_t channel_size = sizeof(float) * samples_per_channel;
518 sizeof(float) * fwd_out_format_.samples_per_channel(); 546 for (int i = 0; i < api_format_.input_stream().num_channels(); ++i)
519 for (int i = 0; i < fwd_out_format_.num_channels(); ++i)
520 msg->add_output_channel(dest[i], channel_size); 547 msg->add_output_channel(dest[i], channel_size);
521 RETURN_ON_ERR(WriteMessageToDebugFile()); 548 RETURN_ON_ERR(WriteMessageToDebugFile());
522 } 549 }
523 #endif 550 #endif
524 551
525 return kNoError; 552 return kNoError;
526 } 553 }
527 554
528 int AudioProcessingImpl::ProcessStream(AudioFrame* frame) { 555 int AudioProcessingImpl::ProcessStream(AudioFrame* frame) {
529 CriticalSectionScoped crit_scoped(crit_); 556 CriticalSectionScoped crit_scoped(crit_);
530 if (!frame) { 557 if (!frame) {
531 return kNullPointerError; 558 return kNullPointerError;
532 } 559 }
533 // Must be a native rate. 560 // Must be a native rate.
534 if (frame->sample_rate_hz_ != kSampleRate8kHz && 561 if (frame->sample_rate_hz_ != kSampleRate8kHz &&
535 frame->sample_rate_hz_ != kSampleRate16kHz && 562 frame->sample_rate_hz_ != kSampleRate16kHz &&
536 frame->sample_rate_hz_ != kSampleRate32kHz && 563 frame->sample_rate_hz_ != kSampleRate32kHz &&
537 frame->sample_rate_hz_ != kSampleRate48kHz) { 564 frame->sample_rate_hz_ != kSampleRate48kHz) {
538 return kBadSampleRateError; 565 return kBadSampleRateError;
539 } 566 }
540 if (echo_control_mobile_->is_enabled() && 567 if (echo_control_mobile_->is_enabled() &&
541 frame->sample_rate_hz_ > kSampleRate16kHz) { 568 frame->sample_rate_hz_ > kSampleRate16kHz) {
542 LOG(LS_ERROR) << "AECM only supports 16 or 8 kHz sample rates"; 569 LOG(LS_ERROR) << "AECM only supports 16 or 8 kHz sample rates";
543 return kUnsupportedComponentError; 570 return kUnsupportedComponentError;
544 } 571 }
545 572
546 // TODO(ajm): The input and output rates and channels are currently 573 // TODO(ajm): The input and output rates and channels are currently
547 // constrained to be identical in the int16 interface. 574 // constrained to be identical in the int16 interface.
548 RETURN_ON_ERR(MaybeInitializeLocked(frame->sample_rate_hz_, 575 ProcessingConfig processing_config = api_format_;
549 frame->sample_rate_hz_, 576 processing_config.input_stream().set_sample_rate_hz(frame->sample_rate_hz_);
550 rev_in_format_.rate(), 577 processing_config.input_stream().set_num_channels(frame->num_channels_);
551 frame->num_channels_, 578 processing_config.output_stream().set_sample_rate_hz(frame->sample_rate_hz_);
552 frame->num_channels_, 579 processing_config.output_stream().set_num_channels(frame->num_channels_);
553 rev_in_format_.num_channels())); 580
554 if (frame->samples_per_channel_ != fwd_in_format_.samples_per_channel()) { 581 RETURN_ON_ERR(MaybeInitializeLocked(processing_config));
582 if (frame->samples_per_channel_ !=
583 api_format_.input_stream().samples_per_channel()) {
555 return kBadDataLengthError; 584 return kBadDataLengthError;
556 } 585 }
557 586
558 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 587 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
559 if (debug_file_->Open()) { 588 if (debug_file_->Open()) {
560 event_msg_->set_type(audioproc::Event::STREAM); 589 event_msg_->set_type(audioproc::Event::STREAM);
561 audioproc::Stream* msg = event_msg_->mutable_stream(); 590 audioproc::Stream* msg = event_msg_->mutable_stream();
562 const size_t data_size = sizeof(int16_t) * 591 const size_t data_size =
563 frame->samples_per_channel_ * 592 sizeof(int16_t) * frame->samples_per_channel_ * frame->num_channels_;
564 frame->num_channels_;
565 msg->set_input_data(frame->data_, data_size); 593 msg->set_input_data(frame->data_, data_size);
566 } 594 }
567 #endif 595 #endif
568 596
569 capture_audio_->DeinterleaveFrom(frame); 597 capture_audio_->DeinterleaveFrom(frame);
570 RETURN_ON_ERR(ProcessStreamLocked()); 598 RETURN_ON_ERR(ProcessStreamLocked());
571 capture_audio_->InterleaveTo(frame, output_copy_needed(is_data_processed())); 599 capture_audio_->InterleaveTo(frame, output_copy_needed(is_data_processed()));
572 600
573 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 601 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
574 if (debug_file_->Open()) { 602 if (debug_file_->Open()) {
575 audioproc::Stream* msg = event_msg_->mutable_stream(); 603 audioproc::Stream* msg = event_msg_->mutable_stream();
576 const size_t data_size = sizeof(int16_t) * 604 const size_t data_size =
577 frame->samples_per_channel_ * 605 sizeof(int16_t) * frame->samples_per_channel_ * frame->num_channels_;
578 frame->num_channels_;
579 msg->set_output_data(frame->data_, data_size); 606 msg->set_output_data(frame->data_, data_size);
580 RETURN_ON_ERR(WriteMessageToDebugFile()); 607 RETURN_ON_ERR(WriteMessageToDebugFile());
581 } 608 }
582 #endif 609 #endif
583 610
584 return kNoError; 611 return kNoError;
585 } 612 }
586 613
587
588 int AudioProcessingImpl::ProcessStreamLocked() { 614 int AudioProcessingImpl::ProcessStreamLocked() {
589 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 615 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
590 if (debug_file_->Open()) { 616 if (debug_file_->Open()) {
591 audioproc::Stream* msg = event_msg_->mutable_stream(); 617 audioproc::Stream* msg = event_msg_->mutable_stream();
592 msg->set_delay(stream_delay_ms_); 618 msg->set_delay(stream_delay_ms_);
593 msg->set_drift(echo_cancellation_->stream_drift_samples()); 619 msg->set_drift(echo_cancellation_->stream_drift_samples());
594 msg->set_level(gain_control()->stream_analog_level()); 620 msg->set_level(gain_control()->stream_analog_level());
595 msg->set_keypress(key_pressed_); 621 msg->set_keypress(key_pressed_);
596 } 622 }
597 #endif 623 #endif
598 624
599 MaybeUpdateHistograms(); 625 MaybeUpdateHistograms();
600 626
601 AudioBuffer* ca = capture_audio_.get(); // For brevity. 627 AudioBuffer* ca = capture_audio_.get(); // For brevity.
602 if (use_new_agc_ && gain_control_->is_enabled()) { 628 if (use_new_agc_ && gain_control_->is_enabled()) {
603 agc_manager_->AnalyzePreProcess(ca->channels()[0], 629 agc_manager_->AnalyzePreProcess(ca->channels()[0], ca->num_channels(),
604 ca->num_channels(),
605 fwd_proc_format_.samples_per_channel()); 630 fwd_proc_format_.samples_per_channel());
606 } 631 }
607 632
608 bool data_processed = is_data_processed(); 633 bool data_processed = is_data_processed();
609 if (analysis_needed(data_processed)) { 634 if (analysis_needed(data_processed)) {
610 ca->SplitIntoFrequencyBands(); 635 ca->SplitIntoFrequencyBands();
611 } 636 }
612 637
613 if (beamformer_enabled_) { 638 if (beamformer_enabled_) {
614 beamformer_->ProcessChunk(*ca->split_data_f(), ca->split_data_f()); 639 beamformer_->ProcessChunk(*ca->split_data_f(), ca->split_data_f());
615 ca->set_num_channels(1); 640 ca->set_num_channels(1);
616 } 641 }
617 642
618 RETURN_ON_ERR(high_pass_filter_->ProcessCaptureAudio(ca)); 643 RETURN_ON_ERR(high_pass_filter_->ProcessCaptureAudio(ca));
619 RETURN_ON_ERR(gain_control_->AnalyzeCaptureAudio(ca)); 644 RETURN_ON_ERR(gain_control_->AnalyzeCaptureAudio(ca));
620 RETURN_ON_ERR(noise_suppression_->AnalyzeCaptureAudio(ca)); 645 RETURN_ON_ERR(noise_suppression_->AnalyzeCaptureAudio(ca));
621 RETURN_ON_ERR(echo_cancellation_->ProcessCaptureAudio(ca)); 646 RETURN_ON_ERR(echo_cancellation_->ProcessCaptureAudio(ca));
622 647
623 if (echo_control_mobile_->is_enabled() && noise_suppression_->is_enabled()) { 648 if (echo_control_mobile_->is_enabled() && noise_suppression_->is_enabled()) {
624 ca->CopyLowPassToReference(); 649 ca->CopyLowPassToReference();
625 } 650 }
626 RETURN_ON_ERR(noise_suppression_->ProcessCaptureAudio(ca)); 651 RETURN_ON_ERR(noise_suppression_->ProcessCaptureAudio(ca));
627 RETURN_ON_ERR(echo_control_mobile_->ProcessCaptureAudio(ca)); 652 RETURN_ON_ERR(echo_control_mobile_->ProcessCaptureAudio(ca));
628 RETURN_ON_ERR(voice_detection_->ProcessCaptureAudio(ca)); 653 RETURN_ON_ERR(voice_detection_->ProcessCaptureAudio(ca));
629 654
630 if (use_new_agc_ && 655 if (use_new_agc_ && gain_control_->is_enabled() &&
631 gain_control_->is_enabled() &&
632 (!beamformer_enabled_ || beamformer_->is_target_present())) { 656 (!beamformer_enabled_ || beamformer_->is_target_present())) {
633 agc_manager_->Process(ca->split_bands_const(0)[kBand0To8kHz], 657 agc_manager_->Process(ca->split_bands_const(0)[kBand0To8kHz],
634 ca->num_frames_per_band(), 658 ca->num_frames_per_band(), split_rate_);
635 split_rate_);
636 } 659 }
637 RETURN_ON_ERR(gain_control_->ProcessCaptureAudio(ca)); 660 RETURN_ON_ERR(gain_control_->ProcessCaptureAudio(ca));
638 661
639 if (synthesis_needed(data_processed)) { 662 if (synthesis_needed(data_processed)) {
640 ca->MergeFrequencyBands(); 663 ca->MergeFrequencyBands();
641 } 664 }
642 665
643 // TODO(aluebs): Investigate if the transient suppression placement should be 666 // TODO(aluebs): Investigate if the transient suppression placement should be
644 // before or after the AGC. 667 // before or after the AGC.
645 if (transient_suppressor_enabled_) { 668 if (transient_suppressor_enabled_) {
646 float voice_probability = 669 float voice_probability =
647 agc_manager_.get() ? agc_manager_->voice_probability() : 1.f; 670 agc_manager_.get() ? agc_manager_->voice_probability() : 1.f;
648 671
649 transient_suppressor_->Suppress(ca->channels_f()[0], 672 transient_suppressor_->Suppress(
mgraczyk 2015/07/10 00:33:36 This is just my clang_format disagreeing with your
650 ca->num_frames(), 673 ca->channels_f()[0], ca->num_frames(), ca->num_channels(),
651 ca->num_channels(), 674 ca->split_bands_const_f(0)[kBand0To8kHz], ca->num_frames_per_band(),
652 ca->split_bands_const_f(0)[kBand0To8kHz], 675 ca->keyboard_data(), ca->num_keyboard_frames(), voice_probability,
653 ca->num_frames_per_band(), 676 key_pressed_);
654 ca->keyboard_data(),
655 ca->num_keyboard_frames(),
656 voice_probability,
657 key_pressed_);
658 } 677 }
659 678
660 // The level estimator operates on the recombined data. 679 // The level estimator operates on the recombined data.
661 RETURN_ON_ERR(level_estimator_->ProcessStream(ca)); 680 RETURN_ON_ERR(level_estimator_->ProcessStream(ca));
662 681
663 was_stream_delay_set_ = false; 682 was_stream_delay_set_ = false;
664 return kNoError; 683 return kNoError;
665 } 684 }
666 685
667 int AudioProcessingImpl::AnalyzeReverseStream(const float* const* data, 686 int AudioProcessingImpl::AnalyzeReverseStream(const float* const* data,
668 int samples_per_channel, 687 int samples_per_channel,
669 int sample_rate_hz, 688 int sample_rate_hz,
670 ChannelLayout layout) { 689 ChannelLayout layout) {
690 const StreamConfig reverse_config = {
691 sample_rate_hz, ChannelsFromLayout(layout), LayoutHasKeyboard(layout),
692 };
693 return AnalyzeReverseStream(data, reverse_config);
694 }
695
696 int AudioProcessingImpl::AnalyzeReverseStream(
697 const float* const* data,
698 const StreamConfig& reverse_config) {
671 CriticalSectionScoped crit_scoped(crit_); 699 CriticalSectionScoped crit_scoped(crit_);
672 if (data == NULL) { 700 if (data == NULL) {
673 return kNullPointerError; 701 return kNullPointerError;
674 } 702 }
675 703
676 const int num_channels = ChannelsFromLayout(layout); 704 if (reverse_config.num_channels() <= 0) {
677 RETURN_ON_ERR(MaybeInitializeLocked(fwd_in_format_.rate(), 705 return kBadNumberChannelsError;
678 fwd_out_format_.rate(), 706 }
679 sample_rate_hz, 707
680 fwd_in_format_.num_channels(), 708 const ProcessingConfig processing_config = {{api_format_.input_stream(),
681 fwd_out_format_.num_channels(), 709 api_format_.output_stream(),
682 num_channels)); 710 reverse_config}};
683 if (samples_per_channel != rev_in_format_.samples_per_channel()) { 711 RETURN_ON_ERR(MaybeInitializeLocked(processing_config));
712 if (reverse_config.samples_per_channel() !=
713 api_format_.reverse_stream().samples_per_channel()) {
684 return kBadDataLengthError; 714 return kBadDataLengthError;
685 } 715 }
686 716
687 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 717 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
688 if (debug_file_->Open()) { 718 if (debug_file_->Open()) {
689 event_msg_->set_type(audioproc::Event::REVERSE_STREAM); 719 event_msg_->set_type(audioproc::Event::REVERSE_STREAM);
690 audioproc::ReverseStream* msg = event_msg_->mutable_reverse_stream(); 720 audioproc::ReverseStream* msg = event_msg_->mutable_reverse_stream();
691 const size_t channel_size = 721 const size_t channel_size =
692 sizeof(float) * rev_in_format_.samples_per_channel(); 722 sizeof(float) * api_format_.reverse_stream().samples_per_channel();
693 for (int i = 0; i < num_channels; ++i) 723 for (int i = 0; i < api_format_.reverse_stream().num_channels(); ++i)
694 msg->add_channel(data[i], channel_size); 724 msg->add_channel(data[i], channel_size);
695 RETURN_ON_ERR(WriteMessageToDebugFile()); 725 RETURN_ON_ERR(WriteMessageToDebugFile());
696 } 726 }
697 #endif 727 #endif
698 728
699 render_audio_->CopyFrom(data, samples_per_channel, layout); 729 render_audio_->CopyFrom(data, api_format_.reverse_stream());
700 return AnalyzeReverseStreamLocked(); 730 return AnalyzeReverseStreamLocked();
701 } 731 }
702 732
703 int AudioProcessingImpl::AnalyzeReverseStream(AudioFrame* frame) { 733 int AudioProcessingImpl::AnalyzeReverseStream(AudioFrame* frame) {
704 CriticalSectionScoped crit_scoped(crit_); 734 CriticalSectionScoped crit_scoped(crit_);
705 if (frame == NULL) { 735 if (frame == NULL) {
706 return kNullPointerError; 736 return kNullPointerError;
707 } 737 }
708 // Must be a native rate. 738 // Must be a native rate.
709 if (frame->sample_rate_hz_ != kSampleRate8kHz && 739 if (frame->sample_rate_hz_ != kSampleRate8kHz &&
710 frame->sample_rate_hz_ != kSampleRate16kHz && 740 frame->sample_rate_hz_ != kSampleRate16kHz &&
711 frame->sample_rate_hz_ != kSampleRate32kHz && 741 frame->sample_rate_hz_ != kSampleRate32kHz &&
712 frame->sample_rate_hz_ != kSampleRate48kHz) { 742 frame->sample_rate_hz_ != kSampleRate48kHz) {
713 return kBadSampleRateError; 743 return kBadSampleRateError;
714 } 744 }
715 // This interface does not tolerate different forward and reverse rates. 745 // This interface does not tolerate different forward and reverse rates.
716 if (frame->sample_rate_hz_ != fwd_in_format_.rate()) { 746 if (frame->sample_rate_hz_ != api_format_.input_stream().sample_rate_hz()) {
717 return kBadSampleRateError; 747 return kBadSampleRateError;
718 } 748 }
719 749
720 RETURN_ON_ERR(MaybeInitializeLocked(fwd_in_format_.rate(), 750 if (frame->num_channels_ <= 0) {
721 fwd_out_format_.rate(), 751 return kBadNumberChannelsError;
722 frame->sample_rate_hz_, 752 }
723 fwd_in_format_.num_channels(), 753
724 fwd_in_format_.num_channels(), 754 const ProcessingConfig processing_config = {{
725 frame->num_channels_)); 755 api_format_.input_stream(),
726 if (frame->samples_per_channel_ != rev_in_format_.samples_per_channel()) { 756 api_format_.output_stream(),
757 {
758 frame->sample_rate_hz_, frame->num_channels_,
759 api_format_.reverse_stream().has_keyboard(),
760 },
761 }};
762 RETURN_ON_ERR(MaybeInitializeLocked(processing_config));
763 if (frame->samples_per_channel_ !=
764 api_format_.reverse_stream().samples_per_channel()) {
727 return kBadDataLengthError; 765 return kBadDataLengthError;
728 } 766 }
729 767
730 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 768 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
731 if (debug_file_->Open()) { 769 if (debug_file_->Open()) {
732 event_msg_->set_type(audioproc::Event::REVERSE_STREAM); 770 event_msg_->set_type(audioproc::Event::REVERSE_STREAM);
733 audioproc::ReverseStream* msg = event_msg_->mutable_reverse_stream(); 771 audioproc::ReverseStream* msg = event_msg_->mutable_reverse_stream();
734 const size_t data_size = sizeof(int16_t) * 772 const size_t data_size =
735 frame->samples_per_channel_ * 773 sizeof(int16_t) * frame->samples_per_channel_ * frame->num_channels_;
736 frame->num_channels_;
737 msg->set_data(frame->data_, data_size); 774 msg->set_data(frame->data_, data_size);
738 RETURN_ON_ERR(WriteMessageToDebugFile()); 775 RETURN_ON_ERR(WriteMessageToDebugFile());
739 } 776 }
740 #endif 777 #endif
741 778
742 render_audio_->DeinterleaveFrom(frame); 779 render_audio_->DeinterleaveFrom(frame);
743 return AnalyzeReverseStreamLocked(); 780 return AnalyzeReverseStreamLocked();
744 } 781 }
745 782
746 int AudioProcessingImpl::AnalyzeReverseStreamLocked() { 783 int AudioProcessingImpl::AnalyzeReverseStreamLocked() {
747 AudioBuffer* ra = render_audio_.get(); // For brevity. 784 AudioBuffer* ra = render_audio_.get(); // For brevity.
748 if (rev_proc_format_.rate() == kSampleRate32kHz) { 785 if (rev_proc_format_.sample_rate_hz() == kSampleRate32kHz) {
749 ra->SplitIntoFrequencyBands(); 786 ra->SplitIntoFrequencyBands();
750 } 787 }
751 788
752 RETURN_ON_ERR(echo_cancellation_->ProcessRenderAudio(ra)); 789 RETURN_ON_ERR(echo_cancellation_->ProcessRenderAudio(ra));
753 RETURN_ON_ERR(echo_control_mobile_->ProcessRenderAudio(ra)); 790 RETURN_ON_ERR(echo_control_mobile_->ProcessRenderAudio(ra));
754 if (!use_new_agc_) { 791 if (!use_new_agc_) {
755 RETURN_ON_ERR(gain_control_->ProcessRenderAudio(ra)); 792 RETURN_ON_ERR(gain_control_->ProcessRenderAudio(ra));
756 } 793 }
757 794
758 return kNoError; 795 return kNoError;
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
940 } else if (enabled_count == 2) { 977 } else if (enabled_count == 2) {
941 if (level_estimator_->is_enabled() && voice_detection_->is_enabled()) { 978 if (level_estimator_->is_enabled() && voice_detection_->is_enabled()) {
942 return false; 979 return false;
943 } 980 }
944 } 981 }
945 return true; 982 return true;
946 } 983 }
947 984
948 bool AudioProcessingImpl::output_copy_needed(bool is_data_processed) const { 985 bool AudioProcessingImpl::output_copy_needed(bool is_data_processed) const {
949 // Check if we've upmixed or downmixed the audio. 986 // Check if we've upmixed or downmixed the audio.
950 return ((fwd_out_format_.num_channels() != fwd_in_format_.num_channels()) || 987 return ((api_format_.output_stream().num_channels() !=
988 api_format_.input_stream().num_channels()) ||
951 is_data_processed || transient_suppressor_enabled_); 989 is_data_processed || transient_suppressor_enabled_);
952 } 990 }
953 991
954 bool AudioProcessingImpl::synthesis_needed(bool is_data_processed) const { 992 bool AudioProcessingImpl::synthesis_needed(bool is_data_processed) const {
955 return (is_data_processed && (fwd_proc_format_.rate() == kSampleRate32kHz || 993 return (is_data_processed &&
956 fwd_proc_format_.rate() == kSampleRate48kHz)); 994 (fwd_proc_format_.sample_rate_hz() == kSampleRate32kHz ||
995 fwd_proc_format_.sample_rate_hz() == kSampleRate48kHz));
957 } 996 }
958 997
959 bool AudioProcessingImpl::analysis_needed(bool is_data_processed) const { 998 bool AudioProcessingImpl::analysis_needed(bool is_data_processed) const {
960 if (!is_data_processed && !voice_detection_->is_enabled() && 999 if (!is_data_processed && !voice_detection_->is_enabled() &&
961 !transient_suppressor_enabled_) { 1000 !transient_suppressor_enabled_) {
962 // Only level_estimator_ is enabled. 1001 // Only level_estimator_ is enabled.
963 return false; 1002 return false;
964 } else if (fwd_proc_format_.rate() == kSampleRate32kHz || 1003 } else if (fwd_proc_format_.sample_rate_hz() == kSampleRate32kHz ||
965 fwd_proc_format_.rate() == kSampleRate48kHz) { 1004 fwd_proc_format_.sample_rate_hz() == kSampleRate48kHz) {
966 // Something besides level_estimator_ is enabled, and we have super-wb. 1005 // Something besides level_estimator_ is enabled, and we have super-wb.
967 return true; 1006 return true;
968 } 1007 }
969 return false; 1008 return false;
970 } 1009 }
971 1010
972 void AudioProcessingImpl::InitializeExperimentalAgc() { 1011 void AudioProcessingImpl::InitializeExperimentalAgc() {
973 if (use_new_agc_) { 1012 if (use_new_agc_) {
974 if (!agc_manager_.get()) { 1013 if (!agc_manager_.get()) {
975 agc_manager_.reset(new AgcManagerDirect(gain_control_, 1014 agc_manager_.reset(new AgcManagerDirect(gain_control_,
976 gain_control_for_new_agc_.get(), 1015 gain_control_for_new_agc_.get(),
977 agc_startup_min_volume_)); 1016 agc_startup_min_volume_));
978 } 1017 }
979 agc_manager_->Initialize(); 1018 agc_manager_->Initialize();
980 agc_manager_->SetCaptureMuted(output_will_be_muted_); 1019 agc_manager_->SetCaptureMuted(output_will_be_muted_);
981 } 1020 }
982 } 1021 }
983 1022
984 void AudioProcessingImpl::InitializeTransient() { 1023 void AudioProcessingImpl::InitializeTransient() {
985 if (transient_suppressor_enabled_) { 1024 if (transient_suppressor_enabled_) {
986 if (!transient_suppressor_.get()) { 1025 if (!transient_suppressor_.get()) {
987 transient_suppressor_.reset(new TransientSuppressor()); 1026 transient_suppressor_.reset(new TransientSuppressor());
988 } 1027 }
989 transient_suppressor_->Initialize(fwd_proc_format_.rate(), 1028 transient_suppressor_->Initialize(
990 split_rate_, 1029 fwd_proc_format_.sample_rate_hz(), split_rate_,
991 fwd_out_format_.num_channels()); 1030 api_format_.output_stream().num_channels());
992 } 1031 }
993 } 1032 }
994 1033
995 void AudioProcessingImpl::InitializeBeamformer() { 1034 void AudioProcessingImpl::InitializeBeamformer() {
996 if (beamformer_enabled_) { 1035 if (beamformer_enabled_) {
997 if (!beamformer_) { 1036 if (!beamformer_) {
998 beamformer_.reset(new NonlinearBeamformer(array_geometry_)); 1037 beamformer_.reset(new NonlinearBeamformer(array_geometry_));
999 } 1038 }
1000 beamformer_->Initialize(kChunkSizeMs, split_rate_); 1039 beamformer_->Initialize(kChunkSizeMs, split_rate_);
1001 } 1040 }
(...skipping 22 matching lines...) Expand all
1024 stream_delay_jumps_ = 0; // Activate counter if needed. 1063 stream_delay_jumps_ = 0; // Activate counter if needed.
1025 } 1064 }
1026 stream_delay_jumps_++; 1065 stream_delay_jumps_++;
1027 } 1066 }
1028 last_stream_delay_ms_ = stream_delay_ms_; 1067 last_stream_delay_ms_ = stream_delay_ms_;
1029 1068
1030 // Detect a jump in AEC system delay and log the difference. 1069 // Detect a jump in AEC system delay and log the difference.
1031 const int frames_per_ms = rtc::CheckedDivExact(split_rate_, 1000); 1070 const int frames_per_ms = rtc::CheckedDivExact(split_rate_, 1000);
1032 const int aec_system_delay_ms = 1071 const int aec_system_delay_ms =
1033 WebRtcAec_system_delay(echo_cancellation()->aec_core()) / frames_per_ms; 1072 WebRtcAec_system_delay(echo_cancellation()->aec_core()) / frames_per_ms;
1034 const int diff_aec_system_delay_ms = aec_system_delay_ms - 1073 const int diff_aec_system_delay_ms =
1035 last_aec_system_delay_ms_; 1074 aec_system_delay_ms - last_aec_system_delay_ms_;
1036 if (diff_aec_system_delay_ms > kMinDiffDelayMs && 1075 if (diff_aec_system_delay_ms > kMinDiffDelayMs &&
1037 last_aec_system_delay_ms_ != 0) { 1076 last_aec_system_delay_ms_ != 0) {
1038 RTC_HISTOGRAM_COUNTS("WebRTC.Audio.AecSystemDelayJump", 1077 RTC_HISTOGRAM_COUNTS("WebRTC.Audio.AecSystemDelayJump",
1039 diff_aec_system_delay_ms, kMinDiffDelayMs, 1000, 1078 diff_aec_system_delay_ms, kMinDiffDelayMs, 1000,
1040 100); 1079 100);
1041 if (aec_system_delay_jumps_ == -1) { 1080 if (aec_system_delay_jumps_ == -1) {
1042 aec_system_delay_jumps_ = 0; // Activate counter if needed. 1081 aec_system_delay_jumps_ = 0; // Activate counter if needed.
1043 } 1082 }
1044 aec_system_delay_jumps_++; 1083 aec_system_delay_jumps_++;
1045 } 1084 }
(...skipping 18 matching lines...) Expand all
1064 aec_system_delay_jumps_ = -1; 1103 aec_system_delay_jumps_ = -1;
1065 last_aec_system_delay_ms_ = 0; 1104 last_aec_system_delay_ms_ = 0;
1066 } 1105 }
1067 1106
1068 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 1107 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
1069 int AudioProcessingImpl::WriteMessageToDebugFile() { 1108 int AudioProcessingImpl::WriteMessageToDebugFile() {
1070 int32_t size = event_msg_->ByteSize(); 1109 int32_t size = event_msg_->ByteSize();
1071 if (size <= 0) { 1110 if (size <= 0) {
1072 return kUnspecifiedError; 1111 return kUnspecifiedError;
1073 } 1112 }
1074 #if defined(WEBRTC_ARCH_BIG_ENDIAN) 1113 #if defined(WEBRTC_ARCH_BIG_ENDIAN)
mgraczyk 2015/07/10 00:33:36 More clang_format here and above.
1075 // TODO(ajm): Use little-endian "on the wire". For the moment, we can be 1114 // TODO(ajm): Use little-endian "on the wire". For the moment, we can be
1076 // pretty safe in assuming little-endian. 1115 // pretty safe in assuming little-endian.
1077 #endif 1116 #endif
1078 1117
1079 if (!event_msg_->SerializeToString(&event_str_)) { 1118 if (!event_msg_->SerializeToString(&event_str_)) {
1080 return kUnspecifiedError; 1119 return kUnspecifiedError;
1081 } 1120 }
1082 1121
1083 // Write message preceded by its size. 1122 // Write message preceded by its size.
1084 if (!debug_file_->Write(&size, sizeof(int32_t))) { 1123 if (!debug_file_->Write(&size, sizeof(int32_t))) {
1085 return kFileError; 1124 return kFileError;
1086 } 1125 }
1087 if (!debug_file_->Write(event_str_.data(), event_str_.length())) { 1126 if (!debug_file_->Write(event_str_.data(), event_str_.length())) {
1088 return kFileError; 1127 return kFileError;
1089 } 1128 }
1090 1129
1091 event_msg_->Clear(); 1130 event_msg_->Clear();
1092 1131
1093 return kNoError; 1132 return kNoError;
1094 } 1133 }
1095 1134
1096 int AudioProcessingImpl::WriteInitMessage() { 1135 int AudioProcessingImpl::WriteInitMessage() {
1097 event_msg_->set_type(audioproc::Event::INIT); 1136 event_msg_->set_type(audioproc::Event::INIT);
1098 audioproc::Init* msg = event_msg_->mutable_init(); 1137 audioproc::Init* msg = event_msg_->mutable_init();
1099 msg->set_sample_rate(fwd_in_format_.rate()); 1138 msg->set_sample_rate(api_format_.input_stream().sample_rate_hz());
1100 msg->set_num_input_channels(fwd_in_format_.num_channels()); 1139 msg->set_num_input_channels(api_format_.input_stream().num_channels());
1101 msg->set_num_output_channels(fwd_out_format_.num_channels()); 1140 msg->set_num_output_channels(api_format_.output_stream().num_channels());
1102 msg->set_num_reverse_channels(rev_in_format_.num_channels()); 1141 msg->set_num_reverse_channels(api_format_.reverse_stream().num_channels());
1103 msg->set_reverse_sample_rate(rev_in_format_.rate()); 1142 msg->set_reverse_sample_rate(api_format_.reverse_stream().sample_rate_hz());
1104 msg->set_output_sample_rate(fwd_out_format_.rate()); 1143 msg->set_output_sample_rate(api_format_.output_stream().sample_rate_hz());
1105 1144
1106 int err = WriteMessageToDebugFile(); 1145 int err = WriteMessageToDebugFile();
1107 if (err != kNoError) { 1146 if (err != kNoError) {
1108 return err; 1147 return err;
1109 } 1148 }
1110 1149
1111 return kNoError; 1150 return kNoError;
1112 } 1151 }
1113 #endif // WEBRTC_AUDIOPROC_DEBUG_DUMP 1152 #endif // WEBRTC_AUDIOPROC_DEBUG_DUMP
1114 1153
1115 } // namespace webrtc 1154 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698