| 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 15 matching lines...) Expand all  Loading... | 
| 26       return kAgcModeAdaptiveAnalog; | 26       return kAgcModeAdaptiveAnalog; | 
| 27     case GainControl::kAdaptiveDigital: | 27     case GainControl::kAdaptiveDigital: | 
| 28       return kAgcModeAdaptiveDigital; | 28       return kAgcModeAdaptiveDigital; | 
| 29     case GainControl::kFixedDigital: | 29     case GainControl::kFixedDigital: | 
| 30       return kAgcModeFixedDigital; | 30       return kAgcModeFixedDigital; | 
| 31   } | 31   } | 
| 32   RTC_DCHECK(false); | 32   RTC_DCHECK(false); | 
| 33   return -1; | 33   return -1; | 
| 34 } | 34 } | 
| 35 | 35 | 
| 36 // Maximum length that a frame of samples can have. |  | 
| 37 static const size_t kMaxAllowedValuesOfSamplesPerFrame = 160; |  | 
| 38 // Maximum number of frames to buffer in the render queue. |  | 
| 39 // TODO(peah): Decrease this once we properly handle hugely unbalanced |  | 
| 40 // reverse and forward call numbers. |  | 
| 41 static const size_t kMaxNumFramesToBuffer = 100; |  | 
| 42 |  | 
| 43 }  // namespace | 36 }  // namespace | 
| 44 | 37 | 
| 45 class GainControlImpl::GainController { | 38 class GainControlImpl::GainController { | 
| 46  public: | 39  public: | 
| 47   explicit GainController() { | 40   explicit GainController() { | 
| 48     state_ = WebRtcAgc_Create(); | 41     state_ = WebRtcAgc_Create(); | 
| 49     RTC_CHECK(state_); | 42     RTC_CHECK(state_); | 
| 50   } | 43   } | 
| 51 | 44 | 
| 52   ~GainController() { | 45   ~GainController() { | 
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 96     : crit_render_(crit_render), | 89     : crit_render_(crit_render), | 
| 97       crit_capture_(crit_capture), | 90       crit_capture_(crit_capture), | 
| 98       mode_(kAdaptiveAnalog), | 91       mode_(kAdaptiveAnalog), | 
| 99       minimum_capture_level_(0), | 92       minimum_capture_level_(0), | 
| 100       maximum_capture_level_(255), | 93       maximum_capture_level_(255), | 
| 101       limiter_enabled_(true), | 94       limiter_enabled_(true), | 
| 102       target_level_dbfs_(3), | 95       target_level_dbfs_(3), | 
| 103       compression_gain_db_(9), | 96       compression_gain_db_(9), | 
| 104       analog_capture_level_(0), | 97       analog_capture_level_(0), | 
| 105       was_analog_level_set_(false), | 98       was_analog_level_set_(false), | 
| 106       stream_is_saturated_(false), | 99       stream_is_saturated_(false) { | 
| 107       render_queue_element_max_size_(0) { |  | 
| 108   RTC_DCHECK(crit_render); | 100   RTC_DCHECK(crit_render); | 
| 109   RTC_DCHECK(crit_capture); | 101   RTC_DCHECK(crit_capture); | 
| 110 } | 102 } | 
| 111 | 103 | 
| 112 GainControlImpl::~GainControlImpl() {} | 104 GainControlImpl::~GainControlImpl() {} | 
| 113 | 105 | 
| 114 int GainControlImpl::ProcessRenderAudio(AudioBuffer* audio) { | 106 void GainControlImpl::ProcessRenderAudio( | 
| 115   rtc::CritScope cs(crit_render_); | 107     rtc::ArrayView<const int16_t> packed_render_audio) { | 
| 116   if (!enabled_) { | 108   rtc::CritScope cs_capture(crit_capture_); | 
| 117     return AudioProcessing::kNoError; |  | 
| 118   } |  | 
| 119 |  | 
| 120   RTC_DCHECK_GE(160u, audio->num_frames_per_band()); |  | 
| 121 |  | 
| 122   render_queue_buffer_.resize(0); |  | 
| 123   for (auto& gain_controller : gain_controllers_) { |  | 
| 124     int err = WebRtcAgc_GetAddFarendError(gain_controller->state(), |  | 
| 125                                           audio->num_frames_per_band()); |  | 
| 126 |  | 
| 127     if (err != AudioProcessing::kNoError) { |  | 
| 128       return AudioProcessing::kUnspecifiedError; |  | 
| 129     } |  | 
| 130 |  | 
| 131     // Buffer the samples in the render queue. |  | 
| 132     render_queue_buffer_.insert( |  | 
| 133         render_queue_buffer_.end(), audio->mixed_low_pass_data(), |  | 
| 134         (audio->mixed_low_pass_data() + audio->num_frames_per_band())); |  | 
| 135   } |  | 
| 136 |  | 
| 137   // Insert the samples into the queue. |  | 
| 138   if (!render_signal_queue_->Insert(&render_queue_buffer_)) { |  | 
| 139     // The data queue is full and needs to be emptied. |  | 
| 140     ReadQueuedRenderData(); |  | 
| 141 |  | 
| 142     // Retry the insert (should always work). |  | 
| 143     RTC_DCHECK_EQ(render_signal_queue_->Insert(&render_queue_buffer_), true); |  | 
| 144   } |  | 
| 145 |  | 
| 146   return AudioProcessing::kNoError; |  | 
| 147 } |  | 
| 148 |  | 
| 149 // Read chunks of data that were received and queued on the render side from |  | 
| 150 // a queue. All the data chunks are buffered into the farend signal of the AGC. |  | 
| 151 void GainControlImpl::ReadQueuedRenderData() { |  | 
| 152   rtc::CritScope cs(crit_capture_); |  | 
| 153 |  | 
| 154   if (!enabled_) { | 109   if (!enabled_) { | 
| 155     return; | 110     return; | 
| 156   } | 111   } | 
| 157 | 112 | 
| 158   while (render_signal_queue_->Remove(&capture_queue_buffer_)) { | 113   for (auto& gain_controller : gain_controllers_) { | 
| 159     size_t buffer_index = 0; | 114     WebRtcAgc_AddFarend(gain_controller->state(), packed_render_audio.data(), | 
| 160     RTC_DCHECK(num_proc_channels_); | 115                         packed_render_audio.size()); | 
| 161     RTC_DCHECK_LT(0ul, *num_proc_channels_); |  | 
| 162     const size_t num_frames_per_band = |  | 
| 163         capture_queue_buffer_.size() / (*num_proc_channels_); |  | 
| 164     for (auto& gain_controller : gain_controllers_) { |  | 
| 165       WebRtcAgc_AddFarend(gain_controller->state(), |  | 
| 166                           &capture_queue_buffer_[buffer_index], |  | 
| 167                           num_frames_per_band); |  | 
| 168 |  | 
| 169       buffer_index += num_frames_per_band; |  | 
| 170     } |  | 
| 171   } | 116   } | 
| 172 } | 117 } | 
| 173 | 118 | 
|  | 119 void GainControlImpl::PackRenderAudioBuffer( | 
|  | 120     AudioBuffer* audio, | 
|  | 121     std::vector<int16_t>* packed_buffer) { | 
|  | 122   RTC_DCHECK_GE(160u, audio->num_frames_per_band()); | 
|  | 123 | 
|  | 124   packed_buffer->clear(); | 
|  | 125   packed_buffer->insert( | 
|  | 126       packed_buffer->end(), audio->mixed_low_pass_data(), | 
|  | 127       (audio->mixed_low_pass_data() + audio->num_frames_per_band())); | 
|  | 128 } | 
|  | 129 | 
| 174 int GainControlImpl::AnalyzeCaptureAudio(AudioBuffer* audio) { | 130 int GainControlImpl::AnalyzeCaptureAudio(AudioBuffer* audio) { | 
| 175   rtc::CritScope cs(crit_capture_); | 131   rtc::CritScope cs(crit_capture_); | 
| 176 | 132 | 
| 177   if (!enabled_) { | 133   if (!enabled_) { | 
| 178     return AudioProcessing::kNoError; | 134     return AudioProcessing::kNoError; | 
| 179   } | 135   } | 
| 180 | 136 | 
| 181   RTC_DCHECK(num_proc_channels_); | 137   RTC_DCHECK(num_proc_channels_); | 
| 182   RTC_DCHECK_GE(160u, audio->num_frames_per_band()); | 138   RTC_DCHECK_GE(160u, audio->num_frames_per_band()); | 
| 183   RTC_DCHECK_EQ(audio->num_channels(), *num_proc_channels_); | 139   RTC_DCHECK_EQ(audio->num_channels(), *num_proc_channels_); | 
| (...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 440   gain_controllers_.resize(*num_proc_channels_); | 396   gain_controllers_.resize(*num_proc_channels_); | 
| 441   for (auto& gain_controller : gain_controllers_) { | 397   for (auto& gain_controller : gain_controllers_) { | 
| 442     if (!gain_controller) { | 398     if (!gain_controller) { | 
| 443       gain_controller.reset(new GainController()); | 399       gain_controller.reset(new GainController()); | 
| 444     } | 400     } | 
| 445     gain_controller->Initialize(minimum_capture_level_, maximum_capture_level_, | 401     gain_controller->Initialize(minimum_capture_level_, maximum_capture_level_, | 
| 446                                 mode_, *sample_rate_hz_, analog_capture_level_); | 402                                 mode_, *sample_rate_hz_, analog_capture_level_); | 
| 447   } | 403   } | 
| 448 | 404 | 
| 449   Configure(); | 405   Configure(); | 
| 450 |  | 
| 451   AllocateRenderQueue(); |  | 
| 452 } |  | 
| 453 |  | 
| 454 void GainControlImpl::AllocateRenderQueue() { |  | 
| 455   rtc::CritScope cs_render(crit_render_); |  | 
| 456   rtc::CritScope cs_capture(crit_capture_); |  | 
| 457 |  | 
| 458   RTC_DCHECK(num_proc_channels_); |  | 
| 459   const size_t new_render_queue_element_max_size = std::max<size_t>( |  | 
| 460       static_cast<size_t>(1), |  | 
| 461       kMaxAllowedValuesOfSamplesPerFrame * (*num_proc_channels_)); |  | 
| 462 |  | 
| 463   if (render_queue_element_max_size_ < new_render_queue_element_max_size) { |  | 
| 464     render_queue_element_max_size_ = new_render_queue_element_max_size; |  | 
| 465     std::vector<int16_t> template_queue_element(render_queue_element_max_size_); |  | 
| 466 |  | 
| 467     render_signal_queue_.reset( |  | 
| 468         new SwapQueue<std::vector<int16_t>, RenderQueueItemVerifier<int16_t>>( |  | 
| 469             kMaxNumFramesToBuffer, template_queue_element, |  | 
| 470             RenderQueueItemVerifier<int16_t>(render_queue_element_max_size_))); |  | 
| 471 |  | 
| 472     render_queue_buffer_.resize(render_queue_element_max_size_); |  | 
| 473     capture_queue_buffer_.resize(render_queue_element_max_size_); |  | 
| 474   } else { |  | 
| 475     render_signal_queue_->Clear(); |  | 
| 476   } |  | 
| 477 } | 406 } | 
| 478 | 407 | 
| 479 int GainControlImpl::Configure() { | 408 int GainControlImpl::Configure() { | 
| 480   rtc::CritScope cs_render(crit_render_); | 409   rtc::CritScope cs_render(crit_render_); | 
| 481   rtc::CritScope cs_capture(crit_capture_); | 410   rtc::CritScope cs_capture(crit_capture_); | 
| 482   WebRtcAgcConfig config; | 411   WebRtcAgcConfig config; | 
| 483   // TODO(ajm): Flip the sign here (since AGC expects a positive value) if we | 412   // TODO(ajm): Flip the sign here (since AGC expects a positive value) if we | 
| 484   //            change the interface. | 413   //            change the interface. | 
| 485   //RTC_DCHECK_LE(target_level_dbfs_, 0); | 414   //RTC_DCHECK_LE(target_level_dbfs_, 0); | 
| 486   //config.targetLevelDbfs = static_cast<int16_t>(-target_level_dbfs_); | 415   //config.targetLevelDbfs = static_cast<int16_t>(-target_level_dbfs_); | 
| 487   config.targetLevelDbfs = static_cast<int16_t>(target_level_dbfs_); | 416   config.targetLevelDbfs = static_cast<int16_t>(target_level_dbfs_); | 
| 488   config.compressionGaindB = | 417   config.compressionGaindB = | 
| 489       static_cast<int16_t>(compression_gain_db_); | 418       static_cast<int16_t>(compression_gain_db_); | 
| 490   config.limiterEnable = limiter_enabled_; | 419   config.limiterEnable = limiter_enabled_; | 
| 491 | 420 | 
| 492   int error = AudioProcessing::kNoError; | 421   int error = AudioProcessing::kNoError; | 
| 493   for (auto& gain_controller : gain_controllers_) { | 422   for (auto& gain_controller : gain_controllers_) { | 
| 494     const int handle_error = | 423     const int handle_error = | 
| 495         WebRtcAgc_set_config(gain_controller->state(), config); | 424         WebRtcAgc_set_config(gain_controller->state(), config); | 
| 496     if (handle_error != AudioProcessing::kNoError) { | 425     if (handle_error != AudioProcessing::kNoError) { | 
| 497       error = handle_error; | 426       error = handle_error; | 
| 498     } | 427     } | 
| 499   } | 428   } | 
| 500   return error; | 429   return error; | 
| 501 } | 430 } | 
| 502 }  // namespace webrtc | 431 }  // namespace webrtc | 
| OLD | NEW | 
|---|