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 | |
11 #include "webrtc/modules/audio_processing/audio_processing_impl.h" | 10 #include "webrtc/modules/audio_processing/audio_processing_impl.h" |
12 | 11 |
13 #include <assert.h> | 12 #include <assert.h> |
14 #include <algorithm> | 13 #include <algorithm> |
15 | 14 |
16 #include "webrtc/base/checks.h" | 15 #include "webrtc/base/checks.h" |
17 #include "webrtc/base/platform_file.h" | 16 #include "webrtc/base/platform_file.h" |
17 #include "webrtc/common_audio/audio_converter.h" | |
18 #include "webrtc/common_audio/channel_buffer.h" | |
18 #include "webrtc/common_audio/include/audio_util.h" | 19 #include "webrtc/common_audio/include/audio_util.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)); |
323 if (rev_conversion_needed()) { | |
324 render_converter_ = AudioConverter::Create( | |
325 api_format_.reverse_input_stream().num_channels(), | |
326 api_format_.reverse_input_stream().num_frames(), | |
327 api_format_.reverse_output_stream().num_channels(), | |
328 api_format_.reverse_output_stream().num_frames()); | |
329 } else { | |
330 render_converter_.reset(nullptr); | |
331 } | |
310 } else { | 332 } else { |
311 render_audio_.reset(nullptr); | 333 render_audio_.reset(nullptr); |
334 render_converter_.reset(nullptr); | |
312 } | 335 } |
313 capture_audio_.reset(new AudioBuffer( | 336 capture_audio_.reset(new AudioBuffer( |
314 api_format_.input_stream().num_frames(), | 337 api_format_.input_stream().num_frames(), |
315 api_format_.input_stream().num_channels(), fwd_proc_format_.num_frames(), | 338 api_format_.input_stream().num_channels(), fwd_proc_format_.num_frames(), |
316 fwd_audio_buffer_channels, api_format_.output_stream().num_frames())); | 339 fwd_audio_buffer_channels, api_format_.output_stream().num_frames())); |
317 | 340 |
318 // Initialize all components. | 341 // Initialize all components. |
319 for (auto item : component_list_) { | 342 for (auto item : component_list_) { |
320 int err = item->Initialize(); | 343 int err = item->Initialize(); |
321 if (err != kNoError) { | 344 if (err != kNoError) { |
322 return err; | 345 return err; |
323 } | 346 } |
324 } | 347 } |
325 | 348 |
326 InitializeExperimentalAgc(); | 349 InitializeExperimentalAgc(); |
327 | 350 |
328 InitializeTransient(); | 351 InitializeTransient(); |
329 | 352 |
330 InitializeBeamformer(); | 353 InitializeBeamformer(); |
331 | 354 |
355 InitializeIntelligibility(); | |
356 | |
332 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP | 357 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP |
333 if (debug_file_->Open()) { | 358 if (debug_file_->Open()) { |
334 int err = WriteInitMessage(); | 359 int err = WriteInitMessage(); |
335 if (err != kNoError) { | 360 if (err != kNoError) { |
336 return err; | 361 return err; |
337 } | 362 } |
338 } | 363 } |
339 #endif | 364 #endif |
340 | 365 |
341 return kNoError; | 366 return kNoError; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
389 } | 414 } |
390 | 415 |
391 fwd_proc_format_ = StreamConfig(fwd_proc_rate); | 416 fwd_proc_format_ = StreamConfig(fwd_proc_rate); |
392 | 417 |
393 // We normally process the reverse stream at 16 kHz. Unless... | 418 // We normally process the reverse stream at 16 kHz. Unless... |
394 int rev_proc_rate = kSampleRate16kHz; | 419 int rev_proc_rate = kSampleRate16kHz; |
395 if (fwd_proc_format_.sample_rate_hz() == kSampleRate8kHz) { | 420 if (fwd_proc_format_.sample_rate_hz() == kSampleRate8kHz) { |
396 // ...the forward stream is at 8 kHz. | 421 // ...the forward stream is at 8 kHz. |
397 rev_proc_rate = kSampleRate8kHz; | 422 rev_proc_rate = kSampleRate8kHz; |
398 } else { | 423 } else { |
399 if (api_format_.reverse_stream().sample_rate_hz() == kSampleRate32kHz) { | 424 if (api_format_.reverse_input_stream().sample_rate_hz() == |
425 kSampleRate32kHz) { | |
400 // ...or the input is at 32 kHz, in which case we use the splitting | 426 // ...or the input is at 32 kHz, in which case we use the splitting |
401 // filter rather than the resampler. | 427 // filter rather than the resampler. |
402 rev_proc_rate = kSampleRate32kHz; | 428 rev_proc_rate = kSampleRate32kHz; |
403 } | 429 } |
404 } | 430 } |
405 | 431 |
406 // Always downmix the reverse stream to mono for analysis. This has been | 432 // Always downmix the reverse stream to mono for analysis. This has been |
407 // demonstrated to work well for AEC in most practical scenarios. | 433 // demonstrated to work well for AEC in most practical scenarios. |
408 rev_proc_format_ = StreamConfig(rev_proc_rate, 1); | 434 rev_proc_format_ = StreamConfig(rev_proc_rate, 1); |
409 | 435 |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
616 msg->set_delay(stream_delay_ms_); | 642 msg->set_delay(stream_delay_ms_); |
617 msg->set_drift(echo_cancellation_->stream_drift_samples()); | 643 msg->set_drift(echo_cancellation_->stream_drift_samples()); |
618 msg->set_level(gain_control()->stream_analog_level()); | 644 msg->set_level(gain_control()->stream_analog_level()); |
619 msg->set_keypress(key_pressed_); | 645 msg->set_keypress(key_pressed_); |
620 } | 646 } |
621 #endif | 647 #endif |
622 | 648 |
623 MaybeUpdateHistograms(); | 649 MaybeUpdateHistograms(); |
624 | 650 |
625 AudioBuffer* ca = capture_audio_.get(); // For brevity. | 651 AudioBuffer* ca = capture_audio_.get(); // For brevity. |
652 | |
626 if (use_new_agc_ && gain_control_->is_enabled()) { | 653 if (use_new_agc_ && gain_control_->is_enabled()) { |
627 agc_manager_->AnalyzePreProcess(ca->channels()[0], ca->num_channels(), | 654 agc_manager_->AnalyzePreProcess(ca->channels()[0], ca->num_channels(), |
628 fwd_proc_format_.num_frames()); | 655 fwd_proc_format_.num_frames()); |
629 } | 656 } |
630 | 657 |
631 bool data_processed = is_data_processed(); | 658 bool data_processed = is_data_processed(); |
632 if (analysis_needed(data_processed)) { | 659 if (analysis_needed(data_processed)) { |
633 ca->SplitIntoFrequencyBands(); | 660 ca->SplitIntoFrequencyBands(); |
634 } | 661 } |
635 | 662 |
663 if (intelligibility_enabled_) { | |
664 intelligibility_enhancer_->AnalyzeCaptureAudio( | |
665 ca->split_channels_f(kBand0To8kHz), split_rate_, ca->num_channels()); | |
666 } | |
667 | |
636 if (beamformer_enabled_) { | 668 if (beamformer_enabled_) { |
637 beamformer_->ProcessChunk(*ca->split_data_f(), ca->split_data_f()); | 669 beamformer_->ProcessChunk(*ca->split_data_f(), ca->split_data_f()); |
638 ca->set_num_channels(1); | 670 ca->set_num_channels(1); |
639 } | 671 } |
640 | 672 |
641 RETURN_ON_ERR(high_pass_filter_->ProcessCaptureAudio(ca)); | 673 RETURN_ON_ERR(high_pass_filter_->ProcessCaptureAudio(ca)); |
642 RETURN_ON_ERR(gain_control_->AnalyzeCaptureAudio(ca)); | 674 RETURN_ON_ERR(gain_control_->AnalyzeCaptureAudio(ca)); |
643 RETURN_ON_ERR(noise_suppression_->AnalyzeCaptureAudio(ca)); | 675 RETURN_ON_ERR(noise_suppression_->AnalyzeCaptureAudio(ca)); |
644 RETURN_ON_ERR(echo_cancellation_->ProcessCaptureAudio(ca)); | 676 RETURN_ON_ERR(echo_cancellation_->ProcessCaptureAudio(ca)); |
645 | 677 |
(...skipping 30 matching lines...) Expand all Loading... | |
676 | 708 |
677 // The level estimator operates on the recombined data. | 709 // The level estimator operates on the recombined data. |
678 RETURN_ON_ERR(level_estimator_->ProcessStream(ca)); | 710 RETURN_ON_ERR(level_estimator_->ProcessStream(ca)); |
679 | 711 |
680 was_stream_delay_set_ = false; | 712 was_stream_delay_set_ = false; |
681 return kNoError; | 713 return kNoError; |
682 } | 714 } |
683 | 715 |
684 int AudioProcessingImpl::AnalyzeReverseStream(const float* const* data, | 716 int AudioProcessingImpl::AnalyzeReverseStream(const float* const* data, |
685 int samples_per_channel, | 717 int samples_per_channel, |
686 int sample_rate_hz, | 718 int rev_sample_rate_hz, |
687 ChannelLayout layout) { | 719 ChannelLayout layout) { |
688 const StreamConfig reverse_config = { | 720 const StreamConfig reverse_config = { |
689 sample_rate_hz, ChannelsFromLayout(layout), LayoutHasKeyboard(layout), | 721 rev_sample_rate_hz, ChannelsFromLayout(layout), LayoutHasKeyboard(layout), |
690 }; | 722 }; |
691 if (samples_per_channel != reverse_config.num_frames()) { | 723 if (samples_per_channel != reverse_config.num_frames()) { |
692 return kBadDataLengthError; | 724 return kBadDataLengthError; |
693 } | 725 } |
694 return AnalyzeReverseStream(data, reverse_config); | 726 return AnalyzeReverseStream(data, reverse_config, reverse_config, data); |
727 } | |
728 | |
729 int AudioProcessingImpl::ProcessReverseStream( | |
730 const float* const* src, | |
731 const StreamConfig& reverse_input_config, | |
732 const StreamConfig& reverse_output_config, | |
733 float* const* dest) { | |
734 RETURN_ON_ERR(AnalyzeReverseStream(src, reverse_input_config, | |
735 reverse_output_config, dest)); | |
736 if (is_rev_processed()) { | |
737 render_audio_->CopyTo(api_format_.reverse_output_stream(), dest); | |
738 } else if (rev_conversion_needed()) { | |
739 render_converter_->Convert(src, reverse_input_config.num_frames(), | |
740 dest, reverse_output_config.num_frames()); | |
741 } | |
742 | |
743 return kNoError; | |
695 } | 744 } |
696 | 745 |
697 int AudioProcessingImpl::AnalyzeReverseStream( | 746 int AudioProcessingImpl::AnalyzeReverseStream( |
698 const float* const* data, | 747 const float* const* src, |
699 const StreamConfig& reverse_config) { | 748 const StreamConfig& reverse_input_config, |
749 const StreamConfig& reverse_output_config, | |
750 const float* const* dest) { | |
700 CriticalSectionScoped crit_scoped(crit_); | 751 CriticalSectionScoped crit_scoped(crit_); |
701 if (data == NULL) { | 752 if (src == NULL) { |
702 return kNullPointerError; | 753 return kNullPointerError; |
703 } | 754 } |
704 | 755 |
705 if (reverse_config.num_channels() <= 0) { | 756 if (reverse_input_config.num_channels() <= 0) { |
706 return kBadNumberChannelsError; | 757 return kBadNumberChannelsError; |
707 } | 758 } |
708 | 759 |
709 ProcessingConfig processing_config = api_format_; | 760 ProcessingConfig processing_config = api_format_; |
710 processing_config.reverse_stream() = reverse_config; | 761 processing_config.reverse_input_stream() = reverse_input_config; |
762 processing_config.reverse_output_stream() = reverse_output_config; | |
711 | 763 |
712 RETURN_ON_ERR(MaybeInitializeLocked(processing_config)); | 764 RETURN_ON_ERR(MaybeInitializeLocked(processing_config)); |
713 assert(reverse_config.num_frames() == | 765 assert(reverse_input_config.num_frames() == |
714 api_format_.reverse_stream().num_frames()); | 766 api_format_.reverse_input_stream().num_frames()); |
715 | 767 |
716 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP | 768 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP |
717 if (debug_file_->Open()) { | 769 if (debug_file_->Open()) { |
718 event_msg_->set_type(audioproc::Event::REVERSE_STREAM); | 770 event_msg_->set_type(audioproc::Event::REVERSE_STREAM); |
719 audioproc::ReverseStream* msg = event_msg_->mutable_reverse_stream(); | 771 audioproc::ReverseStream* msg = event_msg_->mutable_reverse_stream(); |
720 const size_t channel_size = | 772 const size_t channel_size = |
721 sizeof(float) * api_format_.reverse_stream().num_frames(); | 773 sizeof(float) * api_format_.reverse_input_stream().num_frames(); |
722 for (int i = 0; i < api_format_.reverse_stream().num_channels(); ++i) | 774 for (int i = 0; i < api_format_.reverse_input_stream().num_channels(); ++i) |
723 msg->add_channel(data[i], channel_size); | 775 msg->add_channel(src[i], channel_size); |
724 RETURN_ON_ERR(WriteMessageToDebugFile()); | 776 RETURN_ON_ERR(WriteMessageToDebugFile()); |
725 } | 777 } |
726 #endif | 778 #endif |
727 | 779 |
728 render_audio_->CopyFrom(data, api_format_.reverse_stream()); | 780 render_audio_->CopyFrom(src, api_format_.reverse_input_stream()); |
729 return AnalyzeReverseStreamLocked(); | 781 return ProcessReverseStreamLocked(); |
782 } | |
783 | |
784 int AudioProcessingImpl::ProcessReverseStream(AudioFrame* frame) { | |
785 RETURN_ON_ERR(AnalyzeReverseStream(frame)); | |
786 if (is_rev_processed()) { | |
787 render_audio_->InterleaveTo(frame, true); | |
788 } | |
789 | |
790 return kNoError; | |
730 } | 791 } |
731 | 792 |
732 int AudioProcessingImpl::AnalyzeReverseStream(AudioFrame* frame) { | 793 int AudioProcessingImpl::AnalyzeReverseStream(AudioFrame* frame) { |
733 CriticalSectionScoped crit_scoped(crit_); | 794 CriticalSectionScoped crit_scoped(crit_); |
734 if (frame == NULL) { | 795 if (frame == NULL) { |
735 return kNullPointerError; | 796 return kNullPointerError; |
736 } | 797 } |
737 // Must be a native rate. | 798 // Must be a native rate. |
738 if (frame->sample_rate_hz_ != kSampleRate8kHz && | 799 if (frame->sample_rate_hz_ != kSampleRate8kHz && |
739 frame->sample_rate_hz_ != kSampleRate16kHz && | 800 frame->sample_rate_hz_ != kSampleRate16kHz && |
740 frame->sample_rate_hz_ != kSampleRate32kHz && | 801 frame->sample_rate_hz_ != kSampleRate32kHz && |
741 frame->sample_rate_hz_ != kSampleRate48kHz) { | 802 frame->sample_rate_hz_ != kSampleRate48kHz) { |
742 return kBadSampleRateError; | 803 return kBadSampleRateError; |
743 } | 804 } |
744 // This interface does not tolerate different forward and reverse rates. | 805 // This interface does not tolerate different forward and reverse rates. |
745 if (frame->sample_rate_hz_ != api_format_.input_stream().sample_rate_hz()) { | 806 if (frame->sample_rate_hz_ != api_format_.input_stream().sample_rate_hz()) { |
746 return kBadSampleRateError; | 807 return kBadSampleRateError; |
747 } | 808 } |
748 | 809 |
749 if (frame->num_channels_ <= 0) { | 810 if (frame->num_channels_ <= 0) { |
750 return kBadNumberChannelsError; | 811 return kBadNumberChannelsError; |
751 } | 812 } |
752 | 813 |
753 ProcessingConfig processing_config = api_format_; | 814 ProcessingConfig processing_config = api_format_; |
754 processing_config.reverse_stream().set_sample_rate_hz(frame->sample_rate_hz_); | 815 processing_config.reverse_input_stream().set_sample_rate_hz( |
755 processing_config.reverse_stream().set_num_channels(frame->num_channels_); | 816 frame->sample_rate_hz_); |
817 processing_config.reverse_input_stream().set_num_channels( | |
818 frame->num_channels_); | |
819 processing_config.reverse_output_stream().set_sample_rate_hz( | |
820 frame->sample_rate_hz_); | |
821 processing_config.reverse_output_stream().set_num_channels( | |
822 frame->num_channels_); | |
756 | 823 |
757 RETURN_ON_ERR(MaybeInitializeLocked(processing_config)); | 824 RETURN_ON_ERR(MaybeInitializeLocked(processing_config)); |
758 if (frame->samples_per_channel_ != | 825 if (frame->samples_per_channel_ != |
759 api_format_.reverse_stream().num_frames()) { | 826 api_format_.reverse_input_stream().num_frames()) { |
760 return kBadDataLengthError; | 827 return kBadDataLengthError; |
761 } | 828 } |
762 | 829 |
763 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP | 830 #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP |
764 if (debug_file_->Open()) { | 831 if (debug_file_->Open()) { |
765 event_msg_->set_type(audioproc::Event::REVERSE_STREAM); | 832 event_msg_->set_type(audioproc::Event::REVERSE_STREAM); |
766 audioproc::ReverseStream* msg = event_msg_->mutable_reverse_stream(); | 833 audioproc::ReverseStream* msg = event_msg_->mutable_reverse_stream(); |
767 const size_t data_size = | 834 const size_t data_size = |
768 sizeof(int16_t) * frame->samples_per_channel_ * frame->num_channels_; | 835 sizeof(int16_t) * frame->samples_per_channel_ * frame->num_channels_; |
769 msg->set_data(frame->data_, data_size); | 836 msg->set_data(frame->data_, data_size); |
770 RETURN_ON_ERR(WriteMessageToDebugFile()); | 837 RETURN_ON_ERR(WriteMessageToDebugFile()); |
771 } | 838 } |
772 #endif | 839 #endif |
773 | |
774 render_audio_->DeinterleaveFrom(frame); | 840 render_audio_->DeinterleaveFrom(frame); |
775 return AnalyzeReverseStreamLocked(); | 841 return ProcessReverseStreamLocked(); |
776 } | 842 } |
777 | 843 |
778 int AudioProcessingImpl::AnalyzeReverseStreamLocked() { | 844 int AudioProcessingImpl::ProcessReverseStreamLocked() { |
779 AudioBuffer* ra = render_audio_.get(); // For brevity. | 845 AudioBuffer* ra = render_audio_.get(); // For brevity. |
780 if (rev_proc_format_.sample_rate_hz() == kSampleRate32kHz) { | 846 if (rev_proc_format_.sample_rate_hz() == kSampleRate32kHz) { |
781 ra->SplitIntoFrequencyBands(); | 847 ra->SplitIntoFrequencyBands(); |
782 } | 848 } |
783 | 849 |
850 if (intelligibility_enabled_) { | |
851 intelligibility_enhancer_->ProcessRenderAudio( | |
852 ra->split_channels_f(kBand0To8kHz), split_rate_, ra->num_channels()); | |
853 } | |
854 | |
784 RETURN_ON_ERR(echo_cancellation_->ProcessRenderAudio(ra)); | 855 RETURN_ON_ERR(echo_cancellation_->ProcessRenderAudio(ra)); |
785 RETURN_ON_ERR(echo_control_mobile_->ProcessRenderAudio(ra)); | 856 RETURN_ON_ERR(echo_control_mobile_->ProcessRenderAudio(ra)); |
786 if (!use_new_agc_) { | 857 if (!use_new_agc_) { |
787 RETURN_ON_ERR(gain_control_->ProcessRenderAudio(ra)); | 858 RETURN_ON_ERR(gain_control_->ProcessRenderAudio(ra)); |
788 } | 859 } |
789 | 860 |
861 if (rev_proc_format_.sample_rate_hz() == kSampleRate32kHz && | |
862 is_rev_processed()) { | |
863 ra->MergeFrequencyBands(); | |
864 } | |
865 | |
790 return kNoError; | 866 return kNoError; |
791 } | 867 } |
792 | 868 |
793 int AudioProcessingImpl::set_stream_delay_ms(int delay) { | 869 int AudioProcessingImpl::set_stream_delay_ms(int delay) { |
794 Error retval = kNoError; | 870 Error retval = kNoError; |
795 was_stream_delay_set_ = true; | 871 was_stream_delay_set_ = true; |
796 delay += delay_offset_ms_; | 872 delay += delay_offset_ms_; |
797 | 873 |
798 if (delay < 0) { | 874 if (delay < 0) { |
799 delay = 0; | 875 delay = 0; |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
996 // Only level_estimator_ is enabled. | 1072 // Only level_estimator_ is enabled. |
997 return false; | 1073 return false; |
998 } else if (fwd_proc_format_.sample_rate_hz() == kSampleRate32kHz || | 1074 } else if (fwd_proc_format_.sample_rate_hz() == kSampleRate32kHz || |
999 fwd_proc_format_.sample_rate_hz() == kSampleRate48kHz) { | 1075 fwd_proc_format_.sample_rate_hz() == kSampleRate48kHz) { |
1000 // Something besides level_estimator_ is enabled, and we have super-wb. | 1076 // Something besides level_estimator_ is enabled, and we have super-wb. |
1001 return true; | 1077 return true; |
1002 } | 1078 } |
1003 return false; | 1079 return false; |
1004 } | 1080 } |
1005 | 1081 |
1082 bool AudioProcessingImpl::is_rev_processed() const { | |
1083 return intelligibility_enabled_ && intelligibility_enhancer_->active(); | |
1084 } | |
1085 | |
1086 bool AudioProcessingImpl::rev_conversion_needed() const { | |
1087 // Only supports conversions supported by AudioConverter. | |
1088 return ((api_format_.reverse_input_stream() != | |
1089 api_format_.reverse_output_stream()) && | |
1090 ((api_format_.reverse_output_stream().num_channels() == | |
ekm
2015/08/01 04:21:37
Added these constraints because CommonFormats/Audi
aluebs-webrtc
2015/08/03 16:30:50
I think 0 channels just means it doesn't need any
Andrew MacDonald
2015/08/05 06:22:39
If we want to be consistent, I think the test is i
ekm
2015/08/07 06:05:59
Done.
| |
1091 api_format_.reverse_input_stream().num_channels()) || | |
1092 (api_format_.reverse_output_stream().num_channels() == 1) || | |
1093 (api_format_.reverse_output_stream().num_channels() == 1))); | |
1094 } | |
1095 | |
1006 void AudioProcessingImpl::InitializeExperimentalAgc() { | 1096 void AudioProcessingImpl::InitializeExperimentalAgc() { |
1007 if (use_new_agc_) { | 1097 if (use_new_agc_) { |
1008 if (!agc_manager_.get()) { | 1098 if (!agc_manager_.get()) { |
1009 agc_manager_.reset(new AgcManagerDirect(gain_control_, | 1099 agc_manager_.reset(new AgcManagerDirect(gain_control_, |
1010 gain_control_for_new_agc_.get(), | 1100 gain_control_for_new_agc_.get(), |
1011 agc_startup_min_volume_)); | 1101 agc_startup_min_volume_)); |
1012 } | 1102 } |
1013 agc_manager_->Initialize(); | 1103 agc_manager_->Initialize(); |
1014 agc_manager_->SetCaptureMuted(output_will_be_muted_); | 1104 agc_manager_->SetCaptureMuted(output_will_be_muted_); |
1015 } | 1105 } |
(...skipping 12 matching lines...) Expand all Loading... | |
1028 | 1118 |
1029 void AudioProcessingImpl::InitializeBeamformer() { | 1119 void AudioProcessingImpl::InitializeBeamformer() { |
1030 if (beamformer_enabled_) { | 1120 if (beamformer_enabled_) { |
1031 if (!beamformer_) { | 1121 if (!beamformer_) { |
1032 beamformer_.reset(new NonlinearBeamformer(array_geometry_)); | 1122 beamformer_.reset(new NonlinearBeamformer(array_geometry_)); |
1033 } | 1123 } |
1034 beamformer_->Initialize(kChunkSizeMs, split_rate_); | 1124 beamformer_->Initialize(kChunkSizeMs, split_rate_); |
1035 } | 1125 } |
1036 } | 1126 } |
1037 | 1127 |
1128 void AudioProcessingImpl::InitializeIntelligibility() { | |
1129 if (intelligibility_enabled_) { | |
1130 IntelligibilityEnhancer::Config config; | |
1131 config.sample_rate_hz = split_rate_; | |
1132 config.num_capture_channels = capture_audio_->num_channels(); | |
1133 config.num_render_channels = render_audio_->num_channels(); | |
1134 intelligibility_enhancer_.reset(new IntelligibilityEnhancer(config)); | |
1135 } | |
1136 } | |
1137 | |
1038 void AudioProcessingImpl::MaybeUpdateHistograms() { | 1138 void AudioProcessingImpl::MaybeUpdateHistograms() { |
1039 static const int kMinDiffDelayMs = 60; | 1139 static const int kMinDiffDelayMs = 60; |
1040 | 1140 |
1041 if (echo_cancellation()->is_enabled()) { | 1141 if (echo_cancellation()->is_enabled()) { |
1042 // Activate delay_jumps_ counters if we know echo_cancellation is runnning. | 1142 // 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. | 1143 // 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()) { | 1144 if (stream_delay_jumps_ == -1 && echo_cancellation()->stream_has_echo()) { |
1045 stream_delay_jumps_ = 0; | 1145 stream_delay_jumps_ = 0; |
1046 } | 1146 } |
1047 if (aec_system_delay_jumps_ == -1 && | 1147 if (aec_system_delay_jumps_ == -1 && |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1126 | 1226 |
1127 return kNoError; | 1227 return kNoError; |
1128 } | 1228 } |
1129 | 1229 |
1130 int AudioProcessingImpl::WriteInitMessage() { | 1230 int AudioProcessingImpl::WriteInitMessage() { |
1131 event_msg_->set_type(audioproc::Event::INIT); | 1231 event_msg_->set_type(audioproc::Event::INIT); |
1132 audioproc::Init* msg = event_msg_->mutable_init(); | 1232 audioproc::Init* msg = event_msg_->mutable_init(); |
1133 msg->set_sample_rate(api_format_.input_stream().sample_rate_hz()); | 1233 msg->set_sample_rate(api_format_.input_stream().sample_rate_hz()); |
1134 msg->set_num_input_channels(api_format_.input_stream().num_channels()); | 1234 msg->set_num_input_channels(api_format_.input_stream().num_channels()); |
1135 msg->set_num_output_channels(api_format_.output_stream().num_channels()); | 1235 msg->set_num_output_channels(api_format_.output_stream().num_channels()); |
1136 msg->set_num_reverse_channels(api_format_.reverse_stream().num_channels()); | 1236 msg->set_num_reverse_channels( |
1137 msg->set_reverse_sample_rate(api_format_.reverse_stream().sample_rate_hz()); | 1237 api_format_.reverse_input_stream().num_channels()); |
1238 msg->set_reverse_sample_rate( | |
1239 api_format_.reverse_input_stream().sample_rate_hz()); | |
1138 msg->set_output_sample_rate(api_format_.output_stream().sample_rate_hz()); | 1240 msg->set_output_sample_rate(api_format_.output_stream().sample_rate_hz()); |
1241 // TODO(ekmeyerson): Add reverse output fields to event_msg_. | |
1139 | 1242 |
1140 int err = WriteMessageToDebugFile(); | 1243 int err = WriteMessageToDebugFile(); |
1141 if (err != kNoError) { | 1244 if (err != kNoError) { |
1142 return err; | 1245 return err; |
1143 } | 1246 } |
1144 | 1247 |
1145 return kNoError; | 1248 return kNoError; |
1146 } | 1249 } |
1147 #endif // WEBRTC_AUDIOPROC_DEBUG_DUMP | 1250 #endif // WEBRTC_AUDIOPROC_DEBUG_DUMP |
1148 | 1251 |
1149 } // namespace webrtc | 1252 } // namespace webrtc |
OLD | NEW |