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

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

Issue 2778783002: AecDump interface (Closed)
Patch Set: Implemented most of Karl's suggestions. Created 3 years, 9 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/audio_processing_impl.cc
diff --git a/webrtc/modules/audio_processing/audio_processing_impl.cc b/webrtc/modules/audio_processing/audio_processing_impl.cc
index 1f73c5984a68af29d7dd941a64f88a834fd9e72a..1221140953014ed2ae02aafd0b951b653697e8e9 100644
--- a/webrtc/modules/audio_processing/audio_processing_impl.cc
+++ b/webrtc/modules/audio_processing/audio_processing_impl.cc
@@ -21,6 +21,7 @@
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
#include "webrtc/modules/audio_processing/aec/aec_core.h"
#include "webrtc/modules/audio_processing/aec3/echo_canceller3.h"
+#include "webrtc/modules/audio_processing/aec_dumper/null_aec_dumper.h"
#include "webrtc/modules/audio_processing/agc/agc_manager_direct.h"
#include "webrtc/modules/audio_processing/audio_buffer.h"
#include "webrtc/modules/audio_processing/beamformer/nonlinear_beamformer.h"
@@ -305,6 +306,7 @@ AudioProcessingImpl::AudioProcessingImpl(const webrtc::Config& config)
AudioProcessingImpl::AudioProcessingImpl(const webrtc::Config& config,
NonlinearBeamformer* beamformer)
: high_pass_filter_impl_(new HighPassFilterImpl(this)),
+ aec_dumper_(AecDumper::CreateNullDumper()),
peah-webrtc 2017/03/31 07:24:43 Why cannot we use an empty aecdumper?
aleloi 2017/04/06 15:46:11 It's possible. Then we would have to add 'if (aec_
peah-webrtc 2017/04/07 12:57:15 Absolutely, I definitely like the simpler code. Bu
aleloi 2017/04/12 11:05:29 I checked: virtual calls are always generated in r
public_submodules_(new ApmPublicSubmodules()),
private_submodules_(new ApmPrivateSubmodules(beamformer)),
constants_(config.Get<ExperimentalAgc>().startup_min_volume,
@@ -525,6 +527,7 @@ int AudioProcessingImpl::InitializeLocked() {
}
}
#endif
+ aec_dumper_->WriteInitMessage(formats_.api_format);
return kNoError;
}
@@ -815,7 +818,31 @@ int AudioProcessingImpl::ProcessStream(const float* const* src,
}
#endif
+ std::unique_ptr<AecDumper::CaptureStreamInfo> stream_info =
+ aec_dumper_->GetCaptureStreamInfo();
+ const size_t channel_size =
+ sizeof(float) * formats_.api_format.input_stream().num_frames();
+
+ {
+ std::vector<rtc::ArrayView<const float>> src_view;
peah-webrtc 2017/03/31 07:24:43 Afaics, the emplace_back call will cause arrayview
aleloi 2017/04/06 15:46:11 We could use a static array of large enough size.
peah-webrtc 2017/04/07 12:57:15 Yes, the impact of this is definitely not noticeab
+ for (size_t i = 0; i < formats_.api_format.input_stream().num_channels();
+ ++i) {
+ src_view.emplace_back(src[i], channel_size);
+ }
+ stream_info->AddInput(src_view);
+ }
capture_.capture_audio->CopyFrom(src, formats_.api_format.input_stream());
+
+ // This earlier happened in ProcessCaptureStreamLocked().
peah-webrtc 2017/03/31 07:24:43 Please remove this comment. This is more of a comm
aleloi 2017/04/06 15:46:11 Done.
+ RTC_DCHECK(!(public_submodules_->echo_cancellation->is_enabled() &&
+ public_submodules_->echo_control_mobile->is_enabled()));
peah-webrtc 2017/03/31 07:24:43 Why were there DCHECKs moved to here?
aleloi 2017/04/06 15:46:11 The conditions were DCHECKed before the protobuf s
peah-webrtc 2017/04/07 12:57:15 I agree, it should be safe to leave them there. In
+
+ stream_info->set_delay(capture_nonlocked_.stream_delay_ms);
+ stream_info->set_drift(
+ public_submodules_->echo_cancellation->stream_drift_samples());
+ stream_info->set_level(gain_control()->stream_analog_level());
+ stream_info->set_keypress(capture_.key_pressed);
+
RETURN_ON_ERR(ProcessCaptureStreamLocked());
capture_.capture_audio->CopyTo(formats_.api_format.output_stream(), dest);
@@ -832,6 +859,17 @@ int AudioProcessingImpl::ProcessStream(const float* const* src,
&crit_debug_, &debug_dump_.capture));
}
#endif
+ {
+ const size_t channel_size =
+ sizeof(float) * formats_.api_format.output_stream().num_frames();
+ std::vector<rtc::ArrayView<const float>> dest_view;
+ for (size_t i = 0; i < formats_.api_format.output_stream().num_channels();
+ ++i) {
+ dest_view.emplace_back(dest[i], channel_size);
peah-webrtc 2017/03/31 07:24:43 Afaics, the emplace_back call will cause arrayview
aleloi 2017/04/06 15:46:11 Acknowledged.
+ }
+ stream_info->AddOutput(dest_view);
+ }
+ aec_dumper_->WriteCaptureStreamMessage(std::move(stream_info));
return kNoError;
}
@@ -1069,6 +1107,9 @@ int AudioProcessingImpl::ProcessStream(AudioFrame* frame) {
return kBadDataLengthError;
}
+ std::unique_ptr<AecDumper::CaptureStreamInfo> stream_info =
+ aec_dumper_->GetCaptureStreamInfo();
+ stream_info->AddInput(*frame);
#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
if (debug_dump_.debug_file->is_open()) {
RETURN_ON_ERR(WriteConfigMessage(false));
@@ -1082,10 +1123,22 @@ int AudioProcessingImpl::ProcessStream(AudioFrame* frame) {
#endif
capture_.capture_audio->DeinterleaveFrom(frame);
+
+ RTC_DCHECK(!(public_submodules_->echo_cancellation->is_enabled() &&
peah-webrtc 2017/03/31 07:24:43 Why did you move these DCHECKs here?
aleloi 2017/04/06 15:46:11 Same as the DCHECKs above.
+ public_submodules_->echo_control_mobile->is_enabled()));
+
+ stream_info->set_delay(capture_nonlocked_.stream_delay_ms);
+ stream_info->set_drift(
+ public_submodules_->echo_cancellation->stream_drift_samples());
+ stream_info->set_level(gain_control()->stream_analog_level());
+ stream_info->set_keypress(capture_.key_pressed);
+
RETURN_ON_ERR(ProcessCaptureStreamLocked());
capture_.capture_audio->InterleaveTo(
frame, submodule_states_.CaptureMultiBandProcessingActive());
+ stream_info->AddOutput(*frame);
+ aec_dumper_->WriteCaptureStreamMessage(std::move(stream_info));
#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
if (debug_dump_.debug_file->is_open()) {
audioproc::Stream* msg = debug_dump_.capture.event_msg->mutable_stream();
@@ -1362,6 +1415,15 @@ int AudioProcessingImpl::AnalyzeReverseStreamLocked(
&crit_debug_, &debug_dump_.render));
}
#endif
+ std::vector<rtc::ArrayView<const float>> src_view;
+ const size_t channel_size =
+ sizeof(float) * formats_.api_format.reverse_input_stream().num_frames();
+
+ for (size_t i = 0;
+ i < formats_.api_format.reverse_input_stream().num_channels(); ++i) {
+ src_view.emplace_back(src[i], channel_size);
peah-webrtc 2017/03/31 07:24:43 Afaics, the emplace_back call will cause arrayview
aleloi 2017/04/06 15:46:11 Acknowledged.
+ }
+ aec_dumper_->WriteReverseStreamMessage(src_view);
render_.render_audio->CopyFrom(src,
formats_.api_format.reverse_input_stream());
@@ -1415,6 +1477,8 @@ int AudioProcessingImpl::ProcessReverseStream(AudioFrame* frame) {
&crit_debug_, &debug_dump_.render));
}
#endif
+ aec_dumper_->WriteReverseStreamMessage(*frame);
peah-webrtc 2017/03/31 07:24:43 Does this work? This accesses aec_dumper_ holding
aleloi 2017/04/06 15:46:11 Good point. Accesses to AecDump are thread safe, b
+
render_.render_audio->DeinterleaveFrom(frame);
RETURN_ON_ERR(ProcessRenderStreamLocked());
render_.render_audio->InterleaveTo(
@@ -1502,7 +1566,8 @@ int AudioProcessingImpl::delay_offset_ms() const {
int AudioProcessingImpl::StartDebugRecording(
const char filename[AudioProcessing::kMaxFilenameSize],
- int64_t max_log_size_bytes) {
+ int64_t max_log_size_bytes,
+ rtc::TaskQueue* worker_queue) {
// Run in a single-threaded manner.
rtc::CritScope cs_render(&crit_render_);
rtc::CritScope cs_capture(&crit_capture_);
@@ -1512,6 +1577,8 @@ int AudioProcessingImpl::StartDebugRecording(
return kNullPointerError;
}
+ aec_dumper_ = AecDumper::Create(filename, max_log_size_bytes, worker_queue);
+ aec_dumper_->WriteInitMessage(formats_.api_format);
#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
debug_dump_.num_bytes_left_for_log_ = max_log_size_bytes;
// Stop any ongoing recording.
@@ -1530,7 +1597,8 @@ int AudioProcessingImpl::StartDebugRecording(
}
int AudioProcessingImpl::StartDebugRecording(FILE* handle,
- int64_t max_log_size_bytes) {
+ int64_t max_log_size_bytes,
+ rtc::TaskQueue* worker_queue) {
// Run in a single-threaded manner.
rtc::CritScope cs_render(&crit_render_);
rtc::CritScope cs_capture(&crit_capture_);
@@ -1539,6 +1607,8 @@ int AudioProcessingImpl::StartDebugRecording(FILE* handle,
return kNullPointerError;
}
+ aec_dumper_ = AecDumper::Create(handle, max_log_size_bytes, worker_queue);
+ aec_dumper_->WriteInitMessage(formats_.api_format);
#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
debug_dump_.num_bytes_left_for_log_ = max_log_size_bytes;
@@ -1557,20 +1627,23 @@ int AudioProcessingImpl::StartDebugRecording(FILE* handle,
#endif // WEBRTC_AUDIOPROC_DEBUG_DUMP
}
-int AudioProcessingImpl::StartDebugRecording(FILE* handle) {
- return StartDebugRecording(handle, -1);
+int AudioProcessingImpl::StartDebugRecording(FILE* handle,
+ rtc::TaskQueue* worker_queue) {
+ return StartDebugRecording(handle, -1, worker_queue);
}
int AudioProcessingImpl::StartDebugRecordingForPlatformFile(
- rtc::PlatformFile handle) {
+ rtc::PlatformFile handle,
+ rtc::TaskQueue* worker_queue) {
// Run in a single-threaded manner.
rtc::CritScope cs_render(&crit_render_);
rtc::CritScope cs_capture(&crit_capture_);
FILE* stream = rtc::FdopenPlatformFileForWriting(handle);
- return StartDebugRecording(stream, -1);
+ return StartDebugRecording(stream, -1, worker_queue);
}
int AudioProcessingImpl::StopDebugRecording() {
+ aec_dumper_ = AecDumper::CreateNullDumper();
peah-webrtc 2017/03/31 07:24:43 Why do we need to have a null dumper? Is it not su
aleloi 2017/04/06 15:46:11 It is. I can remove the null dumper if there are s
// Run in a single-threaded manner.
rtc::CritScope cs_render(&crit_render_);
rtc::CritScope cs_capture(&crit_capture_);
@@ -1938,6 +2011,43 @@ int AudioProcessingImpl::WriteConfigMessage(bool forced) {
config.set_intelligibility_enhancer_enabled(
capture_nonlocked_.intelligibility_enabled);
+ InternalAPMConfig apm_config;
+
+ apm_config.aec_enabled = public_submodules_->echo_cancellation->is_enabled();
+ apm_config.aec_delay_agnostic_enabled =
+ public_submodules_->echo_cancellation->is_delay_agnostic_enabled();
+ apm_config.aec_drift_compensation_enabled =
+ public_submodules_->echo_cancellation->is_drift_compensation_enabled();
+ apm_config.aec_extended_filter_enabled =
+ public_submodules_->echo_cancellation->is_extended_filter_enabled();
+ apm_config.aec_suppression_level = static_cast<int>(
+ public_submodules_->echo_cancellation->suppression_level());
+
+ apm_config.aecm_enabled =
+ public_submodules_->echo_control_mobile->is_enabled();
+ apm_config.aecm_comfort_noise_enabled =
+ public_submodules_->echo_control_mobile->is_comfort_noise_enabled();
+ apm_config.aecm_routing_mode =
+ static_cast<int>(public_submodules_->echo_control_mobile->routing_mode());
+
+ apm_config.agc_enabled = public_submodules_->gain_control->is_enabled();
+ apm_config.agc_mode =
+ static_cast<int>(public_submodules_->gain_control->mode());
+ apm_config.agc_limiter_enabled =
+ public_submodules_->gain_control->is_limiter_enabled();
+ apm_config.noise_robust_agc_enabled = constants_.use_experimental_agc;
+
+ apm_config.hpf_enabled = config_.high_pass_filter.enabled;
+
+ apm_config.ns_enabled = public_submodules_->noise_suppression->is_enabled();
+ apm_config.ns_level =
+ static_cast<int>(public_submodules_->noise_suppression->level());
+
+ apm_config.transient_suppression_enabled =
+ capture_.transient_suppressor_enabled;
+ apm_config.intelligibility_enhancer_enabled =
+ capture_nonlocked_.intelligibility_enabled;
+
std::string experiments_description =
public_submodules_->echo_cancellation->GetExperimentsDescription();
// TODO(peah): Add semicolon-separated concatenations of experiment
@@ -1953,6 +2063,9 @@ int AudioProcessingImpl::WriteConfigMessage(bool forced) {
}
config.set_experiments_description(experiments_description);
+ apm_config.experiments_description = experiments_description;
+ aec_dumper_->WriteConfig(apm_config, forced);
+
std::string serialized_config = config.SerializeAsString();
if (!forced &&
debug_dump_.capture.last_serialized_config == serialized_config) {

Powered by Google App Engine
This is Rietveld 408576698