audio_processing_impl.cc revision 6955870806624479723addfae6dcf5d13968796c
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> 1486c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk#include <algorithm> 15470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 161ca324f23770e17d19433ccd3a3b021870d709caBjorn Volcker#include "webrtc/base/checks.h" 17e46bc77e941f12ca24b04cf42fca98e15bc139eexians@webrtc.org#include "webrtc/base/platform_file.h" 18369f828bfe9f42e9d1d712e8493fbbd7e776b9c3peah#include "webrtc/base/trace_event.h" 1960d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson#include "webrtc/common_audio/audio_converter.h" 20dfa36058c945cf2ef9932a566987f648c24fa632Michael Graczyk#include "webrtc/common_audio/channel_buffer.h" 2160d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson#include "webrtc/common_audio/include/audio_util.h" 2260730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" 231ca324f23770e17d19433ccd3a3b021870d709caBjorn Volckerextern "C" { 241ca324f23770e17d19433ccd3a3b021870d709caBjorn Volcker#include "webrtc/modules/audio_processing/aec/aec_core.h" 251ca324f23770e17d19433ccd3a3b021870d709caBjorn Volcker} 26788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org#include "webrtc/modules/audio_processing/agc/agc_manager_direct.h" 2778693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/modules/audio_processing/audio_buffer.h" 280f663de2ec25731d538a3a7d9b4d2c21ae61af8dmgraczyk@chromium.org#include "webrtc/modules/audio_processing/beamformer/nonlinear_beamformer.h" 29ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org#include "webrtc/modules/audio_processing/common.h" 3056e4a05053d6addc7dbbe2b4d07271305fdbea75andrew@webrtc.org#include "webrtc/modules/audio_processing/echo_cancellation_impl.h" 3178693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/modules/audio_processing/echo_control_mobile_impl.h" 3278693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/modules/audio_processing/gain_control_impl.h" 3378693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/modules/audio_processing/high_pass_filter_impl.h" 3460d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson#include "webrtc/modules/audio_processing/intelligibility/intelligibility_enhancer.h" 3578693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/modules/audio_processing/level_estimator_impl.h" 3678693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/modules/audio_processing/noise_suppression_impl.h" 3778693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/modules/audio_processing/processing_component.h" 38ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org#include "webrtc/modules/audio_processing/transient/transient_suppressor.h" 3978693fe37ce4b77bb4e93f848768a4ef2b0ab2d8andrew@webrtc.org#include "webrtc/modules/audio_processing/voice_detection_impl.h" 40ff761fba8274d93bd73e76c8b8a1f2d0776dd840Henrik Kjellander#include "webrtc/modules/include/module_common_types.h" 4198f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/file_wrapper.h" 4298f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/logging.h" 4398f53510b222f71fdd8b799b2f33737ceeb28c61Henrik Kjellander#include "webrtc/system_wrappers/include/metrics.h" 447bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org 457bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 467bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org// Files generated at build-time by the protobuf compiler. 47a3736345dd8d90542792d164f269b4bf986dd4baleozwang@webrtc.org#ifdef WEBRTC_ANDROID_PLATFORM_BUILD 48534e495df0bdf2890b10c7ff65e59d96291e1981leozwang@webrtc.org#include "external/webrtc/webrtc/modules/audio_processing/debug.pb.h" 49ce9bfbb33db9ff3e65c9db23ccbfb3467cb0f732leozwang@google.com#else 50808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com#include "webrtc/audio_processing/debug.pb.h" 51ce9bfbb33db9ff3e65c9db23ccbfb3467cb0f732leozwang@google.com#endif 527bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#endif // WEBRTC_AUDIOPROC_DEBUG_DUMP 53470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5486c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk#define RETURN_ON_ERR(expr) \ 5586c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk do { \ 5686c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk int err = (expr); \ 5786c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk if (err != kNoError) { \ 5886c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk return err; \ 5986c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk } \ 6060730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org } while (0) 6160730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org 62470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comnamespace webrtc { 6386c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyknamespace { 6486c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk 6586c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczykstatic bool LayoutHasKeyboard(AudioProcessing::ChannelLayout layout) { 6686c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk switch (layout) { 6786c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk case AudioProcessing::kMono: 6886c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk case AudioProcessing::kStereo: 6986c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk return false; 7086c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk case AudioProcessing::kMonoAndKeyboard: 7186c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk case AudioProcessing::kStereoAndKeyboard: 7286c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk return true; 7386c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk } 7486c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk 7586c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk assert(false); 7686c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk return false; 7786c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk} 7886c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk} // namespace 7960730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org 8060730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org// Throughout webrtc, it's assumed that success is represented by zero. 812ebfac5649a5e48fbbc501b42a4336ff979c03e6kwiberg@webrtc.orgstatic_assert(AudioProcessing::kNoError == 0, "kNoError must be zero"); 8260730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org 83788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org// This class has two main functionalities: 84788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org// 85788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org// 1) It is returned instead of the real GainControl after the new AGC has been 86788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org// enabled in order to prevent an outside user from overriding compression 87788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org// settings. It doesn't do anything in its implementation, except for 88788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org// delegating the const methods and Enable calls to the real GainControl, so 89788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org// AGC can still be disabled. 90788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org// 91788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org// 2) It is injected into AgcManagerDirect and implements volume callbacks for 92788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org// getting and setting the volume level. It just caches this value to be used 93788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org// in VoiceEngine later. 94788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.orgclass GainControlForNewAgc : public GainControl, public VolumeCallbacks { 95788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org public: 96788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org explicit GainControlForNewAgc(GainControlImpl* gain_control) 9786c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk : real_gain_control_(gain_control), volume_(0) {} 98788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org 99788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org // GainControl implementation. 10014665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org int Enable(bool enable) override { 101788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org return real_gain_control_->Enable(enable); 102788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org } 10314665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org bool is_enabled() const override { return real_gain_control_->is_enabled(); } 10414665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org int set_stream_analog_level(int level) override { 105788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org volume_ = level; 106788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org return AudioProcessing::kNoError; 107788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org } 10814665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org int stream_analog_level() override { return volume_; } 10914665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org int set_mode(Mode mode) override { return AudioProcessing::kNoError; } 11014665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org Mode mode() const override { return GainControl::kAdaptiveAnalog; } 11114665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org int set_target_level_dbfs(int level) override { 112788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org return AudioProcessing::kNoError; 113788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org } 11414665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org int target_level_dbfs() const override { 115788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org return real_gain_control_->target_level_dbfs(); 116788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org } 11714665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org int set_compression_gain_db(int gain) override { 118788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org return AudioProcessing::kNoError; 119788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org } 12014665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org int compression_gain_db() const override { 121788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org return real_gain_control_->compression_gain_db(); 122788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org } 12314665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org int enable_limiter(bool enable) override { return AudioProcessing::kNoError; } 12414665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org bool is_limiter_enabled() const override { 125788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org return real_gain_control_->is_limiter_enabled(); 126788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org } 12714665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org int set_analog_level_limits(int minimum, int maximum) override { 128788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org return AudioProcessing::kNoError; 129788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org } 13014665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org int analog_level_minimum() const override { 131788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org return real_gain_control_->analog_level_minimum(); 132788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org } 13314665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org int analog_level_maximum() const override { 134788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org return real_gain_control_->analog_level_maximum(); 135788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org } 13614665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org bool stream_is_saturated() const override { 137788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org return real_gain_control_->stream_is_saturated(); 138788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org } 139788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org 140788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org // VolumeCallbacks implementation. 14114665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org void SetMicVolume(int volume) override { volume_ = volume; } 14214665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org int GetMicVolume() override { return volume_; } 143788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org 144788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org private: 145788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org GainControl* real_gain_control_; 146788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org int volume_; 147788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org}; 148788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org 1495e465c33cac54ed5265f18413f7afc44aae2dfcasolenbergstruct AudioProcessingImpl::ApmPublicSubmodules { 1505e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg ApmPublicSubmodules() 1515e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg : echo_cancellation(nullptr), 1525e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg echo_control_mobile(nullptr), 153a29386c26d515be9fbeaeca3e0bc6019f29142c2solenberg gain_control(nullptr) {} 1545e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg // Accessed externally of APM without any lock acquired. 1555e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg EchoCancellationImpl* echo_cancellation; 1565e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg EchoControlMobileImpl* echo_control_mobile; 1575e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg GainControlImpl* gain_control; 1585e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg rtc::scoped_ptr<HighPassFilterImpl> high_pass_filter; 159949028fbf1e9a01fb96b186b95606c0096e7d13fsolenberg rtc::scoped_ptr<LevelEstimatorImpl> level_estimator; 1605e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg rtc::scoped_ptr<NoiseSuppressionImpl> noise_suppression; 161a29386c26d515be9fbeaeca3e0bc6019f29142c2solenberg rtc::scoped_ptr<VoiceDetectionImpl> voice_detection; 1625e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg rtc::scoped_ptr<GainControlForNewAgc> gain_control_for_new_agc; 1635e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg 1645e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg // Accessed internally from both render and capture. 1655e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg rtc::scoped_ptr<TransientSuppressor> transient_suppressor; 1665e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg rtc::scoped_ptr<IntelligibilityEnhancer> intelligibility_enhancer; 1675e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg}; 1685e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg 1695e465c33cac54ed5265f18413f7afc44aae2dfcasolenbergstruct AudioProcessingImpl::ApmPrivateSubmodules { 1705e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg explicit ApmPrivateSubmodules(Beamformer<float>* beamformer) 1715e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg : beamformer(beamformer) {} 1725e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg // Accessed internally from capture or during initialization 1735e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg std::list<ProcessingComponent*> component_list; 1745e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg rtc::scoped_ptr<Beamformer<float>> beamformer; 1755e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg rtc::scoped_ptr<AgcManagerDirect> agc_manager; 1765e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg}; 1775e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg 178cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebsconst int AudioProcessing::kNativeSampleRatesHz[] = { 179cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs AudioProcessing::kSampleRate8kHz, 180cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs AudioProcessing::kSampleRate16kHz, 181cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs AudioProcessing::kSampleRate32kHz, 182cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs AudioProcessing::kSampleRate48kHz}; 183cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebsconst size_t AudioProcessing::kNumNativeSampleRates = 184cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs arraysize(AudioProcessing::kNativeSampleRatesHz); 185cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebsconst int AudioProcessing::kMaxNativeSampleRateHz = AudioProcessing:: 186cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs kNativeSampleRatesHz[AudioProcessing::kNumNativeSampleRates - 1]; 187cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebsconst int AudioProcessing::kMaxAECMSampleRateHz = kSampleRate16kHz; 188cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs 189e84978f3d8612e7e482791552b94e0847967d3baandrew@webrtc.orgAudioProcessing* AudioProcessing::Create() { 190e84978f3d8612e7e482791552b94e0847967d3baandrew@webrtc.org Config config; 191d82f55d2a73da925d4160e3d1430f79f76170992aluebs@webrtc.org return Create(config, nullptr); 192e84978f3d8612e7e482791552b94e0847967d3baandrew@webrtc.org} 193e84978f3d8612e7e482791552b94e0847967d3baandrew@webrtc.org 194e84978f3d8612e7e482791552b94e0847967d3baandrew@webrtc.orgAudioProcessing* AudioProcessing::Create(const Config& config) { 195d82f55d2a73da925d4160e3d1430f79f76170992aluebs@webrtc.org return Create(config, nullptr); 196d82f55d2a73da925d4160e3d1430f79f76170992aluebs@webrtc.org} 197d82f55d2a73da925d4160e3d1430f79f76170992aluebs@webrtc.org 198d82f55d2a73da925d4160e3d1430f79f76170992aluebs@webrtc.orgAudioProcessing* AudioProcessing::Create(const Config& config, 199dfa36058c945cf2ef9932a566987f648c24fa632Michael Graczyk Beamformer<float>* beamformer) { 200d82f55d2a73da925d4160e3d1430f79f76170992aluebs@webrtc.org AudioProcessingImpl* apm = new AudioProcessingImpl(config, beamformer); 201470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (apm->Initialize() != kNoError) { 202470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com delete apm; 203df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah apm = nullptr; 204470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 205470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 206470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return apm; 207470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 208470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 209e84978f3d8612e7e482791552b94e0847967d3baandrew@webrtc.orgAudioProcessingImpl::AudioProcessingImpl(const Config& config) 210d82f55d2a73da925d4160e3d1430f79f76170992aluebs@webrtc.org : AudioProcessingImpl(config, nullptr) {} 211d82f55d2a73da925d4160e3d1430f79f76170992aluebs@webrtc.org 212d82f55d2a73da925d4160e3d1430f79f76170992aluebs@webrtc.orgAudioProcessingImpl::AudioProcessingImpl(const Config& config, 213dfa36058c945cf2ef9932a566987f648c24fa632Michael Graczyk Beamformer<float>* beamformer) 214df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah : public_submodules_(new ApmPublicSubmodules()), 215df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah private_submodules_(new ApmPrivateSubmodules(beamformer)), 216df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah constants_(config.Get<ExperimentalAgc>().startup_min_volume, 217788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) 218df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah false, 219788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org#else 220df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah config.Get<ExperimentalAgc>().enabled, 221788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org#endif 2222a34688f86517bfd3745e131e4e5d2b7a924f46aaluebs config.Get<Intelligibility>().enabled), 223df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah 2241c7075f076987f31c280060b855b6a31312895a6andrew#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) 2252a34688f86517bfd3745e131e4e5d2b7a924f46aaluebs capture_(false, 2261c7075f076987f31c280060b855b6a31312895a6andrew#else 2272a34688f86517bfd3745e131e4e5d2b7a924f46aaluebs capture_(config.Get<ExperimentalNs>().enabled, 2281c7075f076987f31c280060b855b6a31312895a6andrew#endif 2292a34688f86517bfd3745e131e4e5d2b7a924f46aaluebs config.Get<Beamforming>().array_geometry, 230b2328d11dcc86fba1661ee3fa0d51fc126939764aluebs config.Get<Beamforming>().target_direction), 231b2328d11dcc86fba1661ee3fa0d51fc126939764aluebs capture_nonlocked_(config.Get<Beamforming>().enabled) 232df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah{ 233df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah { 234df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs_render(&crit_render_); 235df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs_capture(&crit_capture_); 236df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah 237df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->echo_cancellation = 238df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah new EchoCancellationImpl(this, &crit_render_, &crit_capture_); 239df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->echo_control_mobile = 240df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah new EchoControlMobileImpl(this, &crit_render_, &crit_capture_); 241df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->gain_control = 242df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah new GainControlImpl(this, &crit_capture_, &crit_capture_); 24370f9903e570931831a027ba6f91c164efc604a85solenberg public_submodules_->high_pass_filter.reset( 24470f9903e570931831a027ba6f91c164efc604a85solenberg new HighPassFilterImpl(&crit_capture_)); 245949028fbf1e9a01fb96b186b95606c0096e7d13fsolenberg public_submodules_->level_estimator.reset( 246949028fbf1e9a01fb96b186b95606c0096e7d13fsolenberg new LevelEstimatorImpl(&crit_capture_)); 2475e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg public_submodules_->noise_suppression.reset( 2485e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg new NoiseSuppressionImpl(&crit_capture_)); 249a29386c26d515be9fbeaeca3e0bc6019f29142c2solenberg public_submodules_->voice_detection.reset( 250a29386c26d515be9fbeaeca3e0bc6019f29142c2solenberg new VoiceDetectionImpl(&crit_capture_)); 251df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->gain_control_for_new_agc.reset( 252df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah new GainControlForNewAgc(public_submodules_->gain_control)); 253df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah 254df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah private_submodules_->component_list.push_back( 255df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->echo_cancellation); 256df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah private_submodules_->component_list.push_back( 257df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->echo_control_mobile); 258df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah private_submodules_->component_list.push_back( 259df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->gain_control); 260df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah } 261788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org 262e84978f3d8612e7e482791552b94e0847967d3baandrew@webrtc.org SetExtraOptions(config); 263470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 264470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 265470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comAudioProcessingImpl::~AudioProcessingImpl() { 266df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Depends on gain_control_ and 267df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // public_submodules_->gain_control_for_new_agc. 268df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah private_submodules_->agc_manager.reset(); 269df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Depends on gain_control_. 270df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->gain_control_for_new_agc.reset(); 271df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah while (!private_submodules_->component_list.empty()) { 272df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah ProcessingComponent* component = 273df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah private_submodules_->component_list.front(); 274df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah component->Destroy(); 275df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah delete component; 276df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah private_submodules_->component_list.pop_front(); 277df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah } 278470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 2797bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 280df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (debug_dump_.debug_file->Open()) { 281df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah debug_dump_.debug_file->CloseFile(); 282470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 283df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah#endif 284470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 285470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 286470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::Initialize() { 287df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Run in a single-threaded manner during initialization. 288df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs_render(&crit_render_); 289df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs_capture(&crit_capture_); 290470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return InitializeLocked(); 291470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 292470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 293ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.orgint AudioProcessingImpl::Initialize(int input_sample_rate_hz, 294ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org int output_sample_rate_hz, 295a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org int reverse_sample_rate_hz, 296ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org ChannelLayout input_layout, 297ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org ChannelLayout output_layout, 298ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org ChannelLayout reverse_layout) { 29986c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk const ProcessingConfig processing_config = { 30060d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson {{input_sample_rate_hz, 30160d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson ChannelsFromLayout(input_layout), 30286c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk LayoutHasKeyboard(input_layout)}, 30360d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson {output_sample_rate_hz, 30460d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson ChannelsFromLayout(output_layout), 30586c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk LayoutHasKeyboard(output_layout)}, 30660d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson {reverse_sample_rate_hz, 30760d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson ChannelsFromLayout(reverse_layout), 30860d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson LayoutHasKeyboard(reverse_layout)}, 30960d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson {reverse_sample_rate_hz, 31060d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson ChannelsFromLayout(reverse_layout), 31186c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk LayoutHasKeyboard(reverse_layout)}}}; 31286c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk 31386c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk return Initialize(processing_config); 31486c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk} 31586c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk 31686c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczykint AudioProcessingImpl::Initialize(const ProcessingConfig& processing_config) { 317df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Run in a single-threaded manner during initialization. 318df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs_render(&crit_render_); 319df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs_capture(&crit_capture_); 32086c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk return InitializeLocked(processing_config); 321a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org} 322a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org 323df3efa8c079294857a8b8e0a02634d06a6d6b6d6peahint AudioProcessingImpl::MaybeInitializeRender( 32481b9bfe6856bb4f9fd0ba79899f72b8385c58979peah const ProcessingConfig& processing_config) { 325df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah return MaybeInitialize(processing_config); 32681b9bfe6856bb4f9fd0ba79899f72b8385c58979peah} 32781b9bfe6856bb4f9fd0ba79899f72b8385c58979peah 328df3efa8c079294857a8b8e0a02634d06a6d6b6d6peahint AudioProcessingImpl::MaybeInitializeCapture( 32981b9bfe6856bb4f9fd0ba79899f72b8385c58979peah const ProcessingConfig& processing_config) { 330df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah return MaybeInitialize(processing_config); 33181b9bfe6856bb4f9fd0ba79899f72b8385c58979peah} 33281b9bfe6856bb4f9fd0ba79899f72b8385c58979peah 333192164eebc9bbb5c5745f19330b203174304e269peah// Calls InitializeLocked() if any of the audio parameters have changed from 334df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah// their current values (needs to be called while holding the crit_render_lock). 335df3efa8c079294857a8b8e0a02634d06a6d6b6d6peahint AudioProcessingImpl::MaybeInitialize( 336192164eebc9bbb5c5745f19330b203174304e269peah const ProcessingConfig& processing_config) { 337df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Called from both threads. Thread check is therefore not possible. 338df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (processing_config == formats_.api_format) { 339192164eebc9bbb5c5745f19330b203174304e269peah return kNoError; 340192164eebc9bbb5c5745f19330b203174304e269peah } 341df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah 342df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs_capture(&crit_capture_); 343192164eebc9bbb5c5745f19330b203174304e269peah return InitializeLocked(processing_config); 344192164eebc9bbb5c5745f19330b203174304e269peah} 345192164eebc9bbb5c5745f19330b203174304e269peah 346470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::InitializeLocked() { 34786c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk const int fwd_audio_buffer_channels = 348b2328d11dcc86fba1661ee3fa0d51fc126939764aluebs capture_nonlocked_.beamformer_enabled 349df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah ? formats_.api_format.input_stream().num_channels() 350df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah : formats_.api_format.output_stream().num_channels(); 35160d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson const int rev_audio_buffer_out_num_frames = 352df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah formats_.api_format.reverse_output_stream().num_frames() == 0 353df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah ? formats_.rev_proc_format.num_frames() 354df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah : formats_.api_format.reverse_output_stream().num_frames(); 355df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (formats_.api_format.reverse_input_stream().num_channels() > 0) { 356df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah render_.render_audio.reset(new AudioBuffer( 357df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah formats_.api_format.reverse_input_stream().num_frames(), 358df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah formats_.api_format.reverse_input_stream().num_channels(), 359df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah formats_.rev_proc_format.num_frames(), 360df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah formats_.rev_proc_format.num_channels(), 36160d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson rev_audio_buffer_out_num_frames)); 36260d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson if (rev_conversion_needed()) { 363df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah render_.render_converter = AudioConverter::Create( 364df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah formats_.api_format.reverse_input_stream().num_channels(), 365df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah formats_.api_format.reverse_input_stream().num_frames(), 366df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah formats_.api_format.reverse_output_stream().num_channels(), 367df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah formats_.api_format.reverse_output_stream().num_frames()); 36860d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson } else { 369df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah render_.render_converter.reset(nullptr); 37060d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson } 37186c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk } else { 372df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah render_.render_audio.reset(nullptr); 373df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah render_.render_converter.reset(nullptr); 37486c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk } 375df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.capture_audio.reset( 376df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah new AudioBuffer(formats_.api_format.input_stream().num_frames(), 377df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah formats_.api_format.input_stream().num_channels(), 378df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_nonlocked_.fwd_proc_format.num_frames(), 379df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah fwd_audio_buffer_channels, 380df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah formats_.api_format.output_stream().num_frames())); 381470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 382470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Initialize all components. 383df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah for (auto item : private_submodules_->component_list) { 384e534086492e92c45d74b176f3c8be4addb69713fmgraczyk@chromium.org int err = item->Initialize(); 385470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (err != kNoError) { 386470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return err; 387470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 388470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 389470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 390adc46c4cf7dd8a015b0757c99787d80525c123abBjorn Volcker InitializeExperimentalAgc(); 391adc46c4cf7dd8a015b0757c99787d80525c123abBjorn Volcker InitializeTransient(); 392ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org InitializeBeamformer(); 39360d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson InitializeIntelligibility(); 39470f9903e570931831a027ba6f91c164efc604a85solenberg InitializeHighPassFilter(); 3955e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg InitializeNoiseSuppression(); 396949028fbf1e9a01fb96b186b95606c0096e7d13fsolenberg InitializeLevelEstimator(); 397a29386c26d515be9fbeaeca3e0bc6019f29142c2solenberg InitializeVoiceDetection(); 39870f9903e570931831a027ba6f91c164efc604a85solenberg 3997bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 400df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (debug_dump_.debug_file->Open()) { 401808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com int err = WriteInitMessage(); 402808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com if (err != kNoError) { 403808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com return err; 404808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com } 405808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com } 4067bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#endif 407808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com 408470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return kNoError; 409470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 410470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 41186c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczykint AudioProcessingImpl::InitializeLocked(const ProcessingConfig& config) { 41286c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk for (const auto& stream : config.streams) { 41386c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk if (stream.num_channels() > 0 && stream.sample_rate_hz() <= 0) { 41486c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk return kBadSampleRateError; 41586c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk } 41664e753c3998a17429418180b3a947231a9fd98cdmagjed } 41786c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk 4186955870806624479723addfae6dcf5d13968796cPeter Kasting const size_t num_in_channels = config.input_stream().num_channels(); 4196955870806624479723addfae6dcf5d13968796cPeter Kasting const size_t num_out_channels = config.output_stream().num_channels(); 42086c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk 42186c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk // Need at least one input channel. 42286c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk // Need either one output channel or as many outputs as there are inputs. 42386c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk if (num_in_channels == 0 || 42486c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk !(num_out_channels == 1 || num_out_channels == num_in_channels)) { 425a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org return kBadNumberChannelsError; 426a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org } 42786c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk 428b2328d11dcc86fba1661ee3fa0d51fc126939764aluebs if (capture_nonlocked_.beamformer_enabled && 4296955870806624479723addfae6dcf5d13968796cPeter Kasting num_in_channels != capture_.array_geometry.size()) { 430d82f55d2a73da925d4160e3d1430f79f76170992aluebs@webrtc.org return kBadNumberChannelsError; 431d82f55d2a73da925d4160e3d1430f79f76170992aluebs@webrtc.org } 432ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org 433df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah formats_.api_format = config; 434ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org 435ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org // We process at the closest native rate >= min(input rate, output rate)... 43686c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk const int min_proc_rate = 437df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah std::min(formats_.api_format.input_stream().sample_rate_hz(), 438df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah formats_.api_format.output_stream().sample_rate_hz()); 439ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org int fwd_proc_rate; 440cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs for (size_t i = 0; i < kNumNativeSampleRates; ++i) { 441cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs fwd_proc_rate = kNativeSampleRatesHz[i]; 442cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs if (fwd_proc_rate >= min_proc_rate) { 443cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs break; 444cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs } 445ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org } 446ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org // ...with one exception. 447df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (public_submodules_->echo_control_mobile->is_enabled() && 448cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs min_proc_rate > kMaxAECMSampleRateHz) { 449cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs fwd_proc_rate = kMaxAECMSampleRateHz; 450ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org } 451ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org 452df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_nonlocked_.fwd_proc_format = StreamConfig(fwd_proc_rate); 453ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org 454ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org // We normally process the reverse stream at 16 kHz. Unless... 455ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org int rev_proc_rate = kSampleRate16kHz; 456df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (capture_nonlocked_.fwd_proc_format.sample_rate_hz() == kSampleRate8kHz) { 457ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org // ...the forward stream is at 8 kHz. 458ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org rev_proc_rate = kSampleRate8kHz; 459ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org } else { 460df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (formats_.api_format.reverse_input_stream().sample_rate_hz() == 46160d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson kSampleRate32kHz) { 462ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org // ...or the input is at 32 kHz, in which case we use the splitting 463ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org // filter rather than the resampler. 464ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org rev_proc_rate = kSampleRate32kHz; 465ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org } 466a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org } 467a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org 46830be827e6a2bfae76c445e62d0853f83d238814aandrew@webrtc.org // Always downmix the reverse stream to mono for analysis. This has been 46930be827e6a2bfae76c445e62d0853f83d238814aandrew@webrtc.org // demonstrated to work well for AEC in most practical scenarios. 470df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah formats_.rev_proc_format = StreamConfig(rev_proc_rate, 1); 471a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org 472df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (capture_nonlocked_.fwd_proc_format.sample_rate_hz() == kSampleRate32kHz || 473df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_nonlocked_.fwd_proc_format.sample_rate_hz() == kSampleRate48kHz) { 474df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_nonlocked_.split_rate = kSampleRate16kHz; 475a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org } else { 476df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_nonlocked_.split_rate = 477df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_nonlocked_.fwd_proc_format.sample_rate_hz(); 478a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org } 479a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org 480a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org return InitializeLocked(); 481a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org} 482a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org 48361e596fc49443971219aa3989b200407d919f6c5andrew@webrtc.orgvoid AudioProcessingImpl::SetExtraOptions(const Config& config) { 484df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Run in a single-threaded manner when setting the extra options. 485df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs_render(&crit_render_); 486df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs_capture(&crit_capture_); 487df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah for (auto item : private_submodules_->component_list) { 488e534086492e92c45d74b176f3c8be4addb69713fmgraczyk@chromium.org item->SetExtraOptions(config); 489e534086492e92c45d74b176f3c8be4addb69713fmgraczyk@chromium.org } 490788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org 491df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (capture_.transient_suppressor_enabled != 492df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah config.Get<ExperimentalNs>().enabled) { 493df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.transient_suppressor_enabled = 494df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah config.Get<ExperimentalNs>().enabled; 495788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org InitializeTransient(); 496788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org } 4972a34688f86517bfd3745e131e4e5d2b7a924f46aaluebs 4982a34688f86517bfd3745e131e4e5d2b7a924f46aaluebs#ifdef WEBRTC_ANDROID_PLATFORM_BUILD 499b2328d11dcc86fba1661ee3fa0d51fc126939764aluebs if (capture_nonlocked_.beamformer_enabled != 500b2328d11dcc86fba1661ee3fa0d51fc126939764aluebs config.Get<Beamforming>().enabled) { 501b2328d11dcc86fba1661ee3fa0d51fc126939764aluebs capture_nonlocked_.beamformer_enabled = config.Get<Beamforming>().enabled; 5022a34688f86517bfd3745e131e4e5d2b7a924f46aaluebs if (config.Get<Beamforming>().array_geometry.size() > 1) { 5032a34688f86517bfd3745e131e4e5d2b7a924f46aaluebs capture_.array_geometry = config.Get<Beamforming>().array_geometry; 5042a34688f86517bfd3745e131e4e5d2b7a924f46aaluebs } 5052a34688f86517bfd3745e131e4e5d2b7a924f46aaluebs capture_.target_direction = config.Get<Beamforming>().target_direction; 5062a34688f86517bfd3745e131e4e5d2b7a924f46aaluebs InitializeBeamformer(); 5072a34688f86517bfd3745e131e4e5d2b7a924f46aaluebs } 5082a34688f86517bfd3745e131e4e5d2b7a924f46aaluebs#endif // WEBRTC_ANDROID_PLATFORM_BUILD 50961e596fc49443971219aa3989b200407d919f6c5andrew@webrtc.org} 51061e596fc49443971219aa3989b200407d919f6c5andrew@webrtc.org 51166085beef83c790a69666b9be8a74bb2eee44fabpeahint AudioProcessingImpl::input_sample_rate_hz() const { 51266085beef83c790a69666b9be8a74bb2eee44fabpeah // Accessed from outside APM, hence a lock is needed. 51366085beef83c790a69666b9be8a74bb2eee44fabpeah rtc::CritScope cs(&crit_capture_); 51466085beef83c790a69666b9be8a74bb2eee44fabpeah return formats_.api_format.input_stream().sample_rate_hz(); 51566085beef83c790a69666b9be8a74bb2eee44fabpeah} 51666085beef83c790a69666b9be8a74bb2eee44fabpeah 517ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.orgint AudioProcessingImpl::proc_sample_rate_hz() const { 518df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Used as callback from submodules, hence locking is not allowed. 519df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah return capture_nonlocked_.fwd_proc_format.sample_rate_hz(); 520470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 521470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 522ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.orgint AudioProcessingImpl::proc_split_sample_rate_hz() const { 523df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Used as callback from submodules, hence locking is not allowed. 524df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah return capture_nonlocked_.split_rate; 525470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 526470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5276955870806624479723addfae6dcf5d13968796cPeter Kastingsize_t AudioProcessingImpl::num_reverse_channels() const { 528df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Used as callback from submodules, hence locking is not allowed. 529df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah return formats_.rev_proc_format.num_channels(); 530470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 531470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5326955870806624479723addfae6dcf5d13968796cPeter Kastingsize_t AudioProcessingImpl::num_input_channels() const { 533df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Used as callback from submodules, hence locking is not allowed. 534df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah return formats_.api_format.input_stream().num_channels(); 535470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 536470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 5376955870806624479723addfae6dcf5d13968796cPeter Kastingsize_t AudioProcessingImpl::num_proc_channels() const { 538b2328d11dcc86fba1661ee3fa0d51fc126939764aluebs // Used as callback from submodules, hence locking is not allowed. 539b2328d11dcc86fba1661ee3fa0d51fc126939764aluebs return capture_nonlocked_.beamformer_enabled ? 1 : num_output_channels(); 540b2328d11dcc86fba1661ee3fa0d51fc126939764aluebs} 541b2328d11dcc86fba1661ee3fa0d51fc126939764aluebs 5426955870806624479723addfae6dcf5d13968796cPeter Kastingsize_t AudioProcessingImpl::num_output_channels() const { 543df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Used as callback from submodules, hence locking is not allowed. 544df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah return formats_.api_format.output_stream().num_channels(); 545470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 546470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 54717342e5092430c3893246077aee3b727298df117andrew@webrtc.orgvoid AudioProcessingImpl::set_output_will_be_muted(bool muted) { 548df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs(&crit_capture_); 549df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.output_will_be_muted = muted; 550df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (private_submodules_->agc_manager.get()) { 551df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah private_submodules_->agc_manager->SetCaptureMuted( 552df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.output_will_be_muted); 553788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org } 55417342e5092430c3893246077aee3b727298df117andrew@webrtc.org} 55517342e5092430c3893246077aee3b727298df117andrew@webrtc.org 55617342e5092430c3893246077aee3b727298df117andrew@webrtc.org 557ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.orgint AudioProcessingImpl::ProcessStream(const float* const* src, 558dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t samples_per_channel, 559ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org int input_sample_rate_hz, 56017e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org ChannelLayout input_layout, 561ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org int output_sample_rate_hz, 562ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org ChannelLayout output_layout, 563ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org float* const* dest) { 564369f828bfe9f42e9d1d712e8493fbbd7e776b9c3peah TRACE_EVENT0("webrtc", "AudioProcessing::ProcessStream_ChannelLayout"); 565df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah StreamConfig input_stream; 566df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah StreamConfig output_stream; 567df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah { 568df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Access the formats_.api_format.input_stream beneath the capture lock. 569df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // The lock must be released as it is later required in the call 570df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // to ProcessStream(,,,); 571df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs(&crit_capture_); 572df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah input_stream = formats_.api_format.input_stream(); 573df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah output_stream = formats_.api_format.output_stream(); 574df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah } 575df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah 57686c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk input_stream.set_sample_rate_hz(input_sample_rate_hz); 57786c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk input_stream.set_num_channels(ChannelsFromLayout(input_layout)); 57886c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk input_stream.set_has_keyboard(LayoutHasKeyboard(input_layout)); 57986c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk output_stream.set_sample_rate_hz(output_sample_rate_hz); 58086c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk output_stream.set_num_channels(ChannelsFromLayout(output_layout)); 58186c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk output_stream.set_has_keyboard(LayoutHasKeyboard(output_layout)); 58286c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk 58386c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk if (samples_per_channel != input_stream.num_frames()) { 58486c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk return kBadDataLengthError; 58586c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk } 58686c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk return ProcessStream(src, input_stream, output_stream, dest); 58786c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk} 58886c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk 58986c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczykint AudioProcessingImpl::ProcessStream(const float* const* src, 59086c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk const StreamConfig& input_config, 59186c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk const StreamConfig& output_config, 59286c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk float* const* dest) { 593369f828bfe9f42e9d1d712e8493fbbd7e776b9c3peah TRACE_EVENT0("webrtc", "AudioProcessing::ProcessStream_StreamConfig"); 594df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah ProcessingConfig processing_config; 595df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah { 596df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Acquire the capture lock in order to safely call the function 597df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // that retrieves the render side data. This function accesses apm 598df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // getters that need the capture lock held when being called. 599df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs_capture(&crit_capture_); 600df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->echo_cancellation->ReadQueuedRenderData(); 601df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->echo_control_mobile->ReadQueuedRenderData(); 602df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->gain_control->ReadQueuedRenderData(); 603df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah 604df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (!src || !dest) { 605df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah return kNullPointerError; 606df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah } 60760730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org 608df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah processing_config = formats_.api_format; 609df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah } 610fa6228e221d818af55e3d8343c792f2c1ecc7252peah 61186c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk processing_config.input_stream() = input_config; 61286c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk processing_config.output_stream() = output_config; 61386c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk 614df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah { 615df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Do conditional reinitialization. 616df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs_render(&crit_render_); 617df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah RETURN_ON_ERR(MaybeInitializeCapture(processing_config)); 618df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah } 619df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs_capture(&crit_capture_); 62086c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk assert(processing_config.input_stream().num_frames() == 621df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah formats_.api_format.input_stream().num_frames()); 62217e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org 62317e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 624df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (debug_dump_.debug_file->Open()) { 62513b96ba90f72164134019cbfc07d4a47cf1fd091Minyue RETURN_ON_ERR(WriteConfigMessage(false)); 62613b96ba90f72164134019cbfc07d4a47cf1fd091Minyue 627df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah debug_dump_.capture.event_msg->set_type(audioproc::Event::STREAM); 628df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah audioproc::Stream* msg = debug_dump_.capture.event_msg->mutable_stream(); 62959a1b1b92850747a0e758b9668f725ed9e961a33aluebs@webrtc.org const size_t channel_size = 630df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah sizeof(float) * formats_.api_format.input_stream().num_frames(); 6316955870806624479723addfae6dcf5d13968796cPeter Kasting for (size_t i = 0; i < formats_.api_format.input_stream().num_channels(); 6326955870806624479723addfae6dcf5d13968796cPeter Kasting ++i) 633ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org msg->add_input_channel(src[i], channel_size); 63417e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org } 63517e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org#endif 63617e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org 637df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.capture_audio->CopyFrom(src, formats_.api_format.input_stream()); 63817e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org RETURN_ON_ERR(ProcessStreamLocked()); 639df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.capture_audio->CopyTo(formats_.api_format.output_stream(), dest); 64017e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org 64117e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 642df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (debug_dump_.debug_file->Open()) { 643df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah audioproc::Stream* msg = debug_dump_.capture.event_msg->mutable_stream(); 64459a1b1b92850747a0e758b9668f725ed9e961a33aluebs@webrtc.org const size_t channel_size = 645df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah sizeof(float) * formats_.api_format.output_stream().num_frames(); 6466955870806624479723addfae6dcf5d13968796cPeter Kasting for (size_t i = 0; i < formats_.api_format.output_stream().num_channels(); 6476955870806624479723addfae6dcf5d13968796cPeter Kasting ++i) 648ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org msg->add_output_channel(dest[i], channel_size); 649df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah RETURN_ON_ERR(WriteMessageToDebugFile(debug_dump_.debug_file.get(), 650df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah &crit_debug_, &debug_dump_.capture)); 65117e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org } 65217e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org#endif 65317e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org 65417e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org return kNoError; 65517e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org} 65617e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org 65717e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.orgint AudioProcessingImpl::ProcessStream(AudioFrame* frame) { 658369f828bfe9f42e9d1d712e8493fbbd7e776b9c3peah TRACE_EVENT0("webrtc", "AudioProcessing::ProcessStream_AudioFrame"); 659df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah { 660df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Acquire the capture lock in order to safely call the function 661df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // that retrieves the render side data. This function accesses apm 662df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // getters that need the capture lock held when being called. 663df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // The lock needs to be released as 664df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // public_submodules_->echo_control_mobile->is_enabled() aquires this lock 665df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // as well. 666df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs_capture(&crit_capture_); 667df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->echo_cancellation->ReadQueuedRenderData(); 668df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->echo_control_mobile->ReadQueuedRenderData(); 669df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->gain_control->ReadQueuedRenderData(); 670df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah } 671fa6228e221d818af55e3d8343c792f2c1ecc7252peah 67217e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org if (!frame) { 67360730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org return kNullPointerError; 67460730cfe3ce80e4023cd678373456cb703f000a4andrew@webrtc.org } 675ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org // Must be a native rate. 676ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org if (frame->sample_rate_hz_ != kSampleRate8kHz && 677ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org frame->sample_rate_hz_ != kSampleRate16kHz && 678087da13fe8be20b61b556f60eac937c9d0b19fb8aluebs@webrtc.org frame->sample_rate_hz_ != kSampleRate32kHz && 679087da13fe8be20b61b556f60eac937c9d0b19fb8aluebs@webrtc.org frame->sample_rate_hz_ != kSampleRate48kHz) { 680ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org return kBadSampleRateError; 681ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org } 682192164eebc9bbb5c5745f19330b203174304e269peah 683df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (public_submodules_->echo_control_mobile->is_enabled() && 684cdfe20bfc1146030aa59eb37635fd2fbcecd6cdbAlejandro Luebs frame->sample_rate_hz_ > kMaxAECMSampleRateHz) { 685ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org LOG(LS_ERROR) << "AECM only supports 16 or 8 kHz sample rates"; 686ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org return kUnsupportedComponentError; 687ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org } 68817e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org 689df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah ProcessingConfig processing_config; 690df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah { 691df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Aquire lock for the access of api_format. 692df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // The lock is released immediately due to the conditional 693df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // reinitialization. 694df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs_capture(&crit_capture_); 695df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // TODO(ajm): The input and output rates and channels are currently 696df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // constrained to be identical in the int16 interface. 697df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah processing_config = formats_.api_format; 698df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah } 69986c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk processing_config.input_stream().set_sample_rate_hz(frame->sample_rate_hz_); 70086c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk processing_config.input_stream().set_num_channels(frame->num_channels_); 70186c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk processing_config.output_stream().set_sample_rate_hz(frame->sample_rate_hz_); 70286c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk processing_config.output_stream().set_num_channels(frame->num_channels_); 70386c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk 704df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah { 705df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Do conditional reinitialization. 706df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs_render(&crit_render_); 707df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah RETURN_ON_ERR(MaybeInitializeCapture(processing_config)); 708df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah } 709df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs_capture(&crit_capture_); 710192164eebc9bbb5c5745f19330b203174304e269peah if (frame->samples_per_channel_ != 711df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah formats_.api_format.input_stream().num_frames()) { 712470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return kBadDataLengthError; 713470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 714470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 7157bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 716df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (debug_dump_.debug_file->Open()) { 717df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah debug_dump_.capture.event_msg->set_type(audioproc::Event::STREAM); 718df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah audioproc::Stream* msg = debug_dump_.capture.event_msg->mutable_stream(); 71986c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk const size_t data_size = 72086c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk sizeof(int16_t) * frame->samples_per_channel_ * frame->num_channels_; 72163a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org msg->set_input_data(frame->data_, data_size); 722470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 7237bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#endif 724470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 725df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.capture_audio->DeinterleaveFrom(frame); 72617e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org RETURN_ON_ERR(ProcessStreamLocked()); 727df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.capture_audio->InterleaveTo(frame, 728df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah output_copy_needed(is_data_processed())); 72917e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org 73017e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 731df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (debug_dump_.debug_file->Open()) { 732df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah audioproc::Stream* msg = debug_dump_.capture.event_msg->mutable_stream(); 73386c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk const size_t data_size = 73486c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk sizeof(int16_t) * frame->samples_per_channel_ * frame->num_channels_; 73517e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org msg->set_output_data(frame->data_, data_size); 736df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah RETURN_ON_ERR(WriteMessageToDebugFile(debug_dump_.debug_file.get(), 737df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah &crit_debug_, &debug_dump_.capture)); 73817e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org } 73917e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org#endif 74017e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org 74117e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org return kNoError; 74217e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org} 74317e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org 74417e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.orgint AudioProcessingImpl::ProcessStreamLocked() { 74517e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 746df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (debug_dump_.debug_file->Open()) { 747df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah audioproc::Stream* msg = debug_dump_.capture.event_msg->mutable_stream(); 748df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah msg->set_delay(capture_nonlocked_.stream_delay_ms); 749df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah msg->set_drift( 750df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->echo_cancellation->stream_drift_samples()); 75163da1dd9720533990842f1e0aa94bf8269c86ae4bjornv@webrtc.org msg->set_level(gain_control()->stream_analog_level()); 752df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah msg->set_keypress(capture_.key_pressed); 75317e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org } 75417e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org#endif 755470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 7561ca324f23770e17d19433ccd3a3b021870d709caBjorn Volcker MaybeUpdateHistograms(); 7571ca324f23770e17d19433ccd3a3b021870d709caBjorn Volcker 758df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah AudioBuffer* ca = capture_.capture_audio.get(); // For brevity. 75960d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson 760df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (constants_.use_new_agc && 761df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->gain_control->is_enabled()) { 762df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah private_submodules_->agc_manager->AnalyzePreProcess( 763df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah ca->channels()[0], ca->num_channels(), 764df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_nonlocked_.fwd_proc_format.num_frames()); 765788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org } 766788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org 767369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.org bool data_processed = is_data_processed(); 768369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.org if (analysis_needed(data_processed)) { 769be05c74ec8ee975f3451809425756d0f6a51ff2ealuebs@webrtc.org ca->SplitIntoFrequencyBands(); 770470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 771470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 772df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (constants_.intelligibility_enabled) { 773df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->intelligibility_enhancer->AnalyzeCaptureAudio( 774df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah ca->split_channels_f(kBand0To8kHz), capture_nonlocked_.split_rate, 775df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah ca->num_channels()); 77660d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson } 77760d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson 778b2328d11dcc86fba1661ee3fa0d51fc126939764aluebs if (capture_nonlocked_.beamformer_enabled) { 779df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah private_submodules_->beamformer->ProcessChunk(*ca->split_data_f(), 780df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah ca->split_data_f()); 781ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org ca->set_num_channels(1); 782ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org } 783ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org 78470f9903e570931831a027ba6f91c164efc604a85solenberg public_submodules_->high_pass_filter->ProcessCaptureAudio(ca); 785df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah RETURN_ON_ERR(public_submodules_->gain_control->AnalyzeCaptureAudio(ca)); 7865e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg public_submodules_->noise_suppression->AnalyzeCaptureAudio(ca); 787df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah RETURN_ON_ERR(public_submodules_->echo_cancellation->ProcessCaptureAudio(ca)); 788470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 789df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (public_submodules_->echo_control_mobile->is_enabled() && 790df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->noise_suppression->is_enabled()) { 791103657b48442dedd1742fca4a73d5131bf4ae624andrew@webrtc.org ca->CopyLowPassToReference(); 792470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 7935e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg public_submodules_->noise_suppression->ProcessCaptureAudio(ca); 794df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah RETURN_ON_ERR( 795df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->echo_control_mobile->ProcessCaptureAudio(ca)); 796a29386c26d515be9fbeaeca3e0bc6019f29142c2solenberg public_submodules_->voice_detection->ProcessCaptureAudio(ca); 797788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org 798df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (constants_.use_new_agc && 799df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->gain_control->is_enabled() && 800b2328d11dcc86fba1661ee3fa0d51fc126939764aluebs (!capture_nonlocked_.beamformer_enabled || 801df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah private_submodules_->beamformer->is_target_present())) { 802df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah private_submodules_->agc_manager->Process( 803df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah ca->split_bands_const(0)[kBand0To8kHz], ca->num_frames_per_band(), 804df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_nonlocked_.split_rate); 805788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org } 806df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah RETURN_ON_ERR(public_submodules_->gain_control->ProcessCaptureAudio(ca)); 807470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 808369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.org if (synthesis_needed(data_processed)) { 809be05c74ec8ee975f3451809425756d0f6a51ff2ealuebs@webrtc.org ca->MergeFrequencyBands(); 810470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 811470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 812788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org // TODO(aluebs): Investigate if the transient suppression placement should be 813788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org // before or after the AGC. 814df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (capture_.transient_suppressor_enabled) { 815788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org float voice_probability = 816df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah private_submodules_->agc_manager.get() 817df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah ? private_submodules_->agc_manager->voice_probability() 818df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah : 1.f; 819788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org 820df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->transient_suppressor->Suppress( 82186c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk ca->channels_f()[0], ca->num_frames(), ca->num_channels(), 82286c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk ca->split_bands_const_f(0)[kBand0To8kHz], ca->num_frames_per_band(), 82386c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk ca->keyboard_data(), ca->num_keyboard_frames(), voice_probability, 824df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.key_pressed); 825788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org } 826788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org 827755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org // The level estimator operates on the recombined data. 828949028fbf1e9a01fb96b186b95606c0096e7d13fsolenberg public_submodules_->level_estimator->ProcessStream(ca); 82917e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org 830df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.was_stream_delay_set = false; 83117e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org return kNoError; 83217e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org} 83317e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org 83417e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.orgint AudioProcessingImpl::AnalyzeReverseStream(const float* const* data, 835dce40cf804019a9898b6ab8d8262466b697c56e0Peter Kasting size_t samples_per_channel, 83660d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson int rev_sample_rate_hz, 83717e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org ChannelLayout layout) { 838369f828bfe9f42e9d1d712e8493fbbd7e776b9c3peah TRACE_EVENT0("webrtc", "AudioProcessing::AnalyzeReverseStream_ChannelLayout"); 839df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs(&crit_render_); 84086c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk const StreamConfig reverse_config = { 84160d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson rev_sample_rate_hz, ChannelsFromLayout(layout), LayoutHasKeyboard(layout), 84286c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk }; 84386c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk if (samples_per_channel != reverse_config.num_frames()) { 84486c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk return kBadDataLengthError; 84586c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk } 846df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah return AnalyzeReverseStreamLocked(data, reverse_config, reverse_config); 84760d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson} 84860d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson 84960d9b332a5391045439bfb6a3a5447973e3d5603ekmeyersonint AudioProcessingImpl::ProcessReverseStream( 85060d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson const float* const* src, 85160d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson const StreamConfig& reverse_input_config, 85260d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson const StreamConfig& reverse_output_config, 85360d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson float* const* dest) { 854369f828bfe9f42e9d1d712e8493fbbd7e776b9c3peah TRACE_EVENT0("webrtc", "AudioProcessing::ProcessReverseStream_StreamConfig"); 855df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs(&crit_render_); 856df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah RETURN_ON_ERR(AnalyzeReverseStreamLocked(src, reverse_input_config, 857df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah reverse_output_config)); 85860d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson if (is_rev_processed()) { 859df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah render_.render_audio->CopyTo(formats_.api_format.reverse_output_stream(), 860df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah dest); 86181b9bfe6856bb4f9fd0ba79899f72b8385c58979peah } else if (render_check_rev_conversion_needed()) { 862df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah render_.render_converter->Convert(src, reverse_input_config.num_samples(), 863df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah dest, 864df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah reverse_output_config.num_samples()); 86560d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson } else { 86660d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson CopyAudioIfNeeded(src, reverse_input_config.num_frames(), 86760d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson reverse_input_config.num_channels(), dest); 86860d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson } 86960d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson 87060d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson return kNoError; 87186c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk} 87286c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk 873df3efa8c079294857a8b8e0a02634d06a6d6b6d6peahint AudioProcessingImpl::AnalyzeReverseStreamLocked( 87460d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson const float* const* src, 87560d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson const StreamConfig& reverse_input_config, 87660d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson const StreamConfig& reverse_output_config) { 877df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (src == nullptr) { 87817e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org return kNullPointerError; 87917e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org } 880755b04a06ec4ae91ae7fb601c641e683f4e9e87dandrew@webrtc.org 8816955870806624479723addfae6dcf5d13968796cPeter Kasting if (reverse_input_config.num_channels() == 0) { 88286c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk return kBadNumberChannelsError; 88317e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org } 884470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 885df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah ProcessingConfig processing_config = formats_.api_format; 88660d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson processing_config.reverse_input_stream() = reverse_input_config; 88760d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson processing_config.reverse_output_stream() = reverse_output_config; 88886c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk 889df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah RETURN_ON_ERR(MaybeInitializeRender(processing_config)); 89060d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson assert(reverse_input_config.num_frames() == 891df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah formats_.api_format.reverse_input_stream().num_frames()); 89286c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk 8937bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 894df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (debug_dump_.debug_file->Open()) { 895df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah debug_dump_.render.event_msg->set_type(audioproc::Event::REVERSE_STREAM); 896df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah audioproc::ReverseStream* msg = 897df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah debug_dump_.render.event_msg->mutable_reverse_stream(); 89859a1b1b92850747a0e758b9668f725ed9e961a33aluebs@webrtc.org const size_t channel_size = 899df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah sizeof(float) * formats_.api_format.reverse_input_stream().num_frames(); 9006955870806624479723addfae6dcf5d13968796cPeter Kasting for (size_t i = 0; 901df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah i < formats_.api_format.reverse_input_stream().num_channels(); ++i) 90260d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson msg->add_channel(src[i], channel_size); 903df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah RETURN_ON_ERR(WriteMessageToDebugFile(debug_dump_.debug_file.get(), 904df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah &crit_debug_, &debug_dump_.render)); 905808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com } 9067bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#endif 907808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com 908df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah render_.render_audio->CopyFrom(src, 909df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah formats_.api_format.reverse_input_stream()); 91060d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson return ProcessReverseStreamLocked(); 91160d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson} 91260d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson 91360d9b332a5391045439bfb6a3a5447973e3d5603ekmeyersonint AudioProcessingImpl::ProcessReverseStream(AudioFrame* frame) { 914369f828bfe9f42e9d1d712e8493fbbd7e776b9c3peah TRACE_EVENT0("webrtc", "AudioProcessing::ProcessReverseStream_AudioFrame"); 91560d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson RETURN_ON_ERR(AnalyzeReverseStream(frame)); 916df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs(&crit_render_); 91760d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson if (is_rev_processed()) { 918df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah render_.render_audio->InterleaveTo(frame, true); 91960d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson } 92060d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson 92160d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson return kNoError; 922470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 923470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 924470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::AnalyzeReverseStream(AudioFrame* frame) { 925369f828bfe9f42e9d1d712e8493fbbd7e776b9c3peah TRACE_EVENT0("webrtc", "AudioProcessing::AnalyzeReverseStream_AudioFrame"); 926df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs(&crit_render_); 927df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (frame == nullptr) { 928470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return kNullPointerError; 929470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 930ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org // Must be a native rate. 931ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org if (frame->sample_rate_hz_ != kSampleRate8kHz && 932ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org frame->sample_rate_hz_ != kSampleRate16kHz && 933087da13fe8be20b61b556f60eac937c9d0b19fb8aluebs@webrtc.org frame->sample_rate_hz_ != kSampleRate32kHz && 934087da13fe8be20b61b556f60eac937c9d0b19fb8aluebs@webrtc.org frame->sample_rate_hz_ != kSampleRate48kHz) { 935ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org return kBadSampleRateError; 936ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org } 937ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org // This interface does not tolerate different forward and reverse rates. 938192164eebc9bbb5c5745f19330b203174304e269peah if (frame->sample_rate_hz_ != 939df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah formats_.api_format.input_stream().sample_rate_hz()) { 940470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return kBadSampleRateError; 941470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 942a8b97373d5d3154357cc6589ff949ee9f6f99d8dandrew@webrtc.org 94386c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk if (frame->num_channels_ <= 0) { 94486c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk return kBadNumberChannelsError; 94586c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk } 94686c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk 947df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah ProcessingConfig processing_config = formats_.api_format; 94860d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson processing_config.reverse_input_stream().set_sample_rate_hz( 94960d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson frame->sample_rate_hz_); 95060d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson processing_config.reverse_input_stream().set_num_channels( 95160d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson frame->num_channels_); 95260d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson processing_config.reverse_output_stream().set_sample_rate_hz( 95360d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson frame->sample_rate_hz_); 95460d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson processing_config.reverse_output_stream().set_num_channels( 95560d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson frame->num_channels_); 95686c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk 957df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah RETURN_ON_ERR(MaybeInitializeRender(processing_config)); 95886c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk if (frame->samples_per_channel_ != 959df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah formats_.api_format.reverse_input_stream().num_frames()) { 96017e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org return kBadDataLengthError; 96117e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org } 962470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 9637bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 964df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (debug_dump_.debug_file->Open()) { 965df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah debug_dump_.render.event_msg->set_type(audioproc::Event::REVERSE_STREAM); 966df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah audioproc::ReverseStream* msg = 967df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah debug_dump_.render.event_msg->mutable_reverse_stream(); 96886c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk const size_t data_size = 96986c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk sizeof(int16_t) * frame->samples_per_channel_ * frame->num_channels_; 97063a509858d3988299726640c664b699d6229a1d4andrew@webrtc.org msg->set_data(frame->data_, data_size); 971df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah RETURN_ON_ERR(WriteMessageToDebugFile(debug_dump_.debug_file.get(), 972df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah &crit_debug_, &debug_dump_.render)); 973470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 9747bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#endif 975df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah render_.render_audio->DeinterleaveFrom(frame); 97660d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson return ProcessReverseStreamLocked(); 97717e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org} 978470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 97960d9b332a5391045439bfb6a3a5447973e3d5603ekmeyersonint AudioProcessingImpl::ProcessReverseStreamLocked() { 980df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah AudioBuffer* ra = render_.render_audio.get(); // For brevity. 981df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (formats_.rev_proc_format.sample_rate_hz() == kSampleRate32kHz) { 982be05c74ec8ee975f3451809425756d0f6a51ff2ealuebs@webrtc.org ra->SplitIntoFrequencyBands(); 983470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 984470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 985df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (constants_.intelligibility_enabled) { 986df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Currently run in single-threaded mode when the intelligibility 987df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // enhancer is activated. 988df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // TODO(peah): Fix to be properly multi-threaded. 989df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs(&crit_capture_); 990df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->intelligibility_enhancer->ProcessRenderAudio( 991df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah ra->split_channels_f(kBand0To8kHz), capture_nonlocked_.split_rate, 992df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah ra->num_channels()); 99360d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson } 99460d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson 995df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah RETURN_ON_ERR(public_submodules_->echo_cancellation->ProcessRenderAudio(ra)); 996df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah RETURN_ON_ERR( 997df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->echo_control_mobile->ProcessRenderAudio(ra)); 998df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (!constants_.use_new_agc) { 999df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah RETURN_ON_ERR(public_submodules_->gain_control->ProcessRenderAudio(ra)); 1000788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org } 1001470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1002df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (formats_.rev_proc_format.sample_rate_hz() == kSampleRate32kHz && 100360d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson is_rev_processed()) { 100460d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson ra->MergeFrequencyBands(); 100560d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson } 100660d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson 100717e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org return kNoError; 1008470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1009470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1010470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::set_stream_delay_ms(int delay) { 1011df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs(&crit_capture_); 10125f23d64cf2da06b45c2c1c837bb11d260cb85ecfandrew@webrtc.org Error retval = kNoError; 1013df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.was_stream_delay_set = true; 1014df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah delay += capture_.delay_offset_ms; 10156f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.org 1016470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (delay < 0) { 10175f23d64cf2da06b45c2c1c837bb11d260cb85ecfandrew@webrtc.org delay = 0; 10185f23d64cf2da06b45c2c1c837bb11d260cb85ecfandrew@webrtc.org retval = kBadStreamParameterWarning; 1019470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1020470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1021470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // TODO(ajm): the max is rather arbitrarily chosen; investigate. 1022470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com if (delay > 500) { 10235f23d64cf2da06b45c2c1c837bb11d260cb85ecfandrew@webrtc.org delay = 500; 10245f23d64cf2da06b45c2c1c837bb11d260cb85ecfandrew@webrtc.org retval = kBadStreamParameterWarning; 1025470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1026470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1027df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_nonlocked_.stream_delay_ms = delay; 10285f23d64cf2da06b45c2c1c837bb11d260cb85ecfandrew@webrtc.org return retval; 1029470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1030470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1031470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::stream_delay_ms() const { 1032df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Used as callback from submodules, hence locking is not allowed. 1033df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah return capture_nonlocked_.stream_delay_ms; 1034470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1035470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1036470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.combool AudioProcessingImpl::was_stream_delay_set() const { 1037df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Used as callback from submodules, hence locking is not allowed. 1038df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah return capture_.was_stream_delay_set; 1039470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1040470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 104117e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.orgvoid AudioProcessingImpl::set_stream_key_pressed(bool key_pressed) { 1042df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs(&crit_capture_); 1043df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.key_pressed = key_pressed; 104417e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org} 104517e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org 10466f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.orgvoid AudioProcessingImpl::set_delay_offset_ms(int offset) { 1047df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs(&crit_capture_); 1048df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.delay_offset_ms = offset; 10496f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.org} 10506f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.org 10516f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.orgint AudioProcessingImpl::delay_offset_ms() const { 1052df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs(&crit_capture_); 1053df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah return capture_.delay_offset_ms; 10546f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.org} 10556f9f817e06776f0c181809dc7748639599bcf42eandrew@webrtc.org 1056470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::StartDebugRecording( 1057a4df27b6713583045e51e20c4eb93718d15ca33eivoc const char filename[AudioProcessing::kMaxFilenameSize]) { 1058df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Run in a single-threaded manner. 1059df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs_render(&crit_render_); 1060df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs_capture(&crit_capture_); 1061664cdafb8ad7ccef531cb6bf7bd42752841f220fAndré Susano Pinto static_assert(kMaxFilenameSize == FileWrapper::kMaxFileNameSize, ""); 1062470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1063df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (filename == nullptr) { 1064470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return kNullPointerError; 1065470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1066470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 10677bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 1068470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // Stop any ongoing recording. 1069df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (debug_dump_.debug_file->Open()) { 1070df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (debug_dump_.debug_file->CloseFile() == -1) { 1071470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return kFileError; 1072470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1073470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1074470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1075df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (debug_dump_.debug_file->OpenFile(filename, false) == -1) { 1076df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah debug_dump_.debug_file->CloseFile(); 1077470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return kFileError; 1078470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1079470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 108013b96ba90f72164134019cbfc07d4a47cf1fd091Minyue RETURN_ON_ERR(WriteConfigMessage(true)); 108113b96ba90f72164134019cbfc07d4a47cf1fd091Minyue RETURN_ON_ERR(WriteInitMessage()); 1082863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org return kNoError; 1083863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org#else 1084863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org return kUnsupportedFunctionError; 1085863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org#endif // WEBRTC_AUDIOPROC_DEBUG_DUMP 1086863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org} 1087863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org 1088a4df27b6713583045e51e20c4eb93718d15ca33eivocint AudioProcessingImpl::StartDebugRecording(FILE* handle) { 1089df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Run in a single-threaded manner. 1090df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs_render(&crit_render_); 1091df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs_capture(&crit_capture_); 1092863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org 1093df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (handle == nullptr) { 1094863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org return kNullPointerError; 1095863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org } 1096863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org 1097863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 1098863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org // Stop any ongoing recording. 1099df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (debug_dump_.debug_file->Open()) { 1100df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (debug_dump_.debug_file->CloseFile() == -1) { 1101863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org return kFileError; 1102863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org } 1103863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org } 1104863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org 1105df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (debug_dump_.debug_file->OpenFromFileHandle(handle, true, false) == -1) { 1106863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org return kFileError; 1107863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org } 1108863b5361003e36451a946ca6f9886efb3c1bfa53henrikg@webrtc.org 110913b96ba90f72164134019cbfc07d4a47cf1fd091Minyue RETURN_ON_ERR(WriteConfigMessage(true)); 111013b96ba90f72164134019cbfc07d4a47cf1fd091Minyue RETURN_ON_ERR(WriteInitMessage()); 1111470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return kNoError; 11127bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#else 11137bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org return kUnsupportedFunctionError; 11147bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#endif // WEBRTC_AUDIOPROC_DEBUG_DUMP 1115470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1116470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1117e46bc77e941f12ca24b04cf42fca98e15bc139eexians@webrtc.orgint AudioProcessingImpl::StartDebugRecordingForPlatformFile( 1118e46bc77e941f12ca24b04cf42fca98e15bc139eexians@webrtc.org rtc::PlatformFile handle) { 1119df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Run in a single-threaded manner. 1120df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs_render(&crit_render_); 1121df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs_capture(&crit_capture_); 1122e46bc77e941f12ca24b04cf42fca98e15bc139eexians@webrtc.org FILE* stream = rtc::FdopenPlatformFileForWriting(handle); 1123a4df27b6713583045e51e20c4eb93718d15ca33eivoc return StartDebugRecording(stream); 1124e46bc77e941f12ca24b04cf42fca98e15bc139eexians@webrtc.org} 1125e46bc77e941f12ca24b04cf42fca98e15bc139eexians@webrtc.org 1126470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comint AudioProcessingImpl::StopDebugRecording() { 1127df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Run in a single-threaded manner. 1128df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs_render(&crit_render_); 1129df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs_capture(&crit_capture_); 11307bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org 11317bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 1132470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com // We just return if recording hasn't started. 1133df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (debug_dump_.debug_file->Open()) { 1134df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (debug_dump_.debug_file->CloseFile() == -1) { 1135470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return kFileError; 1136470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1137470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com } 1138470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com return kNoError; 11397bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#else 11407bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org return kUnsupportedFunctionError; 11417bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#endif // WEBRTC_AUDIOPROC_DEBUG_DUMP 1142470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1143470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1144470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comEchoCancellation* AudioProcessingImpl::echo_cancellation() const { 1145df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Adding a lock here has no effect as it allows any access to the submodule 1146df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // from the returned pointer. 1147df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah return public_submodules_->echo_cancellation; 1148470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1149470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1150470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comEchoControlMobile* AudioProcessingImpl::echo_control_mobile() const { 1151df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Adding a lock here has no effect as it allows any access to the submodule 1152df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // from the returned pointer. 1153df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah return public_submodules_->echo_control_mobile; 1154470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1155470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1156470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comGainControl* AudioProcessingImpl::gain_control() const { 1157df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Adding a lock here has no effect as it allows any access to the submodule 1158df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // from the returned pointer. 1159df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (constants_.use_new_agc) { 1160df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah return public_submodules_->gain_control_for_new_agc.get(); 1161788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org } 1162df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah return public_submodules_->gain_control; 1163470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1164470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1165470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comHighPassFilter* AudioProcessingImpl::high_pass_filter() const { 1166df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Adding a lock here has no effect as it allows any access to the submodule 1167df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // from the returned pointer. 116870f9903e570931831a027ba6f91c164efc604a85solenberg return public_submodules_->high_pass_filter.get(); 1169470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1170470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1171470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comLevelEstimator* AudioProcessingImpl::level_estimator() const { 1172df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Adding a lock here has no effect as it allows any access to the submodule 1173df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // from the returned pointer. 1174949028fbf1e9a01fb96b186b95606c0096e7d13fsolenberg return public_submodules_->level_estimator.get(); 1175470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1176470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1177470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comNoiseSuppression* AudioProcessingImpl::noise_suppression() const { 1178df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Adding a lock here has no effect as it allows any access to the submodule 1179df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // from the returned pointer. 11805e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg return public_submodules_->noise_suppression.get(); 1181470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1182470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1183470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.comVoiceDetection* AudioProcessingImpl::voice_detection() const { 1184df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Adding a lock here has no effect as it allows any access to the submodule 1185df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // from the returned pointer. 1186a29386c26d515be9fbeaeca3e0bc6019f29142c2solenberg return public_submodules_->voice_detection.get(); 1187470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} 1188470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com 1189369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.orgbool AudioProcessingImpl::is_data_processed() const { 1190b2328d11dcc86fba1661ee3fa0d51fc126939764aluebs if (capture_nonlocked_.beamformer_enabled) { 1191ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org return true; 1192ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org } 1193ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org 11947bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org int enabled_count = 0; 1195df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah for (auto item : private_submodules_->component_list) { 1196e534086492e92c45d74b176f3c8be4addb69713fmgraczyk@chromium.org if (item->is_component_enabled()) { 11977bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org enabled_count++; 11987bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org } 11997bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org } 120070f9903e570931831a027ba6f91c164efc604a85solenberg if (public_submodules_->high_pass_filter->is_enabled()) { 120170f9903e570931831a027ba6f91c164efc604a85solenberg enabled_count++; 120270f9903e570931831a027ba6f91c164efc604a85solenberg } 12035e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg if (public_submodules_->noise_suppression->is_enabled()) { 12045e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg enabled_count++; 12055e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg } 1206949028fbf1e9a01fb96b186b95606c0096e7d13fsolenberg if (public_submodules_->level_estimator->is_enabled()) { 1207949028fbf1e9a01fb96b186b95606c0096e7d13fsolenberg enabled_count++; 1208949028fbf1e9a01fb96b186b95606c0096e7d13fsolenberg } 1209a29386c26d515be9fbeaeca3e0bc6019f29142c2solenberg if (public_submodules_->voice_detection->is_enabled()) { 1210a29386c26d515be9fbeaeca3e0bc6019f29142c2solenberg enabled_count++; 1211a29386c26d515be9fbeaeca3e0bc6019f29142c2solenberg } 12127bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org 1213df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Data is unchanged if no components are enabled, or if only 1214df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // public_submodules_->level_estimator 1215df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // or public_submodules_->voice_detection is enabled. 12167bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org if (enabled_count == 0) { 12177bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org return false; 12187bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org } else if (enabled_count == 1) { 1219df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (public_submodules_->level_estimator->is_enabled() || 1220df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->voice_detection->is_enabled()) { 12217bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org return false; 12227bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org } 12237bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org } else if (enabled_count == 2) { 1224df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (public_submodules_->level_estimator->is_enabled() && 1225df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->voice_detection->is_enabled()) { 12267bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org return false; 12277bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org } 12287bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org } 12297bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org return true; 12307bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org} 12317bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org 123217e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.orgbool AudioProcessingImpl::output_copy_needed(bool is_data_processed) const { 1233369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.org // Check if we've upmixed or downmixed the audio. 1234df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah return ((formats_.api_format.output_stream().num_channels() != 1235df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah formats_.api_format.input_stream().num_channels()) || 1236df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah is_data_processed || capture_.transient_suppressor_enabled); 12377bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org} 12387bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org 1239369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.orgbool AudioProcessingImpl::synthesis_needed(bool is_data_processed) const { 124086c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk return (is_data_processed && 1241df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah (capture_nonlocked_.fwd_proc_format.sample_rate_hz() == 1242df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah kSampleRate32kHz || 1243df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_nonlocked_.fwd_proc_format.sample_rate_hz() == 1244df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah kSampleRate48kHz)); 1245369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.org} 1246369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.org 1247369166a179a201494beeff4ec060c6dff8b27affandrew@webrtc.orgbool AudioProcessingImpl::analysis_needed(bool is_data_processed) const { 1248df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (!is_data_processed && 1249df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah !public_submodules_->voice_detection->is_enabled() && 1250df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah !capture_.transient_suppressor_enabled) { 1251df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Only public_submodules_->level_estimator is enabled. 12527bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org return false; 1253df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah } else if (capture_nonlocked_.fwd_proc_format.sample_rate_hz() == 1254df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah kSampleRate32kHz || 1255df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_nonlocked_.fwd_proc_format.sample_rate_hz() == 1256df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah kSampleRate48kHz) { 1257df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Something besides public_submodules_->level_estimator is enabled, and we 1258df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // have super-wb. 12597bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org return true; 12607bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org } 12617bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org return false; 12627bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org} 12637bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org 126460d9b332a5391045439bfb6a3a5447973e3d5603ekmeyersonbool AudioProcessingImpl::is_rev_processed() const { 1265df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah return constants_.intelligibility_enabled && 1266df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->intelligibility_enhancer->active(); 126760d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson} 126860d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson 126981b9bfe6856bb4f9fd0ba79899f72b8385c58979peahbool AudioProcessingImpl::render_check_rev_conversion_needed() const { 127081b9bfe6856bb4f9fd0ba79899f72b8385c58979peah return rev_conversion_needed(); 127181b9bfe6856bb4f9fd0ba79899f72b8385c58979peah} 127281b9bfe6856bb4f9fd0ba79899f72b8385c58979peah 127360d9b332a5391045439bfb6a3a5447973e3d5603ekmeyersonbool AudioProcessingImpl::rev_conversion_needed() const { 1274df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah return (formats_.api_format.reverse_input_stream() != 1275df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah formats_.api_format.reverse_output_stream()); 127660d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson} 127760d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson 1278adc46c4cf7dd8a015b0757c99787d80525c123abBjorn Volckervoid AudioProcessingImpl::InitializeExperimentalAgc() { 1279df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (constants_.use_new_agc) { 1280df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (!private_submodules_->agc_manager.get()) { 1281df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah private_submodules_->agc_manager.reset(new AgcManagerDirect( 1282df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->gain_control, 1283df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->gain_control_for_new_agc.get(), 1284df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah constants_.agc_startup_min_volume)); 1285788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org } 1286df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah private_submodules_->agc_manager->Initialize(); 1287df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah private_submodules_->agc_manager->SetCaptureMuted( 1288df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.output_will_be_muted); 1289788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org } 1290788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org} 1291788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org 1292adc46c4cf7dd8a015b0757c99787d80525c123abBjorn Volckervoid AudioProcessingImpl::InitializeTransient() { 1293df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (capture_.transient_suppressor_enabled) { 1294df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (!public_submodules_->transient_suppressor.get()) { 1295df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->transient_suppressor.reset(new TransientSuppressor()); 1296788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org } 1297df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->transient_suppressor->Initialize( 1298df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_nonlocked_.fwd_proc_format.sample_rate_hz(), 1299df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_nonlocked_.split_rate, 1300b2328d11dcc86fba1661ee3fa0d51fc126939764aluebs num_proc_channels()); 1301788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org } 1302788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org} 1303788acd17adf6b3d605b5ea66cf394eb81fc086a9pbos@webrtc.org 1304ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.orgvoid AudioProcessingImpl::InitializeBeamformer() { 1305b2328d11dcc86fba1661ee3fa0d51fc126939764aluebs if (capture_nonlocked_.beamformer_enabled) { 1306df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (!private_submodules_->beamformer) { 1307df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah private_submodules_->beamformer.reset(new NonlinearBeamformer( 13082a34688f86517bfd3745e131e4e5d2b7a924f46aaluebs capture_.array_geometry, capture_.target_direction)); 1309d82f55d2a73da925d4160e3d1430f79f76170992aluebs@webrtc.org } 1310df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah private_submodules_->beamformer->Initialize(kChunkSizeMs, 1311df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_nonlocked_.split_rate); 1312ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org } 1313ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org} 1314ae643ce280876d3b1ebcf0cc628f27ba7116b534aluebs@webrtc.org 131560d9b332a5391045439bfb6a3a5447973e3d5603ekmeyersonvoid AudioProcessingImpl::InitializeIntelligibility() { 1316df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (constants_.intelligibility_enabled) { 131760d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson IntelligibilityEnhancer::Config config; 1318df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah config.sample_rate_hz = capture_nonlocked_.split_rate; 1319df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah config.num_capture_channels = capture_.capture_audio->num_channels(); 1320df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah config.num_render_channels = render_.render_audio->num_channels(); 1321df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->intelligibility_enhancer.reset( 1322df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah new IntelligibilityEnhancer(config)); 132360d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson } 132460d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson} 132560d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson 132670f9903e570931831a027ba6f91c164efc604a85solenbergvoid AudioProcessingImpl::InitializeHighPassFilter() { 1327b2328d11dcc86fba1661ee3fa0d51fc126939764aluebs public_submodules_->high_pass_filter->Initialize(num_proc_channels(), 132870f9903e570931831a027ba6f91c164efc604a85solenberg proc_sample_rate_hz()); 13295e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg} 13305e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg 13315e465c33cac54ed5265f18413f7afc44aae2dfcasolenbergvoid AudioProcessingImpl::InitializeNoiseSuppression() { 1332b2328d11dcc86fba1661ee3fa0d51fc126939764aluebs public_submodules_->noise_suppression->Initialize(num_proc_channels(), 13335e465c33cac54ed5265f18413f7afc44aae2dfcasolenberg proc_sample_rate_hz()); 133470f9903e570931831a027ba6f91c164efc604a85solenberg} 133570f9903e570931831a027ba6f91c164efc604a85solenberg 1336949028fbf1e9a01fb96b186b95606c0096e7d13fsolenbergvoid AudioProcessingImpl::InitializeLevelEstimator() { 1337949028fbf1e9a01fb96b186b95606c0096e7d13fsolenberg public_submodules_->level_estimator->Initialize(); 1338949028fbf1e9a01fb96b186b95606c0096e7d13fsolenberg} 1339949028fbf1e9a01fb96b186b95606c0096e7d13fsolenberg 1340a29386c26d515be9fbeaeca3e0bc6019f29142c2solenbergvoid AudioProcessingImpl::InitializeVoiceDetection() { 1341a29386c26d515be9fbeaeca3e0bc6019f29142c2solenberg public_submodules_->voice_detection->Initialize(proc_split_sample_rate_hz()); 1342a29386c26d515be9fbeaeca3e0bc6019f29142c2solenberg} 1343a29386c26d515be9fbeaeca3e0bc6019f29142c2solenberg 13441ca324f23770e17d19433ccd3a3b021870d709caBjorn Volckervoid AudioProcessingImpl::MaybeUpdateHistograms() { 1345d92f2674d7e99ae69b26d434b47ea0adf14aff0cBjorn Volcker static const int kMinDiffDelayMs = 60; 13461ca324f23770e17d19433ccd3a3b021870d709caBjorn Volcker 13471ca324f23770e17d19433ccd3a3b021870d709caBjorn Volcker if (echo_cancellation()->is_enabled()) { 13484e7aa43ea0fd7106cd39036798877301398966a6Bjorn Volcker // Activate delay_jumps_ counters if we know echo_cancellation is runnning. 13494e7aa43ea0fd7106cd39036798877301398966a6Bjorn Volcker // If a stream has echo we know that the echo_cancellation is in process. 1350df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (capture_.stream_delay_jumps == -1 && 1351df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah echo_cancellation()->stream_has_echo()) { 1352df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.stream_delay_jumps = 0; 13534e7aa43ea0fd7106cd39036798877301398966a6Bjorn Volcker } 1354df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (capture_.aec_system_delay_jumps == -1 && 13554e7aa43ea0fd7106cd39036798877301398966a6Bjorn Volcker echo_cancellation()->stream_has_echo()) { 1356df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.aec_system_delay_jumps = 0; 13574e7aa43ea0fd7106cd39036798877301398966a6Bjorn Volcker } 13584e7aa43ea0fd7106cd39036798877301398966a6Bjorn Volcker 13591ca324f23770e17d19433ccd3a3b021870d709caBjorn Volcker // Detect a jump in platform reported system delay and log the difference. 1360df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah const int diff_stream_delay_ms = 1361df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_nonlocked_.stream_delay_ms - capture_.last_stream_delay_ms; 1362df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (diff_stream_delay_ms > kMinDiffDelayMs && 1363df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.last_stream_delay_ms != 0) { 136453805324c0fa904d796cc0b333868c591f2c5f2casapersson RTC_HISTOGRAM_COUNTS_SPARSE( 136553805324c0fa904d796cc0b333868c591f2c5f2casapersson "WebRTC.Audio.PlatformReportedStreamDelayJump", diff_stream_delay_ms, 136653805324c0fa904d796cc0b333868c591f2c5f2casapersson kMinDiffDelayMs, 1000, 100); 1367df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (capture_.stream_delay_jumps == -1) { 1368df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.stream_delay_jumps = 0; // Activate counter if needed. 13694e7aa43ea0fd7106cd39036798877301398966a6Bjorn Volcker } 1370df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.stream_delay_jumps++; 13711ca324f23770e17d19433ccd3a3b021870d709caBjorn Volcker } 1372df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.last_stream_delay_ms = capture_nonlocked_.stream_delay_ms; 13731ca324f23770e17d19433ccd3a3b021870d709caBjorn Volcker 13741ca324f23770e17d19433ccd3a3b021870d709caBjorn Volcker // Detect a jump in AEC system delay and log the difference. 1375df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah const int frames_per_ms = 1376df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CheckedDivExact(capture_nonlocked_.split_rate, 1000); 13771ca324f23770e17d19433ccd3a3b021870d709caBjorn Volcker const int aec_system_delay_ms = 13781ca324f23770e17d19433ccd3a3b021870d709caBjorn Volcker WebRtcAec_system_delay(echo_cancellation()->aec_core()) / frames_per_ms; 137986c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk const int diff_aec_system_delay_ms = 1380df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah aec_system_delay_ms - capture_.last_aec_system_delay_ms; 13811ca324f23770e17d19433ccd3a3b021870d709caBjorn Volcker if (diff_aec_system_delay_ms > kMinDiffDelayMs && 1382df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.last_aec_system_delay_ms != 0) { 138353805324c0fa904d796cc0b333868c591f2c5f2casapersson RTC_HISTOGRAM_COUNTS_SPARSE("WebRTC.Audio.AecSystemDelayJump", 138453805324c0fa904d796cc0b333868c591f2c5f2casapersson diff_aec_system_delay_ms, kMinDiffDelayMs, 138553805324c0fa904d796cc0b333868c591f2c5f2casapersson 1000, 100); 1386df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (capture_.aec_system_delay_jumps == -1) { 1387df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.aec_system_delay_jumps = 0; // Activate counter if needed. 13884e7aa43ea0fd7106cd39036798877301398966a6Bjorn Volcker } 1389df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.aec_system_delay_jumps++; 13901ca324f23770e17d19433ccd3a3b021870d709caBjorn Volcker } 1391df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.last_aec_system_delay_ms = aec_system_delay_ms; 13921ca324f23770e17d19433ccd3a3b021870d709caBjorn Volcker } 13931ca324f23770e17d19433ccd3a3b021870d709caBjorn Volcker} 13941ca324f23770e17d19433ccd3a3b021870d709caBjorn Volcker 13954e7aa43ea0fd7106cd39036798877301398966a6Bjorn Volckervoid AudioProcessingImpl::UpdateHistogramsOnCallEnd() { 1396df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Run in a single-threaded manner. 1397df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs_render(&crit_render_); 1398df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CritScope cs_capture(&crit_capture_); 1399df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah 1400df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (capture_.stream_delay_jumps > -1) { 140153805324c0fa904d796cc0b333868c591f2c5f2casapersson RTC_HISTOGRAM_ENUMERATION_SPARSE( 14024e7aa43ea0fd7106cd39036798877301398966a6Bjorn Volcker "WebRTC.Audio.NumOfPlatformReportedStreamDelayJumps", 1403df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.stream_delay_jumps, 51); 14044e7aa43ea0fd7106cd39036798877301398966a6Bjorn Volcker } 1405df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.stream_delay_jumps = -1; 1406df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.last_stream_delay_ms = 0; 14074e7aa43ea0fd7106cd39036798877301398966a6Bjorn Volcker 1408df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (capture_.aec_system_delay_jumps > -1) { 140953805324c0fa904d796cc0b333868c591f2c5f2casapersson RTC_HISTOGRAM_ENUMERATION_SPARSE("WebRTC.Audio.NumOfAecSystemDelayJumps", 141053805324c0fa904d796cc0b333868c591f2c5f2casapersson capture_.aec_system_delay_jumps, 51); 14114e7aa43ea0fd7106cd39036798877301398966a6Bjorn Volcker } 1412df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.aec_system_delay_jumps = -1; 1413df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.last_aec_system_delay_ms = 0; 14144e7aa43ea0fd7106cd39036798877301398966a6Bjorn Volcker} 14154e7aa43ea0fd7106cd39036798877301398966a6Bjorn Volcker 14167bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 1417df3efa8c079294857a8b8e0a02634d06a6d6b6d6peahint AudioProcessingImpl::WriteMessageToDebugFile( 1418df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah FileWrapper* debug_file, 1419df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah rtc::CriticalSection* crit_debug, 1420df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah ApmDebugDumpThreadState* debug_state) { 1421df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah int32_t size = debug_state->event_msg->ByteSize(); 1422808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com if (size <= 0) { 1423808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com return kUnspecifiedError; 1424808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com } 1425621df678c8690f36875b0b34d45393df58662172andrew@webrtc.org#if defined(WEBRTC_ARCH_BIG_ENDIAN) 142686c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk// TODO(ajm): Use little-endian "on the wire". For the moment, we can be 142786c6d33aec684d08189d498912e47cbc17c4d2dbMichael Graczyk// pretty safe in assuming little-endian. 1428808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com#endif 1429808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com 1430df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (!debug_state->event_msg->SerializeToString(&debug_state->event_str)) { 1431808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com return kUnspecifiedError; 1432808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com } 1433808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com 1434df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah { 1435df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Ensure atomic writes of the message. 1436a4df27b6713583045e51e20c4eb93718d15ca33eivoc rtc::CritScope cs_capture(crit_debug); 1437df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // Write message preceded by its size. 1438df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (!debug_file->Write(&size, sizeof(int32_t))) { 1439df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah return kFileError; 1440df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah } 1441df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (!debug_file->Write(debug_state->event_str.data(), 1442df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah debug_state->event_str.length())) { 1443df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah return kFileError; 1444df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah } 1445808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com } 1446808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com 1447df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah debug_state->event_msg->Clear(); 1448808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com 144917e40641b30559602e26382e500bd9708bad37e3andrew@webrtc.org return kNoError; 1450808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com} 1451808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com 1452808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.comint AudioProcessingImpl::WriteInitMessage() { 1453df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah debug_dump_.capture.event_msg->set_type(audioproc::Event::INIT); 1454df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah audioproc::Init* msg = debug_dump_.capture.event_msg->mutable_init(); 1455df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah msg->set_sample_rate(formats_.api_format.input_stream().sample_rate_hz()); 1456df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah 14576955870806624479723addfae6dcf5d13968796cPeter Kasting msg->set_num_input_channels(static_cast<google::protobuf::int32>( 14586955870806624479723addfae6dcf5d13968796cPeter Kasting formats_.api_format.input_stream().num_channels())); 14596955870806624479723addfae6dcf5d13968796cPeter Kasting msg->set_num_output_channels(static_cast<google::protobuf::int32>( 14606955870806624479723addfae6dcf5d13968796cPeter Kasting formats_.api_format.output_stream().num_channels())); 14616955870806624479723addfae6dcf5d13968796cPeter Kasting msg->set_num_reverse_channels(static_cast<google::protobuf::int32>( 14626955870806624479723addfae6dcf5d13968796cPeter Kasting formats_.api_format.reverse_input_stream().num_channels())); 146360d9b332a5391045439bfb6a3a5447973e3d5603ekmeyerson msg->set_reverse_sample_rate( 1464df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah formats_.api_format.reverse_input_stream().sample_rate_hz()); 1465192164eebc9bbb5c5745f19330b203174304e269peah msg->set_output_sample_rate( 1466df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah formats_.api_format.output_stream().sample_rate_hz()); 1467df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // TODO(ekmeyerson): Add reverse output fields to 1468df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah // debug_dump_.capture.event_msg. 1469808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com 1470df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah RETURN_ON_ERR(WriteMessageToDebugFile(debug_dump_.debug_file.get(), 1471df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah &crit_debug_, &debug_dump_.capture)); 147213b96ba90f72164134019cbfc07d4a47cf1fd091Minyue return kNoError; 147313b96ba90f72164134019cbfc07d4a47cf1fd091Minyue} 147413b96ba90f72164134019cbfc07d4a47cf1fd091Minyue 147513b96ba90f72164134019cbfc07d4a47cf1fd091Minyueint AudioProcessingImpl::WriteConfigMessage(bool forced) { 147613b96ba90f72164134019cbfc07d4a47cf1fd091Minyue audioproc::Config config; 147713b96ba90f72164134019cbfc07d4a47cf1fd091Minyue 1478df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah config.set_aec_enabled(public_submodules_->echo_cancellation->is_enabled()); 147913b96ba90f72164134019cbfc07d4a47cf1fd091Minyue config.set_aec_delay_agnostic_enabled( 1480df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->echo_cancellation->is_delay_agnostic_enabled()); 148113b96ba90f72164134019cbfc07d4a47cf1fd091Minyue config.set_aec_drift_compensation_enabled( 1482df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->echo_cancellation->is_drift_compensation_enabled()); 148313b96ba90f72164134019cbfc07d4a47cf1fd091Minyue config.set_aec_extended_filter_enabled( 1484df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->echo_cancellation->is_extended_filter_enabled()); 1485df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah config.set_aec_suppression_level(static_cast<int>( 1486df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->echo_cancellation->suppression_level())); 148713b96ba90f72164134019cbfc07d4a47cf1fd091Minyue 1488df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah config.set_aecm_enabled( 1489df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->echo_control_mobile->is_enabled()); 149013b96ba90f72164134019cbfc07d4a47cf1fd091Minyue config.set_aecm_comfort_noise_enabled( 1491df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->echo_control_mobile->is_comfort_noise_enabled()); 1492df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah config.set_aecm_routing_mode(static_cast<int>( 1493df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->echo_control_mobile->routing_mode())); 149413b96ba90f72164134019cbfc07d4a47cf1fd091Minyue 1495df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah config.set_agc_enabled(public_submodules_->gain_control->is_enabled()); 1496df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah config.set_agc_mode( 1497df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah static_cast<int>(public_submodules_->gain_control->mode())); 1498df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah config.set_agc_limiter_enabled( 1499df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah public_submodules_->gain_control->is_limiter_enabled()); 1500df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah config.set_noise_robust_agc_enabled(constants_.use_new_agc); 150113b96ba90f72164134019cbfc07d4a47cf1fd091Minyue 1502df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah config.set_hpf_enabled(public_submodules_->high_pass_filter->is_enabled()); 150313b96ba90f72164134019cbfc07d4a47cf1fd091Minyue 1504df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah config.set_ns_enabled(public_submodules_->noise_suppression->is_enabled()); 1505df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah config.set_ns_level( 1506df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah static_cast<int>(public_submodules_->noise_suppression->level())); 150713b96ba90f72164134019cbfc07d4a47cf1fd091Minyue 1508df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah config.set_transient_suppression_enabled( 1509df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah capture_.transient_suppressor_enabled); 151013b96ba90f72164134019cbfc07d4a47cf1fd091Minyue 151113b96ba90f72164134019cbfc07d4a47cf1fd091Minyue std::string serialized_config = config.SerializeAsString(); 1512df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah if (!forced && 1513df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah debug_dump_.capture.last_serialized_config == serialized_config) { 151413b96ba90f72164134019cbfc07d4a47cf1fd091Minyue return kNoError; 1515808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com } 1516808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com 1517df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah debug_dump_.capture.last_serialized_config = serialized_config; 151813b96ba90f72164134019cbfc07d4a47cf1fd091Minyue 1519df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah debug_dump_.capture.event_msg->set_type(audioproc::Event::CONFIG); 1520df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah debug_dump_.capture.event_msg->mutable_config()->CopyFrom(config); 152113b96ba90f72164134019cbfc07d4a47cf1fd091Minyue 1522df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah RETURN_ON_ERR(WriteMessageToDebugFile(debug_dump_.debug_file.get(), 1523df3efa8c079294857a8b8e0a02634d06a6d6b6d6peah &crit_debug_, &debug_dump_.capture)); 1524808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com return kNoError; 1525808e0e0dac055f8b87ad6878f046e35b4b2c1c27ajm@google.com} 15267bf2646e4dc82e0a46bbde40b82c047acd70e0f1andrew@webrtc.org#endif // WEBRTC_AUDIOPROC_DEBUG_DUMP 1527ddbb8a2c243f9d54cb0ce0092e341dfc6e126bb3andrew@webrtc.org 1528470e71d3649f6cac4688e83819640b012b5d38bbniklase@google.com} // namespace webrtc 1529