1e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent/* 2e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. 3e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * 4e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * Use of this source code is governed by a BSD-style license 5e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * that can be found in the LICENSE file in the root of the source 6e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * tree. An additional intellectual property rights grant can be found 7e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * in the file PATENTS. All contributing project authors may 8e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent * be found in the AUTHORS file in the root of the source tree. 9e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent */ 10e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 11e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include "audio_processing_impl.h" 12e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 13c55a96383497a772a307b346368133960b02ad03Eric Laurent#include <assert.h> 14e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 15e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include "audio_buffer.h" 16c55a96383497a772a307b346368133960b02ad03Eric Laurent#include "critical_section_wrapper.h" 17e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include "echo_cancellation_impl.h" 18e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include "echo_control_mobile_impl.h" 19c55a96383497a772a307b346368133960b02ad03Eric Laurent#include "file_wrapper.h" 20e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include "high_pass_filter_impl.h" 21e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include "gain_control_impl.h" 22e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include "level_estimator_impl.h" 23c55a96383497a772a307b346368133960b02ad03Eric Laurent#include "module_common_types.h" 24e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include "noise_suppression_impl.h" 25e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include "processing_component.h" 26e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include "splitting_filter.h" 27e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent#include "voice_detection_impl.h" 28e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 29c55a96383497a772a307b346368133960b02ad03Eric Laurent#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 30c55a96383497a772a307b346368133960b02ad03Eric Laurent// Files generated at build-time by the protobuf compiler. 31c55a96383497a772a307b346368133960b02ad03Eric Laurent#ifdef WEBRTC_ANDROID 32c55a96383497a772a307b346368133960b02ad03Eric Laurent#include "external/webrtc/src/modules/audio_processing/debug.pb.h" 33c55a96383497a772a307b346368133960b02ad03Eric Laurent#else 34c55a96383497a772a307b346368133960b02ad03Eric Laurent#include "webrtc/audio_processing/debug.pb.h" 35c55a96383497a772a307b346368133960b02ad03Eric Laurent#endif 36c55a96383497a772a307b346368133960b02ad03Eric Laurent#endif // WEBRTC_AUDIOPROC_DEBUG_DUMP 37e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 38c55a96383497a772a307b346368133960b02ad03Eric Laurentnamespace webrtc { 39e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentAudioProcessing* AudioProcessing::Create(int id) { 40e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent /*WEBRTC_TRACE(webrtc::kTraceModuleCall, 41e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent webrtc::kTraceAudioProcessing, 42e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent id, 43e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent "AudioProcessing::Create()");*/ 44e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 45e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent AudioProcessingImpl* apm = new AudioProcessingImpl(id); 46e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (apm->Initialize() != kNoError) { 47e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent delete apm; 48e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent apm = NULL; 49e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 50e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 51e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return apm; 52e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 53e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 54e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentvoid AudioProcessing::Destroy(AudioProcessing* apm) { 55e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent delete static_cast<AudioProcessingImpl*>(apm); 56e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 57e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 58e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentAudioProcessingImpl::AudioProcessingImpl(int id) 59e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent : id_(id), 60e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent echo_cancellation_(NULL), 61e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent echo_control_mobile_(NULL), 62e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent gain_control_(NULL), 63e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent high_pass_filter_(NULL), 64e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent level_estimator_(NULL), 65e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent noise_suppression_(NULL), 66e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent voice_detection_(NULL), 67e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent crit_(CriticalSectionWrapper::CreateCriticalSection()), 68e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent render_audio_(NULL), 69e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent capture_audio_(NULL), 70c55a96383497a772a307b346368133960b02ad03Eric Laurent#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 71c55a96383497a772a307b346368133960b02ad03Eric Laurent debug_file_(FileWrapper::Create()), 72c55a96383497a772a307b346368133960b02ad03Eric Laurent event_msg_(new audioproc::Event()), 73c55a96383497a772a307b346368133960b02ad03Eric Laurent#endif 74e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent sample_rate_hz_(kSampleRate16kHz), 75e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent split_sample_rate_hz_(kSampleRate16kHz), 76e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent samples_per_channel_(sample_rate_hz_ / 100), 77e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent stream_delay_ms_(0), 78e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent was_stream_delay_set_(false), 79c55a96383497a772a307b346368133960b02ad03Eric Laurent num_reverse_channels_(1), 80c55a96383497a772a307b346368133960b02ad03Eric Laurent num_input_channels_(1), 81c55a96383497a772a307b346368133960b02ad03Eric Laurent num_output_channels_(1) { 82e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 83e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent echo_cancellation_ = new EchoCancellationImpl(this); 84e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent component_list_.push_back(echo_cancellation_); 85e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 86e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent echo_control_mobile_ = new EchoControlMobileImpl(this); 87e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent component_list_.push_back(echo_control_mobile_); 88e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 89e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent gain_control_ = new GainControlImpl(this); 90e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent component_list_.push_back(gain_control_); 91e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 92e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent high_pass_filter_ = new HighPassFilterImpl(this); 93e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent component_list_.push_back(high_pass_filter_); 94e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 95e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent level_estimator_ = new LevelEstimatorImpl(this); 96e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent component_list_.push_back(level_estimator_); 97e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 98e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent noise_suppression_ = new NoiseSuppressionImpl(this); 99e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent component_list_.push_back(noise_suppression_); 100e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 101e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent voice_detection_ = new VoiceDetectionImpl(this); 102e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent component_list_.push_back(voice_detection_); 103e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 104e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 105e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentAudioProcessingImpl::~AudioProcessingImpl() { 106e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent while (!component_list_.empty()) { 107e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent ProcessingComponent* component = component_list_.front(); 108e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent component->Destroy(); 109e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent delete component; 110e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent component_list_.pop_front(); 111e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 112e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 113c55a96383497a772a307b346368133960b02ad03Eric Laurent#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 114e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (debug_file_->Open()) { 115e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent debug_file_->CloseFile(); 116e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 117c55a96383497a772a307b346368133960b02ad03Eric Laurent#endif 118e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 119e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent delete crit_; 120e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent crit_ = NULL; 121e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 122c55a96383497a772a307b346368133960b02ad03Eric Laurent if (render_audio_) { 123e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent delete render_audio_; 124e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent render_audio_ = NULL; 125e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 126e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 127c55a96383497a772a307b346368133960b02ad03Eric Laurent if (capture_audio_) { 128e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent delete capture_audio_; 129e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent capture_audio_ = NULL; 130e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 131e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 132e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 133e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentCriticalSectionWrapper* AudioProcessingImpl::crit() const { 134e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return crit_; 135e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 136e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 137e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint AudioProcessingImpl::split_sample_rate_hz() const { 138e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return split_sample_rate_hz_; 139e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 140e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 141e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint AudioProcessingImpl::Initialize() { 142e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent CriticalSectionScoped crit_scoped(*crit_); 143e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return InitializeLocked(); 144e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 145e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 146e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint AudioProcessingImpl::InitializeLocked() { 147e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (render_audio_ != NULL) { 148e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent delete render_audio_; 149e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent render_audio_ = NULL; 150e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 151e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 152e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (capture_audio_ != NULL) { 153e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent delete capture_audio_; 154e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent capture_audio_ = NULL; 155e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 156e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 157c55a96383497a772a307b346368133960b02ad03Eric Laurent render_audio_ = new AudioBuffer(num_reverse_channels_, 158e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent samples_per_channel_); 159c55a96383497a772a307b346368133960b02ad03Eric Laurent capture_audio_ = new AudioBuffer(num_input_channels_, 160e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent samples_per_channel_); 161e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 162e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent was_stream_delay_set_ = false; 163e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 164e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Initialize all components. 165e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent std::list<ProcessingComponent*>::iterator it; 166e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (it = component_list_.begin(); it != component_list_.end(); it++) { 167e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int err = (*it)->Initialize(); 168e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (err != kNoError) { 169e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return err; 170e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 171e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 172e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 173c55a96383497a772a307b346368133960b02ad03Eric Laurent#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 174c55a96383497a772a307b346368133960b02ad03Eric Laurent if (debug_file_->Open()) { 175c55a96383497a772a307b346368133960b02ad03Eric Laurent int err = WriteInitMessage(); 176c55a96383497a772a307b346368133960b02ad03Eric Laurent if (err != kNoError) { 177c55a96383497a772a307b346368133960b02ad03Eric Laurent return err; 178c55a96383497a772a307b346368133960b02ad03Eric Laurent } 179c55a96383497a772a307b346368133960b02ad03Eric Laurent } 180c55a96383497a772a307b346368133960b02ad03Eric Laurent#endif 181c55a96383497a772a307b346368133960b02ad03Eric Laurent 182e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return kNoError; 183e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 184e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 185e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint AudioProcessingImpl::set_sample_rate_hz(int rate) { 186e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent CriticalSectionScoped crit_scoped(*crit_); 187e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (rate != kSampleRate8kHz && 188e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent rate != kSampleRate16kHz && 189e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent rate != kSampleRate32kHz) { 190e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return kBadParameterError; 191e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 192e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 193e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent sample_rate_hz_ = rate; 194e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent samples_per_channel_ = rate / 100; 195e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 196e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (sample_rate_hz_ == kSampleRate32kHz) { 197e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent split_sample_rate_hz_ = kSampleRate16kHz; 198e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } else { 199e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent split_sample_rate_hz_ = sample_rate_hz_; 200e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 201e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 202e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return InitializeLocked(); 203e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 204e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 205e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint AudioProcessingImpl::sample_rate_hz() const { 206e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return sample_rate_hz_; 207e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 208e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 209e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint AudioProcessingImpl::set_num_reverse_channels(int channels) { 210e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent CriticalSectionScoped crit_scoped(*crit_); 211e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Only stereo supported currently. 212e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (channels > 2 || channels < 1) { 213e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return kBadParameterError; 214e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 215e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 216c55a96383497a772a307b346368133960b02ad03Eric Laurent num_reverse_channels_ = channels; 217e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 218e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return InitializeLocked(); 219e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 220e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 221e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint AudioProcessingImpl::num_reverse_channels() const { 222c55a96383497a772a307b346368133960b02ad03Eric Laurent return num_reverse_channels_; 223e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 224e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 225e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint AudioProcessingImpl::set_num_channels( 226e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int input_channels, 227e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int output_channels) { 228e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent CriticalSectionScoped crit_scoped(*crit_); 229e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (output_channels > input_channels) { 230e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return kBadParameterError; 231e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 232e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 233e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Only stereo supported currently. 234e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (input_channels > 2 || input_channels < 1) { 235e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return kBadParameterError; 236e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 237e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 238e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (output_channels > 2 || output_channels < 1) { 239e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return kBadParameterError; 240e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 241e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 242c55a96383497a772a307b346368133960b02ad03Eric Laurent num_input_channels_ = input_channels; 243c55a96383497a772a307b346368133960b02ad03Eric Laurent num_output_channels_ = output_channels; 244e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 245e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return InitializeLocked(); 246e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 247e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 248e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint AudioProcessingImpl::num_input_channels() const { 249c55a96383497a772a307b346368133960b02ad03Eric Laurent return num_input_channels_; 250e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 251e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 252e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint AudioProcessingImpl::num_output_channels() const { 253c55a96383497a772a307b346368133960b02ad03Eric Laurent return num_output_channels_; 254e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 255e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 256e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint AudioProcessingImpl::ProcessStream(AudioFrame* frame) { 257e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent CriticalSectionScoped crit_scoped(*crit_); 258e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int err = kNoError; 259e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 260e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (frame == NULL) { 261e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return kNullPointerError; 262e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 263e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 264c55a96383497a772a307b346368133960b02ad03Eric Laurent if (frame->_frequencyInHz != sample_rate_hz_) { 265e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return kBadSampleRateError; 266e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 267e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 268c55a96383497a772a307b346368133960b02ad03Eric Laurent if (frame->_audioChannel != num_input_channels_) { 269e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return kBadNumberChannelsError; 270e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 271e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 272e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (frame->_payloadDataLengthInSamples != samples_per_channel_) { 273e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return kBadDataLengthError; 274e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 275e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 276c55a96383497a772a307b346368133960b02ad03Eric Laurent#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 277e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (debug_file_->Open()) { 278c55a96383497a772a307b346368133960b02ad03Eric Laurent event_msg_->set_type(audioproc::Event::STREAM); 279c55a96383497a772a307b346368133960b02ad03Eric Laurent audioproc::Stream* msg = event_msg_->mutable_stream(); 280c55a96383497a772a307b346368133960b02ad03Eric Laurent const size_t data_size = sizeof(int16_t) * 281c55a96383497a772a307b346368133960b02ad03Eric Laurent frame->_payloadDataLengthInSamples * 282c55a96383497a772a307b346368133960b02ad03Eric Laurent frame->_audioChannel; 283c55a96383497a772a307b346368133960b02ad03Eric Laurent msg->set_input_data(frame->_payloadData, data_size); 284c55a96383497a772a307b346368133960b02ad03Eric Laurent msg->set_delay(stream_delay_ms_); 285c55a96383497a772a307b346368133960b02ad03Eric Laurent msg->set_drift(echo_cancellation_->stream_drift_samples()); 286c55a96383497a772a307b346368133960b02ad03Eric Laurent msg->set_level(gain_control_->stream_analog_level()); 287c55a96383497a772a307b346368133960b02ad03Eric Laurent } 288c55a96383497a772a307b346368133960b02ad03Eric Laurent#endif 289e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 290e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent capture_audio_->DeinterleaveFrom(frame); 291e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 292e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // TODO(ajm): experiment with mixing and AEC placement. 293c55a96383497a772a307b346368133960b02ad03Eric Laurent if (num_output_channels_ < num_input_channels_) { 294c55a96383497a772a307b346368133960b02ad03Eric Laurent capture_audio_->Mix(num_output_channels_); 295c55a96383497a772a307b346368133960b02ad03Eric Laurent frame->_audioChannel = num_output_channels_; 296e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 297e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 298c55a96383497a772a307b346368133960b02ad03Eric Laurent bool data_changed = stream_data_changed(); 299c55a96383497a772a307b346368133960b02ad03Eric Laurent if (analysis_needed(data_changed)) { 300c55a96383497a772a307b346368133960b02ad03Eric Laurent for (int i = 0; i < num_output_channels_; i++) { 301e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Split into a low and high band. 302e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent SplittingFilterAnalysis(capture_audio_->data(i), 303e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent capture_audio_->low_pass_split_data(i), 304e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent capture_audio_->high_pass_split_data(i), 305e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent capture_audio_->analysis_filter_state1(i), 306e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent capture_audio_->analysis_filter_state2(i)); 307e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 308e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 309e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 310e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent err = high_pass_filter_->ProcessCaptureAudio(capture_audio_); 311e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (err != kNoError) { 312e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return err; 313e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 314e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 315e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent err = gain_control_->AnalyzeCaptureAudio(capture_audio_); 316e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (err != kNoError) { 317e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return err; 318e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 319e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 320e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent err = echo_cancellation_->ProcessCaptureAudio(capture_audio_); 321e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (err != kNoError) { 322e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return err; 323e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 324e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 325e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (echo_control_mobile_->is_enabled() && 326e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent noise_suppression_->is_enabled()) { 327e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent capture_audio_->CopyLowPassToReference(); 328e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 329e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 330e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent err = noise_suppression_->ProcessCaptureAudio(capture_audio_); 331e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (err != kNoError) { 332e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return err; 333e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 334e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 335e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent err = echo_control_mobile_->ProcessCaptureAudio(capture_audio_); 336e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (err != kNoError) { 337e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return err; 338e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 339e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 340e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent err = voice_detection_->ProcessCaptureAudio(capture_audio_); 341e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (err != kNoError) { 342e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return err; 343e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 344e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 345e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent err = gain_control_->ProcessCaptureAudio(capture_audio_); 346e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (err != kNoError) { 347e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return err; 348e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 349e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 350c55a96383497a772a307b346368133960b02ad03Eric Laurent if (synthesis_needed(data_changed)) { 351c55a96383497a772a307b346368133960b02ad03Eric Laurent for (int i = 0; i < num_output_channels_; i++) { 352e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Recombine low and high bands. 353e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent SplittingFilterSynthesis(capture_audio_->low_pass_split_data(i), 354e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent capture_audio_->high_pass_split_data(i), 355e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent capture_audio_->data(i), 356e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent capture_audio_->synthesis_filter_state1(i), 357e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent capture_audio_->synthesis_filter_state2(i)); 358e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 359e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 360e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 361c55a96383497a772a307b346368133960b02ad03Eric Laurent // The level estimator operates on the recombined data. 362c55a96383497a772a307b346368133960b02ad03Eric Laurent err = level_estimator_->ProcessStream(capture_audio_); 363c55a96383497a772a307b346368133960b02ad03Eric Laurent if (err != kNoError) { 364c55a96383497a772a307b346368133960b02ad03Eric Laurent return err; 365c55a96383497a772a307b346368133960b02ad03Eric Laurent } 366c55a96383497a772a307b346368133960b02ad03Eric Laurent 367c55a96383497a772a307b346368133960b02ad03Eric Laurent capture_audio_->InterleaveTo(frame, data_changed); 368c55a96383497a772a307b346368133960b02ad03Eric Laurent 369c55a96383497a772a307b346368133960b02ad03Eric Laurent#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 370c55a96383497a772a307b346368133960b02ad03Eric Laurent if (debug_file_->Open()) { 371c55a96383497a772a307b346368133960b02ad03Eric Laurent audioproc::Stream* msg = event_msg_->mutable_stream(); 372c55a96383497a772a307b346368133960b02ad03Eric Laurent const size_t data_size = sizeof(int16_t) * 373c55a96383497a772a307b346368133960b02ad03Eric Laurent frame->_payloadDataLengthInSamples * 374c55a96383497a772a307b346368133960b02ad03Eric Laurent frame->_audioChannel; 375c55a96383497a772a307b346368133960b02ad03Eric Laurent msg->set_output_data(frame->_payloadData, data_size); 376c55a96383497a772a307b346368133960b02ad03Eric Laurent err = WriteMessageToDebugFile(); 377c55a96383497a772a307b346368133960b02ad03Eric Laurent if (err != kNoError) { 378c55a96383497a772a307b346368133960b02ad03Eric Laurent return err; 379c55a96383497a772a307b346368133960b02ad03Eric Laurent } 380c55a96383497a772a307b346368133960b02ad03Eric Laurent } 381c55a96383497a772a307b346368133960b02ad03Eric Laurent#endif 382e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 383c55a96383497a772a307b346368133960b02ad03Eric Laurent was_stream_delay_set_ = false; 384e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return kNoError; 385e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 386e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 387e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint AudioProcessingImpl::AnalyzeReverseStream(AudioFrame* frame) { 388e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent CriticalSectionScoped crit_scoped(*crit_); 389e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent int err = kNoError; 390e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 391e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (frame == NULL) { 392e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return kNullPointerError; 393e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 394e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 395c55a96383497a772a307b346368133960b02ad03Eric Laurent if (frame->_frequencyInHz != sample_rate_hz_) { 396e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return kBadSampleRateError; 397e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 398e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 399c55a96383497a772a307b346368133960b02ad03Eric Laurent if (frame->_audioChannel != num_reverse_channels_) { 400e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return kBadNumberChannelsError; 401e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 402e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 403e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (frame->_payloadDataLengthInSamples != samples_per_channel_) { 404e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return kBadDataLengthError; 405e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 406e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 407c55a96383497a772a307b346368133960b02ad03Eric Laurent#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 408e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (debug_file_->Open()) { 409c55a96383497a772a307b346368133960b02ad03Eric Laurent event_msg_->set_type(audioproc::Event::REVERSE_STREAM); 410c55a96383497a772a307b346368133960b02ad03Eric Laurent audioproc::ReverseStream* msg = event_msg_->mutable_reverse_stream(); 411c55a96383497a772a307b346368133960b02ad03Eric Laurent const size_t data_size = sizeof(int16_t) * 412c55a96383497a772a307b346368133960b02ad03Eric Laurent frame->_payloadDataLengthInSamples * 413c55a96383497a772a307b346368133960b02ad03Eric Laurent frame->_audioChannel; 414c55a96383497a772a307b346368133960b02ad03Eric Laurent msg->set_data(frame->_payloadData, data_size); 415c55a96383497a772a307b346368133960b02ad03Eric Laurent err = WriteMessageToDebugFile(); 416c55a96383497a772a307b346368133960b02ad03Eric Laurent if (err != kNoError) { 417c55a96383497a772a307b346368133960b02ad03Eric Laurent return err; 418e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 419e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 420c55a96383497a772a307b346368133960b02ad03Eric Laurent#endif 421e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 422e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent render_audio_->DeinterleaveFrom(frame); 423e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 424e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // TODO(ajm): turn the splitting filter into a component? 425e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (sample_rate_hz_ == kSampleRate32kHz) { 426c55a96383497a772a307b346368133960b02ad03Eric Laurent for (int i = 0; i < num_reverse_channels_; i++) { 427e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Split into low and high band. 428e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent SplittingFilterAnalysis(render_audio_->data(i), 429e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent render_audio_->low_pass_split_data(i), 430e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent render_audio_->high_pass_split_data(i), 431e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent render_audio_->analysis_filter_state1(i), 432e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent render_audio_->analysis_filter_state2(i)); 433e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 434e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 435e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 436e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // TODO(ajm): warnings possible from components? 437e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent err = echo_cancellation_->ProcessRenderAudio(render_audio_); 438e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (err != kNoError) { 439e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return err; 440e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 441e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 442e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent err = echo_control_mobile_->ProcessRenderAudio(render_audio_); 443e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (err != kNoError) { 444e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return err; 445e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 446e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 447e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent err = gain_control_->ProcessRenderAudio(render_audio_); 448e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (err != kNoError) { 449e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return err; 450e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 451e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 452e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return err; // TODO(ajm): this is for returning warnings; necessary? 453e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 454e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 455e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint AudioProcessingImpl::set_stream_delay_ms(int delay) { 456e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent was_stream_delay_set_ = true; 457e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (delay < 0) { 458e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return kBadParameterError; 459e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 460e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 461e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // TODO(ajm): the max is rather arbitrarily chosen; investigate. 462e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (delay > 500) { 463e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent stream_delay_ms_ = 500; 464e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return kBadStreamParameterWarning; 465e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 466e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 467e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent stream_delay_ms_ = delay; 468e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return kNoError; 469e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 470e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 471e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint AudioProcessingImpl::stream_delay_ms() const { 472e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return stream_delay_ms_; 473e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 474e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 475e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentbool AudioProcessingImpl::was_stream_delay_set() const { 476e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return was_stream_delay_set_; 477e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 478e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 479e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint AudioProcessingImpl::StartDebugRecording( 480e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent const char filename[AudioProcessing::kMaxFilenameSize]) { 481e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent CriticalSectionScoped crit_scoped(*crit_); 482e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent assert(kMaxFilenameSize == FileWrapper::kMaxFileNameSize); 483e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 484e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (filename == NULL) { 485e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return kNullPointerError; 486e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 487e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 488c55a96383497a772a307b346368133960b02ad03Eric Laurent#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 489e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // Stop any ongoing recording. 490e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (debug_file_->Open()) { 491e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (debug_file_->CloseFile() == -1) { 492e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return kFileError; 493e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 494e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 495e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 496e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (debug_file_->OpenFile(filename, false) == -1) { 497e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent debug_file_->CloseFile(); 498e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return kFileError; 499e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 500e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 501c55a96383497a772a307b346368133960b02ad03Eric Laurent int err = WriteInitMessage(); 502c55a96383497a772a307b346368133960b02ad03Eric Laurent if (err != kNoError) { 503c55a96383497a772a307b346368133960b02ad03Eric Laurent return err; 504e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 505e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return kNoError; 506c55a96383497a772a307b346368133960b02ad03Eric Laurent#else 507c55a96383497a772a307b346368133960b02ad03Eric Laurent return kUnsupportedFunctionError; 508c55a96383497a772a307b346368133960b02ad03Eric Laurent#endif // WEBRTC_AUDIOPROC_DEBUG_DUMP 509e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 510e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 511e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurentint AudioProcessingImpl::StopDebugRecording() { 512e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent CriticalSectionScoped crit_scoped(*crit_); 513c55a96383497a772a307b346368133960b02ad03Eric Laurent 514c55a96383497a772a307b346368133960b02ad03Eric Laurent#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 515e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent // We just return if recording hasn't started. 516e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (debug_file_->Open()) { 517e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent if (debug_file_->CloseFile() == -1) { 518e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return kFileError; 519e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 520e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 521e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return kNoError; 522c55a96383497a772a307b346368133960b02ad03Eric Laurent#else 523c55a96383497a772a307b346368133960b02ad03Eric Laurent return kUnsupportedFunctionError; 524c55a96383497a772a307b346368133960b02ad03Eric Laurent#endif // WEBRTC_AUDIOPROC_DEBUG_DUMP 525e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 526e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 527e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentEchoCancellation* AudioProcessingImpl::echo_cancellation() const { 528e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return echo_cancellation_; 529e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 530e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 531e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentEchoControlMobile* AudioProcessingImpl::echo_control_mobile() const { 532e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return echo_control_mobile_; 533e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 534e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 535e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentGainControl* AudioProcessingImpl::gain_control() const { 536e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return gain_control_; 537e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 538e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 539e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentHighPassFilter* AudioProcessingImpl::high_pass_filter() const { 540e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return high_pass_filter_; 541e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 542e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 543e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentLevelEstimator* AudioProcessingImpl::level_estimator() const { 544e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return level_estimator_; 545e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 546e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 547e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentNoiseSuppression* AudioProcessingImpl::noise_suppression() const { 548e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return noise_suppression_; 549e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 550e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 551e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric LaurentVoiceDetection* AudioProcessingImpl::voice_detection() const { 552e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return voice_detection_; 553e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 554e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 555c55a96383497a772a307b346368133960b02ad03Eric LaurentWebRtc_Word32 AudioProcessingImpl::ChangeUniqueId(const WebRtc_Word32 id) { 556c55a96383497a772a307b346368133960b02ad03Eric Laurent CriticalSectionScoped crit_scoped(*crit_); 557c55a96383497a772a307b346368133960b02ad03Eric Laurent /*WEBRTC_TRACE(webrtc::kTraceModuleCall, 558c55a96383497a772a307b346368133960b02ad03Eric Laurent webrtc::kTraceAudioProcessing, 559c55a96383497a772a307b346368133960b02ad03Eric Laurent id_, 560c55a96383497a772a307b346368133960b02ad03Eric Laurent "ChangeUniqueId(new id = %d)", 561c55a96383497a772a307b346368133960b02ad03Eric Laurent id);*/ 562c55a96383497a772a307b346368133960b02ad03Eric Laurent id_ = id; 563e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 564c55a96383497a772a307b346368133960b02ad03Eric Laurent return kNoError; 565c55a96383497a772a307b346368133960b02ad03Eric Laurent} 566e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 567c55a96383497a772a307b346368133960b02ad03Eric Laurentbool AudioProcessingImpl::stream_data_changed() const { 568c55a96383497a772a307b346368133960b02ad03Eric Laurent int enabled_count = 0; 569e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent std::list<ProcessingComponent*>::const_iterator it; 570e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent for (it = component_list_.begin(); it != component_list_.end(); it++) { 571c55a96383497a772a307b346368133960b02ad03Eric Laurent if ((*it)->is_component_enabled()) { 572c55a96383497a772a307b346368133960b02ad03Eric Laurent enabled_count++; 573e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 574c55a96383497a772a307b346368133960b02ad03Eric Laurent } 575e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 576c55a96383497a772a307b346368133960b02ad03Eric Laurent // Data is unchanged if no components are enabled, or if only level_estimator_ 577c55a96383497a772a307b346368133960b02ad03Eric Laurent // or voice_detection_ is enabled. 578c55a96383497a772a307b346368133960b02ad03Eric Laurent if (enabled_count == 0) { 579c55a96383497a772a307b346368133960b02ad03Eric Laurent return false; 580c55a96383497a772a307b346368133960b02ad03Eric Laurent } else if (enabled_count == 1) { 581c55a96383497a772a307b346368133960b02ad03Eric Laurent if (level_estimator_->is_enabled() || voice_detection_->is_enabled()) { 582c55a96383497a772a307b346368133960b02ad03Eric Laurent return false; 583c55a96383497a772a307b346368133960b02ad03Eric Laurent } 584c55a96383497a772a307b346368133960b02ad03Eric Laurent } else if (enabled_count == 2) { 585c55a96383497a772a307b346368133960b02ad03Eric Laurent if (level_estimator_->is_enabled() && voice_detection_->is_enabled()) { 586c55a96383497a772a307b346368133960b02ad03Eric Laurent return false; 587e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 588e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent } 589c55a96383497a772a307b346368133960b02ad03Eric Laurent return true; 590c55a96383497a772a307b346368133960b02ad03Eric Laurent} 591e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 592c55a96383497a772a307b346368133960b02ad03Eric Laurentbool AudioProcessingImpl::synthesis_needed(bool stream_data_changed) const { 593c55a96383497a772a307b346368133960b02ad03Eric Laurent return (stream_data_changed && sample_rate_hz_ == kSampleRate32kHz); 594e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 595e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 596c55a96383497a772a307b346368133960b02ad03Eric Laurentbool AudioProcessingImpl::analysis_needed(bool stream_data_changed) const { 597c55a96383497a772a307b346368133960b02ad03Eric Laurent if (!stream_data_changed && !voice_detection_->is_enabled()) { 598c55a96383497a772a307b346368133960b02ad03Eric Laurent // Only level_estimator_ is enabled. 599c55a96383497a772a307b346368133960b02ad03Eric Laurent return false; 600c55a96383497a772a307b346368133960b02ad03Eric Laurent } else if (sample_rate_hz_ == kSampleRate32kHz) { 601c55a96383497a772a307b346368133960b02ad03Eric Laurent // Something besides level_estimator_ is enabled, and we have super-wb. 602c55a96383497a772a307b346368133960b02ad03Eric Laurent return true; 603c55a96383497a772a307b346368133960b02ad03Eric Laurent } 604c55a96383497a772a307b346368133960b02ad03Eric Laurent return false; 605c55a96383497a772a307b346368133960b02ad03Eric Laurent} 606c55a96383497a772a307b346368133960b02ad03Eric Laurent 607c55a96383497a772a307b346368133960b02ad03Eric Laurent#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 608c55a96383497a772a307b346368133960b02ad03Eric Laurentint AudioProcessingImpl::WriteMessageToDebugFile() { 609c55a96383497a772a307b346368133960b02ad03Eric Laurent int32_t size = event_msg_->ByteSize(); 610c55a96383497a772a307b346368133960b02ad03Eric Laurent if (size <= 0) { 611c55a96383497a772a307b346368133960b02ad03Eric Laurent return kUnspecifiedError; 612c55a96383497a772a307b346368133960b02ad03Eric Laurent } 613c55a96383497a772a307b346368133960b02ad03Eric Laurent#if defined(WEBRTC_BIG_ENDIAN) 614c55a96383497a772a307b346368133960b02ad03Eric Laurent // TODO(ajm): Use little-endian "on the wire". For the moment, we can be 615c55a96383497a772a307b346368133960b02ad03Eric Laurent // pretty safe in assuming little-endian. 616c55a96383497a772a307b346368133960b02ad03Eric Laurent#endif 617c55a96383497a772a307b346368133960b02ad03Eric Laurent 618c55a96383497a772a307b346368133960b02ad03Eric Laurent if (!event_msg_->SerializeToString(&event_str_)) { 619c55a96383497a772a307b346368133960b02ad03Eric Laurent return kUnspecifiedError; 620c55a96383497a772a307b346368133960b02ad03Eric Laurent } 621c55a96383497a772a307b346368133960b02ad03Eric Laurent 622c55a96383497a772a307b346368133960b02ad03Eric Laurent // Write message preceded by its size. 623c55a96383497a772a307b346368133960b02ad03Eric Laurent if (!debug_file_->Write(&size, sizeof(int32_t))) { 624c55a96383497a772a307b346368133960b02ad03Eric Laurent return kFileError; 625c55a96383497a772a307b346368133960b02ad03Eric Laurent } 626c55a96383497a772a307b346368133960b02ad03Eric Laurent if (!debug_file_->Write(event_str_.data(), event_str_.length())) { 627c55a96383497a772a307b346368133960b02ad03Eric Laurent return kFileError; 628c55a96383497a772a307b346368133960b02ad03Eric Laurent } 629c55a96383497a772a307b346368133960b02ad03Eric Laurent 630c55a96383497a772a307b346368133960b02ad03Eric Laurent event_msg_->Clear(); 631c55a96383497a772a307b346368133960b02ad03Eric Laurent 632c55a96383497a772a307b346368133960b02ad03Eric Laurent return 0; 633c55a96383497a772a307b346368133960b02ad03Eric Laurent} 634c55a96383497a772a307b346368133960b02ad03Eric Laurent 635c55a96383497a772a307b346368133960b02ad03Eric Laurentint AudioProcessingImpl::WriteInitMessage() { 636c55a96383497a772a307b346368133960b02ad03Eric Laurent event_msg_->set_type(audioproc::Event::INIT); 637c55a96383497a772a307b346368133960b02ad03Eric Laurent audioproc::Init* msg = event_msg_->mutable_init(); 638c55a96383497a772a307b346368133960b02ad03Eric Laurent msg->set_sample_rate(sample_rate_hz_); 639c55a96383497a772a307b346368133960b02ad03Eric Laurent msg->set_device_sample_rate(echo_cancellation_->device_sample_rate_hz()); 640c55a96383497a772a307b346368133960b02ad03Eric Laurent msg->set_num_input_channels(num_input_channels_); 641c55a96383497a772a307b346368133960b02ad03Eric Laurent msg->set_num_output_channels(num_output_channels_); 642c55a96383497a772a307b346368133960b02ad03Eric Laurent msg->set_num_reverse_channels(num_reverse_channels_); 643c55a96383497a772a307b346368133960b02ad03Eric Laurent 644c55a96383497a772a307b346368133960b02ad03Eric Laurent int err = WriteMessageToDebugFile(); 645c55a96383497a772a307b346368133960b02ad03Eric Laurent if (err != kNoError) { 646c55a96383497a772a307b346368133960b02ad03Eric Laurent return err; 647c55a96383497a772a307b346368133960b02ad03Eric Laurent } 648e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent 649e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent return kNoError; 650e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} 651c55a96383497a772a307b346368133960b02ad03Eric Laurent#endif // WEBRTC_AUDIOPROC_DEBUG_DUMP 652e48d5845c8b35de2ab73ea055c18a61fa3a9f0beEric Laurent} // namespace webrtc 653