Index: webrtc/modules/audio_processing/gain_control_impl.cc |
diff --git a/webrtc/modules/audio_processing/gain_control_impl.cc b/webrtc/modules/audio_processing/gain_control_impl.cc |
index 3b1537e796f26558b8814d3c2f28e0dc4112e51a..db7b8d9b1c48a31581d502cef7704dec447466d5 100644 |
--- a/webrtc/modules/audio_processing/gain_control_impl.cc |
+++ b/webrtc/modules/audio_processing/gain_control_impl.cc |
@@ -35,20 +35,26 @@ int16_t MapSetting(GainControl::Mode mode) { |
} |
} // namespace |
+const size_t GainControlImpl::kAllowedValuesOfSamplesPerFrame1; |
+const size_t GainControlImpl::kAllowedValuesOfSamplesPerFrame2; |
+ |
GainControlImpl::GainControlImpl(const AudioProcessing* apm, |
CriticalSectionWrapper* crit) |
- : ProcessingComponent(), |
- apm_(apm), |
- crit_(crit), |
- mode_(kAdaptiveAnalog), |
- minimum_capture_level_(0), |
- maximum_capture_level_(255), |
- limiter_enabled_(true), |
- target_level_dbfs_(3), |
- compression_gain_db_(9), |
- analog_capture_level_(0), |
- was_analog_level_set_(false), |
- stream_is_saturated_(false) {} |
+ : ProcessingComponent(), |
+ apm_(apm), |
+ crit_(crit), |
+ mode_(kAdaptiveAnalog), |
+ minimum_capture_level_(0), |
+ maximum_capture_level_(255), |
+ limiter_enabled_(true), |
+ target_level_dbfs_(3), |
+ compression_gain_db_(9), |
+ analog_capture_level_(0), |
+ was_analog_level_set_(false), |
+ stream_is_saturated_(false), |
+ render_queue_element_max_size_(0) { |
+ AllocateRenderQueue(); |
+} |
GainControlImpl::~GainControlImpl() {} |
@@ -59,21 +65,49 @@ int GainControlImpl::ProcessRenderAudio(AudioBuffer* audio) { |
assert(audio->num_frames_per_band() <= 160); |
+ render_queue_buffer_.resize(0); |
for (int i = 0; i < num_handles(); i++) { |
Handle* my_handle = static_cast<Handle*>(handle(i)); |
- int err = WebRtcAgc_AddFarend( |
- my_handle, |
- audio->mixed_low_pass_data(), |
- audio->num_frames_per_band()); |
+ int err = |
+ WebRtcAgc_GetAddFarendError(my_handle, audio->num_frames_per_band()); |
- if (err != apm_->kNoError) { |
+ if (err != apm_->kNoError) |
return GetHandleError(my_handle); |
- } |
+ |
+ // Buffer the samples in the render queue. |
+ render_queue_buffer_.insert( |
+ render_queue_buffer_.end(), audio->mixed_low_pass_data(), |
+ (audio->mixed_low_pass_data() + audio->num_frames_per_band())); |
} |
+ // Check of success is temporarily disabled as it breaks a unit test. |
+ // TODO(peah): Will be fixed in the next CL. |
+ (void)render_signal_queue_->Insert(&render_queue_buffer_); |
hlundin-webrtc
2015/11/05 13:01:09
Drop (void).
peah-webrtc
2015/11/06 07:10:58
I think is needed due to the WARN_UNUSED_RESULT an
hlundin-webrtc
2015/11/06 07:52:33
Acknowledged.
peah-webrtc
2015/11/06 08:10:03
Acknowledged.
|
+ |
return apm_->kNoError; |
} |
+// Read chunks of data that were received and queued on the render side from |
+// a queue. All the data chunks are buffered into the farend signal of the AGC. |
+void GainControlImpl::ReadQueuedRenderData() { |
+ if (!is_component_enabled()) { |
+ return; |
+ } |
+ |
+ while (render_signal_queue_->Remove(&capture_queue_buffer_)) { |
+ int buffer_index = 0; |
+ const int num_frames_per_band = |
+ capture_queue_buffer_.size() / num_handles(); |
+ for (int i = 0; i < num_handles(); i++) { |
+ Handle* my_handle = static_cast<Handle*>(handle(i)); |
+ (void)WebRtcAgc_AddFarend(my_handle, &capture_queue_buffer_[buffer_index], |
hlundin-webrtc
2015/11/05 13:01:09
Drop (void).
peah-webrtc
2015/11/06 07:10:58
Done.
|
+ num_frames_per_band); |
+ |
+ buffer_index += num_frames_per_band; |
+ } |
+ } |
+} |
+ |
int GainControlImpl::AnalyzeCaptureAudio(AudioBuffer* audio) { |
if (!is_component_enabled()) { |
return apm_->kNoError; |
@@ -179,6 +213,12 @@ int GainControlImpl::ProcessCaptureAudio(AudioBuffer* audio) { |
// TODO(ajm): ensure this is called under kAdaptiveAnalog. |
int GainControlImpl::set_stream_analog_level(int level) { |
+ // TODO(peah): Verify that this is really needed to do the reading. |
hlundin-webrtc
2015/11/05 13:01:09
Extra . at end of line.
peah-webrtc
2015/11/06 07:10:58
Done.
|
+ // here as well as in ProcessStream. It works since these functions |
+ // are called from the same thread, but it is not nice to do it in two |
+ // places if not needed. |
+ ReadQueuedRenderData(); |
+ |
CriticalSectionScoped crit_scoped(crit_); |
was_analog_level_set_ = true; |
if (level < minimum_capture_level_ || level > maximum_capture_level_) { |
@@ -296,10 +336,35 @@ int GainControlImpl::Initialize() { |
return err; |
} |
+ AllocateRenderQueue(); |
+ |
capture_levels_.assign(num_handles(), analog_capture_level_); |
return apm_->kNoError; |
} |
+void GainControlImpl::AllocateRenderQueue() { |
+ const size_t max_frame_size = std::max(kAllowedValuesOfSamplesPerFrame1, |
+ kAllowedValuesOfSamplesPerFrame2); |
+ |
+ const size_t new_render_queue_element_max_size = |
+ std::max(1UL, (max_frame_size * num_handles())); |
hlundin-webrtc
2015/11/05 13:01:09
1UL...
peah-webrtc
2015/11/06 07:10:58
Done.
|
+ |
+ if (new_render_queue_element_max_size > render_queue_element_max_size_) { |
+ std::vector<int16_t> template_queue_element(render_queue_element_max_size_); |
+ |
+ render_signal_queue_.reset( |
+ new SwapQueue<std::vector<int16_t>, AgcRenderQueueItemVerifier>( |
+ kMaxNumFramesToBuffer, |
+ AgcRenderQueueItemVerifier(render_queue_element_max_size_), |
+ template_queue_element)); |
+ } else { |
+ render_signal_queue_->Clear(); |
+ } |
+ |
+ render_queue_buffer_.resize(new_render_queue_element_max_size); |
+ capture_queue_buffer_.resize(new_render_queue_element_max_size); |
+} |
+ |
void* GainControlImpl::CreateHandle() const { |
return WebRtcAgc_Create(); |
} |