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 |