Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(479)

Side by Side Diff: webrtc/modules/audio_processing/audio_processing_impl.cc

Issue 1234463003: Integrate Intelligibility with APM (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Added support for distinct reverse input/output streams. Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
(...skipping 11 matching lines...) Expand all
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
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
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 if (api_format_.reverse_input_stream().num_channels() > 0) {
305 render_audio_.reset(new AudioBuffer( 314 render_audio_.reset(new AudioBuffer(
306 api_format_.reverse_stream().num_frames(), 315 api_format_.reverse_input_stream().num_frames(),
307 api_format_.reverse_stream().num_channels(), 316 api_format_.reverse_input_stream().num_channels(),
308 rev_proc_format_.num_frames(), rev_proc_format_.num_channels(), 317 rev_proc_format_.num_frames(), rev_proc_format_.num_channels(),
309 rev_proc_format_.num_frames())); 318 api_format_.reverse_output_stream().num_frames()));
310 } else { 319 } else {
311 render_audio_.reset(nullptr); 320 render_audio_.reset(nullptr);
312 } 321 }
313 capture_audio_.reset(new AudioBuffer( 322 capture_audio_.reset(new AudioBuffer(
314 api_format_.input_stream().num_frames(), 323 api_format_.input_stream().num_frames(),
315 api_format_.input_stream().num_channels(), fwd_proc_format_.num_frames(), 324 api_format_.input_stream().num_channels(), fwd_proc_format_.num_frames(),
316 fwd_audio_buffer_channels, api_format_.output_stream().num_frames())); 325 fwd_audio_buffer_channels, api_format_.output_stream().num_frames()));
317 326
318 // Initialize all components. 327 // Initialize all components.
319 for (auto item : component_list_) { 328 for (auto item : component_list_) {
320 int err = item->Initialize(); 329 int err = item->Initialize();
321 if (err != kNoError) { 330 if (err != kNoError) {
322 return err; 331 return err;
323 } 332 }
324 } 333 }
325 334
326 InitializeExperimentalAgc(); 335 InitializeExperimentalAgc();
327 336
328 InitializeTransient(); 337 InitializeTransient();
329 338
330 InitializeBeamformer(); 339 InitializeBeamformer();
331 340
341 InitializeIntelligibility();
342
332 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 343 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
333 if (debug_file_->Open()) { 344 if (debug_file_->Open()) {
334 int err = WriteInitMessage(); 345 int err = WriteInitMessage();
335 if (err != kNoError) { 346 if (err != kNoError) {
336 return err; 347 return err;
337 } 348 }
338 } 349 }
339 #endif 350 #endif
340 351
341 return kNoError; 352 return kNoError;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 } 400 }
390 401
391 fwd_proc_format_ = StreamConfig(fwd_proc_rate); 402 fwd_proc_format_ = StreamConfig(fwd_proc_rate);
392 403
393 // We normally process the reverse stream at 16 kHz. Unless... 404 // We normally process the reverse stream at 16 kHz. Unless...
394 int rev_proc_rate = kSampleRate16kHz; 405 int rev_proc_rate = kSampleRate16kHz;
395 if (fwd_proc_format_.sample_rate_hz() == kSampleRate8kHz) { 406 if (fwd_proc_format_.sample_rate_hz() == kSampleRate8kHz) {
396 // ...the forward stream is at 8 kHz. 407 // ...the forward stream is at 8 kHz.
397 rev_proc_rate = kSampleRate8kHz; 408 rev_proc_rate = kSampleRate8kHz;
398 } else { 409 } else {
399 if (api_format_.reverse_stream().sample_rate_hz() == kSampleRate32kHz) { 410 if (api_format_.reverse_input_stream().sample_rate_hz() ==
411 kSampleRate32kHz) {
400 // ...or the input is at 32 kHz, in which case we use the splitting 412 // ...or the input is at 32 kHz, in which case we use the splitting
401 // filter rather than the resampler. 413 // filter rather than the resampler.
402 rev_proc_rate = kSampleRate32kHz; 414 rev_proc_rate = kSampleRate32kHz;
403 } 415 }
404 } 416 }
405 417
406 // Always downmix the reverse stream to mono for analysis. This has been 418 // Always downmix the reverse stream to mono for analysis. This has been
407 // demonstrated to work well for AEC in most practical scenarios. 419 // demonstrated to work well for AEC in most practical scenarios.
408 rev_proc_format_ = StreamConfig(rev_proc_rate, 1); 420 rev_proc_format_ = StreamConfig(rev_proc_rate, 1);
409 421
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 msg->set_delay(stream_delay_ms_); 628 msg->set_delay(stream_delay_ms_);
617 msg->set_drift(echo_cancellation_->stream_drift_samples()); 629 msg->set_drift(echo_cancellation_->stream_drift_samples());
618 msg->set_level(gain_control()->stream_analog_level()); 630 msg->set_level(gain_control()->stream_analog_level());
619 msg->set_keypress(key_pressed_); 631 msg->set_keypress(key_pressed_);
620 } 632 }
621 #endif 633 #endif
622 634
623 MaybeUpdateHistograms(); 635 MaybeUpdateHistograms();
624 636
625 AudioBuffer* ca = capture_audio_.get(); // For brevity. 637 AudioBuffer* ca = capture_audio_.get(); // For brevity.
638
626 if (use_new_agc_ && gain_control_->is_enabled()) { 639 if (use_new_agc_ && gain_control_->is_enabled()) {
627 agc_manager_->AnalyzePreProcess(ca->channels()[0], ca->num_channels(), 640 agc_manager_->AnalyzePreProcess(ca->channels()[0], ca->num_channels(),
628 fwd_proc_format_.num_frames()); 641 fwd_proc_format_.num_frames());
629 } 642 }
630 643
631 bool data_processed = is_data_processed(); 644 bool data_processed = is_data_processed();
632 if (analysis_needed(data_processed)) { 645 if (analysis_needed(data_processed)) {
633 ca->SplitIntoFrequencyBands(); 646 ca->SplitIntoFrequencyBands();
634 } 647 }
635 648
649 if (intelligibility_enabled_) {
650 intelligibility_enhancer_->AnalyzeCaptureAudio(
651 ca->split_channels_f(kBand0To8kHz), split_rate_, ca->num_channels());
652 }
653
636 if (beamformer_enabled_) { 654 if (beamformer_enabled_) {
637 beamformer_->ProcessChunk(*ca->split_data_f(), ca->split_data_f()); 655 beamformer_->ProcessChunk(*ca->split_data_f(), ca->split_data_f());
638 ca->set_num_channels(1); 656 ca->set_num_channels(1);
639 } 657 }
640 658
641 RETURN_ON_ERR(high_pass_filter_->ProcessCaptureAudio(ca)); 659 RETURN_ON_ERR(high_pass_filter_->ProcessCaptureAudio(ca));
642 RETURN_ON_ERR(gain_control_->AnalyzeCaptureAudio(ca)); 660 RETURN_ON_ERR(gain_control_->AnalyzeCaptureAudio(ca));
643 RETURN_ON_ERR(noise_suppression_->AnalyzeCaptureAudio(ca)); 661 RETURN_ON_ERR(noise_suppression_->AnalyzeCaptureAudio(ca));
644 RETURN_ON_ERR(echo_cancellation_->ProcessCaptureAudio(ca)); 662 RETURN_ON_ERR(echo_cancellation_->ProcessCaptureAudio(ca));
645 663
(...skipping 30 matching lines...) Expand all
676 694
677 // The level estimator operates on the recombined data. 695 // The level estimator operates on the recombined data.
678 RETURN_ON_ERR(level_estimator_->ProcessStream(ca)); 696 RETURN_ON_ERR(level_estimator_->ProcessStream(ca));
679 697
680 was_stream_delay_set_ = false; 698 was_stream_delay_set_ = false;
681 return kNoError; 699 return kNoError;
682 } 700 }
683 701
684 int AudioProcessingImpl::AnalyzeReverseStream(const float* const* data, 702 int AudioProcessingImpl::AnalyzeReverseStream(const float* const* data,
685 int samples_per_channel, 703 int samples_per_channel,
686 int sample_rate_hz, 704 int rev_sample_rate_hz,
687 ChannelLayout layout) { 705 ChannelLayout layout) {
688 const StreamConfig reverse_config = { 706 const StreamConfig reverse_config = {
689 sample_rate_hz, ChannelsFromLayout(layout), LayoutHasKeyboard(layout), 707 rev_sample_rate_hz, ChannelsFromLayout(layout), LayoutHasKeyboard(layout),
690 }; 708 };
691 if (samples_per_channel != reverse_config.num_frames()) { 709 if (samples_per_channel != reverse_config.num_frames()) {
692 return kBadDataLengthError; 710 return kBadDataLengthError;
693 } 711 }
694 return AnalyzeReverseStream(data, reverse_config); 712 return AnalyzeReverseStream(data, reverse_config, reverse_config, data);
713 }
714
715 int AudioProcessingImpl::ProcessReverseStream(
716 const float* const* src,
717 const StreamConfig& reverse_input_config,
718 const StreamConfig& reverse_output_config,
719 float* const* dest) {
720 RETURN_ON_ERR(AnalyzeReverseStream(src, reverse_input_config,
721 reverse_output_config, dest));
722 if (is_rev_processed()) {
723 render_audio_->CopyTo(api_format_.reverse_output_stream(), dest);
724 }
725
726 return kNoError;
695 } 727 }
696 728
697 int AudioProcessingImpl::AnalyzeReverseStream( 729 int AudioProcessingImpl::AnalyzeReverseStream(
698 const float* const* data, 730 const float* const* src,
699 const StreamConfig& reverse_config) { 731 const StreamConfig& reverse_input_config,
732 const StreamConfig& reverse_output_config,
733 const float* const* dest) {
700 CriticalSectionScoped crit_scoped(crit_); 734 CriticalSectionScoped crit_scoped(crit_);
701 if (data == NULL) { 735 if (src == NULL) {
702 return kNullPointerError; 736 return kNullPointerError;
703 } 737 }
704 738
705 if (reverse_config.num_channels() <= 0) { 739 if (reverse_input_config.num_channels() <= 0) {
706 return kBadNumberChannelsError; 740 return kBadNumberChannelsError;
707 } 741 }
708 742
709 ProcessingConfig processing_config = api_format_; 743 ProcessingConfig processing_config = api_format_;
710 processing_config.reverse_stream() = reverse_config; 744 processing_config.reverse_input_stream() = reverse_input_config;
745 processing_config.reverse_output_stream() = reverse_output_config;
711 746
712 RETURN_ON_ERR(MaybeInitializeLocked(processing_config)); 747 RETURN_ON_ERR(MaybeInitializeLocked(processing_config));
713 assert(reverse_config.num_frames() == 748 assert(reverse_input_config.num_frames() ==
714 api_format_.reverse_stream().num_frames()); 749 api_format_.reverse_input_stream().num_frames());
715 750
716 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 751 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
717 if (debug_file_->Open()) { 752 if (debug_file_->Open()) {
718 event_msg_->set_type(audioproc::Event::REVERSE_STREAM); 753 event_msg_->set_type(audioproc::Event::REVERSE_STREAM);
719 audioproc::ReverseStream* msg = event_msg_->mutable_reverse_stream(); 754 audioproc::ReverseStream* msg = event_msg_->mutable_reverse_stream();
720 const size_t channel_size = 755 const size_t channel_size =
721 sizeof(float) * api_format_.reverse_stream().num_frames(); 756 sizeof(float) * api_format_.reverse_input_stream().num_frames();
722 for (int i = 0; i < api_format_.reverse_stream().num_channels(); ++i) 757 for (int i = 0; i < api_format_.reverse_input_stream().num_channels(); ++i)
723 msg->add_channel(data[i], channel_size); 758 msg->add_channel(src[i], channel_size);
724 RETURN_ON_ERR(WriteMessageToDebugFile()); 759 RETURN_ON_ERR(WriteMessageToDebugFile());
725 } 760 }
726 #endif 761 #endif
727 762
728 render_audio_->CopyFrom(data, api_format_.reverse_stream()); 763 render_audio_->CopyFrom(src, api_format_.reverse_input_stream());
729 return AnalyzeReverseStreamLocked(); 764 return ProcessReverseStreamLocked();
765 }
766
767 int AudioProcessingImpl::ProcessReverseStream(AudioFrame* frame) {
768 RETURN_ON_ERR(AnalyzeReverseStream(frame));
769 if (is_rev_processed()) {
770 render_audio_->InterleaveTo(frame, true);
771 }
772
773 return kNoError;
730 } 774 }
731 775
732 int AudioProcessingImpl::AnalyzeReverseStream(AudioFrame* frame) { 776 int AudioProcessingImpl::AnalyzeReverseStream(AudioFrame* frame) {
733 CriticalSectionScoped crit_scoped(crit_); 777 CriticalSectionScoped crit_scoped(crit_);
734 if (frame == NULL) { 778 if (frame == NULL) {
735 return kNullPointerError; 779 return kNullPointerError;
736 } 780 }
737 // Must be a native rate. 781 // Must be a native rate.
738 if (frame->sample_rate_hz_ != kSampleRate8kHz && 782 if (frame->sample_rate_hz_ != kSampleRate8kHz &&
739 frame->sample_rate_hz_ != kSampleRate16kHz && 783 frame->sample_rate_hz_ != kSampleRate16kHz &&
740 frame->sample_rate_hz_ != kSampleRate32kHz && 784 frame->sample_rate_hz_ != kSampleRate32kHz &&
741 frame->sample_rate_hz_ != kSampleRate48kHz) { 785 frame->sample_rate_hz_ != kSampleRate48kHz) {
742 return kBadSampleRateError; 786 return kBadSampleRateError;
743 } 787 }
744 // This interface does not tolerate different forward and reverse rates. 788 // This interface does not tolerate different forward and reverse rates.
745 if (frame->sample_rate_hz_ != api_format_.input_stream().sample_rate_hz()) { 789 if (frame->sample_rate_hz_ != api_format_.input_stream().sample_rate_hz()) {
746 return kBadSampleRateError; 790 return kBadSampleRateError;
747 } 791 }
748 792
749 if (frame->num_channels_ <= 0) { 793 if (frame->num_channels_ <= 0) {
750 return kBadNumberChannelsError; 794 return kBadNumberChannelsError;
751 } 795 }
752 796
753 ProcessingConfig processing_config = api_format_; 797 ProcessingConfig processing_config = api_format_;
754 processing_config.reverse_stream().set_sample_rate_hz(frame->sample_rate_hz_); 798 processing_config.reverse_input_stream().set_sample_rate_hz(
755 processing_config.reverse_stream().set_num_channels(frame->num_channels_); 799 frame->sample_rate_hz_);
800 processing_config.reverse_input_stream().set_num_channels(
801 frame->num_channels_);
802 processing_config.reverse_output_stream().set_sample_rate_hz(
803 frame->sample_rate_hz_);
804 processing_config.reverse_output_stream().set_num_channels(
805 frame->num_channels_);
756 806
757 RETURN_ON_ERR(MaybeInitializeLocked(processing_config)); 807 RETURN_ON_ERR(MaybeInitializeLocked(processing_config));
758 if (frame->samples_per_channel_ != 808 if (frame->samples_per_channel_ !=
759 api_format_.reverse_stream().num_frames()) { 809 api_format_.reverse_input_stream().num_frames()) {
760 return kBadDataLengthError; 810 return kBadDataLengthError;
761 } 811 }
762 812
763 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP 813 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
764 if (debug_file_->Open()) { 814 if (debug_file_->Open()) {
765 event_msg_->set_type(audioproc::Event::REVERSE_STREAM); 815 event_msg_->set_type(audioproc::Event::REVERSE_STREAM);
766 audioproc::ReverseStream* msg = event_msg_->mutable_reverse_stream(); 816 audioproc::ReverseStream* msg = event_msg_->mutable_reverse_stream();
767 const size_t data_size = 817 const size_t data_size =
768 sizeof(int16_t) * frame->samples_per_channel_ * frame->num_channels_; 818 sizeof(int16_t) * frame->samples_per_channel_ * frame->num_channels_;
769 msg->set_data(frame->data_, data_size); 819 msg->set_data(frame->data_, data_size);
770 RETURN_ON_ERR(WriteMessageToDebugFile()); 820 RETURN_ON_ERR(WriteMessageToDebugFile());
771 } 821 }
772 #endif 822 #endif
773
774 render_audio_->DeinterleaveFrom(frame); 823 render_audio_->DeinterleaveFrom(frame);
775 return AnalyzeReverseStreamLocked(); 824 return ProcessReverseStreamLocked();
776 } 825 }
777 826
778 int AudioProcessingImpl::AnalyzeReverseStreamLocked() { 827 int AudioProcessingImpl::ProcessReverseStreamLocked() {
779 AudioBuffer* ra = render_audio_.get(); // For brevity. 828 AudioBuffer* ra = render_audio_.get(); // For brevity.
780 if (rev_proc_format_.sample_rate_hz() == kSampleRate32kHz) { 829 if (rev_proc_format_.sample_rate_hz() == kSampleRate32kHz) {
781 ra->SplitIntoFrequencyBands(); 830 ra->SplitIntoFrequencyBands();
782 } 831 }
783 832
833 if (intelligibility_enabled_) {
834 intelligibility_enhancer_->ProcessRenderAudio(
835 ra->split_channels_f(kBand0To8kHz), split_rate_, ra->num_channels());
836 }
837
784 RETURN_ON_ERR(echo_cancellation_->ProcessRenderAudio(ra)); 838 RETURN_ON_ERR(echo_cancellation_->ProcessRenderAudio(ra));
785 RETURN_ON_ERR(echo_control_mobile_->ProcessRenderAudio(ra)); 839 RETURN_ON_ERR(echo_control_mobile_->ProcessRenderAudio(ra));
786 if (!use_new_agc_) { 840 if (!use_new_agc_) {
787 RETURN_ON_ERR(gain_control_->ProcessRenderAudio(ra)); 841 RETURN_ON_ERR(gain_control_->ProcessRenderAudio(ra));
788 } 842 }
789 843
844 if (rev_proc_format_.sample_rate_hz() == kSampleRate32kHz &&
845 is_rev_processed()) {
846 ra->MergeFrequencyBands();
847 }
848
790 return kNoError; 849 return kNoError;
791 } 850 }
792 851
793 int AudioProcessingImpl::set_stream_delay_ms(int delay) { 852 int AudioProcessingImpl::set_stream_delay_ms(int delay) {
794 Error retval = kNoError; 853 Error retval = kNoError;
795 was_stream_delay_set_ = true; 854 was_stream_delay_set_ = true;
796 delay += delay_offset_ms_; 855 delay += delay_offset_ms_;
797 856
798 if (delay < 0) { 857 if (delay < 0) {
799 delay = 0; 858 delay = 0;
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
996 // Only level_estimator_ is enabled. 1055 // Only level_estimator_ is enabled.
997 return false; 1056 return false;
998 } else if (fwd_proc_format_.sample_rate_hz() == kSampleRate32kHz || 1057 } else if (fwd_proc_format_.sample_rate_hz() == kSampleRate32kHz ||
999 fwd_proc_format_.sample_rate_hz() == kSampleRate48kHz) { 1058 fwd_proc_format_.sample_rate_hz() == kSampleRate48kHz) {
1000 // Something besides level_estimator_ is enabled, and we have super-wb. 1059 // Something besides level_estimator_ is enabled, and we have super-wb.
1001 return true; 1060 return true;
1002 } 1061 }
1003 return false; 1062 return false;
1004 } 1063 }
1005 1064
1065 bool AudioProcessingImpl::is_rev_processed() const {
1066 return intelligibility_enabled_ && intelligibility_enhancer_->active();
1067 }
1068
1006 void AudioProcessingImpl::InitializeExperimentalAgc() { 1069 void AudioProcessingImpl::InitializeExperimentalAgc() {
1007 if (use_new_agc_) { 1070 if (use_new_agc_) {
1008 if (!agc_manager_.get()) { 1071 if (!agc_manager_.get()) {
1009 agc_manager_.reset(new AgcManagerDirect(gain_control_, 1072 agc_manager_.reset(new AgcManagerDirect(gain_control_,
1010 gain_control_for_new_agc_.get(), 1073 gain_control_for_new_agc_.get(),
1011 agc_startup_min_volume_)); 1074 agc_startup_min_volume_));
1012 } 1075 }
1013 agc_manager_->Initialize(); 1076 agc_manager_->Initialize();
1014 agc_manager_->SetCaptureMuted(output_will_be_muted_); 1077 agc_manager_->SetCaptureMuted(output_will_be_muted_);
1015 } 1078 }
(...skipping 12 matching lines...) Expand all
1028 1091
1029 void AudioProcessingImpl::InitializeBeamformer() { 1092 void AudioProcessingImpl::InitializeBeamformer() {
1030 if (beamformer_enabled_) { 1093 if (beamformer_enabled_) {
1031 if (!beamformer_) { 1094 if (!beamformer_) {
1032 beamformer_.reset(new NonlinearBeamformer(array_geometry_)); 1095 beamformer_.reset(new NonlinearBeamformer(array_geometry_));
1033 } 1096 }
1034 beamformer_->Initialize(kChunkSizeMs, split_rate_); 1097 beamformer_->Initialize(kChunkSizeMs, split_rate_);
1035 } 1098 }
1036 } 1099 }
1037 1100
1101 void AudioProcessingImpl::InitializeIntelligibility() {
1102 if (intelligibility_enabled_) {
1103 IntelligibilityEnhancer::Config config;
1104 config.sample_rate_hz = split_rate_;
1105 config.num_capture_channels = capture_audio_->num_channels();
1106 config.num_render_channels = render_audio_->num_channels();
1107 intelligibility_enhancer_.reset(new IntelligibilityEnhancer(config));
1108 }
1109 }
1110
1038 void AudioProcessingImpl::MaybeUpdateHistograms() { 1111 void AudioProcessingImpl::MaybeUpdateHistograms() {
1039 static const int kMinDiffDelayMs = 60; 1112 static const int kMinDiffDelayMs = 60;
1040 1113
1041 if (echo_cancellation()->is_enabled()) { 1114 if (echo_cancellation()->is_enabled()) {
1042 // Activate delay_jumps_ counters if we know echo_cancellation is runnning. 1115 // 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. 1116 // 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()) { 1117 if (stream_delay_jumps_ == -1 && echo_cancellation()->stream_has_echo()) {
1045 stream_delay_jumps_ = 0; 1118 stream_delay_jumps_ = 0;
1046 } 1119 }
1047 if (aec_system_delay_jumps_ == -1 && 1120 if (aec_system_delay_jumps_ == -1 &&
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1126 1199
1127 return kNoError; 1200 return kNoError;
1128 } 1201 }
1129 1202
1130 int AudioProcessingImpl::WriteInitMessage() { 1203 int AudioProcessingImpl::WriteInitMessage() {
1131 event_msg_->set_type(audioproc::Event::INIT); 1204 event_msg_->set_type(audioproc::Event::INIT);
1132 audioproc::Init* msg = event_msg_->mutable_init(); 1205 audioproc::Init* msg = event_msg_->mutable_init();
1133 msg->set_sample_rate(api_format_.input_stream().sample_rate_hz()); 1206 msg->set_sample_rate(api_format_.input_stream().sample_rate_hz());
1134 msg->set_num_input_channels(api_format_.input_stream().num_channels()); 1207 msg->set_num_input_channels(api_format_.input_stream().num_channels());
1135 msg->set_num_output_channels(api_format_.output_stream().num_channels()); 1208 msg->set_num_output_channels(api_format_.output_stream().num_channels());
1136 msg->set_num_reverse_channels(api_format_.reverse_stream().num_channels()); 1209 msg->set_num_reverse_channels(
1137 msg->set_reverse_sample_rate(api_format_.reverse_stream().sample_rate_hz()); 1210 api_format_.reverse_input_stream().num_channels());
1211 msg->set_reverse_sample_rate(
1212 api_format_.reverse_input_stream().sample_rate_hz());
1138 msg->set_output_sample_rate(api_format_.output_stream().sample_rate_hz()); 1213 msg->set_output_sample_rate(api_format_.output_stream().sample_rate_hz());
1214 // TODO(ekmeyerson): Add reverse output fields to event_msg_.
1139 1215
1140 int err = WriteMessageToDebugFile(); 1216 int err = WriteMessageToDebugFile();
1141 if (err != kNoError) { 1217 if (err != kNoError) {
1142 return err; 1218 return err;
1143 } 1219 }
1144 1220
1145 return kNoError; 1221 return kNoError;
1146 } 1222 }
1147 #endif // WEBRTC_AUDIOPROC_DEBUG_DUMP 1223 #endif // WEBRTC_AUDIOPROC_DEBUG_DUMP
1148 1224
1149 } // namespace webrtc 1225 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698