Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
|
aluebs-webrtc
2015/08/03 16:30:49
Re-add blank line.
ekm
2015/08/05 05:24:08
Done.
| |
| 11 #include "webrtc/modules/audio_processing/audio_processing_impl.h" | 11 #include "webrtc/modules/audio_processing/audio_processing_impl.h" |
| 12 | 12 |
| 13 #include <assert.h> | 13 #include <assert.h> |
| 14 #include <algorithm> | 14 #include <algorithm> |
| 15 | 15 |
| 16 #include "webrtc/base/checks.h" | 16 #include "webrtc/base/checks.h" |
| 17 #include "webrtc/base/platform_file.h" | 17 #include "webrtc/base/platform_file.h" |
| 18 #include "webrtc/common_audio/include/audio_util.h" | 18 #include "webrtc/common_audio/include/audio_util.h" |
| 19 #include "webrtc/common_audio/channel_buffer.h" | 19 #include "webrtc/common_audio/channel_buffer.h" |
| 20 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar y.h" | 20 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar y.h" |
| 21 extern "C" { | 21 extern "C" { |
| 22 #include "webrtc/modules/audio_processing/aec/aec_core.h" | 22 #include "webrtc/modules/audio_processing/aec/aec_core.h" |
| 23 } | 23 } |
| 24 #include "webrtc/modules/audio_processing/agc/agc_manager_direct.h" | 24 #include "webrtc/modules/audio_processing/agc/agc_manager_direct.h" |
| 25 #include "webrtc/modules/audio_processing/audio_buffer.h" | 25 #include "webrtc/modules/audio_processing/audio_buffer.h" |
| 26 #include "webrtc/modules/audio_processing/beamformer/nonlinear_beamformer.h" | 26 #include "webrtc/modules/audio_processing/beamformer/nonlinear_beamformer.h" |
| 27 #include "webrtc/modules/audio_processing/common.h" | 27 #include "webrtc/modules/audio_processing/common.h" |
| 28 #include "webrtc/modules/audio_processing/echo_cancellation_impl.h" | 28 #include "webrtc/modules/audio_processing/echo_cancellation_impl.h" |
| 29 #include "webrtc/modules/audio_processing/echo_control_mobile_impl.h" | 29 #include "webrtc/modules/audio_processing/echo_control_mobile_impl.h" |
| 30 #include "webrtc/modules/audio_processing/gain_control_impl.h" | 30 #include "webrtc/modules/audio_processing/gain_control_impl.h" |
| 31 #include "webrtc/modules/audio_processing/high_pass_filter_impl.h" | 31 #include "webrtc/modules/audio_processing/high_pass_filter_impl.h" |
| 32 #include "webrtc/modules/audio_processing/intelligibility/intelligibility_enhanc er.h" | |
| 32 #include "webrtc/modules/audio_processing/level_estimator_impl.h" | 33 #include "webrtc/modules/audio_processing/level_estimator_impl.h" |
| 33 #include "webrtc/modules/audio_processing/noise_suppression_impl.h" | 34 #include "webrtc/modules/audio_processing/noise_suppression_impl.h" |
| 34 #include "webrtc/modules/audio_processing/processing_component.h" | 35 #include "webrtc/modules/audio_processing/processing_component.h" |
| 35 #include "webrtc/modules/audio_processing/transient/transient_suppressor.h" | 36 #include "webrtc/modules/audio_processing/transient/transient_suppressor.h" |
| 36 #include "webrtc/modules/audio_processing/voice_detection_impl.h" | 37 #include "webrtc/modules/audio_processing/voice_detection_impl.h" |
| 37 #include "webrtc/modules/interface/module_common_types.h" | 38 #include "webrtc/modules/interface/module_common_types.h" |
| 38 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" | 39 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" |
| 39 #include "webrtc/system_wrappers/interface/file_wrapper.h" | 40 #include "webrtc/system_wrappers/interface/file_wrapper.h" |
| 40 #include "webrtc/system_wrappers/interface/logging.h" | 41 #include "webrtc/system_wrappers/interface/logging.h" |
| 41 #include "webrtc/system_wrappers/interface/metrics.h" | 42 #include "webrtc/system_wrappers/interface/metrics.h" |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 177 level_estimator_(NULL), | 178 level_estimator_(NULL), |
| 178 noise_suppression_(NULL), | 179 noise_suppression_(NULL), |
| 179 voice_detection_(NULL), | 180 voice_detection_(NULL), |
| 180 crit_(CriticalSectionWrapper::CreateCriticalSection()), | 181 crit_(CriticalSectionWrapper::CreateCriticalSection()), |
| 181 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP | 182 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP |
| 182 debug_file_(FileWrapper::Create()), | 183 debug_file_(FileWrapper::Create()), |
| 183 event_msg_(new audioproc::Event()), | 184 event_msg_(new audioproc::Event()), |
| 184 #endif | 185 #endif |
| 185 api_format_({{{kSampleRate16kHz, 1, false}, | 186 api_format_({{{kSampleRate16kHz, 1, false}, |
| 186 {kSampleRate16kHz, 1, false}, | 187 {kSampleRate16kHz, 1, false}, |
| 188 {kSampleRate16kHz, 1, false}, | |
| 187 {kSampleRate16kHz, 1, false}}}), | 189 {kSampleRate16kHz, 1, false}}}), |
| 188 fwd_proc_format_(kSampleRate16kHz), | 190 fwd_proc_format_(kSampleRate16kHz), |
| 189 rev_proc_format_(kSampleRate16kHz, 1), | 191 rev_proc_format_(kSampleRate16kHz, 1), |
| 190 split_rate_(kSampleRate16kHz), | 192 split_rate_(kSampleRate16kHz), |
| 191 stream_delay_ms_(0), | 193 stream_delay_ms_(0), |
| 192 delay_offset_ms_(0), | 194 delay_offset_ms_(0), |
| 193 was_stream_delay_set_(false), | 195 was_stream_delay_set_(false), |
| 194 last_stream_delay_ms_(0), | 196 last_stream_delay_ms_(0), |
| 195 last_aec_system_delay_ms_(0), | 197 last_aec_system_delay_ms_(0), |
| 196 stream_delay_jumps_(-1), | 198 stream_delay_jumps_(-1), |
| 197 aec_system_delay_jumps_(-1), | 199 aec_system_delay_jumps_(-1), |
| 198 output_will_be_muted_(false), | 200 output_will_be_muted_(false), |
| 199 key_pressed_(false), | 201 key_pressed_(false), |
| 200 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) | 202 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) |
| 201 use_new_agc_(false), | 203 use_new_agc_(false), |
| 202 #else | 204 #else |
| 203 use_new_agc_(config.Get<ExperimentalAgc>().enabled), | 205 use_new_agc_(config.Get<ExperimentalAgc>().enabled), |
| 204 #endif | 206 #endif |
| 205 agc_startup_min_volume_(config.Get<ExperimentalAgc>().startup_min_volume), | 207 agc_startup_min_volume_(config.Get<ExperimentalAgc>().startup_min_volume), |
| 206 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) | 208 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) |
| 207 transient_suppressor_enabled_(false), | 209 transient_suppressor_enabled_(false), |
| 208 #else | 210 #else |
| 209 transient_suppressor_enabled_(config.Get<ExperimentalNs>().enabled), | 211 transient_suppressor_enabled_(config.Get<ExperimentalNs>().enabled), |
| 210 #endif | 212 #endif |
| 211 beamformer_enabled_(config.Get<Beamforming>().enabled), | 213 beamformer_enabled_(config.Get<Beamforming>().enabled), |
| 212 beamformer_(beamformer), | 214 beamformer_(beamformer), |
| 213 array_geometry_(config.Get<Beamforming>().array_geometry) { | 215 array_geometry_(config.Get<Beamforming>().array_geometry), |
| 216 intelligibility_enabled_(config.Get<Intelligibility>().enabled) { | |
| 214 echo_cancellation_ = new EchoCancellationImpl(this, crit_); | 217 echo_cancellation_ = new EchoCancellationImpl(this, crit_); |
| 215 component_list_.push_back(echo_cancellation_); | 218 component_list_.push_back(echo_cancellation_); |
| 216 | 219 |
| 217 echo_control_mobile_ = new EchoControlMobileImpl(this, crit_); | 220 echo_control_mobile_ = new EchoControlMobileImpl(this, crit_); |
| 218 component_list_.push_back(echo_control_mobile_); | 221 component_list_.push_back(echo_control_mobile_); |
| 219 | 222 |
| 220 gain_control_ = new GainControlImpl(this, crit_); | 223 gain_control_ = new GainControlImpl(this, crit_); |
| 221 component_list_.push_back(gain_control_); | 224 component_list_.push_back(gain_control_); |
| 222 | 225 |
| 223 high_pass_filter_ = new HighPassFilterImpl(this, crit_); | 226 high_pass_filter_ = new HighPassFilterImpl(this, crit_); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 275 return InitializeLocked(processing_config); | 278 return InitializeLocked(processing_config); |
| 276 } | 279 } |
| 277 | 280 |
| 278 int AudioProcessingImpl::Initialize(int input_sample_rate_hz, | 281 int AudioProcessingImpl::Initialize(int input_sample_rate_hz, |
| 279 int output_sample_rate_hz, | 282 int output_sample_rate_hz, |
| 280 int reverse_sample_rate_hz, | 283 int reverse_sample_rate_hz, |
| 281 ChannelLayout input_layout, | 284 ChannelLayout input_layout, |
| 282 ChannelLayout output_layout, | 285 ChannelLayout output_layout, |
| 283 ChannelLayout reverse_layout) { | 286 ChannelLayout reverse_layout) { |
| 284 const ProcessingConfig processing_config = { | 287 const ProcessingConfig processing_config = { |
| 285 {{input_sample_rate_hz, ChannelsFromLayout(input_layout), | 288 {{input_sample_rate_hz, |
| 289 ChannelsFromLayout(input_layout), | |
| 286 LayoutHasKeyboard(input_layout)}, | 290 LayoutHasKeyboard(input_layout)}, |
| 287 {output_sample_rate_hz, ChannelsFromLayout(output_layout), | 291 {output_sample_rate_hz, |
| 292 ChannelsFromLayout(output_layout), | |
| 288 LayoutHasKeyboard(output_layout)}, | 293 LayoutHasKeyboard(output_layout)}, |
| 289 {reverse_sample_rate_hz, ChannelsFromLayout(reverse_layout), | 294 {reverse_sample_rate_hz, |
| 295 ChannelsFromLayout(reverse_layout), | |
| 296 LayoutHasKeyboard(reverse_layout)}, | |
| 297 {reverse_sample_rate_hz, | |
| 298 ChannelsFromLayout(reverse_layout), | |
| 290 LayoutHasKeyboard(reverse_layout)}}}; | 299 LayoutHasKeyboard(reverse_layout)}}}; |
| 291 | 300 |
| 292 return Initialize(processing_config); | 301 return Initialize(processing_config); |
| 293 } | 302 } |
| 294 | 303 |
| 295 int AudioProcessingImpl::Initialize(const ProcessingConfig& processing_config) { | 304 int AudioProcessingImpl::Initialize(const ProcessingConfig& processing_config) { |
| 296 CriticalSectionScoped crit_scoped(crit_); | 305 CriticalSectionScoped crit_scoped(crit_); |
| 297 return InitializeLocked(processing_config); | 306 return InitializeLocked(processing_config); |
| 298 } | 307 } |
| 299 | 308 |
| 300 int AudioProcessingImpl::InitializeLocked() { | 309 int AudioProcessingImpl::InitializeLocked() { |
| 301 const int fwd_audio_buffer_channels = | 310 const int fwd_audio_buffer_channels = |
| 302 beamformer_enabled_ ? api_format_.input_stream().num_channels() | 311 beamformer_enabled_ ? api_format_.input_stream().num_channels() |
| 303 : api_format_.output_stream().num_channels(); | 312 : api_format_.output_stream().num_channels(); |
| 304 if (api_format_.reverse_stream().num_channels() > 0) { | 313 const int rev_audio_buffer_out_num_frames = |
| 314 api_format_.reverse_output_stream().num_frames() == 0 | |
| 315 ? rev_proc_format_.num_frames() | |
| 316 : api_format_.reverse_output_stream().num_frames(); | |
| 317 if (api_format_.reverse_input_stream().num_channels() > 0) { | |
| 305 render_audio_.reset(new AudioBuffer( | 318 render_audio_.reset(new AudioBuffer( |
| 306 api_format_.reverse_stream().num_frames(), | 319 api_format_.reverse_input_stream().num_frames(), |
| 307 api_format_.reverse_stream().num_channels(), | 320 api_format_.reverse_input_stream().num_channels(), |
| 308 rev_proc_format_.num_frames(), rev_proc_format_.num_channels(), | 321 rev_proc_format_.num_frames(), rev_proc_format_.num_channels(), |
| 309 rev_proc_format_.num_frames())); | 322 rev_audio_buffer_out_num_frames)); |
| 310 } else { | 323 } else { |
| 311 render_audio_.reset(nullptr); | 324 render_audio_.reset(nullptr); |
| 312 } | 325 } |
| 313 capture_audio_.reset(new AudioBuffer( | 326 capture_audio_.reset(new AudioBuffer( |
| 314 api_format_.input_stream().num_frames(), | 327 api_format_.input_stream().num_frames(), |
| 315 api_format_.input_stream().num_channels(), fwd_proc_format_.num_frames(), | 328 api_format_.input_stream().num_channels(), fwd_proc_format_.num_frames(), |
| 316 fwd_audio_buffer_channels, api_format_.output_stream().num_frames())); | 329 fwd_audio_buffer_channels, api_format_.output_stream().num_frames())); |
| 317 | 330 |
| 318 // Initialize all components. | 331 // Initialize all components. |
| 319 for (auto item : component_list_) { | 332 for (auto item : component_list_) { |
| 320 int err = item->Initialize(); | 333 int err = item->Initialize(); |
| 321 if (err != kNoError) { | 334 if (err != kNoError) { |
| 322 return err; | 335 return err; |
| 323 } | 336 } |
| 324 } | 337 } |
| 325 | 338 |
| 326 InitializeExperimentalAgc(); | 339 InitializeExperimentalAgc(); |
| 327 | 340 |
| 328 InitializeTransient(); | 341 InitializeTransient(); |
| 329 | 342 |
| 330 InitializeBeamformer(); | 343 InitializeBeamformer(); |
| 331 | 344 |
| 345 InitializeIntelligibility(); | |
| 346 | |
| 332 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP | 347 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP |
| 333 if (debug_file_->Open()) { | 348 if (debug_file_->Open()) { |
| 334 int err = WriteInitMessage(); | 349 int err = WriteInitMessage(); |
| 335 if (err != kNoError) { | 350 if (err != kNoError) { |
| 336 return err; | 351 return err; |
| 337 } | 352 } |
| 338 } | 353 } |
| 339 #endif | 354 #endif |
| 340 | 355 |
| 341 return kNoError; | 356 return kNoError; |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 389 } | 404 } |
| 390 | 405 |
| 391 fwd_proc_format_ = StreamConfig(fwd_proc_rate); | 406 fwd_proc_format_ = StreamConfig(fwd_proc_rate); |
| 392 | 407 |
| 393 // We normally process the reverse stream at 16 kHz. Unless... | 408 // We normally process the reverse stream at 16 kHz. Unless... |
| 394 int rev_proc_rate = kSampleRate16kHz; | 409 int rev_proc_rate = kSampleRate16kHz; |
| 395 if (fwd_proc_format_.sample_rate_hz() == kSampleRate8kHz) { | 410 if (fwd_proc_format_.sample_rate_hz() == kSampleRate8kHz) { |
| 396 // ...the forward stream is at 8 kHz. | 411 // ...the forward stream is at 8 kHz. |
| 397 rev_proc_rate = kSampleRate8kHz; | 412 rev_proc_rate = kSampleRate8kHz; |
| 398 } else { | 413 } else { |
| 399 if (api_format_.reverse_stream().sample_rate_hz() == kSampleRate32kHz) { | 414 if (api_format_.reverse_input_stream().sample_rate_hz() == |
| 415 kSampleRate32kHz) { | |
| 400 // ...or the input is at 32 kHz, in which case we use the splitting | 416 // ...or the input is at 32 kHz, in which case we use the splitting |
| 401 // filter rather than the resampler. | 417 // filter rather than the resampler. |
| 402 rev_proc_rate = kSampleRate32kHz; | 418 rev_proc_rate = kSampleRate32kHz; |
| 403 } | 419 } |
| 404 } | 420 } |
| 405 | 421 |
| 406 // Always downmix the reverse stream to mono for analysis. This has been | 422 // Always downmix the reverse stream to mono for analysis. This has been |
| 407 // demonstrated to work well for AEC in most practical scenarios. | 423 // demonstrated to work well for AEC in most practical scenarios. |
| 408 rev_proc_format_ = StreamConfig(rev_proc_rate, 1); | 424 rev_proc_format_ = StreamConfig(rev_proc_rate, 1); |
| 409 | 425 |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 616 msg->set_delay(stream_delay_ms_); | 632 msg->set_delay(stream_delay_ms_); |
| 617 msg->set_drift(echo_cancellation_->stream_drift_samples()); | 633 msg->set_drift(echo_cancellation_->stream_drift_samples()); |
| 618 msg->set_level(gain_control()->stream_analog_level()); | 634 msg->set_level(gain_control()->stream_analog_level()); |
| 619 msg->set_keypress(key_pressed_); | 635 msg->set_keypress(key_pressed_); |
| 620 } | 636 } |
| 621 #endif | 637 #endif |
| 622 | 638 |
| 623 MaybeUpdateHistograms(); | 639 MaybeUpdateHistograms(); |
| 624 | 640 |
| 625 AudioBuffer* ca = capture_audio_.get(); // For brevity. | 641 AudioBuffer* ca = capture_audio_.get(); // For brevity. |
| 642 | |
| 626 if (use_new_agc_ && gain_control_->is_enabled()) { | 643 if (use_new_agc_ && gain_control_->is_enabled()) { |
| 627 agc_manager_->AnalyzePreProcess(ca->channels()[0], ca->num_channels(), | 644 agc_manager_->AnalyzePreProcess(ca->channels()[0], ca->num_channels(), |
| 628 fwd_proc_format_.num_frames()); | 645 fwd_proc_format_.num_frames()); |
| 629 } | 646 } |
| 630 | 647 |
| 631 bool data_processed = is_data_processed(); | 648 bool data_processed = is_data_processed(); |
| 632 if (analysis_needed(data_processed)) { | 649 if (analysis_needed(data_processed)) { |
| 633 ca->SplitIntoFrequencyBands(); | 650 ca->SplitIntoFrequencyBands(); |
| 634 } | 651 } |
| 635 | 652 |
| 653 if (intelligibility_enabled_) { | |
| 654 intelligibility_enhancer_->AnalyzeCaptureAudio( | |
| 655 ca->split_channels_f(kBand0To8kHz), split_rate_, ca->num_channels()); | |
| 656 } | |
| 657 | |
| 636 if (beamformer_enabled_) { | 658 if (beamformer_enabled_) { |
| 637 beamformer_->ProcessChunk(*ca->split_data_f(), ca->split_data_f()); | 659 beamformer_->ProcessChunk(*ca->split_data_f(), ca->split_data_f()); |
| 638 ca->set_num_channels(1); | 660 ca->set_num_channels(1); |
| 639 } | 661 } |
| 640 | 662 |
| 641 RETURN_ON_ERR(high_pass_filter_->ProcessCaptureAudio(ca)); | 663 RETURN_ON_ERR(high_pass_filter_->ProcessCaptureAudio(ca)); |
| 642 RETURN_ON_ERR(gain_control_->AnalyzeCaptureAudio(ca)); | 664 RETURN_ON_ERR(gain_control_->AnalyzeCaptureAudio(ca)); |
| 643 RETURN_ON_ERR(noise_suppression_->AnalyzeCaptureAudio(ca)); | 665 RETURN_ON_ERR(noise_suppression_->AnalyzeCaptureAudio(ca)); |
| 644 RETURN_ON_ERR(echo_cancellation_->ProcessCaptureAudio(ca)); | 666 RETURN_ON_ERR(echo_cancellation_->ProcessCaptureAudio(ca)); |
| 645 | 667 |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 676 | 698 |
| 677 // The level estimator operates on the recombined data. | 699 // The level estimator operates on the recombined data. |
| 678 RETURN_ON_ERR(level_estimator_->ProcessStream(ca)); | 700 RETURN_ON_ERR(level_estimator_->ProcessStream(ca)); |
| 679 | 701 |
| 680 was_stream_delay_set_ = false; | 702 was_stream_delay_set_ = false; |
| 681 return kNoError; | 703 return kNoError; |
| 682 } | 704 } |
| 683 | 705 |
| 684 int AudioProcessingImpl::AnalyzeReverseStream(const float* const* data, | 706 int AudioProcessingImpl::AnalyzeReverseStream(const float* const* data, |
| 685 int samples_per_channel, | 707 int samples_per_channel, |
| 686 int sample_rate_hz, | 708 int rev_sample_rate_hz, |
| 687 ChannelLayout layout) { | 709 ChannelLayout layout) { |
| 688 const StreamConfig reverse_config = { | 710 const StreamConfig reverse_config = { |
| 689 sample_rate_hz, ChannelsFromLayout(layout), LayoutHasKeyboard(layout), | 711 rev_sample_rate_hz, ChannelsFromLayout(layout), LayoutHasKeyboard(layout), |
| 690 }; | 712 }; |
| 691 if (samples_per_channel != reverse_config.num_frames()) { | 713 if (samples_per_channel != reverse_config.num_frames()) { |
| 692 return kBadDataLengthError; | 714 return kBadDataLengthError; |
| 693 } | 715 } |
| 694 return AnalyzeReverseStream(data, reverse_config); | 716 return AnalyzeReverseStream(data, reverse_config, reverse_config, data); |
| 717 } | |
| 718 | |
| 719 int AudioProcessingImpl::ProcessReverseStream( | |
| 720 const float* const* src, | |
| 721 const StreamConfig& reverse_input_config, | |
| 722 const StreamConfig& reverse_output_config, | |
| 723 float* const* dest) { | |
| 724 RETURN_ON_ERR(AnalyzeReverseStream(src, reverse_input_config, | |
| 725 reverse_output_config, dest)); | |
| 726 if (is_rev_processed()) { | |
|
Andrew MacDonald
2015/07/31 01:22:42
So, we need to change this part. This is what I me
aluebs-webrtc
2015/07/31 16:51:03
I like your proposal. I don't think that dropping
ekm
2015/08/01 04:21:37
I was intrigued and added the AudioConverter metho
| |
| 727 render_audio_->CopyTo(api_format_.reverse_output_stream(), dest); | |
| 728 } | |
| 729 | |
| 730 return kNoError; | |
| 695 } | 731 } |
| 696 | 732 |
| 697 int AudioProcessingImpl::AnalyzeReverseStream( | 733 int AudioProcessingImpl::AnalyzeReverseStream( |
| 698 const float* const* data, | 734 const float* const* src, |
| 699 const StreamConfig& reverse_config) { | 735 const StreamConfig& reverse_input_config, |
| 736 const StreamConfig& reverse_output_config, | |
| 737 const float* const* dest) { | |
| 700 CriticalSectionScoped crit_scoped(crit_); | 738 CriticalSectionScoped crit_scoped(crit_); |
| 701 if (data == NULL) { | 739 if (src == NULL) { |
| 702 return kNullPointerError; | 740 return kNullPointerError; |
| 703 } | 741 } |
| 704 | 742 |
| 705 if (reverse_config.num_channels() <= 0) { | 743 if (reverse_input_config.num_channels() <= 0) { |
| 706 return kBadNumberChannelsError; | 744 return kBadNumberChannelsError; |
| 707 } | 745 } |
| 708 | 746 |
| 709 ProcessingConfig processing_config = api_format_; | 747 ProcessingConfig processing_config = api_format_; |
| 710 processing_config.reverse_stream() = reverse_config; | 748 processing_config.reverse_input_stream() = reverse_input_config; |
| 749 processing_config.reverse_output_stream() = reverse_output_config; | |
| 711 | 750 |
| 712 RETURN_ON_ERR(MaybeInitializeLocked(processing_config)); | 751 RETURN_ON_ERR(MaybeInitializeLocked(processing_config)); |
| 713 assert(reverse_config.num_frames() == | 752 assert(reverse_input_config.num_frames() == |
| 714 api_format_.reverse_stream().num_frames()); | 753 api_format_.reverse_input_stream().num_frames()); |
| 715 | 754 |
| 716 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP | 755 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP |
| 717 if (debug_file_->Open()) { | 756 if (debug_file_->Open()) { |
| 718 event_msg_->set_type(audioproc::Event::REVERSE_STREAM); | 757 event_msg_->set_type(audioproc::Event::REVERSE_STREAM); |
| 719 audioproc::ReverseStream* msg = event_msg_->mutable_reverse_stream(); | 758 audioproc::ReverseStream* msg = event_msg_->mutable_reverse_stream(); |
| 720 const size_t channel_size = | 759 const size_t channel_size = |
| 721 sizeof(float) * api_format_.reverse_stream().num_frames(); | 760 sizeof(float) * api_format_.reverse_input_stream().num_frames(); |
| 722 for (int i = 0; i < api_format_.reverse_stream().num_channels(); ++i) | 761 for (int i = 0; i < api_format_.reverse_input_stream().num_channels(); ++i) |
| 723 msg->add_channel(data[i], channel_size); | 762 msg->add_channel(src[i], channel_size); |
| 724 RETURN_ON_ERR(WriteMessageToDebugFile()); | 763 RETURN_ON_ERR(WriteMessageToDebugFile()); |
| 725 } | 764 } |
| 726 #endif | 765 #endif |
| 727 | 766 |
| 728 render_audio_->CopyFrom(data, api_format_.reverse_stream()); | 767 render_audio_->CopyFrom(src, api_format_.reverse_input_stream()); |
| 729 return AnalyzeReverseStreamLocked(); | 768 return ProcessReverseStreamLocked(); |
| 769 } | |
| 770 | |
| 771 int AudioProcessingImpl::ProcessReverseStream(AudioFrame* frame) { | |
| 772 RETURN_ON_ERR(AnalyzeReverseStream(frame)); | |
| 773 if (is_rev_processed()) { | |
|
Andrew MacDonald
2015/07/31 01:22:42
You can leave this one, because the user has no wa
ekm
2015/08/01 04:21:37
Acknowledged.
| |
| 774 render_audio_->InterleaveTo(frame, true); | |
| 775 } | |
| 776 | |
| 777 return kNoError; | |
| 730 } | 778 } |
| 731 | 779 |
| 732 int AudioProcessingImpl::AnalyzeReverseStream(AudioFrame* frame) { | 780 int AudioProcessingImpl::AnalyzeReverseStream(AudioFrame* frame) { |
| 733 CriticalSectionScoped crit_scoped(crit_); | 781 CriticalSectionScoped crit_scoped(crit_); |
| 734 if (frame == NULL) { | 782 if (frame == NULL) { |
| 735 return kNullPointerError; | 783 return kNullPointerError; |
| 736 } | 784 } |
| 737 // Must be a native rate. | 785 // Must be a native rate. |
| 738 if (frame->sample_rate_hz_ != kSampleRate8kHz && | 786 if (frame->sample_rate_hz_ != kSampleRate8kHz && |
| 739 frame->sample_rate_hz_ != kSampleRate16kHz && | 787 frame->sample_rate_hz_ != kSampleRate16kHz && |
| 740 frame->sample_rate_hz_ != kSampleRate32kHz && | 788 frame->sample_rate_hz_ != kSampleRate32kHz && |
| 741 frame->sample_rate_hz_ != kSampleRate48kHz) { | 789 frame->sample_rate_hz_ != kSampleRate48kHz) { |
| 742 return kBadSampleRateError; | 790 return kBadSampleRateError; |
| 743 } | 791 } |
| 744 // This interface does not tolerate different forward and reverse rates. | 792 // This interface does not tolerate different forward and reverse rates. |
| 745 if (frame->sample_rate_hz_ != api_format_.input_stream().sample_rate_hz()) { | 793 if (frame->sample_rate_hz_ != api_format_.input_stream().sample_rate_hz()) { |
| 746 return kBadSampleRateError; | 794 return kBadSampleRateError; |
| 747 } | 795 } |
| 748 | 796 |
| 749 if (frame->num_channels_ <= 0) { | 797 if (frame->num_channels_ <= 0) { |
| 750 return kBadNumberChannelsError; | 798 return kBadNumberChannelsError; |
| 751 } | 799 } |
| 752 | 800 |
| 753 ProcessingConfig processing_config = api_format_; | 801 ProcessingConfig processing_config = api_format_; |
| 754 processing_config.reverse_stream().set_sample_rate_hz(frame->sample_rate_hz_); | 802 processing_config.reverse_input_stream().set_sample_rate_hz( |
| 755 processing_config.reverse_stream().set_num_channels(frame->num_channels_); | 803 frame->sample_rate_hz_); |
| 804 processing_config.reverse_input_stream().set_num_channels( | |
| 805 frame->num_channels_); | |
| 806 processing_config.reverse_output_stream().set_sample_rate_hz( | |
| 807 frame->sample_rate_hz_); | |
| 808 processing_config.reverse_output_stream().set_num_channels( | |
| 809 frame->num_channels_); | |
| 756 | 810 |
| 757 RETURN_ON_ERR(MaybeInitializeLocked(processing_config)); | 811 RETURN_ON_ERR(MaybeInitializeLocked(processing_config)); |
| 758 if (frame->samples_per_channel_ != | 812 if (frame->samples_per_channel_ != |
| 759 api_format_.reverse_stream().num_frames()) { | 813 api_format_.reverse_input_stream().num_frames()) { |
| 760 return kBadDataLengthError; | 814 return kBadDataLengthError; |
| 761 } | 815 } |
| 762 | 816 |
| 763 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP | 817 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP |
| 764 if (debug_file_->Open()) { | 818 if (debug_file_->Open()) { |
| 765 event_msg_->set_type(audioproc::Event::REVERSE_STREAM); | 819 event_msg_->set_type(audioproc::Event::REVERSE_STREAM); |
| 766 audioproc::ReverseStream* msg = event_msg_->mutable_reverse_stream(); | 820 audioproc::ReverseStream* msg = event_msg_->mutable_reverse_stream(); |
| 767 const size_t data_size = | 821 const size_t data_size = |
| 768 sizeof(int16_t) * frame->samples_per_channel_ * frame->num_channels_; | 822 sizeof(int16_t) * frame->samples_per_channel_ * frame->num_channels_; |
| 769 msg->set_data(frame->data_, data_size); | 823 msg->set_data(frame->data_, data_size); |
| 770 RETURN_ON_ERR(WriteMessageToDebugFile()); | 824 RETURN_ON_ERR(WriteMessageToDebugFile()); |
| 771 } | 825 } |
| 772 #endif | 826 #endif |
| 773 | |
| 774 render_audio_->DeinterleaveFrom(frame); | 827 render_audio_->DeinterleaveFrom(frame); |
| 775 return AnalyzeReverseStreamLocked(); | 828 return ProcessReverseStreamLocked(); |
| 776 } | 829 } |
| 777 | 830 |
| 778 int AudioProcessingImpl::AnalyzeReverseStreamLocked() { | 831 int AudioProcessingImpl::ProcessReverseStreamLocked() { |
| 779 AudioBuffer* ra = render_audio_.get(); // For brevity. | 832 AudioBuffer* ra = render_audio_.get(); // For brevity. |
| 780 if (rev_proc_format_.sample_rate_hz() == kSampleRate32kHz) { | 833 if (rev_proc_format_.sample_rate_hz() == kSampleRate32kHz) { |
| 781 ra->SplitIntoFrequencyBands(); | 834 ra->SplitIntoFrequencyBands(); |
| 782 } | 835 } |
| 783 | 836 |
| 837 if (intelligibility_enabled_) { | |
| 838 intelligibility_enhancer_->ProcessRenderAudio( | |
| 839 ra->split_channels_f(kBand0To8kHz), split_rate_, ra->num_channels()); | |
| 840 } | |
| 841 | |
| 784 RETURN_ON_ERR(echo_cancellation_->ProcessRenderAudio(ra)); | 842 RETURN_ON_ERR(echo_cancellation_->ProcessRenderAudio(ra)); |
| 785 RETURN_ON_ERR(echo_control_mobile_->ProcessRenderAudio(ra)); | 843 RETURN_ON_ERR(echo_control_mobile_->ProcessRenderAudio(ra)); |
| 786 if (!use_new_agc_) { | 844 if (!use_new_agc_) { |
| 787 RETURN_ON_ERR(gain_control_->ProcessRenderAudio(ra)); | 845 RETURN_ON_ERR(gain_control_->ProcessRenderAudio(ra)); |
| 788 } | 846 } |
| 789 | 847 |
| 848 if (rev_proc_format_.sample_rate_hz() == kSampleRate32kHz && | |
| 849 is_rev_processed()) { | |
| 850 ra->MergeFrequencyBands(); | |
| 851 } | |
| 852 | |
| 790 return kNoError; | 853 return kNoError; |
| 791 } | 854 } |
| 792 | 855 |
| 793 int AudioProcessingImpl::set_stream_delay_ms(int delay) { | 856 int AudioProcessingImpl::set_stream_delay_ms(int delay) { |
| 794 Error retval = kNoError; | 857 Error retval = kNoError; |
| 795 was_stream_delay_set_ = true; | 858 was_stream_delay_set_ = true; |
| 796 delay += delay_offset_ms_; | 859 delay += delay_offset_ms_; |
| 797 | 860 |
| 798 if (delay < 0) { | 861 if (delay < 0) { |
| 799 delay = 0; | 862 delay = 0; |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 996 // Only level_estimator_ is enabled. | 1059 // Only level_estimator_ is enabled. |
| 997 return false; | 1060 return false; |
| 998 } else if (fwd_proc_format_.sample_rate_hz() == kSampleRate32kHz || | 1061 } else if (fwd_proc_format_.sample_rate_hz() == kSampleRate32kHz || |
| 999 fwd_proc_format_.sample_rate_hz() == kSampleRate48kHz) { | 1062 fwd_proc_format_.sample_rate_hz() == kSampleRate48kHz) { |
| 1000 // Something besides level_estimator_ is enabled, and we have super-wb. | 1063 // Something besides level_estimator_ is enabled, and we have super-wb. |
| 1001 return true; | 1064 return true; |
| 1002 } | 1065 } |
| 1003 return false; | 1066 return false; |
| 1004 } | 1067 } |
| 1005 | 1068 |
| 1069 bool AudioProcessingImpl::is_rev_processed() const { | |
| 1070 return intelligibility_enabled_ && intelligibility_enhancer_->active(); | |
| 1071 } | |
| 1072 | |
| 1006 void AudioProcessingImpl::InitializeExperimentalAgc() { | 1073 void AudioProcessingImpl::InitializeExperimentalAgc() { |
| 1007 if (use_new_agc_) { | 1074 if (use_new_agc_) { |
| 1008 if (!agc_manager_.get()) { | 1075 if (!agc_manager_.get()) { |
| 1009 agc_manager_.reset(new AgcManagerDirect(gain_control_, | 1076 agc_manager_.reset(new AgcManagerDirect(gain_control_, |
| 1010 gain_control_for_new_agc_.get(), | 1077 gain_control_for_new_agc_.get(), |
| 1011 agc_startup_min_volume_)); | 1078 agc_startup_min_volume_)); |
| 1012 } | 1079 } |
| 1013 agc_manager_->Initialize(); | 1080 agc_manager_->Initialize(); |
| 1014 agc_manager_->SetCaptureMuted(output_will_be_muted_); | 1081 agc_manager_->SetCaptureMuted(output_will_be_muted_); |
| 1015 } | 1082 } |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 1028 | 1095 |
| 1029 void AudioProcessingImpl::InitializeBeamformer() { | 1096 void AudioProcessingImpl::InitializeBeamformer() { |
| 1030 if (beamformer_enabled_) { | 1097 if (beamformer_enabled_) { |
| 1031 if (!beamformer_) { | 1098 if (!beamformer_) { |
| 1032 beamformer_.reset(new NonlinearBeamformer(array_geometry_)); | 1099 beamformer_.reset(new NonlinearBeamformer(array_geometry_)); |
| 1033 } | 1100 } |
| 1034 beamformer_->Initialize(kChunkSizeMs, split_rate_); | 1101 beamformer_->Initialize(kChunkSizeMs, split_rate_); |
| 1035 } | 1102 } |
| 1036 } | 1103 } |
| 1037 | 1104 |
| 1105 void AudioProcessingImpl::InitializeIntelligibility() { | |
| 1106 if (intelligibility_enabled_) { | |
| 1107 IntelligibilityEnhancer::Config config; | |
| 1108 config.sample_rate_hz = split_rate_; | |
| 1109 config.num_capture_channels = capture_audio_->num_channels(); | |
| 1110 config.num_render_channels = render_audio_->num_channels(); | |
| 1111 intelligibility_enhancer_.reset(new IntelligibilityEnhancer(config)); | |
| 1112 } | |
| 1113 } | |
| 1114 | |
| 1038 void AudioProcessingImpl::MaybeUpdateHistograms() { | 1115 void AudioProcessingImpl::MaybeUpdateHistograms() { |
| 1039 static const int kMinDiffDelayMs = 60; | 1116 static const int kMinDiffDelayMs = 60; |
| 1040 | 1117 |
| 1041 if (echo_cancellation()->is_enabled()) { | 1118 if (echo_cancellation()->is_enabled()) { |
| 1042 // Activate delay_jumps_ counters if we know echo_cancellation is runnning. | 1119 // Activate delay_jumps_ counters if we know echo_cancellation is runnning. |
| 1043 // If a stream has echo we know that the echo_cancellation is in process. | 1120 // If a stream has echo we know that the echo_cancellation is in process. |
| 1044 if (stream_delay_jumps_ == -1 && echo_cancellation()->stream_has_echo()) { | 1121 if (stream_delay_jumps_ == -1 && echo_cancellation()->stream_has_echo()) { |
| 1045 stream_delay_jumps_ = 0; | 1122 stream_delay_jumps_ = 0; |
| 1046 } | 1123 } |
| 1047 if (aec_system_delay_jumps_ == -1 && | 1124 if (aec_system_delay_jumps_ == -1 && |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1126 | 1203 |
| 1127 return kNoError; | 1204 return kNoError; |
| 1128 } | 1205 } |
| 1129 | 1206 |
| 1130 int AudioProcessingImpl::WriteInitMessage() { | 1207 int AudioProcessingImpl::WriteInitMessage() { |
| 1131 event_msg_->set_type(audioproc::Event::INIT); | 1208 event_msg_->set_type(audioproc::Event::INIT); |
| 1132 audioproc::Init* msg = event_msg_->mutable_init(); | 1209 audioproc::Init* msg = event_msg_->mutable_init(); |
| 1133 msg->set_sample_rate(api_format_.input_stream().sample_rate_hz()); | 1210 msg->set_sample_rate(api_format_.input_stream().sample_rate_hz()); |
| 1134 msg->set_num_input_channels(api_format_.input_stream().num_channels()); | 1211 msg->set_num_input_channels(api_format_.input_stream().num_channels()); |
| 1135 msg->set_num_output_channels(api_format_.output_stream().num_channels()); | 1212 msg->set_num_output_channels(api_format_.output_stream().num_channels()); |
| 1136 msg->set_num_reverse_channels(api_format_.reverse_stream().num_channels()); | 1213 msg->set_num_reverse_channels( |
| 1137 msg->set_reverse_sample_rate(api_format_.reverse_stream().sample_rate_hz()); | 1214 api_format_.reverse_input_stream().num_channels()); |
| 1215 msg->set_reverse_sample_rate( | |
| 1216 api_format_.reverse_input_stream().sample_rate_hz()); | |
| 1138 msg->set_output_sample_rate(api_format_.output_stream().sample_rate_hz()); | 1217 msg->set_output_sample_rate(api_format_.output_stream().sample_rate_hz()); |
| 1218 // TODO(ekmeyerson): Add reverse output fields to event_msg_. | |
| 1139 | 1219 |
| 1140 int err = WriteMessageToDebugFile(); | 1220 int err = WriteMessageToDebugFile(); |
| 1141 if (err != kNoError) { | 1221 if (err != kNoError) { |
| 1142 return err; | 1222 return err; |
| 1143 } | 1223 } |
| 1144 | 1224 |
| 1145 return kNoError; | 1225 return kNoError; |
| 1146 } | 1226 } |
| 1147 #endif // WEBRTC_AUDIOPROC_DEBUG_DUMP | 1227 #endif // WEBRTC_AUDIOPROC_DEBUG_DUMP |
| 1148 | 1228 |
| 1149 } // namespace webrtc | 1229 } // namespace webrtc |
| OLD | NEW |