 Chromium Code Reviews
 Chromium Code Reviews Issue 2427553003:
  Moved the AEC render sample queue into the audio processing module  (Closed)
    
  
    Issue 2427553003:
  Moved the AEC render sample queue into the audio processing module  (Closed) 
  | 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 | 
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 112 return uppermost_native_rate; | 112 return uppermost_native_rate; | 
| 113 } | 113 } | 
| 114 if (rate >= minimum_rate) { | 114 if (rate >= minimum_rate) { | 
| 115 return rate; | 115 return rate; | 
| 116 } | 116 } | 
| 117 } | 117 } | 
| 118 RTC_NOTREACHED(); | 118 RTC_NOTREACHED(); | 
| 119 return uppermost_native_rate; | 119 return uppermost_native_rate; | 
| 120 } | 120 } | 
| 121 | 121 | 
| 122 // Maximum length that a frame of samples can have. | |
| 123 static const size_t kMaxAllowedValuesOfSamplesPerFrame = 160; | |
| 124 // Maximum number of frames to buffer in the render queue. | |
| 125 // TODO(peah): Decrease this once we properly handle hugely unbalanced | |
| 126 // reverse and forward call numbers. | |
| 127 static const size_t kMaxNumFramesToBuffer = 100; | |
| 128 | |
| 122 } // namespace | 129 } // namespace | 
| 123 | 130 | 
| 124 // Throughout webrtc, it's assumed that success is represented by zero. | 131 // Throughout webrtc, it's assumed that success is represented by zero. | 
| 125 static_assert(AudioProcessing::kNoError == 0, "kNoError must be zero"); | 132 static_assert(AudioProcessing::kNoError == 0, "kNoError must be zero"); | 
| 126 | 133 | 
| 127 AudioProcessingImpl::ApmSubmoduleStates::ApmSubmoduleStates() {} | 134 AudioProcessingImpl::ApmSubmoduleStates::ApmSubmoduleStates() {} | 
| 128 | 135 | 
| 129 bool AudioProcessingImpl::ApmSubmoduleStates::Update( | 136 bool AudioProcessingImpl::ApmSubmoduleStates::Update( | 
| 130 bool high_pass_filter_enabled, | 137 bool high_pass_filter_enabled, | 
| 131 bool echo_canceller_enabled, | 138 bool echo_canceller_enabled, | 
| (...skipping 291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 423 } | 430 } | 
| 424 capture_.capture_audio.reset( | 431 capture_.capture_audio.reset( | 
| 425 new AudioBuffer(formats_.api_format.input_stream().num_frames(), | 432 new AudioBuffer(formats_.api_format.input_stream().num_frames(), | 
| 426 formats_.api_format.input_stream().num_channels(), | 433 formats_.api_format.input_stream().num_channels(), | 
| 427 capture_nonlocked_.capture_processing_format.num_frames(), | 434 capture_nonlocked_.capture_processing_format.num_frames(), | 
| 428 capture_audiobuffer_num_channels, | 435 capture_audiobuffer_num_channels, | 
| 429 formats_.api_format.output_stream().num_frames())); | 436 formats_.api_format.output_stream().num_frames())); | 
| 430 | 437 | 
| 431 public_submodules_->gain_control->Initialize(num_proc_channels(), | 438 public_submodules_->gain_control->Initialize(num_proc_channels(), | 
| 432 proc_sample_rate_hz()); | 439 proc_sample_rate_hz()); | 
| 440 | |
| 433 public_submodules_->echo_cancellation->Initialize( | 441 public_submodules_->echo_cancellation->Initialize( | 
| 434 proc_sample_rate_hz(), num_reverse_channels(), num_output_channels(), | 442 proc_sample_rate_hz(), num_reverse_channels(), num_output_channels(), | 
| 435 num_proc_channels()); | 443 num_proc_channels()); | 
| 444 AllocateRenderQueue(); | |
| 445 | |
| 436 public_submodules_->echo_control_mobile->Initialize( | 446 public_submodules_->echo_control_mobile->Initialize( | 
| 437 proc_split_sample_rate_hz(), num_reverse_channels(), | 447 proc_split_sample_rate_hz(), num_reverse_channels(), | 
| 438 num_output_channels()); | 448 num_output_channels()); | 
| 439 if (constants_.use_experimental_agc) { | 449 if (constants_.use_experimental_agc) { | 
| 440 if (!private_submodules_->agc_manager.get()) { | 450 if (!private_submodules_->agc_manager.get()) { | 
| 441 private_submodules_->agc_manager.reset(new AgcManagerDirect( | 451 private_submodules_->agc_manager.reset(new AgcManagerDirect( | 
| 442 public_submodules_->gain_control.get(), | 452 public_submodules_->gain_control.get(), | 
| 443 public_submodules_->gain_control_for_experimental_agc.get(), | 453 public_submodules_->gain_control_for_experimental_agc.get(), | 
| 444 constants_.agc_startup_min_volume)); | 454 constants_.agc_startup_min_volume)); | 
| 445 } | 455 } | 
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 690 const StreamConfig& output_config, | 700 const StreamConfig& output_config, | 
| 691 float* const* dest) { | 701 float* const* dest) { | 
| 692 TRACE_EVENT0("webrtc", "AudioProcessing::ProcessStream_StreamConfig"); | 702 TRACE_EVENT0("webrtc", "AudioProcessing::ProcessStream_StreamConfig"); | 
| 693 ProcessingConfig processing_config; | 703 ProcessingConfig processing_config; | 
| 694 bool reinitialization_required = false; | 704 bool reinitialization_required = false; | 
| 695 { | 705 { | 
| 696 // Acquire the capture lock in order to safely call the function | 706 // Acquire the capture lock in order to safely call the function | 
| 697 // that retrieves the render side data. This function accesses apm | 707 // that retrieves the render side data. This function accesses apm | 
| 698 // getters that need the capture lock held when being called. | 708 // getters that need the capture lock held when being called. | 
| 699 rtc::CritScope cs_capture(&crit_capture_); | 709 rtc::CritScope cs_capture(&crit_capture_); | 
| 700 public_submodules_->echo_cancellation->ReadQueuedRenderData(); | 710 EmptyQueuedRenderAudio(); | 
| 701 public_submodules_->echo_control_mobile->ReadQueuedRenderData(); | 711 public_submodules_->echo_control_mobile->ReadQueuedRenderData(); | 
| 702 public_submodules_->gain_control->ReadQueuedRenderData(); | 712 public_submodules_->gain_control->ReadQueuedRenderData(); | 
| 703 | 713 | 
| 704 if (!src || !dest) { | 714 if (!src || !dest) { | 
| 705 return kNullPointerError; | 715 return kNullPointerError; | 
| 706 } | 716 } | 
| 707 | 717 | 
| 708 processing_config = formats_.api_format; | 718 processing_config = formats_.api_format; | 
| 709 reinitialization_required = UpdateActiveSubmoduleStates(); | 719 reinitialization_required = UpdateActiveSubmoduleStates(); | 
| 710 } | 720 } | 
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 750 msg->add_output_channel(dest[i], channel_size); | 760 msg->add_output_channel(dest[i], channel_size); | 
| 751 RETURN_ON_ERR(WriteMessageToDebugFile(debug_dump_.debug_file.get(), | 761 RETURN_ON_ERR(WriteMessageToDebugFile(debug_dump_.debug_file.get(), | 
| 752 &debug_dump_.num_bytes_left_for_log_, | 762 &debug_dump_.num_bytes_left_for_log_, | 
| 753 &crit_debug_, &debug_dump_.capture)); | 763 &crit_debug_, &debug_dump_.capture)); | 
| 754 } | 764 } | 
| 755 #endif | 765 #endif | 
| 756 | 766 | 
| 757 return kNoError; | 767 return kNoError; | 
| 758 } | 768 } | 
| 759 | 769 | 
| 770 void AudioProcessingImpl::QueueRenderAudio(const AudioBuffer* audio) { | |
| 771 EchoCancellationImpl::PackRenderAudioBuffer( | |
| 772 audio, num_output_channels(), num_proc_channels(), &render_queue_buffer_); | |
| 773 | |
| 774 RTC_DCHECK_GE(160u, audio->num_frames_per_band()); | |
| 
ivoc
2016/10/17 14:11:36
I think this should actually be RTC_DCHECK_LE(audi
 
peah-webrtc
2016/10/19 05:19:44
That makes a lot of sense! But I think that curren
 | |
| 775 | |
| 776 // Insert the samples into the queue. | |
| 777 if (!render_signal_queue_->Insert(&render_queue_buffer_)) { | |
| 778 // The data queue is full and needs to be emptied. | |
| 779 EmptyQueuedRenderAudio(); | |
| 780 | |
| 781 // Retry the insert (should always work). | |
| 782 bool result = render_signal_queue_->Insert(&render_queue_buffer_); | |
| 783 RTC_DCHECK(result); | |
| 784 } | |
| 785 } | |
| 786 | |
| 787 void AudioProcessingImpl::AllocateRenderQueue() { | |
| 788 const size_t new_render_queue_element_max_size = | |
| 789 std::max<size_t>(static_cast<size_t>(1), | |
| 
ivoc
2016/10/17 14:11:36
I think you can remove the <size_t> after std::max
 
peah-webrtc
2016/10/19 05:19:44
Done.
 | |
| 790 kMaxAllowedValuesOfSamplesPerFrame * | |
| 791 EchoCancellationImpl::NumCancellersRequired( | |
| 792 num_output_channels(), num_reverse_channels())); | |
| 793 | |
| 794 // Reallocate the queue if the queue item size is too small to fit the | |
| 795 // data to put in the queue. | |
| 796 if (render_queue_element_max_size_ < new_render_queue_element_max_size) { | |
| 797 render_queue_element_max_size_ = new_render_queue_element_max_size; | |
| 798 | |
| 799 std::vector<float> template_queue_element(render_queue_element_max_size_); | |
| 800 | |
| 801 render_signal_queue_.reset( | |
| 802 new SwapQueue<std::vector<float>, RenderQueueItemVerifier<float>>( | |
| 803 kMaxNumFramesToBuffer, template_queue_element, | |
| 804 RenderQueueItemVerifier<float>(render_queue_element_max_size_))); | |
| 805 | |
| 806 render_queue_buffer_.resize(render_queue_element_max_size_); | |
| 807 capture_queue_buffer_.resize(render_queue_element_max_size_); | |
| 808 } else { | |
| 809 render_signal_queue_->Clear(); | |
| 810 } | |
| 811 } | |
| 812 | |
| 813 void AudioProcessingImpl::EmptyQueuedRenderAudio() { | |
| 814 rtc::CritScope cs_capture(&crit_capture_); | |
| 815 while (render_signal_queue_->Remove(&capture_queue_buffer_)) { | |
| 816 public_submodules_->echo_cancellation->ProcessRenderAudio( | |
| 817 capture_queue_buffer_); | |
| 818 } | |
| 819 } | |
| 820 | |
| 760 int AudioProcessingImpl::ProcessStream(AudioFrame* frame) { | 821 int AudioProcessingImpl::ProcessStream(AudioFrame* frame) { | 
| 761 TRACE_EVENT0("webrtc", "AudioProcessing::ProcessStream_AudioFrame"); | 822 TRACE_EVENT0("webrtc", "AudioProcessing::ProcessStream_AudioFrame"); | 
| 762 { | 823 { | 
| 763 // Acquire the capture lock in order to safely call the function | 824 // Acquire the capture lock in order to safely call the function | 
| 764 // that retrieves the render side data. This function accesses apm | 825 // that retrieves the render side data. This function accesses apm | 
| 765 // getters that need the capture lock held when being called. | 826 // getters that need the capture lock held when being called. | 
| 766 // The lock needs to be released as | 827 // The lock needs to be released as | 
| 767 // public_submodules_->echo_control_mobile->is_enabled() aquires this lock | 828 // public_submodules_->echo_control_mobile->is_enabled() aquires this lock | 
| 768 // as well. | 829 // as well. | 
| 769 rtc::CritScope cs_capture(&crit_capture_); | 830 rtc::CritScope cs_capture(&crit_capture_); | 
| 770 public_submodules_->echo_cancellation->ReadQueuedRenderData(); | 831 EmptyQueuedRenderAudio(); | 
| 771 public_submodules_->echo_control_mobile->ReadQueuedRenderData(); | 832 public_submodules_->echo_control_mobile->ReadQueuedRenderData(); | 
| 772 public_submodules_->gain_control->ReadQueuedRenderData(); | 833 public_submodules_->gain_control->ReadQueuedRenderData(); | 
| 773 } | 834 } | 
| 774 | 835 | 
| 775 if (!frame) { | 836 if (!frame) { | 
| 776 return kNullPointerError; | 837 return kNullPointerError; | 
| 777 } | 838 } | 
| 778 // Must be a native rate. | 839 // Must be a native rate. | 
| 779 if (frame->sample_rate_hz_ != kSampleRate8kHz && | 840 if (frame->sample_rate_hz_ != kSampleRate8kHz && | 
| 780 frame->sample_rate_hz_ != kSampleRate16kHz && | 841 frame->sample_rate_hz_ != kSampleRate16kHz && | 
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1123 render_buffer->SplitIntoFrequencyBands(); | 1184 render_buffer->SplitIntoFrequencyBands(); | 
| 1124 } | 1185 } | 
| 1125 | 1186 | 
| 1126 #if WEBRTC_INTELLIGIBILITY_ENHANCER | 1187 #if WEBRTC_INTELLIGIBILITY_ENHANCER | 
| 1127 if (capture_nonlocked_.intelligibility_enabled) { | 1188 if (capture_nonlocked_.intelligibility_enabled) { | 
| 1128 public_submodules_->intelligibility_enhancer->ProcessRenderAudio( | 1189 public_submodules_->intelligibility_enhancer->ProcessRenderAudio( | 
| 1129 render_buffer); | 1190 render_buffer); | 
| 1130 } | 1191 } | 
| 1131 #endif | 1192 #endif | 
| 1132 | 1193 | 
| 1133 RETURN_ON_ERR( | 1194 QueueRenderAudio(render_buffer); | 
| 1134 public_submodules_->echo_cancellation->ProcessRenderAudio(render_buffer)); | |
| 1135 RETURN_ON_ERR(public_submodules_->echo_control_mobile->ProcessRenderAudio( | 1195 RETURN_ON_ERR(public_submodules_->echo_control_mobile->ProcessRenderAudio( | 
| 1136 render_buffer)); | 1196 render_buffer)); | 
| 1137 if (!constants_.use_experimental_agc) { | 1197 if (!constants_.use_experimental_agc) { | 
| 1138 RETURN_ON_ERR( | 1198 RETURN_ON_ERR( | 
| 1139 public_submodules_->gain_control->ProcessRenderAudio(render_buffer)); | 1199 public_submodules_->gain_control->ProcessRenderAudio(render_buffer)); | 
| 1140 } | 1200 } | 
| 1141 | 1201 | 
| 1142 if (submodule_states_.RenderMultiBandProcessingActive() && | 1202 if (submodule_states_.RenderMultiBandProcessingActive() && | 
| 1143 SampleRateSupportsMultiBand( | 1203 SampleRateSupportsMultiBand( | 
| 1144 formats_.render_processing_format.sample_rate_hz())) { | 1204 formats_.render_processing_format.sample_rate_hz())) { | 
| (...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1594 capture_processing_format(kSampleRate16kHz), | 1654 capture_processing_format(kSampleRate16kHz), | 
| 1595 split_rate(kSampleRate16kHz) {} | 1655 split_rate(kSampleRate16kHz) {} | 
| 1596 | 1656 | 
| 1597 AudioProcessingImpl::ApmCaptureState::~ApmCaptureState() = default; | 1657 AudioProcessingImpl::ApmCaptureState::~ApmCaptureState() = default; | 
| 1598 | 1658 | 
| 1599 AudioProcessingImpl::ApmRenderState::ApmRenderState() = default; | 1659 AudioProcessingImpl::ApmRenderState::ApmRenderState() = default; | 
| 1600 | 1660 | 
| 1601 AudioProcessingImpl::ApmRenderState::~ApmRenderState() = default; | 1661 AudioProcessingImpl::ApmRenderState::~ApmRenderState() = default; | 
| 1602 | 1662 | 
| 1603 } // namespace webrtc | 1663 } // namespace webrtc | 
| OLD | NEW |