Chromium Code Reviews| 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 17 matching lines...) Expand all Loading... | |
| 28 case GainControl::kAdaptiveDigital: | 28 case GainControl::kAdaptiveDigital: |
| 29 return kAgcModeAdaptiveDigital; | 29 return kAgcModeAdaptiveDigital; |
| 30 case GainControl::kFixedDigital: | 30 case GainControl::kFixedDigital: |
| 31 return kAgcModeFixedDigital; | 31 return kAgcModeFixedDigital; |
| 32 } | 32 } |
| 33 assert(false); | 33 assert(false); |
| 34 return -1; | 34 return -1; |
| 35 } | 35 } |
| 36 } // namespace | 36 } // namespace |
| 37 | 37 |
| 38 const size_t GainControlImpl::kAllowedValuesOfSamplesPerFrame1; | |
|
The Sun (google.com)
2015/11/17 09:34:13
Why did you need to declare these in the .cc but n
peah-webrtc
2015/11/17 10:18:23
(I think) This is needed because the constants are
| |
| 39 const size_t GainControlImpl::kAllowedValuesOfSamplesPerFrame2; | |
| 40 | |
| 38 GainControlImpl::GainControlImpl(const AudioProcessing* apm, | 41 GainControlImpl::GainControlImpl(const AudioProcessing* apm, |
| 39 CriticalSectionWrapper* crit) | 42 CriticalSectionWrapper* crit) |
| 40 : ProcessingComponent(), | 43 : ProcessingComponent(), |
| 41 apm_(apm), | 44 apm_(apm), |
| 42 crit_(crit), | 45 crit_(crit), |
| 43 mode_(kAdaptiveAnalog), | 46 mode_(kAdaptiveAnalog), |
| 44 minimum_capture_level_(0), | 47 minimum_capture_level_(0), |
| 45 maximum_capture_level_(255), | 48 maximum_capture_level_(255), |
| 46 limiter_enabled_(true), | 49 limiter_enabled_(true), |
| 47 target_level_dbfs_(3), | 50 target_level_dbfs_(3), |
| 48 compression_gain_db_(9), | 51 compression_gain_db_(9), |
| 49 analog_capture_level_(0), | 52 analog_capture_level_(0), |
| 50 was_analog_level_set_(false), | 53 was_analog_level_set_(false), |
| 51 stream_is_saturated_(false) {} | 54 stream_is_saturated_(false), |
| 55 render_queue_element_max_size_(0) { | |
| 56 AllocateRenderQueue(); | |
|
The Sun (google.com)
2015/11/17 09:34:13
Isn't Initialize() always called for processing co
peah-webrtc
2015/11/17 10:18:23
Good point!
Done.
| |
| 57 } | |
| 52 | 58 |
| 53 GainControlImpl::~GainControlImpl() {} | 59 GainControlImpl::~GainControlImpl() {} |
| 54 | 60 |
| 55 int GainControlImpl::ProcessRenderAudio(AudioBuffer* audio) { | 61 int GainControlImpl::ProcessRenderAudio(AudioBuffer* audio) { |
| 56 if (!is_component_enabled()) { | 62 if (!is_component_enabled()) { |
| 57 return apm_->kNoError; | 63 return apm_->kNoError; |
| 58 } | 64 } |
| 59 | 65 |
| 60 assert(audio->num_frames_per_band() <= 160); | 66 assert(audio->num_frames_per_band() <= 160); |
| 61 | 67 |
| 68 render_queue_buffer_.resize(0); | |
| 62 for (int i = 0; i < num_handles(); i++) { | 69 for (int i = 0; i < num_handles(); i++) { |
| 63 Handle* my_handle = static_cast<Handle*>(handle(i)); | 70 Handle* my_handle = static_cast<Handle*>(handle(i)); |
| 64 int err = WebRtcAgc_AddFarend( | 71 int err = |
| 65 my_handle, | 72 WebRtcAgc_GetAddFarendError(my_handle, audio->num_frames_per_band()); |
| 66 audio->mixed_low_pass_data(), | |
| 67 audio->num_frames_per_band()); | |
| 68 | 73 |
| 69 if (err != apm_->kNoError) { | 74 if (err != apm_->kNoError) |
| 70 return GetHandleError(my_handle); | 75 return GetHandleError(my_handle); |
| 71 } | 76 |
| 77 // Buffer the samples in the render queue. | |
| 78 render_queue_buffer_.insert( | |
| 79 render_queue_buffer_.end(), audio->mixed_low_pass_data(), | |
| 80 (audio->mixed_low_pass_data() + audio->num_frames_per_band())); | |
| 81 } | |
| 82 | |
| 83 // Insert the samples into the queue. | |
| 84 if (!render_signal_queue_->Insert(&render_queue_buffer_)) { | |
| 85 ReadQueuedRenderData(); | |
| 86 | |
| 87 // Retry the insert (should always work). | |
| 88 RTC_DCHECK_EQ(render_signal_queue_->Insert(&render_queue_buffer_), true); | |
| 72 } | 89 } |
| 73 | 90 |
| 74 return apm_->kNoError; | 91 return apm_->kNoError; |
| 75 } | 92 } |
| 76 | 93 |
| 94 // Read chunks of data that were received and queued on the render side from | |
| 95 // a queue. All the data chunks are buffered into the farend signal of the AGC. | |
| 96 void GainControlImpl::ReadQueuedRenderData() { | |
| 97 if (!is_component_enabled()) { | |
| 98 return; | |
| 99 } | |
| 100 | |
| 101 while (render_signal_queue_->Remove(&capture_queue_buffer_)) { | |
| 102 int buffer_index = 0; | |
| 103 const int num_frames_per_band = | |
| 104 capture_queue_buffer_.size() / num_handles(); | |
| 105 for (int i = 0; i < num_handles(); i++) { | |
| 106 Handle* my_handle = static_cast<Handle*>(handle(i)); | |
| 107 WebRtcAgc_AddFarend(my_handle, &capture_queue_buffer_[buffer_index], | |
| 108 num_frames_per_band); | |
| 109 | |
| 110 buffer_index += num_frames_per_band; | |
| 111 } | |
| 112 } | |
| 113 } | |
| 114 | |
| 77 int GainControlImpl::AnalyzeCaptureAudio(AudioBuffer* audio) { | 115 int GainControlImpl::AnalyzeCaptureAudio(AudioBuffer* audio) { |
| 78 if (!is_component_enabled()) { | 116 if (!is_component_enabled()) { |
| 79 return apm_->kNoError; | 117 return apm_->kNoError; |
| 80 } | 118 } |
| 81 | 119 |
| 82 assert(audio->num_frames_per_band() <= 160); | 120 assert(audio->num_frames_per_band() <= 160); |
| 83 assert(audio->num_channels() == num_handles()); | 121 assert(audio->num_channels() == num_handles()); |
| 84 | 122 |
| 85 int err = apm_->kNoError; | 123 int err = apm_->kNoError; |
| 86 | 124 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 172 | 210 |
| 173 analog_capture_level_ /= num_handles(); | 211 analog_capture_level_ /= num_handles(); |
| 174 } | 212 } |
| 175 | 213 |
| 176 was_analog_level_set_ = false; | 214 was_analog_level_set_ = false; |
| 177 return apm_->kNoError; | 215 return apm_->kNoError; |
| 178 } | 216 } |
| 179 | 217 |
| 180 // TODO(ajm): ensure this is called under kAdaptiveAnalog. | 218 // TODO(ajm): ensure this is called under kAdaptiveAnalog. |
| 181 int GainControlImpl::set_stream_analog_level(int level) { | 219 int GainControlImpl::set_stream_analog_level(int level) { |
| 220 // TODO(peah): Verify that this is really needed to do the reading | |
| 221 // here as well as in ProcessStream. It works since these functions | |
| 222 // are called from the same thread, but it is not nice to do it in two | |
| 223 // places if not needed. | |
| 224 ReadQueuedRenderData(); | |
|
The Sun (google.com)
2015/11/17 09:34:13
You may want to add a comment here as to why you'r
peah-webrtc
2015/11/17 10:18:23
Removed it.
Done.
| |
| 225 | |
| 182 CriticalSectionScoped crit_scoped(crit_); | 226 CriticalSectionScoped crit_scoped(crit_); |
| 183 was_analog_level_set_ = true; | 227 was_analog_level_set_ = true; |
| 184 if (level < minimum_capture_level_ || level > maximum_capture_level_) { | 228 if (level < minimum_capture_level_ || level > maximum_capture_level_) { |
| 185 return apm_->kBadParameterError; | 229 return apm_->kBadParameterError; |
| 186 } | 230 } |
| 187 analog_capture_level_ = level; | 231 analog_capture_level_ = level; |
| 188 | 232 |
| 189 return apm_->kNoError; | 233 return apm_->kNoError; |
| 190 } | 234 } |
| 191 | 235 |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 289 bool GainControlImpl::is_limiter_enabled() const { | 333 bool GainControlImpl::is_limiter_enabled() const { |
| 290 return limiter_enabled_; | 334 return limiter_enabled_; |
| 291 } | 335 } |
| 292 | 336 |
| 293 int GainControlImpl::Initialize() { | 337 int GainControlImpl::Initialize() { |
| 294 int err = ProcessingComponent::Initialize(); | 338 int err = ProcessingComponent::Initialize(); |
| 295 if (err != apm_->kNoError || !is_component_enabled()) { | 339 if (err != apm_->kNoError || !is_component_enabled()) { |
| 296 return err; | 340 return err; |
| 297 } | 341 } |
| 298 | 342 |
| 343 AllocateRenderQueue(); | |
| 344 | |
| 299 const int n = num_handles(); | 345 const int n = num_handles(); |
| 300 RTC_CHECK_GE(n, 0) << "Bad number of handles: " << n; | 346 RTC_CHECK_GE(n, 0) << "Bad number of handles: " << n; |
| 301 capture_levels_.assign(n, analog_capture_level_); | 347 capture_levels_.assign(n, analog_capture_level_); |
| 302 return apm_->kNoError; | 348 return apm_->kNoError; |
| 303 } | 349 } |
| 304 | 350 |
| 351 void GainControlImpl::AllocateRenderQueue() { | |
| 352 const size_t max_frame_size = std::max<size_t>( | |
|
The Sun (google.com)
2015/11/17 09:34:13
Template type should be deduced by the compiler. N
peah-webrtc
2015/11/17 10:18:23
Done.
| |
| 353 kAllowedValuesOfSamplesPerFrame1, kAllowedValuesOfSamplesPerFrame2); | |
| 354 | |
| 355 const size_t new_render_queue_element_max_size = std::max<size_t>( | |
|
The Sun (google.com)
2015/11/17 09:34:12
is this the queue size, or size of an element in t
peah-webrtc
2015/11/17 10:18:23
This is the size of an element in the queue. The q
| |
| 356 static_cast<size_t>(1), (max_frame_size * num_handles())); | |
| 357 | |
| 358 if (new_render_queue_element_max_size > render_queue_element_max_size_) { | |
| 359 std::vector<int16_t> template_queue_element(render_queue_element_max_size_); | |
|
The Sun (google.com)
2015/11/17 09:34:13
you're using what looks like the old item size, an
peah-webrtc
2015/11/17 10:18:23
Fully true, and it worked since the verification b
| |
| 360 | |
| 361 render_signal_queue_.reset( | |
| 362 new SwapQueue<std::vector<int16_t>, RenderQueueItemVerifier<int16_t>>( | |
| 363 kMaxNumFramesToBuffer, template_queue_element, | |
| 364 RenderQueueItemVerifier<int16_t>(render_queue_element_max_size_))); | |
| 365 } else { | |
| 366 render_signal_queue_->Clear(); | |
| 367 } | |
| 368 | |
| 369 render_queue_buffer_.resize(new_render_queue_element_max_size); | |
| 370 capture_queue_buffer_.resize(new_render_queue_element_max_size); | |
| 371 } | |
| 372 | |
| 305 void* GainControlImpl::CreateHandle() const { | 373 void* GainControlImpl::CreateHandle() const { |
| 306 return WebRtcAgc_Create(); | 374 return WebRtcAgc_Create(); |
| 307 } | 375 } |
| 308 | 376 |
| 309 void GainControlImpl::DestroyHandle(void* handle) const { | 377 void GainControlImpl::DestroyHandle(void* handle) const { |
| 310 WebRtcAgc_Free(static_cast<Handle*>(handle)); | 378 WebRtcAgc_Free(static_cast<Handle*>(handle)); |
| 311 } | 379 } |
| 312 | 380 |
| 313 int GainControlImpl::InitializeHandle(void* handle) const { | 381 int GainControlImpl::InitializeHandle(void* handle) const { |
| 314 return WebRtcAgc_Init(static_cast<Handle*>(handle), | 382 return WebRtcAgc_Init(static_cast<Handle*>(handle), |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 336 return apm_->num_output_channels(); | 404 return apm_->num_output_channels(); |
| 337 } | 405 } |
| 338 | 406 |
| 339 int GainControlImpl::GetHandleError(void* handle) const { | 407 int GainControlImpl::GetHandleError(void* handle) const { |
| 340 // The AGC has no get_error() function. | 408 // The AGC has no get_error() function. |
| 341 // (Despite listing errors in its interface...) | 409 // (Despite listing errors in its interface...) |
| 342 assert(handle != NULL); | 410 assert(handle != NULL); |
| 343 return apm_->kUnspecifiedError; | 411 return apm_->kUnspecifiedError; |
| 344 } | 412 } |
| 345 } // namespace webrtc | 413 } // namespace webrtc |
| OLD | NEW |