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

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

Issue 2444283002: Moved the AGC render sample queue into the audio processing module (Closed)
Patch Set: Rebase Created 4 years, 1 month 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 15 matching lines...) Expand all
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
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
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
OLDNEW
« no previous file with comments | « webrtc/modules/audio_processing/gain_control_impl.h ('k') | webrtc/modules/audio_processing/gain_control_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698