audio_processing_impl.cc revision ae643ce280876d3b1ebcf0cc628f27ba7116b534
1470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com/*
240654039cde13b3338cc7084cd87d5decbc06fbaandrew@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *
4470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  Use of this source code is governed by a BSD-style license
5470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  that can be found in the LICENSE file in the root of the source
6470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  tree. An additional intellectual property rights grant can be found
7470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  in the file PATENTS.  All contributing project authors may
8470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com *  be found in the AUTHORS file in the root of the source tree.
9470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com */
10470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1178693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/modules/audio_processing/audio_processing_impl.h"
12470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
13808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com#include <assert.h>
14470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
15e46bc77e941f12ca24b04cf42fca98e15bc139eexians@webrtc.org#include "webrtc/base/platform_file.h"
1617e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org#include "webrtc/common_audio/include/audio_util.h"
1760730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
18788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org#include "webrtc/modules/audio_processing/agc/agc_manager_direct.h"
1978693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/modules/audio_processing/audio_buffer.h"
20ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org#include "webrtc/modules/audio_processing/beamformer/beamformer.h"
218789376cd35e055765a72248a8ad444ea2e9438caluebs@webrtc.org#include "webrtc/modules/audio_processing/channel_buffer.h"
22ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org#include "webrtc/modules/audio_processing/common.h"
2356e4a05053d6addc7dbbe2b4d07271305fdbea75andrew@webrtc.org#include "webrtc/modules/audio_processing/echo_cancellation_impl.h"
2478693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/modules/audio_processing/echo_control_mobile_impl.h"
2578693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/modules/audio_processing/gain_control_impl.h"
2678693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/modules/audio_processing/high_pass_filter_impl.h"
2778693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/modules/audio_processing/level_estimator_impl.h"
2878693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/modules/audio_processing/noise_suppression_impl.h"
2978693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/modules/audio_processing/processing_component.h"
30ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org#include "webrtc/modules/audio_processing/transient/transient_suppressor.h"
3178693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/modules/audio_processing/voice_detection_impl.h"
3278693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/modules/interface/module_common_types.h"
3360730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org#include "webrtc/system_wrappers/interface/compile_assert.h"
3478693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
3578693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/system_wrappers/interface/file_wrapper.h"
3678693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/system_wrappers/interface/logging.h"
377bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org
387bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
397bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org// Files generated at build-time by the protobuf compiler.
40a3736345dd8d90542792d164f269b4bf986dd4baleozwang@webrtc.org#ifdef WEBRTC_ANDROID_PLATFORM_BUILD
41534e495df0bdf2890b10c7ff65e59d96291e1981leozwang@webrtc.org#include "external/webrtc/webrtc/modules/audio_processing/debug.pb.h"
42ce9bfbb33db9ff3e65c9db23ccbfb3467cb0f732leozwang@google.com#else
43808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com#include "webrtc/audio_processing/debug.pb.h"
44ce9bfbb33db9ff3e65c9db23ccbfb3467cb0f732leozwang@google.com#endif
457bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#endif  // WEBRTC_AUDIOPROC_DEBUG_DUMP
46470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
4760730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org#define RETURN_ON_ERR(expr)  \
4860730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org  do {                       \
4960730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org    int err = expr;          \
5060730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org    if (err != kNoError) {   \
5160730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org      return err;            \
5260730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org    }                        \
5360730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org  } while (0)
5460730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org
55470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comnamespace webrtc {
5660730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org
5760730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org// Throughout webrtc, it's assumed that success is represented by zero.
5860730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.orgCOMPILE_ASSERT(AudioProcessing::kNoError == 0, no_error_must_be_zero);
5960730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org
60788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org// This class has two main functionalities:
61788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org//
62788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org// 1) It is returned instead of the real GainControl after the new AGC has been
63788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org//    enabled in order to prevent an outside user from overriding compression
64788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org//    settings. It doesn't do anything in its implementation, except for
65788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org//    delegating the const methods and Enable calls to the real GainControl, so
66788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org//    AGC can still be disabled.
67788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org//
68788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org// 2) It is injected into AgcManagerDirect and implements volume callbacks for
69788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org//    getting and setting the volume level. It just caches this value to be used
70788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org//    in VoiceEngine later.
71788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.orgclass GainControlForNewAgc : public GainControl, public VolumeCallbacks {
72788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org public:
73788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  explicit GainControlForNewAgc(GainControlImpl* gain_control)
74788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org      : real_gain_control_(gain_control),
75788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org        volume_(0) {
76788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
77788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org
78788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  // GainControl implementation.
79788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  virtual int Enable(bool enable) OVERRIDE {
80788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    return real_gain_control_->Enable(enable);
81788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
82788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  virtual bool is_enabled() const OVERRIDE {
83788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    return real_gain_control_->is_enabled();
84788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
85788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  virtual int set_stream_analog_level(int level) OVERRIDE {
86788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    volume_ = level;
87788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    return AudioProcessing::kNoError;
88788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
89788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  virtual int stream_analog_level() OVERRIDE {
90788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    return volume_;
91788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
92788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  virtual int set_mode(Mode mode) OVERRIDE { return AudioProcessing::kNoError; }
93788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  virtual Mode mode() const OVERRIDE { return GainControl::kAdaptiveAnalog; }
94788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  virtual int set_target_level_dbfs(int level) OVERRIDE {
95788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    return AudioProcessing::kNoError;
96788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
97788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  virtual int target_level_dbfs() const OVERRIDE {
98788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    return real_gain_control_->target_level_dbfs();
99788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
100788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  virtual int set_compression_gain_db(int gain) OVERRIDE {
101788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    return AudioProcessing::kNoError;
102788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
103788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  virtual int compression_gain_db() const OVERRIDE {
104788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    return real_gain_control_->compression_gain_db();
105788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
106788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  virtual int enable_limiter(bool enable) OVERRIDE {
107788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    return AudioProcessing::kNoError;
108788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
109788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  virtual bool is_limiter_enabled() const OVERRIDE {
110788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    return real_gain_control_->is_limiter_enabled();
111788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
112788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  virtual int set_analog_level_limits(int minimum,
113788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org                                      int maximum) OVERRIDE {
114788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    return AudioProcessing::kNoError;
115788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
116788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  virtual int analog_level_minimum() const OVERRIDE {
117788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    return real_gain_control_->analog_level_minimum();
118788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
119788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  virtual int analog_level_maximum() const OVERRIDE {
120788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    return real_gain_control_->analog_level_maximum();
121788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
122788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  virtual bool stream_is_saturated() const OVERRIDE {
123788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    return real_gain_control_->stream_is_saturated();
124788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
125788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org
126788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  // VolumeCallbacks implementation.
127788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  virtual void SetMicVolume(int volume) OVERRIDE {
128788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    volume_ = volume;
129788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
130788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  virtual int GetMicVolume() OVERRIDE {
131788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    return volume_;
132788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
133788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org
134788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org private:
135788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  GainControl* real_gain_control_;
136788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  int volume_;
137788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org};
138788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org
139470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comAudioProcessing* AudioProcessing::Create(int id) {
140e84978f3d8612e7e482791552b94e0847967d3baandrew@webrtc.org  return Create();
141e84978f3d8612e7e482791552b94e0847967d3baandrew@webrtc.org}
142e84978f3d8612e7e482791552b94e0847967d3baandrew@webrtc.org
143e84978f3d8612e7e482791552b94e0847967d3baandrew@webrtc.orgAudioProcessing* AudioProcessing::Create() {
144e84978f3d8612e7e482791552b94e0847967d3baandrew@webrtc.org  Config config;
145e84978f3d8612e7e482791552b94e0847967d3baandrew@webrtc.org  return Create(config);
146e84978f3d8612e7e482791552b94e0847967d3baandrew@webrtc.org}
147e84978f3d8612e7e482791552b94e0847967d3baandrew@webrtc.org
148e84978f3d8612e7e482791552b94e0847967d3baandrew@webrtc.orgAudioProcessing* AudioProcessing::Create(const Config& config) {
149e84978f3d8612e7e482791552b94e0847967d3baandrew@webrtc.org  AudioProcessingImpl* apm = new AudioProcessingImpl(config);
150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (apm->Initialize() != kNoError) {
151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    delete apm;
152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    apm = NULL;
153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
155470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return apm;
156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
157470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
158e84978f3d8612e7e482791552b94e0847967d3baandrew@webrtc.orgAudioProcessingImpl::AudioProcessingImpl(const Config& config)
15960730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org    : echo_cancellation_(NULL),
160470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      echo_control_mobile_(NULL),
161470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      gain_control_(NULL),
162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      high_pass_filter_(NULL),
163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      level_estimator_(NULL),
164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      noise_suppression_(NULL),
165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      voice_detection_(NULL),
166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      crit_(CriticalSectionWrapper::CreateCriticalSection()),
1677bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
1687bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org      debug_file_(FileWrapper::Create()),
1697bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org      event_msg_(new audioproc::Event()),
1707bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#endif
171ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org      fwd_in_format_(kSampleRate16kHz, 1),
17227d106bcf7eaf864e8433f1fc303475b953498b3aluebs@webrtc.org      fwd_proc_format_(kSampleRate16kHz),
17327d106bcf7eaf864e8433f1fc303475b953498b3aluebs@webrtc.org      fwd_out_format_(kSampleRate16kHz, 1),
174ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org      rev_in_format_(kSampleRate16kHz, 1),
175ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org      rev_proc_format_(kSampleRate16kHz, 1),
176ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org      split_rate_(kSampleRate16kHz),
177470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      stream_delay_ms_(0),
1786f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.org      delay_offset_ms_(0),
179470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      was_stream_delay_set_(false),
18038bf249049a16233904c8617edaf0f0b6155d9a2andrew@webrtc.org      output_will_be_muted_(false),
181788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org      key_pressed_(false),
182788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
183788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org      use_new_agc_(false),
184788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org#else
185788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org      use_new_agc_(config.Get<ExperimentalAgc>().enabled),
186788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org#endif
187ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org      transient_suppressor_enabled_(config.Get<ExperimentalNs>().enabled),
188ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org      beamformer_enabled_(config.Get<Beamforming>().enabled) {
18956e4a05053d6addc7dbbe2b4d07271305fdbea75andrew@webrtc.org  echo_cancellation_ = new EchoCancellationImpl(this, crit_);
190470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  component_list_.push_back(echo_cancellation_);
191470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
19256e4a05053d6addc7dbbe2b4d07271305fdbea75andrew@webrtc.org  echo_control_mobile_ = new EchoControlMobileImpl(this, crit_);
193470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  component_list_.push_back(echo_control_mobile_);
194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
19556e4a05053d6addc7dbbe2b4d07271305fdbea75andrew@webrtc.org  gain_control_ = new GainControlImpl(this, crit_);
196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  component_list_.push_back(gain_control_);
197470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
19856e4a05053d6addc7dbbe2b4d07271305fdbea75andrew@webrtc.org  high_pass_filter_ = new HighPassFilterImpl(this, crit_);
199470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  component_list_.push_back(high_pass_filter_);
200470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
20156e4a05053d6addc7dbbe2b4d07271305fdbea75andrew@webrtc.org  level_estimator_ = new LevelEstimatorImpl(this, crit_);
202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  component_list_.push_back(level_estimator_);
203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
20456e4a05053d6addc7dbbe2b4d07271305fdbea75andrew@webrtc.org  noise_suppression_ = new NoiseSuppressionImpl(this, crit_);
205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  component_list_.push_back(noise_suppression_);
206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
20756e4a05053d6addc7dbbe2b4d07271305fdbea75andrew@webrtc.org  voice_detection_ = new VoiceDetectionImpl(this, crit_);
208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  component_list_.push_back(voice_detection_);
209e84978f3d8612e7e482791552b94e0847967d3baandrew@webrtc.org
210788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  gain_control_for_new_agc_.reset(new GainControlForNewAgc(gain_control_));
211788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org
212e84978f3d8612e7e482791552b94e0847967d3baandrew@webrtc.org  SetExtraOptions(config);
213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comAudioProcessingImpl::~AudioProcessingImpl() {
2168186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org  {
2178186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org    CriticalSectionScoped crit_scoped(crit_);
218788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    // Depends on gain_control_ and gain_control_for_new_agc_.
219788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    agc_manager_.reset();
220788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    // Depends on gain_control_.
221788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    gain_control_for_new_agc_.reset();
2228186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org    while (!component_list_.empty()) {
2238186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org      ProcessingComponent* component = component_list_.front();
2248186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org      component->Destroy();
2258186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org      delete component;
2268186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org      component_list_.pop_front();
2278186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org    }
228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
2297bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
2308186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org    if (debug_file_->Open()) {
2318186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org      debug_file_->CloseFile();
2328186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org    }
2337bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#endif
234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
23516cfbe2e89d528eb09195b3959640d70efa83578andrew@webrtc.org  delete crit_;
23616cfbe2e89d528eb09195b3959640d70efa83578andrew@webrtc.org  crit_ = NULL;
237470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
238470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::Initialize() {
24040654039cde13b3338cc7084cd87d5decbc06fbaandrew@webrtc.org  CriticalSectionScoped crit_scoped(crit_);
241470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return InitializeLocked();
242470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
243470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
244ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.orgint AudioProcessingImpl::set_sample_rate_hz(int rate) {
245ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  CriticalSectionScoped crit_scoped(crit_);
246ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  return InitializeLocked(rate,
247ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                          rate,
248ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                          rev_in_format_.rate(),
249ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                          fwd_in_format_.num_channels(),
25027d106bcf7eaf864e8433f1fc303475b953498b3aluebs@webrtc.org                          fwd_out_format_.num_channels(),
251ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                          rev_in_format_.num_channels());
252ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org}
253ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org
254ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.orgint AudioProcessingImpl::Initialize(int input_sample_rate_hz,
255ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                    int output_sample_rate_hz,
256a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org                                    int reverse_sample_rate_hz,
257ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                    ChannelLayout input_layout,
258ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                    ChannelLayout output_layout,
259ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                    ChannelLayout reverse_layout) {
260a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org  CriticalSectionScoped crit_scoped(crit_);
261ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  return InitializeLocked(input_sample_rate_hz,
262ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                          output_sample_rate_hz,
263a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org                          reverse_sample_rate_hz,
264ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                          ChannelsFromLayout(input_layout),
265ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                          ChannelsFromLayout(output_layout),
266ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                          ChannelsFromLayout(reverse_layout));
267a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org}
268a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org
269470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::InitializeLocked() {
270ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org  const int fwd_audio_buffer_channels = beamformer_enabled_ ?
271ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org                                        fwd_in_format_.num_channels() :
272ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org                                        fwd_out_format_.num_channels();
273ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  render_audio_.reset(new AudioBuffer(rev_in_format_.samples_per_channel(),
274ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                      rev_in_format_.num_channels(),
275ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                      rev_proc_format_.samples_per_channel(),
276ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                      rev_proc_format_.num_channels(),
277ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                      rev_proc_format_.samples_per_channel()));
278ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  capture_audio_.reset(new AudioBuffer(fwd_in_format_.samples_per_channel(),
279ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                       fwd_in_format_.num_channels(),
280ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                       fwd_proc_format_.samples_per_channel(),
281ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org                                       fwd_audio_buffer_channels,
282ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                       fwd_out_format_.samples_per_channel()));
283470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
284470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  // Initialize all components.
285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  std::list<ProcessingComponent*>::iterator it;
2868186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org  for (it = component_list_.begin(); it != component_list_.end(); ++it) {
287470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    int err = (*it)->Initialize();
288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if (err != kNoError) {
289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      return err;
290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
293788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  int err = InitializeExperimentalAgc();
294788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  if (err != kNoError) {
295788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    return err;
296788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
297788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org
298788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  err = InitializeTransient();
299788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  if (err != kNoError) {
300788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    return err;
301788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
302788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org
303ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org  InitializeBeamformer();
304ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org
3057bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
306808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  if (debug_file_->Open()) {
307808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    int err = WriteInitMessage();
308808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    if (err != kNoError) {
309808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com      return err;
310808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    }
311808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  }
3127bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#endif
313808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com
314470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return kNoError;
315470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
316470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
317ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.orgint AudioProcessingImpl::InitializeLocked(int input_sample_rate_hz,
318ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                          int output_sample_rate_hz,
319a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org                                          int reverse_sample_rate_hz,
320a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org                                          int num_input_channels,
321a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org                                          int num_output_channels,
322a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org                                          int num_reverse_channels) {
323ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  if (input_sample_rate_hz <= 0 ||
324ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org      output_sample_rate_hz <= 0 ||
325ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org      reverse_sample_rate_hz <= 0) {
326a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org    return kBadSampleRateError;
327a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org  }
328a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org  if (num_output_channels > num_input_channels) {
329a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org    return kBadNumberChannelsError;
330a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org  }
331a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org  // Only mono and stereo supported currently.
332a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org  if (num_input_channels > 2 || num_input_channels < 1 ||
333a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org      num_output_channels > 2 || num_output_channels < 1 ||
334a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org      num_reverse_channels > 2 || num_reverse_channels < 1) {
335a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org    return kBadNumberChannelsError;
336a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org  }
337ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org
338ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  fwd_in_format_.set(input_sample_rate_hz, num_input_channels);
33927d106bcf7eaf864e8433f1fc303475b953498b3aluebs@webrtc.org  fwd_out_format_.set(output_sample_rate_hz, num_output_channels);
340ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  rev_in_format_.set(reverse_sample_rate_hz, num_reverse_channels);
341ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org
342ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  // We process at the closest native rate >= min(input rate, output rate)...
343ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  int min_proc_rate = std::min(fwd_in_format_.rate(), fwd_out_format_.rate());
344ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  int fwd_proc_rate;
345ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  if (min_proc_rate > kSampleRate16kHz) {
346ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org    fwd_proc_rate = kSampleRate32kHz;
347ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  } else if (min_proc_rate > kSampleRate8kHz) {
348ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org    fwd_proc_rate = kSampleRate16kHz;
349ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  } else {
350ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org    fwd_proc_rate = kSampleRate8kHz;
351ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  }
352ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  // ...with one exception.
353ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  if (echo_control_mobile_->is_enabled() && min_proc_rate > kSampleRate16kHz) {
354ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org    fwd_proc_rate = kSampleRate16kHz;
355ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  }
356ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org
35727d106bcf7eaf864e8433f1fc303475b953498b3aluebs@webrtc.org  fwd_proc_format_.set(fwd_proc_rate);
358ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org
359ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  // We normally process the reverse stream at 16 kHz. Unless...
360ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  int rev_proc_rate = kSampleRate16kHz;
361ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  if (fwd_proc_format_.rate() == kSampleRate8kHz) {
362ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org    // ...the forward stream is at 8 kHz.
363ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org    rev_proc_rate = kSampleRate8kHz;
364ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  } else {
365ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org    if (rev_in_format_.rate() == kSampleRate32kHz) {
366ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org      // ...or the input is at 32 kHz, in which case we use the splitting
367ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org      // filter rather than the resampler.
368ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org      rev_proc_rate = kSampleRate32kHz;
369ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org    }
370a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org  }
371a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org
37230be827e6a2bfae76c445e62d0853f83d238814aandrew@webrtc.org  // Always downmix the reverse stream to mono for analysis. This has been
37330be827e6a2bfae76c445e62d0853f83d238814aandrew@webrtc.org  // demonstrated to work well for AEC in most practical scenarios.
37430be827e6a2bfae76c445e62d0853f83d238814aandrew@webrtc.org  rev_proc_format_.set(rev_proc_rate, 1);
375a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org
376087da13fe8be20b61b556f60eac937c9d0b19fb8aluebs@webrtc.org  if (fwd_proc_format_.rate() == kSampleRate32kHz ||
377087da13fe8be20b61b556f60eac937c9d0b19fb8aluebs@webrtc.org      fwd_proc_format_.rate() == kSampleRate48kHz) {
378ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org    split_rate_ = kSampleRate16kHz;
379a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org  } else {
380ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org    split_rate_ = fwd_proc_format_.rate();
381a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org  }
382a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org
383a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org  return InitializeLocked();
384a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org}
385a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org
386a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org// Calls InitializeLocked() if any of the audio parameters have changed from
387a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org// their current values.
388ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.orgint AudioProcessingImpl::MaybeInitializeLocked(int input_sample_rate_hz,
389ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                               int output_sample_rate_hz,
390a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org                                               int reverse_sample_rate_hz,
391a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org                                               int num_input_channels,
392a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org                                               int num_output_channels,
393a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org                                               int num_reverse_channels) {
394ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  if (input_sample_rate_hz == fwd_in_format_.rate() &&
395ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org      output_sample_rate_hz == fwd_out_format_.rate() &&
396ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org      reverse_sample_rate_hz == rev_in_format_.rate() &&
397ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org      num_input_channels == fwd_in_format_.num_channels() &&
39827d106bcf7eaf864e8433f1fc303475b953498b3aluebs@webrtc.org      num_output_channels == fwd_out_format_.num_channels() &&
399ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org      num_reverse_channels == rev_in_format_.num_channels()) {
400a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org    return kNoError;
401a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org  }
402ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org  if (beamformer_enabled_ &&
403ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org      (num_input_channels < 2 || num_output_channels > 1)) {
404ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org    return kBadNumberChannelsError;
405ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org  }
406ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  return InitializeLocked(input_sample_rate_hz,
407ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                          output_sample_rate_hz,
408a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org                          reverse_sample_rate_hz,
409a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org                          num_input_channels,
410a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org                          num_output_channels,
411a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org                          num_reverse_channels);
412a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org}
413a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org
41461e596fc49443971219aa3989b200407d919f6c5andrew@webrtc.orgvoid AudioProcessingImpl::SetExtraOptions(const Config& config) {
415e84978f3d8612e7e482791552b94e0847967d3baandrew@webrtc.org  CriticalSectionScoped crit_scoped(crit_);
41661e596fc49443971219aa3989b200407d919f6c5andrew@webrtc.org  std::list<ProcessingComponent*>::iterator it;
41761e596fc49443971219aa3989b200407d919f6c5andrew@webrtc.org  for (it = component_list_.begin(); it != component_list_.end(); ++it)
41861e596fc49443971219aa3989b200407d919f6c5andrew@webrtc.org    (*it)->SetExtraOptions(config);
419788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org
420788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  if (transient_suppressor_enabled_ != config.Get<ExperimentalNs>().enabled) {
421788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    transient_suppressor_enabled_ = config.Get<ExperimentalNs>().enabled;
422788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    InitializeTransient();
423788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
42461e596fc49443971219aa3989b200407d919f6c5andrew@webrtc.org}
42561e596fc49443971219aa3989b200407d919f6c5andrew@webrtc.org
426ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.orgint AudioProcessingImpl::input_sample_rate_hz() const {
42740654039cde13b3338cc7084cd87d5decbc06fbaandrew@webrtc.org  CriticalSectionScoped crit_scoped(crit_);
428ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  return fwd_in_format_.rate();
429470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
430470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
43146b31b17df576e78fb7603f587a93b7dc3dea872andrew@webrtc.orgint AudioProcessingImpl::sample_rate_hz() const {
43246b31b17df576e78fb7603f587a93b7dc3dea872andrew@webrtc.org  CriticalSectionScoped crit_scoped(crit_);
43346b31b17df576e78fb7603f587a93b7dc3dea872andrew@webrtc.org  return fwd_in_format_.rate();
43446b31b17df576e78fb7603f587a93b7dc3dea872andrew@webrtc.org}
43546b31b17df576e78fb7603f587a93b7dc3dea872andrew@webrtc.org
436ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.orgint AudioProcessingImpl::proc_sample_rate_hz() const {
437ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  return fwd_proc_format_.rate();
438470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
439470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
440ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.orgint AudioProcessingImpl::proc_split_sample_rate_hz() const {
441ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  return split_rate_;
442470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
444470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::num_reverse_channels() const {
445ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  return rev_proc_format_.num_channels();
446470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
447470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
448470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::num_input_channels() const {
449ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  return fwd_in_format_.num_channels();
450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
451470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
452470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::num_output_channels() const {
45327d106bcf7eaf864e8433f1fc303475b953498b3aluebs@webrtc.org  return fwd_out_format_.num_channels();
454470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
455470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
45617342e5092430c3893246077aee3b727298df117andrew@webrtc.orgvoid AudioProcessingImpl::set_output_will_be_muted(bool muted) {
45717342e5092430c3893246077aee3b727298df117andrew@webrtc.org  output_will_be_muted_ = muted;
458788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  CriticalSectionScoped lock(crit_);
459788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  if (agc_manager_.get()) {
460788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    agc_manager_->SetCaptureMuted(output_will_be_muted_);
461788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
46217342e5092430c3893246077aee3b727298df117andrew@webrtc.org}
46317342e5092430c3893246077aee3b727298df117andrew@webrtc.org
46417342e5092430c3893246077aee3b727298df117andrew@webrtc.orgbool AudioProcessingImpl::output_will_be_muted() const {
46517342e5092430c3893246077aee3b727298df117andrew@webrtc.org  return output_will_be_muted_;
46617342e5092430c3893246077aee3b727298df117andrew@webrtc.org}
46717342e5092430c3893246077aee3b727298df117andrew@webrtc.org
468ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.orgint AudioProcessingImpl::ProcessStream(const float* const* src,
46917e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org                                       int samples_per_channel,
470ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                       int input_sample_rate_hz,
47117e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org                                       ChannelLayout input_layout,
472ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                       int output_sample_rate_hz,
473ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                       ChannelLayout output_layout,
474ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                       float* const* dest) {
47560730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org  CriticalSectionScoped crit_scoped(crit_);
476ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  if (!src || !dest) {
47717e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org    return kNullPointerError;
47817e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  }
47960730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org
480ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  RETURN_ON_ERR(MaybeInitializeLocked(input_sample_rate_hz,
481ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                      output_sample_rate_hz,
482ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                      rev_in_format_.rate(),
483ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                      ChannelsFromLayout(input_layout),
484ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                      ChannelsFromLayout(output_layout),
485ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                      rev_in_format_.num_channels()));
486ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  if (samples_per_channel != fwd_in_format_.samples_per_channel()) {
48717e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org    return kBadDataLengthError;
48817e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  }
48917e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org
49017e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
49117e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  if (debug_file_->Open()) {
49217e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org    event_msg_->set_type(audioproc::Event::STREAM);
49317e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org    audioproc::Stream* msg = event_msg_->mutable_stream();
49459a1b1b92850747a0e758b9668f725ed9e961a33aluebs@webrtc.org    const size_t channel_size =
49559a1b1b92850747a0e758b9668f725ed9e961a33aluebs@webrtc.org        sizeof(float) * fwd_in_format_.samples_per_channel();
496ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org    for (int i = 0; i < fwd_in_format_.num_channels(); ++i)
497ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org      msg->add_input_channel(src[i], channel_size);
49817e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  }
49917e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org#endif
50017e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org
501ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  capture_audio_->CopyFrom(src, samples_per_channel, input_layout);
50217e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  RETURN_ON_ERR(ProcessStreamLocked());
50317e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  if (output_copy_needed(is_data_processed())) {
504ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org    capture_audio_->CopyTo(fwd_out_format_.samples_per_channel(),
505ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                           output_layout,
506ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                           dest);
50717e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  }
50817e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org
50917e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
51017e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  if (debug_file_->Open()) {
51117e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org    audioproc::Stream* msg = event_msg_->mutable_stream();
51259a1b1b92850747a0e758b9668f725ed9e961a33aluebs@webrtc.org    const size_t channel_size =
51359a1b1b92850747a0e758b9668f725ed9e961a33aluebs@webrtc.org        sizeof(float) * fwd_out_format_.samples_per_channel();
51427d106bcf7eaf864e8433f1fc303475b953498b3aluebs@webrtc.org    for (int i = 0; i < fwd_out_format_.num_channels(); ++i)
515ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org      msg->add_output_channel(dest[i], channel_size);
51617e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org    RETURN_ON_ERR(WriteMessageToDebugFile());
51717e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  }
51817e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org#endif
51917e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org
52017e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  return kNoError;
52117e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org}
52217e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org
52317e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.orgint AudioProcessingImpl::ProcessStream(AudioFrame* frame) {
52417e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  CriticalSectionScoped crit_scoped(crit_);
52517e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  if (!frame) {
52660730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org    return kNullPointerError;
52760730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org  }
528ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  // Must be a native rate.
529ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  if (frame->sample_rate_hz_ != kSampleRate8kHz &&
530ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org      frame->sample_rate_hz_ != kSampleRate16kHz &&
531087da13fe8be20b61b556f60eac937c9d0b19fb8aluebs@webrtc.org      frame->sample_rate_hz_ != kSampleRate32kHz &&
532087da13fe8be20b61b556f60eac937c9d0b19fb8aluebs@webrtc.org      frame->sample_rate_hz_ != kSampleRate48kHz) {
533ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org    return kBadSampleRateError;
534ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  }
535ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  if (echo_control_mobile_->is_enabled() &&
536ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org      frame->sample_rate_hz_ > kSampleRate16kHz) {
537ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org    LOG(LS_ERROR) << "AECM only supports 16 or 8 kHz sample rates";
538ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org    return kUnsupportedComponentError;
539ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  }
54017e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org
541ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  // TODO(ajm): The input and output rates and channels are currently
542ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  // constrained to be identical in the int16 interface.
54360730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org  RETURN_ON_ERR(MaybeInitializeLocked(frame->sample_rate_hz_,
544ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                      frame->sample_rate_hz_,
545ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                      rev_in_format_.rate(),
546ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                      frame->num_channels_,
547ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                      frame->num_channels_,
548ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                      rev_in_format_.num_channels()));
549ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  if (frame->samples_per_channel_ != fwd_in_format_.samples_per_channel()) {
550470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return kBadDataLengthError;
551470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
552470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
5537bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
554470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (debug_file_->Open()) {
555808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    event_msg_->set_type(audioproc::Event::STREAM);
556808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    audioproc::Stream* msg = event_msg_->mutable_stream();
557755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org    const size_t data_size = sizeof(int16_t) *
55863a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org                             frame->samples_per_channel_ *
55963a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org                             frame->num_channels_;
56063a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org    msg->set_input_data(frame->data_, data_size);
561470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
5627bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#endif
563470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
564470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  capture_audio_->DeinterleaveFrom(frame);
56517e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  RETURN_ON_ERR(ProcessStreamLocked());
56617e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  capture_audio_->InterleaveTo(frame, output_copy_needed(is_data_processed()));
56717e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org
56817e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
56917e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  if (debug_file_->Open()) {
57017e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org    audioproc::Stream* msg = event_msg_->mutable_stream();
57117e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org    const size_t data_size = sizeof(int16_t) *
57217e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org                             frame->samples_per_channel_ *
57317e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org                             frame->num_channels_;
57417e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org    msg->set_output_data(frame->data_, data_size);
57517e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org    RETURN_ON_ERR(WriteMessageToDebugFile());
57617e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  }
57717e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org#endif
57817e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org
57917e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  return kNoError;
58017e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org}
58117e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org
58217e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org
58317e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.orgint AudioProcessingImpl::ProcessStreamLocked() {
58417e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
58517e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  if (debug_file_->Open()) {
58617e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org    audioproc::Stream* msg = event_msg_->mutable_stream();
58717e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org    msg->set_delay(stream_delay_ms_);
58817e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org    msg->set_drift(echo_cancellation_->stream_drift_samples());
58917e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org    msg->set_level(gain_control_->stream_analog_level());
59017e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org    msg->set_keypress(key_pressed_);
59117e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  }
59217e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org#endif
593470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
594103657b48442dedd1742fca4a73d5131bf4ae624andrew@webrtc.org  AudioBuffer* ca = capture_audio_.get();  // For brevity.
595788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  if (use_new_agc_ && gain_control_->is_enabled()) {
596788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    agc_manager_->AnalyzePreProcess(ca->data(0),
597788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org                                    ca->num_channels(),
598788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org                                    fwd_proc_format_.samples_per_channel());
599788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
600788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org
601369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.org  bool data_processed = is_data_processed();
602369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.org  if (analysis_needed(data_processed)) {
603be05c74ec8ee975f3451809425756d0f6a51ff2ealuebs@webrtc.org    ca->SplitIntoFrequencyBands();
604470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
605470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
606ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org#ifdef WEBRTC_BEAMFORMER
607ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org  if (beamformer_enabled_) {
608ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org    beamformer_->ProcessChunk(ca->split_channels_const_f(kBand0To8kHz),
609ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org                              ca->split_channels_const_f(kBand8To16kHz),
610ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org                              ca->num_channels(),
611ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org                              ca->samples_per_split_channel(),
612ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org                              ca->split_channels_f(kBand0To8kHz),
613ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org                              ca->split_channels_f(kBand8To16kHz));
614ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org    ca->set_num_channels(1);
615ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org  }
616ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org#endif
617ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org
618103657b48442dedd1742fca4a73d5131bf4ae624andrew@webrtc.org  RETURN_ON_ERR(high_pass_filter_->ProcessCaptureAudio(ca));
619103657b48442dedd1742fca4a73d5131bf4ae624andrew@webrtc.org  RETURN_ON_ERR(gain_control_->AnalyzeCaptureAudio(ca));
620a0ce9fa2a65a693ca9a6ee4920fb41d5cdd92e3baluebs@webrtc.org  RETURN_ON_ERR(noise_suppression_->AnalyzeCaptureAudio(ca));
621103657b48442dedd1742fca4a73d5131bf4ae624andrew@webrtc.org  RETURN_ON_ERR(echo_cancellation_->ProcessCaptureAudio(ca));
622470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
623ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  if (echo_control_mobile_->is_enabled() && noise_suppression_->is_enabled()) {
624103657b48442dedd1742fca4a73d5131bf4ae624andrew@webrtc.org    ca->CopyLowPassToReference();
625470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
626103657b48442dedd1742fca4a73d5131bf4ae624andrew@webrtc.org  RETURN_ON_ERR(noise_suppression_->ProcessCaptureAudio(ca));
627103657b48442dedd1742fca4a73d5131bf4ae624andrew@webrtc.org  RETURN_ON_ERR(echo_control_mobile_->ProcessCaptureAudio(ca));
628103657b48442dedd1742fca4a73d5131bf4ae624andrew@webrtc.org  RETURN_ON_ERR(voice_detection_->ProcessCaptureAudio(ca));
629788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org
630788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  if (use_new_agc_ && gain_control_->is_enabled()) {
631788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    agc_manager_->Process(ca->split_bands_const(0)[kBand0To8kHz],
632788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org                          ca->samples_per_split_channel(),
633788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org                          split_rate_);
634788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
635103657b48442dedd1742fca4a73d5131bf4ae624andrew@webrtc.org  RETURN_ON_ERR(gain_control_->ProcessCaptureAudio(ca));
636470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
637369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.org  if (synthesis_needed(data_processed)) {
638be05c74ec8ee975f3451809425756d0f6a51ff2ealuebs@webrtc.org    ca->MergeFrequencyBands();
639470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
640470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
641788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  // TODO(aluebs): Investigate if the transient suppression placement should be
642788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  // before or after the AGC.
643788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  if (transient_suppressor_enabled_) {
644788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    float voice_probability =
645788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org        agc_manager_.get() ? agc_manager_->voice_probability() : 1.f;
646788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org
647788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    transient_suppressor_->Suppress(ca->data_f(0),
648788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org                                    ca->samples_per_channel(),
649788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org                                    ca->num_channels(),
650788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org                                    ca->split_bands_const_f(0)[kBand0To8kHz],
651788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org                                    ca->samples_per_split_channel(),
652788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org                                    ca->keyboard_data(),
653788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org                                    ca->samples_per_keyboard_channel(),
654788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org                                    voice_probability,
655788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org                                    key_pressed_);
656788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
657788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org
658755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org  // The level estimator operates on the recombined data.
659103657b48442dedd1742fca4a73d5131bf4ae624andrew@webrtc.org  RETURN_ON_ERR(level_estimator_->ProcessStream(ca));
66017e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org
66117e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  was_stream_delay_set_ = false;
66217e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  return kNoError;
66317e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org}
66417e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org
66517e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.orgint AudioProcessingImpl::AnalyzeReverseStream(const float* const* data,
66617e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org                                              int samples_per_channel,
66717e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org                                              int sample_rate_hz,
66817e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org                                              ChannelLayout layout) {
66917e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  CriticalSectionScoped crit_scoped(crit_);
67017e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  if (data == NULL) {
67117e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org    return kNullPointerError;
67217e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  }
673755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org
67417e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  const int num_channels = ChannelsFromLayout(layout);
675ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  RETURN_ON_ERR(MaybeInitializeLocked(fwd_in_format_.rate(),
676ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                      fwd_out_format_.rate(),
677ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                      sample_rate_hz,
678ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                      fwd_in_format_.num_channels(),
67927d106bcf7eaf864e8433f1fc303475b953498b3aluebs@webrtc.org                                      fwd_out_format_.num_channels(),
680ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                      num_channels));
681ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  if (samples_per_channel != rev_in_format_.samples_per_channel()) {
68217e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org    return kBadDataLengthError;
68317e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  }
684470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
6857bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
686808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  if (debug_file_->Open()) {
68717e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org    event_msg_->set_type(audioproc::Event::REVERSE_STREAM);
68817e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org    audioproc::ReverseStream* msg = event_msg_->mutable_reverse_stream();
68959a1b1b92850747a0e758b9668f725ed9e961a33aluebs@webrtc.org    const size_t channel_size =
69059a1b1b92850747a0e758b9668f725ed9e961a33aluebs@webrtc.org        sizeof(float) * rev_in_format_.samples_per_channel();
69117e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org    for (int i = 0; i < num_channels; ++i)
692a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org      msg->add_channel(data[i], channel_size);
69317e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org    RETURN_ON_ERR(WriteMessageToDebugFile());
694808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  }
6957bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#endif
696808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com
697ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  render_audio_->CopyFrom(data, samples_per_channel, layout);
69817e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  return AnalyzeReverseStreamLocked();
699470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
700470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
701470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::AnalyzeReverseStream(AudioFrame* frame) {
70240654039cde13b3338cc7084cd87d5decbc06fbaandrew@webrtc.org  CriticalSectionScoped crit_scoped(crit_);
703470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (frame == NULL) {
704470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return kNullPointerError;
705470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
706ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  // Must be a native rate.
707ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  if (frame->sample_rate_hz_ != kSampleRate8kHz &&
708ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org      frame->sample_rate_hz_ != kSampleRate16kHz &&
709087da13fe8be20b61b556f60eac937c9d0b19fb8aluebs@webrtc.org      frame->sample_rate_hz_ != kSampleRate32kHz &&
710087da13fe8be20b61b556f60eac937c9d0b19fb8aluebs@webrtc.org      frame->sample_rate_hz_ != kSampleRate48kHz) {
711ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org    return kBadSampleRateError;
712ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  }
713ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  // This interface does not tolerate different forward and reverse rates.
714ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  if (frame->sample_rate_hz_ != fwd_in_format_.rate()) {
715470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return kBadSampleRateError;
716470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
717a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org
718ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  RETURN_ON_ERR(MaybeInitializeLocked(fwd_in_format_.rate(),
719ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                      fwd_out_format_.rate(),
720ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                      frame->sample_rate_hz_,
721ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                      fwd_in_format_.num_channels(),
722ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                      fwd_in_format_.num_channels(),
723ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org                                      frame->num_channels_));
724ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  if (frame->samples_per_channel_ != rev_in_format_.samples_per_channel()) {
72517e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org    return kBadDataLengthError;
72617e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  }
727470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
7287bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
729470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (debug_file_->Open()) {
730808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    event_msg_->set_type(audioproc::Event::REVERSE_STREAM);
731808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    audioproc::ReverseStream* msg = event_msg_->mutable_reverse_stream();
732755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org    const size_t data_size = sizeof(int16_t) *
73363a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org                             frame->samples_per_channel_ *
73463a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org                             frame->num_channels_;
73563a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org    msg->set_data(frame->data_, data_size);
73617e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org    RETURN_ON_ERR(WriteMessageToDebugFile());
737470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
7387bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#endif
739470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
740470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  render_audio_->DeinterleaveFrom(frame);
74117e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  return AnalyzeReverseStreamLocked();
74217e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org}
743470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
74417e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.orgint AudioProcessingImpl::AnalyzeReverseStreamLocked() {
745103657b48442dedd1742fca4a73d5131bf4ae624andrew@webrtc.org  AudioBuffer* ra = render_audio_.get();  // For brevity.
746ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  if (rev_proc_format_.rate() == kSampleRate32kHz) {
747be05c74ec8ee975f3451809425756d0f6a51ff2ealuebs@webrtc.org    ra->SplitIntoFrequencyBands();
748470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
749470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
750103657b48442dedd1742fca4a73d5131bf4ae624andrew@webrtc.org  RETURN_ON_ERR(echo_cancellation_->ProcessRenderAudio(ra));
751103657b48442dedd1742fca4a73d5131bf4ae624andrew@webrtc.org  RETURN_ON_ERR(echo_control_mobile_->ProcessRenderAudio(ra));
752788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  if (!use_new_agc_) {
753788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    RETURN_ON_ERR(gain_control_->ProcessRenderAudio(ra));
754788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
755470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
75617e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  return kNoError;
757470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
758470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
759470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::set_stream_delay_ms(int delay) {
7605f23d64cf2da06b45c2c1c837bb11d260cb85ecfandrew@webrtc.org  Error retval = kNoError;
761470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  was_stream_delay_set_ = true;
7626f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.org  delay += delay_offset_ms_;
7636f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.org
764470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (delay < 0) {
7655f23d64cf2da06b45c2c1c837bb11d260cb85ecfandrew@webrtc.org    delay = 0;
7665f23d64cf2da06b45c2c1c837bb11d260cb85ecfandrew@webrtc.org    retval = kBadStreamParameterWarning;
767470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
768470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
769470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  // TODO(ajm): the max is rather arbitrarily chosen; investigate.
770470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (delay > 500) {
7715f23d64cf2da06b45c2c1c837bb11d260cb85ecfandrew@webrtc.org    delay = 500;
7725f23d64cf2da06b45c2c1c837bb11d260cb85ecfandrew@webrtc.org    retval = kBadStreamParameterWarning;
773470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
774470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
775470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  stream_delay_ms_ = delay;
7765f23d64cf2da06b45c2c1c837bb11d260cb85ecfandrew@webrtc.org  return retval;
777470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
778470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
779470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::stream_delay_ms() const {
780470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return stream_delay_ms_;
781470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
782470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
783470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.combool AudioProcessingImpl::was_stream_delay_set() const {
784470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return was_stream_delay_set_;
785470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
786470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
78717e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.orgvoid AudioProcessingImpl::set_stream_key_pressed(bool key_pressed) {
78817e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  key_pressed_ = key_pressed;
78917e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org}
79017e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org
79117e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.orgbool AudioProcessingImpl::stream_key_pressed() const {
79217e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  return key_pressed_;
79317e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org}
79417e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org
7956f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.orgvoid AudioProcessingImpl::set_delay_offset_ms(int offset) {
7966f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.org  CriticalSectionScoped crit_scoped(crit_);
7976f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.org  delay_offset_ms_ = offset;
7986f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.org}
7996f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.org
8006f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.orgint AudioProcessingImpl::delay_offset_ms() const {
8016f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.org  return delay_offset_ms_;
8026f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.org}
8036f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.org
804470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::StartDebugRecording(
805470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    const char filename[AudioProcessing::kMaxFilenameSize]) {
80640654039cde13b3338cc7084cd87d5decbc06fbaandrew@webrtc.org  CriticalSectionScoped crit_scoped(crit_);
807470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  assert(kMaxFilenameSize == FileWrapper::kMaxFileNameSize);
808470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
809470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (filename == NULL) {
810470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return kNullPointerError;
811470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
812470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
8137bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
814470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  // Stop any ongoing recording.
815470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (debug_file_->Open()) {
816470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if (debug_file_->CloseFile() == -1) {
817470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      return kFileError;
818470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
819470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
820470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
821470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (debug_file_->OpenFile(filename, false) == -1) {
822470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    debug_file_->CloseFile();
823470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return kFileError;
824470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
825470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
826808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  int err = WriteInitMessage();
827808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  if (err != kNoError) {
828863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org    return err;
829863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org  }
830863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org  return kNoError;
831863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org#else
832863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org  return kUnsupportedFunctionError;
833863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org#endif  // WEBRTC_AUDIOPROC_DEBUG_DUMP
834863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org}
835863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org
836863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.orgint AudioProcessingImpl::StartDebugRecording(FILE* handle) {
837863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org  CriticalSectionScoped crit_scoped(crit_);
838863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org
839863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org  if (handle == NULL) {
840863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org    return kNullPointerError;
841863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org  }
842863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org
843863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
844863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org  // Stop any ongoing recording.
845863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org  if (debug_file_->Open()) {
846863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org    if (debug_file_->CloseFile() == -1) {
847863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org      return kFileError;
848863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org    }
849863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org  }
850863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org
851863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org  if (debug_file_->OpenFromFileHandle(handle, true, false) == -1) {
852863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org    return kFileError;
853863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org  }
854863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org
855863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org  int err = WriteInitMessage();
856863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org  if (err != kNoError) {
857808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    return err;
858470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
859470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return kNoError;
8607bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#else
8617bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  return kUnsupportedFunctionError;
8627bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#endif  // WEBRTC_AUDIOPROC_DEBUG_DUMP
863470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
864470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
865e46bc77e941f12ca24b04cf42fca98e15bc139eexians@webrtc.orgint AudioProcessingImpl::StartDebugRecordingForPlatformFile(
866e46bc77e941f12ca24b04cf42fca98e15bc139eexians@webrtc.org    rtc::PlatformFile handle) {
867e46bc77e941f12ca24b04cf42fca98e15bc139eexians@webrtc.org  FILE* stream = rtc::FdopenPlatformFileForWriting(handle);
868e46bc77e941f12ca24b04cf42fca98e15bc139eexians@webrtc.org  return StartDebugRecording(stream);
869e46bc77e941f12ca24b04cf42fca98e15bc139eexians@webrtc.org}
870e46bc77e941f12ca24b04cf42fca98e15bc139eexians@webrtc.org
871470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::StopDebugRecording() {
87240654039cde13b3338cc7084cd87d5decbc06fbaandrew@webrtc.org  CriticalSectionScoped crit_scoped(crit_);
8737bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org
8747bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
875470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  // We just return if recording hasn't started.
876470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (debug_file_->Open()) {
877470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if (debug_file_->CloseFile() == -1) {
878470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      return kFileError;
879470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
880470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
881470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return kNoError;
8827bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#else
8837bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  return kUnsupportedFunctionError;
8847bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#endif  // WEBRTC_AUDIOPROC_DEBUG_DUMP
885470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
886470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
887470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comEchoCancellation* AudioProcessingImpl::echo_cancellation() const {
888470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return echo_cancellation_;
889470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
890470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
891470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comEchoControlMobile* AudioProcessingImpl::echo_control_mobile() const {
892470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return echo_control_mobile_;
893470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
894470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
895470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comGainControl* AudioProcessingImpl::gain_control() const {
896788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  if (use_new_agc_) {
897788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    return gain_control_for_new_agc_.get();
898788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
899470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return gain_control_;
900470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
901470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
902470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comHighPassFilter* AudioProcessingImpl::high_pass_filter() const {
903470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return high_pass_filter_;
904470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
905470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
906470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comLevelEstimator* AudioProcessingImpl::level_estimator() const {
907470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return level_estimator_;
908470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
909470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
910470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comNoiseSuppression* AudioProcessingImpl::noise_suppression() const {
911470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return noise_suppression_;
912470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
913470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
914470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comVoiceDetection* AudioProcessingImpl::voice_detection() const {
915470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return voice_detection_;
916470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
917470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
918369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.orgbool AudioProcessingImpl::is_data_processed() const {
919ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org  if (beamformer_enabled_) {
920ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org    return true;
921ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org  }
922ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org
9237bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  int enabled_count = 0;
9247bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  std::list<ProcessingComponent*>::const_iterator it;
9257bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  for (it = component_list_.begin(); it != component_list_.end(); it++) {
9267bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org    if ((*it)->is_component_enabled()) {
9277bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org      enabled_count++;
9287bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org    }
9297bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  }
9307bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org
9317bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  // Data is unchanged if no components are enabled, or if only level_estimator_
9327bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  // or voice_detection_ is enabled.
9337bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  if (enabled_count == 0) {
9347bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org    return false;
9357bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  } else if (enabled_count == 1) {
9367bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org    if (level_estimator_->is_enabled() || voice_detection_->is_enabled()) {
9377bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org      return false;
9387bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org    }
9397bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  } else if (enabled_count == 2) {
9407bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org    if (level_estimator_->is_enabled() && voice_detection_->is_enabled()) {
9417bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org      return false;
9427bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org    }
9437bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  }
9447bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  return true;
9457bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org}
9467bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org
94717e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.orgbool AudioProcessingImpl::output_copy_needed(bool is_data_processed) const {
948369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.org  // Check if we've upmixed or downmixed the audio.
94927d106bcf7eaf864e8433f1fc303475b953498b3aluebs@webrtc.org  return ((fwd_out_format_.num_channels() != fwd_in_format_.num_channels()) ||
950788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org          is_data_processed || transient_suppressor_enabled_);
9517bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org}
9527bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org
953369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.orgbool AudioProcessingImpl::synthesis_needed(bool is_data_processed) const {
954087da13fe8be20b61b556f60eac937c9d0b19fb8aluebs@webrtc.org  return (is_data_processed && (fwd_proc_format_.rate() == kSampleRate32kHz ||
955087da13fe8be20b61b556f60eac937c9d0b19fb8aluebs@webrtc.org          fwd_proc_format_.rate() == kSampleRate48kHz));
956369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.org}
957369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.org
958369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.orgbool AudioProcessingImpl::analysis_needed(bool is_data_processed) const {
959788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  if (!is_data_processed && !voice_detection_->is_enabled() &&
960788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org      !transient_suppressor_enabled_) {
9617bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org    // Only level_estimator_ is enabled.
9627bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org    return false;
963087da13fe8be20b61b556f60eac937c9d0b19fb8aluebs@webrtc.org  } else if (fwd_proc_format_.rate() == kSampleRate32kHz ||
964087da13fe8be20b61b556f60eac937c9d0b19fb8aluebs@webrtc.org             fwd_proc_format_.rate() == kSampleRate48kHz) {
9657bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org    // Something besides level_estimator_ is enabled, and we have super-wb.
9667bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org    return true;
9677bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  }
9687bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  return false;
9697bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org}
9707bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org
971788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.orgint AudioProcessingImpl::InitializeExperimentalAgc() {
972788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  if (use_new_agc_) {
973788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    if (!agc_manager_.get()) {
974788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org      agc_manager_.reset(
975788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org          new AgcManagerDirect(gain_control_, gain_control_for_new_agc_.get()));
976788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    }
977788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    agc_manager_->Initialize();
978788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    agc_manager_->SetCaptureMuted(output_will_be_muted_);
979788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
980788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  return kNoError;
981788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org}
982788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org
983788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.orgint AudioProcessingImpl::InitializeTransient() {
984788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  if (transient_suppressor_enabled_) {
985788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    if (!transient_suppressor_.get()) {
986788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org      transient_suppressor_.reset(new TransientSuppressor());
987788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    }
988788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org    transient_suppressor_->Initialize(fwd_proc_format_.rate(),
989788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org                                      split_rate_,
990788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org                                      fwd_out_format_.num_channels());
991788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  }
992788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org  return kNoError;
993788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org}
994788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org
995ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.orgvoid AudioProcessingImpl::InitializeBeamformer() {
996ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org  if (beamformer_enabled_) {
997ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org#ifdef WEBRTC_BEAMFORMER
998ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org    // TODO(aluebs): Don't use a hard-coded microphone spacing.
999ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org    beamformer_.reset(new Beamformer(kChunkSizeMs,
1000ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org                                     split_rate_,
1001ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org                                     fwd_in_format_.num_channels(),
1002ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org                                     0.05f));
1003ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org#else
1004ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org    assert(false);
1005ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org#endif
1006ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org  }
1007ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org}
1008ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org
10097bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
1010808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.comint AudioProcessingImpl::WriteMessageToDebugFile() {
1011808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  int32_t size = event_msg_->ByteSize();
1012808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  if (size <= 0) {
1013808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    return kUnspecifiedError;
1014808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  }
1015621df678c8690f36875b0b34d45393df58662172andrew@webrtc.org#if defined(WEBRTC_ARCH_BIG_ENDIAN)
1016808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  // TODO(ajm): Use little-endian "on the wire". For the moment, we can be
1017808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  //            pretty safe in assuming little-endian.
1018808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com#endif
1019808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com
1020808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  if (!event_msg_->SerializeToString(&event_str_)) {
1021808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    return kUnspecifiedError;
1022808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  }
1023808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com
1024808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  // Write message preceded by its size.
1025808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  if (!debug_file_->Write(&size, sizeof(int32_t))) {
1026808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    return kFileError;
1027808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  }
1028808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  if (!debug_file_->Write(event_str_.data(), event_str_.length())) {
1029808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    return kFileError;
1030808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  }
1031808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com
1032808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  event_msg_->Clear();
1033808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com
103417e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org  return kNoError;
1035808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com}
1036808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com
1037808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.comint AudioProcessingImpl::WriteInitMessage() {
1038808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  event_msg_->set_type(audioproc::Event::INIT);
1039808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  audioproc::Init* msg = event_msg_->mutable_init();
1040ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  msg->set_sample_rate(fwd_in_format_.rate());
1041ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  msg->set_num_input_channels(fwd_in_format_.num_channels());
104227d106bcf7eaf864e8433f1fc303475b953498b3aluebs@webrtc.org  msg->set_num_output_channels(fwd_out_format_.num_channels());
1043ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  msg->set_num_reverse_channels(rev_in_format_.num_channels());
1044ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  msg->set_reverse_sample_rate(rev_in_format_.rate());
1045ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org  msg->set_output_sample_rate(fwd_out_format_.rate());
1046808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com
1047808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  int err = WriteMessageToDebugFile();
1048808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  if (err != kNoError) {
1049808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    return err;
1050808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  }
1051808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com
1052808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  return kNoError;
1053808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com}
10547bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#endif  // WEBRTC_AUDIOPROC_DEBUG_DUMP
1055ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org
1056470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}  // namespace webrtc
1057