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

Unified Diff: webrtc/modules/audio_processing/echo_control_mobile_impl.cc

Issue 1410833002: Lock scheme #4: Introduced the render sample queue for the aec and aecm (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@aec_error_report_CL
Patch Set: Created 5 years, 2 months 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 side-by-side diff with in-line comments
Download patch
Index: webrtc/modules/audio_processing/echo_control_mobile_impl.cc
diff --git a/webrtc/modules/audio_processing/echo_control_mobile_impl.cc b/webrtc/modules/audio_processing/echo_control_mobile_impl.cc
index d0161e0b4644fa91911b338835e915e5aa6f7d11..7068df27d9d7e3dd498529faa9ab43fe17b9a7ba 100644
--- a/webrtc/modules/audio_processing/echo_control_mobile_impl.cc
+++ b/webrtc/modules/audio_processing/echo_control_mobile_impl.cc
@@ -40,6 +40,22 @@ int16_t MapSetting(EchoControlMobile::RoutingMode mode) {
return -1;
}
+AudioProcessing::Error MapError(int err) {
+ switch (err) {
+ case AECM_UNSUPPORTED_FUNCTION_ERROR:
+ return AudioProcessing::kUnsupportedFunctionError;
+ case AECM_NULL_POINTER_ERROR:
+ return AudioProcessing::kNullPointerError;
+ case AECM_BAD_PARAMETER_ERROR:
+ return AudioProcessing::kBadParameterError;
+ case AECM_BAD_PARAMETER_WARNING:
+ return AudioProcessing::kBadStreamParameterWarning;
+ default:
+ // AECM_UNSPECIFIED_ERROR
+ // AECM_UNINITIALIZED_ERROR
+ return AudioProcessing::kUnspecifiedError;
+ }
+}
} // namespace
size_t EchoControlMobile::echo_path_size_bytes() {
@@ -48,12 +64,21 @@ size_t EchoControlMobile::echo_path_size_bytes() {
EchoControlMobileImpl::EchoControlMobileImpl(const AudioProcessing* apm,
CriticalSectionWrapper* crit)
- : ProcessingComponent(),
- apm_(apm),
- crit_(crit),
- routing_mode_(kSpeakerphone),
- comfort_noise_enabled_(true),
- external_echo_path_(NULL) {}
+ : ProcessingComponent(),
+ apm_(apm),
+ crit_(crit),
+ routing_mode_(kSpeakerphone),
+ comfort_noise_enabled_(true),
+ external_echo_path_(NULL),
+ render_queue_buffer_(kMaxNumSamplesPerFrameToBuffer),
+ capture_queue_buffer_(kMaxNumSamplesPerFrameToBuffer) {
+ std::vector<int16_t> template_queue_element(kMaxNumSamplesPerFrameToBuffer);
+
+ render_signal_queue_.reset(
+ new SwapQueue<std::vector<int16_t>, &RenderQueueItemVerifier>(
+ (kMaxNumFramesToBuffer * kMaxNumChannelsPerFrameToBuffer),
+ template_queue_element));
+}
EchoControlMobileImpl::~EchoControlMobileImpl() {
if (external_echo_path_ != NULL) {
@@ -77,14 +102,25 @@ int EchoControlMobileImpl::ProcessRenderAudio(const AudioBuffer* audio) {
for (int i = 0; i < apm_->num_output_channels(); i++) {
for (int j = 0; j < audio->num_channels(); j++) {
Handle* my_handle = static_cast<Handle*>(handle(handle_index));
- err = WebRtcAecm_BufferFarend(
- my_handle,
- audio->split_bands_const(j)[kBand0To8kHz],
+ err = WebRtcAecm_GetBufferFarendError(
+ my_handle, audio->split_bands_const(j)[kBand0To8kHz],
audio->num_frames_per_band());
- if (err != apm_->kNoError) {
- return GetHandleError(my_handle); // TODO(ajm): warning possible?
- }
+ if (err != apm_->kNoError)
+ return MapError(err); // TODO(ajm): warning possible?);
+
+ // Buffer the samples in the render queue.
+ // TODO(peah): Do a proper size check agains the actual sample size
+ // once the APM properly checks the sample type passed to AECM.
+ memcpy(&render_queue_buffer_[0],
+ audio->split_bands_const_f(j)[kBand0To8kHz],
+ (audio->num_frames_per_band() * sizeof(int16_t)));
+ render_queue_buffer_.resize(audio->num_frames_per_band());
+ // TODO(peah): Refactor so that it is possible to check the
+ // return value of Insert. Currently, that is not possible
+ // due to the code design when the capture thread is never
+ // started.
+ render_signal_queue_->Insert(&render_queue_buffer_);
handle_index++;
}
@@ -93,6 +129,25 @@ int EchoControlMobileImpl::ProcessRenderAudio(const AudioBuffer* audio) {
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 AEC.
+void EchoControlMobileImpl::ReadQueuedRenderData() {
+ if (!is_component_enabled()) {
+ return;
+ }
+
+ while (render_signal_queue_->Remove(&capture_queue_buffer_)) {
+ size_t handle_index = 0;
+ for (int i = 0; i < apm_->num_output_channels(); i++) {
+ for (int j = 0; j < apm_->num_reverse_channels(); j++) {
+ Handle* my_handle = static_cast<Handle*>(handle(handle_index));
+ (void)WebRtcAecm_BufferFarend(my_handle, &capture_queue_buffer_[0],
+ capture_queue_buffer_.size());
+ }
+ }
+ }
+}
+
int EchoControlMobileImpl::ProcessCaptureAudio(AudioBuffer* audio) {
if (!is_component_enabled()) {
return apm_->kNoError;
@@ -128,9 +183,8 @@ int EchoControlMobileImpl::ProcessCaptureAudio(AudioBuffer* audio) {
audio->num_frames_per_band(),
apm_->stream_delay_ms());
- if (err != apm_->kNoError) {
- return GetHandleError(my_handle); // TODO(ajm): warning possible?
- }
+ if (err != apm_->kNoError)
+ return MapError(err);
handle_index++;
}
@@ -213,9 +267,9 @@ int EchoControlMobileImpl::GetEchoPath(void* echo_path,
// Get the echo path from the first channel
Handle* my_handle = static_cast<Handle*>(handle(0));
- if (WebRtcAecm_GetEchoPath(my_handle, echo_path, size_bytes) != 0) {
- return GetHandleError(my_handle);
- }
+ int32_t err = WebRtcAecm_GetEchoPath(my_handle, echo_path, size_bytes);
+ if (err != 0)
+ return MapError(err);
return apm_->kNoError;
}
@@ -225,6 +279,8 @@ int EchoControlMobileImpl::Initialize() {
return apm_->kNoError;
}
+ render_signal_queue_->Clear();
+
if (apm_->proc_sample_rate_hz() > apm_->kSampleRate16kHz) {
LOG(LS_ERROR) << "AECM only supports 16 kHz or lower sample rates";
return apm_->kBadSampleRateError;
@@ -275,4 +331,11 @@ int EchoControlMobileImpl::GetHandleError(void* handle) const {
assert(handle != NULL);
return AudioProcessing::kUnspecifiedError;
}
+
+bool EchoControlMobileImpl::RenderQueueItemVerifier(
+ const std::vector<int16_t>& v) {
+ return ((v.size() == kMinNumSamplesPerFrameToBuffer) ||
+ (v.size() == kMaxNumSamplesPerFrameToBuffer));
+}
+
} // namespace webrtc

Powered by Google App Engine
This is Rietveld 408576698