audio_processing_impl.cc revision 621df678c8690f36875b0b34d45393df58662172
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
1578693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/modules/audio_processing/audio_buffer.h"
1661e596fc49443971219aa3989b200407d919f6c5andrew@webrtc.org#include "webrtc/modules/audio_processing/echo_cancellation_impl_wrapper.h"
1778693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/modules/audio_processing/echo_control_mobile_impl.h"
1878693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/modules/audio_processing/gain_control_impl.h"
1978693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/modules/audio_processing/high_pass_filter_impl.h"
2078693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/modules/audio_processing/level_estimator_impl.h"
2178693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/modules/audio_processing/noise_suppression_impl.h"
2278693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/modules/audio_processing/processing_component.h"
2378693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/modules/audio_processing/splitting_filter.h"
2478693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/modules/audio_processing/voice_detection_impl.h"
2578693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/modules/interface/module_common_types.h"
2678693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
2778693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/system_wrappers/interface/file_wrapper.h"
2878693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/system_wrappers/interface/logging.h"
297bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org
307bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
317bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org// Files generated at build-time by the protobuf compiler.
32a3736345dd8d90542792d164f269b4bf986dd4baleozwang@webrtc.org#ifdef WEBRTC_ANDROID_PLATFORM_BUILD
33534e495df0bdf2890b10c7ff65e59d96291e1981leozwang@webrtc.org#include "external/webrtc/webrtc/modules/audio_processing/debug.pb.h"
34ce9bfbb33db9ff3e65c9db23ccbfb3467cb0f732leozwang@google.com#else
35808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com#include "webrtc/audio_processing/debug.pb.h"
36ce9bfbb33db9ff3e65c9db23ccbfb3467cb0f732leozwang@google.com#endif
377bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#endif  // WEBRTC_AUDIOPROC_DEBUG_DUMP
38470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
39470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comnamespace webrtc {
40470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comAudioProcessing* AudioProcessing::Create(int id) {
41470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  AudioProcessingImpl* apm = new AudioProcessingImpl(id);
42470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (apm->Initialize() != kNoError) {
43470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    delete apm;
44470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    apm = NULL;
45470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
46470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
47470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return apm;
48470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
49470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
509162080527af5a58df6c06c4aac2209ec1989999pbos@webrtc.orgint32_t AudioProcessing::TimeUntilNextProcess() { return -1; }
519162080527af5a58df6c06c4aac2209ec1989999pbos@webrtc.orgint32_t AudioProcessing::Process() { return -1; }
529162080527af5a58df6c06c4aac2209ec1989999pbos@webrtc.org
53470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comAudioProcessingImpl::AudioProcessingImpl(int id)
54470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    : id_(id),
55470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      echo_cancellation_(NULL),
56470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      echo_control_mobile_(NULL),
57470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      gain_control_(NULL),
58470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      high_pass_filter_(NULL),
59470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      level_estimator_(NULL),
60470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      noise_suppression_(NULL),
61470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      voice_detection_(NULL),
62470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      crit_(CriticalSectionWrapper::CreateCriticalSection()),
63470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      render_audio_(NULL),
64470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      capture_audio_(NULL),
657bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
667bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org      debug_file_(FileWrapper::Create()),
677bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org      event_msg_(new audioproc::Event()),
687bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#endif
69470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      sample_rate_hz_(kSampleRate16kHz),
70470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      split_sample_rate_hz_(kSampleRate16kHz),
71470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      samples_per_channel_(sample_rate_hz_ / 100),
72470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      stream_delay_ms_(0),
736f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.org      delay_offset_ms_(0),
74470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      was_stream_delay_set_(false),
75808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com      num_reverse_channels_(1),
76808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com      num_input_channels_(1),
77808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com      num_output_channels_(1) {
7861e596fc49443971219aa3989b200407d919f6c5andrew@webrtc.org  echo_cancellation_ = EchoCancellationImplWrapper::Create(this);
79470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  component_list_.push_back(echo_cancellation_);
80470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
81470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  echo_control_mobile_ = new EchoControlMobileImpl(this);
82470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  component_list_.push_back(echo_control_mobile_);
83470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
84470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  gain_control_ = new GainControlImpl(this);
85470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  component_list_.push_back(gain_control_);
86470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
87470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  high_pass_filter_ = new HighPassFilterImpl(this);
88470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  component_list_.push_back(high_pass_filter_);
89470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
90470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  level_estimator_ = new LevelEstimatorImpl(this);
91470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  component_list_.push_back(level_estimator_);
92470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
93470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  noise_suppression_ = new NoiseSuppressionImpl(this);
94470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  component_list_.push_back(noise_suppression_);
95470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
96470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  voice_detection_ = new VoiceDetectionImpl(this);
97470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  component_list_.push_back(voice_detection_);
98470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
99470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
100470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comAudioProcessingImpl::~AudioProcessingImpl() {
1018186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org  {
1028186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org    CriticalSectionScoped crit_scoped(crit_);
1038186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org    while (!component_list_.empty()) {
1048186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org      ProcessingComponent* component = component_list_.front();
1058186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org      component->Destroy();
1068186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org      delete component;
1078186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org      component_list_.pop_front();
1088186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org    }
109470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1107bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
1118186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org    if (debug_file_->Open()) {
1128186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org      debug_file_->CloseFile();
1138186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org    }
1147bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#endif
115808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com
1168186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org    if (render_audio_) {
1178186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org      delete render_audio_;
1188186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org      render_audio_ = NULL;
1198186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org    }
120470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1218186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org    if (capture_audio_) {
1228186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org      delete capture_audio_;
1238186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org      capture_audio_ = NULL;
1248186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org    }
125470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
12616cfbe2e89d528eb09195b3959640d70efa83578andrew@webrtc.org
12716cfbe2e89d528eb09195b3959640d70efa83578andrew@webrtc.org  delete crit_;
12816cfbe2e89d528eb09195b3959640d70efa83578andrew@webrtc.org  crit_ = NULL;
129470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
130470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
131470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comCriticalSectionWrapper* AudioProcessingImpl::crit() const {
132470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return crit_;
133470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
134470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
135470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::split_sample_rate_hz() const {
136470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return split_sample_rate_hz_;
137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
138470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
139470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::Initialize() {
14040654039cde13b3338cc7084cd87d5decbc06fbaandrew@webrtc.org  CriticalSectionScoped crit_scoped(crit_);
141470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return InitializeLocked();
142470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
143470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
144470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::InitializeLocked() {
145470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (render_audio_ != NULL) {
146470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    delete render_audio_;
147470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    render_audio_ = NULL;
148470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
149470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (capture_audio_ != NULL) {
151470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    delete capture_audio_;
152470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    capture_audio_ = NULL;
153470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
155808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  render_audio_ = new AudioBuffer(num_reverse_channels_,
156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                  samples_per_channel_);
157808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  capture_audio_ = new AudioBuffer(num_input_channels_,
158470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                                   samples_per_channel_);
159470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
160470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  was_stream_delay_set_ = false;
161470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
162470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  // Initialize all components.
163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  std::list<ProcessingComponent*>::iterator it;
1648186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org  for (it = component_list_.begin(); it != component_list_.end(); ++it) {
165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    int err = (*it)->Initialize();
166470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if (err != kNoError) {
167470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      return err;
168470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
1717bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
172808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  if (debug_file_->Open()) {
173808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    int err = WriteInitMessage();
174808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    if (err != kNoError) {
175808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com      return err;
176808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    }
177808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  }
1787bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#endif
179808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com
180470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return kNoError;
181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
18361e596fc49443971219aa3989b200407d919f6c5andrew@webrtc.orgvoid AudioProcessingImpl::SetExtraOptions(const Config& config) {
18461e596fc49443971219aa3989b200407d919f6c5andrew@webrtc.org  std::list<ProcessingComponent*>::iterator it;
18561e596fc49443971219aa3989b200407d919f6c5andrew@webrtc.org  for (it = component_list_.begin(); it != component_list_.end(); ++it)
18661e596fc49443971219aa3989b200407d919f6c5andrew@webrtc.org    (*it)->SetExtraOptions(config);
18761e596fc49443971219aa3989b200407d919f6c5andrew@webrtc.org}
18861e596fc49443971219aa3989b200407d919f6c5andrew@webrtc.org
189470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::set_sample_rate_hz(int rate) {
19040654039cde13b3338cc7084cd87d5decbc06fbaandrew@webrtc.org  CriticalSectionScoped crit_scoped(crit_);
1918186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org  if (rate == sample_rate_hz_) {
1928186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org    return kNoError;
1938186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org  }
194470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (rate != kSampleRate8kHz &&
195470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      rate != kSampleRate16kHz &&
196470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      rate != kSampleRate32kHz) {
197470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return kBadParameterError;
198470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
19978693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org  if (echo_control_mobile_->is_enabled() && rate > kSampleRate16kHz) {
20078693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org    LOG(LS_ERROR) << "AECM only supports 16 kHz or lower sample rates";
20178693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org    return kUnsupportedComponentError;
20278693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org  }
203470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  sample_rate_hz_ = rate;
205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  samples_per_channel_ = rate / 100;
206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
207470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (sample_rate_hz_ == kSampleRate32kHz) {
208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    split_sample_rate_hz_ = kSampleRate16kHz;
209470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  } else {
210470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    split_sample_rate_hz_ = sample_rate_hz_;
211470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
212470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
213470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return InitializeLocked();
214470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
215470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
216470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::sample_rate_hz() const {
21719da719a5febb4baa6e5dcdef8270792f9d31d6dhenrika@webrtc.org  CriticalSectionScoped crit_scoped(crit_);
218470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return sample_rate_hz_;
219470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
220470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
221470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::set_num_reverse_channels(int channels) {
22240654039cde13b3338cc7084cd87d5decbc06fbaandrew@webrtc.org  CriticalSectionScoped crit_scoped(crit_);
2238186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org  if (channels == num_reverse_channels_) {
2248186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org    return kNoError;
2258186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org  }
226470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  // Only stereo supported currently.
227470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (channels > 2 || channels < 1) {
228470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return kBadParameterError;
229470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
230470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
231808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  num_reverse_channels_ = channels;
232470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
233470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return InitializeLocked();
234470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
235470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
236470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::num_reverse_channels() const {
237808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  return num_reverse_channels_;
238470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
239470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
240470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::set_num_channels(
241470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    int input_channels,
242470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    int output_channels) {
24340654039cde13b3338cc7084cd87d5decbc06fbaandrew@webrtc.org  CriticalSectionScoped crit_scoped(crit_);
2448186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org  if (input_channels == num_input_channels_ &&
2458186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org      output_channels == num_output_channels_) {
2468186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org    return kNoError;
2478186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org  }
248470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (output_channels > input_channels) {
249470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return kBadParameterError;
250470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
251470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  // Only stereo supported currently.
2528186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org  if (input_channels > 2 || input_channels < 1 ||
2538186534111bf74a8689f63b40dd1f40872bab14dandrew@webrtc.org      output_channels > 2 || output_channels < 1) {
254470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return kBadParameterError;
255470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
256470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
257808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  num_input_channels_ = input_channels;
258808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  num_output_channels_ = output_channels;
259470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
260470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return InitializeLocked();
261470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
262470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::num_input_channels() const {
264808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  return num_input_channels_;
265470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
266470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
267470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::num_output_channels() const {
268808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  return num_output_channels_;
269470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
270470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
271470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::ProcessStream(AudioFrame* frame) {
27240654039cde13b3338cc7084cd87d5decbc06fbaandrew@webrtc.org  CriticalSectionScoped crit_scoped(crit_);
273470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  int err = kNoError;
274470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
275470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (frame == NULL) {
276470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return kNullPointerError;
277470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
278470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
27963a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org  if (frame->sample_rate_hz_ != sample_rate_hz_) {
280470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return kBadSampleRateError;
281470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
28363a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org  if (frame->num_channels_ != num_input_channels_) {
284470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return kBadNumberChannelsError;
285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
28763a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org  if (frame->samples_per_channel_ != samples_per_channel_) {
288470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return kBadDataLengthError;
289470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
2917bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (debug_file_->Open()) {
293808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    event_msg_->set_type(audioproc::Event::STREAM);
294808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    audioproc::Stream* msg = event_msg_->mutable_stream();
295755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org    const size_t data_size = sizeof(int16_t) *
29663a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org                             frame->samples_per_channel_ *
29763a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org                             frame->num_channels_;
29863a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org    msg->set_input_data(frame->data_, data_size);
299808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    msg->set_delay(stream_delay_ms_);
300808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    msg->set_drift(echo_cancellation_->stream_drift_samples());
301808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    msg->set_level(gain_control_->stream_analog_level());
302470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
3037bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#endif
304470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
305470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  capture_audio_->DeinterleaveFrom(frame);
306470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
307470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  // TODO(ajm): experiment with mixing and AEC placement.
308808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  if (num_output_channels_ < num_input_channels_) {
309808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    capture_audio_->Mix(num_output_channels_);
31063a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org    frame->num_channels_ = num_output_channels_;
311470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
312470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
313369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.org  bool data_processed = is_data_processed();
314369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.org  if (analysis_needed(data_processed)) {
315755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org    for (int i = 0; i < num_output_channels_; i++) {
316470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      // Split into a low and high band.
317470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      SplittingFilterAnalysis(capture_audio_->data(i),
318470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                              capture_audio_->low_pass_split_data(i),
319470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                              capture_audio_->high_pass_split_data(i),
320470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                              capture_audio_->analysis_filter_state1(i),
321470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                              capture_audio_->analysis_filter_state2(i));
322470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
323470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
324470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
325470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  err = high_pass_filter_->ProcessCaptureAudio(capture_audio_);
326470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (err != kNoError) {
327470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return err;
328470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
329470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
330470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  err = gain_control_->AnalyzeCaptureAudio(capture_audio_);
331470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (err != kNoError) {
332470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return err;
333470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
334470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
335470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  err = echo_cancellation_->ProcessCaptureAudio(capture_audio_);
336470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (err != kNoError) {
337470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return err;
338470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
339470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
340470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (echo_control_mobile_->is_enabled() &&
341470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      noise_suppression_->is_enabled()) {
342470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    capture_audio_->CopyLowPassToReference();
343470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
344470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
345470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  err = noise_suppression_->ProcessCaptureAudio(capture_audio_);
346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (err != kNoError) {
347470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return err;
348470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
349470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
350470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  err = echo_control_mobile_->ProcessCaptureAudio(capture_audio_);
351470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (err != kNoError) {
352470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return err;
353470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
354470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
355470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  err = voice_detection_->ProcessCaptureAudio(capture_audio_);
356470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (err != kNoError) {
357470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return err;
358470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
359470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
360470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  err = gain_control_->ProcessCaptureAudio(capture_audio_);
361470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (err != kNoError) {
362470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return err;
363470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
364470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
365369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.org  if (synthesis_needed(data_processed)) {
366808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    for (int i = 0; i < num_output_channels_; i++) {
367470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      // Recombine low and high bands.
368470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      SplittingFilterSynthesis(capture_audio_->low_pass_split_data(i),
369470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                               capture_audio_->high_pass_split_data(i),
370470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                               capture_audio_->data(i),
371470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                               capture_audio_->synthesis_filter_state1(i),
372470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                               capture_audio_->synthesis_filter_state2(i));
373470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
374470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
375470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
376755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org  // The level estimator operates on the recombined data.
377755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org  err = level_estimator_->ProcessStream(capture_audio_);
378755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org  if (err != kNoError) {
379755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org    return err;
380755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org  }
381755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org
382369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.org  capture_audio_->InterleaveTo(frame, interleave_needed(data_processed));
383470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
3847bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
385808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  if (debug_file_->Open()) {
386808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    audioproc::Stream* msg = event_msg_->mutable_stream();
387755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org    const size_t data_size = sizeof(int16_t) *
38863a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org                             frame->samples_per_channel_ *
38963a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org                             frame->num_channels_;
39063a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org    msg->set_output_data(frame->data_, data_size);
391808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    err = WriteMessageToDebugFile();
392808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    if (err != kNoError) {
393808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com      return err;
394808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    }
395808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  }
3967bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#endif
397808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com
3981e91693fe293cdf708ea6d3c20a289fd122799bcandrew@webrtc.org  was_stream_delay_set_ = false;
399470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return kNoError;
400470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
401470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
402470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::AnalyzeReverseStream(AudioFrame* frame) {
40340654039cde13b3338cc7084cd87d5decbc06fbaandrew@webrtc.org  CriticalSectionScoped crit_scoped(crit_);
404470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  int err = kNoError;
405470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
406470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (frame == NULL) {
407470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return kNullPointerError;
408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
409470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
41063a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org  if (frame->sample_rate_hz_ != sample_rate_hz_) {
411470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return kBadSampleRateError;
412470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
413470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
41463a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org  if (frame->num_channels_ != num_reverse_channels_) {
415470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return kBadNumberChannelsError;
416470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
417470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
41863a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org  if (frame->samples_per_channel_ != samples_per_channel_) {
419470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return kBadDataLengthError;
420470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
421470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
4227bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
423470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (debug_file_->Open()) {
424808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    event_msg_->set_type(audioproc::Event::REVERSE_STREAM);
425808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    audioproc::ReverseStream* msg = event_msg_->mutable_reverse_stream();
426755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org    const size_t data_size = sizeof(int16_t) *
42763a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org                             frame->samples_per_channel_ *
42863a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org                             frame->num_channels_;
42963a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org    msg->set_data(frame->data_, data_size);
430808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    err = WriteMessageToDebugFile();
431808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    if (err != kNoError) {
432808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com      return err;
433470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
434470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
4357bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#endif
436470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
437470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  render_audio_->DeinterleaveFrom(frame);
438470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
439470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  // TODO(ajm): turn the splitting filter into a component?
440470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (sample_rate_hz_ == kSampleRate32kHz) {
441808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    for (int i = 0; i < num_reverse_channels_; i++) {
442470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      // Split into low and high band.
443470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      SplittingFilterAnalysis(render_audio_->data(i),
444470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                              render_audio_->low_pass_split_data(i),
445470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                              render_audio_->high_pass_split_data(i),
446470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                              render_audio_->analysis_filter_state1(i),
447470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com                              render_audio_->analysis_filter_state2(i));
448470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
449470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
450470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
451470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  // TODO(ajm): warnings possible from components?
452470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  err = echo_cancellation_->ProcessRenderAudio(render_audio_);
453470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (err != kNoError) {
454470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return err;
455470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
456470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
457470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  err = echo_control_mobile_->ProcessRenderAudio(render_audio_);
458470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (err != kNoError) {
459470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return err;
460470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
461470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
462470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  err = gain_control_->ProcessRenderAudio(render_audio_);
463470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (err != kNoError) {
464470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return err;
465470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
466470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
467470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return err;  // TODO(ajm): this is for returning warnings; necessary?
468470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
469470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
470470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::set_stream_delay_ms(int delay) {
4715f23d64cf2da06b45c2c1c837bb11d260cb85ecfandrew@webrtc.org  Error retval = kNoError;
472470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  was_stream_delay_set_ = true;
4736f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.org  delay += delay_offset_ms_;
4746f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.org
475470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (delay < 0) {
4765f23d64cf2da06b45c2c1c837bb11d260cb85ecfandrew@webrtc.org    delay = 0;
4775f23d64cf2da06b45c2c1c837bb11d260cb85ecfandrew@webrtc.org    retval = kBadStreamParameterWarning;
478470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
479470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
480470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  // TODO(ajm): the max is rather arbitrarily chosen; investigate.
481470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (delay > 500) {
4825f23d64cf2da06b45c2c1c837bb11d260cb85ecfandrew@webrtc.org    delay = 500;
4835f23d64cf2da06b45c2c1c837bb11d260cb85ecfandrew@webrtc.org    retval = kBadStreamParameterWarning;
484470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
485470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
486470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  stream_delay_ms_ = delay;
4875f23d64cf2da06b45c2c1c837bb11d260cb85ecfandrew@webrtc.org  return retval;
488470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
489470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
490470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::stream_delay_ms() const {
491470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return stream_delay_ms_;
492470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
493470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
494470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.combool AudioProcessingImpl::was_stream_delay_set() const {
495470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return was_stream_delay_set_;
496470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
497470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
4986f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.orgvoid AudioProcessingImpl::set_delay_offset_ms(int offset) {
4996f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.org  CriticalSectionScoped crit_scoped(crit_);
5006f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.org  delay_offset_ms_ = offset;
5016f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.org}
5026f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.org
5036f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.orgint AudioProcessingImpl::delay_offset_ms() const {
5046f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.org  return delay_offset_ms_;
5056f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.org}
5066f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.org
507470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::StartDebugRecording(
508470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    const char filename[AudioProcessing::kMaxFilenameSize]) {
50940654039cde13b3338cc7084cd87d5decbc06fbaandrew@webrtc.org  CriticalSectionScoped crit_scoped(crit_);
510470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  assert(kMaxFilenameSize == FileWrapper::kMaxFileNameSize);
511470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
512470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (filename == NULL) {
513470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return kNullPointerError;
514470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
515470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
5167bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
517470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  // Stop any ongoing recording.
518470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (debug_file_->Open()) {
519470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if (debug_file_->CloseFile() == -1) {
520470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      return kFileError;
521470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
522470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
523470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
524470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (debug_file_->OpenFile(filename, false) == -1) {
525470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    debug_file_->CloseFile();
526470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    return kFileError;
527470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
528470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
529808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  int err = WriteInitMessage();
530808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  if (err != kNoError) {
531808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    return err;
532470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
533470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return kNoError;
5347bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#else
5357bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  return kUnsupportedFunctionError;
5367bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#endif  // WEBRTC_AUDIOPROC_DEBUG_DUMP
537470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
538470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
539470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::StopDebugRecording() {
54040654039cde13b3338cc7084cd87d5decbc06fbaandrew@webrtc.org  CriticalSectionScoped crit_scoped(crit_);
5417bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org
5427bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
543470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  // We just return if recording hasn't started.
544470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  if (debug_file_->Open()) {
545470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    if (debug_file_->CloseFile() == -1) {
546470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com      return kFileError;
547470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com    }
548470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  }
549470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return kNoError;
5507bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#else
5517bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  return kUnsupportedFunctionError;
5527bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#endif  // WEBRTC_AUDIOPROC_DEBUG_DUMP
553470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
554470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
555470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comEchoCancellation* AudioProcessingImpl::echo_cancellation() const {
556470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return echo_cancellation_;
557470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
558470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
559470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comEchoControlMobile* AudioProcessingImpl::echo_control_mobile() const {
560470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return echo_control_mobile_;
561470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
562470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
563470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comGainControl* AudioProcessingImpl::gain_control() const {
564470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return gain_control_;
565470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
566470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
567470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comHighPassFilter* AudioProcessingImpl::high_pass_filter() const {
568470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return high_pass_filter_;
569470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
570470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
571470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comLevelEstimator* AudioProcessingImpl::level_estimator() const {
572470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return level_estimator_;
573470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
574470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
575470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comNoiseSuppression* AudioProcessingImpl::noise_suppression() const {
576470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return noise_suppression_;
577470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
578470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
579470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comVoiceDetection* AudioProcessingImpl::voice_detection() const {
580470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return voice_detection_;
581470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
582470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
583b7192b82476d00384fdc153e6a09a6ac53cef67bpbos@webrtc.orgint32_t AudioProcessingImpl::ChangeUniqueId(const int32_t id) {
58440654039cde13b3338cc7084cd87d5decbc06fbaandrew@webrtc.org  CriticalSectionScoped crit_scoped(crit_);
585470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  id_ = id;
586470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com
587470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com  return kNoError;
588470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}
589808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com
590369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.orgbool AudioProcessingImpl::is_data_processed() const {
5917bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  int enabled_count = 0;
5927bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  std::list<ProcessingComponent*>::const_iterator it;
5937bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  for (it = component_list_.begin(); it != component_list_.end(); it++) {
5947bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org    if ((*it)->is_component_enabled()) {
5957bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org      enabled_count++;
5967bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org    }
5977bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  }
5987bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org
5997bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  // Data is unchanged if no components are enabled, or if only level_estimator_
6007bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  // or voice_detection_ is enabled.
6017bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  if (enabled_count == 0) {
6027bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org    return false;
6037bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  } else if (enabled_count == 1) {
6047bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org    if (level_estimator_->is_enabled() || voice_detection_->is_enabled()) {
6057bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org      return false;
6067bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org    }
6077bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  } else if (enabled_count == 2) {
6087bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org    if (level_estimator_->is_enabled() && voice_detection_->is_enabled()) {
6097bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org      return false;
6107bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org    }
6117bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  }
6127bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  return true;
6137bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org}
6147bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org
615369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.orgbool AudioProcessingImpl::interleave_needed(bool is_data_processed) const {
616369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.org  // Check if we've upmixed or downmixed the audio.
617369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.org  return (num_output_channels_ != num_input_channels_ || is_data_processed);
6187bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org}
6197bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org
620369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.orgbool AudioProcessingImpl::synthesis_needed(bool is_data_processed) const {
621369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.org  return (is_data_processed && sample_rate_hz_ == kSampleRate32kHz);
622369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.org}
623369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.org
624369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.orgbool AudioProcessingImpl::analysis_needed(bool is_data_processed) const {
625369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.org  if (!is_data_processed && !voice_detection_->is_enabled()) {
6267bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org    // Only level_estimator_ is enabled.
6277bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org    return false;
6287bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  } else if (sample_rate_hz_ == kSampleRate32kHz) {
6297bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org    // Something besides level_estimator_ is enabled, and we have super-wb.
6307bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org    return true;
6317bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  }
6327bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org  return false;
6337bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org}
6347bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org
6357bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
636808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.comint AudioProcessingImpl::WriteMessageToDebugFile() {
637808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  int32_t size = event_msg_->ByteSize();
638808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  if (size <= 0) {
639808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    return kUnspecifiedError;
640808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  }
641621df678c8690f36875b0b34d45393df58662172andrew@webrtc.org#if defined(WEBRTC_ARCH_BIG_ENDIAN)
642808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  // TODO(ajm): Use little-endian "on the wire". For the moment, we can be
643808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  //            pretty safe in assuming little-endian.
644808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com#endif
645808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com
646808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  if (!event_msg_->SerializeToString(&event_str_)) {
647808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    return kUnspecifiedError;
648808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  }
649808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com
650808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  // Write message preceded by its size.
651808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  if (!debug_file_->Write(&size, sizeof(int32_t))) {
652808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    return kFileError;
653808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  }
654808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  if (!debug_file_->Write(event_str_.data(), event_str_.length())) {
655808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    return kFileError;
656808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  }
657808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com
658808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  event_msg_->Clear();
659808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com
660808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  return 0;
661808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com}
662808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com
663808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.comint AudioProcessingImpl::WriteInitMessage() {
664808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  event_msg_->set_type(audioproc::Event::INIT);
665808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  audioproc::Init* msg = event_msg_->mutable_init();
666808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  msg->set_sample_rate(sample_rate_hz_);
667808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  msg->set_device_sample_rate(echo_cancellation_->device_sample_rate_hz());
668808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  msg->set_num_input_channels(num_input_channels_);
669808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  msg->set_num_output_channels(num_output_channels_);
670808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  msg->set_num_reverse_channels(num_reverse_channels_);
671808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com
672808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  int err = WriteMessageToDebugFile();
673808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  if (err != kNoError) {
674808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com    return err;
675808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  }
676808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com
677808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com  return kNoError;
678808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com}
6797bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#endif  // WEBRTC_AUDIOPROC_DEBUG_DUMP
680470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com}  // namespace webrtc
681