Index: webrtc/modules/audio_processing/aec_dump/aec_dump.cc |
diff --git a/webrtc/modules/audio_processing/aec_dump/aec_dump.cc b/webrtc/modules/audio_processing/aec_dump/aec_dump.cc |
index efc56d2bf844920278b20022ba09200ef2326606..c9e3665f067dc58d5017044a99778fecb98c1386 100644 |
--- a/webrtc/modules/audio_processing/aec_dump/aec_dump.cc |
+++ b/webrtc/modules/audio_processing/aec_dump/aec_dump.cc |
@@ -10,55 +10,171 @@ |
#include "webrtc/modules/audio_processing/aec_dump/aec_dump.h" |
+#include "webrtc/base/checks.h" |
+#include "webrtc/base/event.h" |
+#include "webrtc/base/ignore_wundef.h" |
+#include "webrtc/base/protobuf_utils.h" |
+#include "webrtc/modules/audio_processing/aec_dump/write_to_file_task.h" |
+ |
+// Files generated at build-time by the protobuf compiler. |
+RTC_PUSH_IGNORING_WUNDEF() |
+#ifdef WEBRTC_ANDROID_PLATFORM_BUILD |
+#include "external/webrtc/webrtc/modules/audio_processing/debug.pb.h" |
+#else |
+#include "webrtc/modules/audio_processing/debug.pb.h" |
+#endif |
+RTC_POP_IGNORING_WUNDEF() |
+ |
namespace webrtc { |
InternalAPMConfig::InternalAPMConfig() = default; |
InternalAPMConfig::InternalAPMConfig(const InternalAPMConfig&) = default; |
InternalAPMConfig::InternalAPMConfig(InternalAPMConfig&&) = default; |
-AecDump::AecDump(int64_t max_log_size_bytes, rtc::TaskQueue* worker_queue) {} |
+AecDump::AecDump(int64_t max_log_size_bytes, rtc::TaskQueue* worker_queue) |
+ : debug_file_(FileWrapper::Create()), |
+ num_bytes_left_for_log_(max_log_size_bytes), |
+ worker_queue_(worker_queue) {} |
AecDump::AecDump(rtc::PlatformFile file, |
int64_t max_log_size_bytes, |
- rtc::TaskQueue* worker_queue) {} |
+ rtc::TaskQueue* worker_queue) |
+ : AecDump(max_log_size_bytes, worker_queue) { |
+ FILE* handle = rtc::FdopenPlatformFileForWriting(file); |
+ RTC_DCHECK(handle); |
+ debug_file_->OpenFromFileHandle(handle); |
+} |
AecDump::AecDump(std::string file_name, |
int64_t max_log_size_bytes, |
- rtc::TaskQueue* worker_queue) {} |
+ rtc::TaskQueue* worker_queue) |
+ : AecDump(max_log_size_bytes, worker_queue) { |
+ RTC_DCHECK(debug_file_); |
+ debug_file_->OpenFile(file_name.c_str(), false); |
+} |
AecDump::AecDump(FILE* handle, |
int64_t max_log_size_bytes, |
- rtc::TaskQueue* worker_queue) {} |
+ rtc::TaskQueue* worker_queue) |
+ : AecDump(max_log_size_bytes, worker_queue) { |
+ RTC_DCHECK(debug_file_); |
+ debug_file_->OpenFromFileHandle(handle); |
+} |
-AecDump::~AecDump() {} |
+AecDump::~AecDump() { |
+ // Block until all tasks have finished running. |
+ rtc::Event thread_sync_event(false /* manual_reset */, false); |
+ worker_queue_->PostTask([&thread_sync_event] { thread_sync_event.Set(); }); |
+ thread_sync_event.Wait(rtc::Event::kForever); |
peah-webrtc
2017/05/09 07:14:57
What does this do? Can this wait forever in the de
aleloi
2017/05/12 13:07:56
It pauses execution until 'thread_sync_event.Set()
|
+} |
-AecDump::CaptureStreamInfo::CaptureStreamInfo() = default; |
-AecDump::CaptureStreamInfo::~CaptureStreamInfo() = default; |
+void AecDump::WriteInitMessage(const InternalAPMStreamsConfig& streams_config) { |
+ auto event = std::unique_ptr<audioproc::Event>(new audioproc::Event()); |
+ event->set_type(audioproc::Event::INIT); |
+ audioproc::Init* msg = event->mutable_init(); |
+ |
+ msg->set_sample_rate(streams_config.input_sample_rate); |
+ msg->set_output_sample_rate(streams_config.output_sample_rate); |
+ msg->set_reverse_sample_rate(streams_config.render_input_sample_rate); |
+ msg->set_reverse_output_sample_rate(streams_config.render_output_sample_rate); |
+ |
+ msg->set_num_input_channels( |
+ static_cast<int32_t>(streams_config.input_num_channels)); |
+ msg->set_num_output_channels( |
+ static_cast<int32_t>(streams_config.output_num_channels)); |
+ msg->set_num_reverse_channels( |
+ static_cast<int32_t>(streams_config.render_input_num_channels)); |
+ msg->set_num_reverse_output_channels( |
+ streams_config.render_output_num_channels); |
+ |
+ PostTask(std::move(event)); |
+} |
-void AecDump::CaptureStreamInfo::AddInput(FloatAudioFrame src) {} |
-void AecDump::CaptureStreamInfo::AddOutput(FloatAudioFrame src) {} |
+void AecDump::WriteRenderStreamMessage(const AudioFrame& frame) { |
+ auto event = std::unique_ptr<audioproc::Event>(new audioproc::Event()); |
-void AecDump::CaptureStreamInfo::AddInput(const AudioFrame& frame) {} |
-void AecDump::CaptureStreamInfo::AddOutput(const AudioFrame& frame) {} |
+ event->set_type(audioproc::Event::REVERSE_STREAM); |
+ audioproc::ReverseStream* msg = event->mutable_reverse_stream(); |
+ const size_t data_size = |
+ sizeof(int16_t) * frame.samples_per_channel_ * frame.num_channels_; |
+ msg->set_data(frame.data_, data_size); |
-void AecDump::CaptureStreamInfo::set_delay(int delay) {} |
-void AecDump::CaptureStreamInfo::set_drift(int drift) {} |
-void AecDump::CaptureStreamInfo::set_level(int level) {} |
-void AecDump::CaptureStreamInfo::set_keypress(bool keypress) {} |
+ PostTask(std::move(event)); |
+} |
-std::unique_ptr<audioproc::Event> GetEventMsg(); |
+void AecDump::WriteRenderStreamMessage(FloatAudioFrame src) { |
peah-webrtc
2017/05/09 07:14:57
Instead of passing a FloatAudioFrame as
aec_dump_-
aleloi
2017/05/12 13:07:56
I have a mild preference for leaving FloatAudioFra
|
+ auto event = std::unique_ptr<audioproc::Event>(new audioproc::Event()); |
+ event->set_type(audioproc::Event::REVERSE_STREAM); |
-void AecDump::WriteInitMessage(const InternalAPMStreamsConfig& streams_config) { |
-} |
+ audioproc::ReverseStream* msg = event->mutable_reverse_stream(); |
-void AecDump::WriteRenderStreamMessage(const AudioFrame& frame) {} |
+ for (size_t i = 0; i < src.num_channels(); ++i) { |
+ const auto& channel_view = src.channel(i); |
+ msg->add_channel(channel_view.begin(), sizeof(float) * channel_view.size()); |
+ } |
-void AecDump::WriteRenderStreamMessage(FloatAudioFrame src) {} |
+ PostTask(std::move(event)); |
+} |
void AecDump::WriteCaptureStreamMessage( |
- CaptureStreamInfo* capture_stream_info) {} |
+ CaptureStreamInfo* capture_stream_info) { |
+ auto event_ptr = capture_stream_info->GetEventMsg(); |
+ if (event_ptr) { |
+ PostTask(std::move(event_ptr)); |
+ } |
+} |
+ |
+void CopyFromConfigToEvent(const webrtc::InternalAPMConfig& config, |
+ webrtc::audioproc::Config* pb_cfg) { |
+ pb_cfg->set_aec_enabled(config.aec_enabled); |
+ pb_cfg->set_aec_delay_agnostic_enabled(config.aec_delay_agnostic_enabled); |
+ pb_cfg->set_aec_drift_compensation_enabled( |
+ config.aec_drift_compensation_enabled); |
+ pb_cfg->set_aec_extended_filter_enabled(config.aec_extended_filter_enabled); |
+ pb_cfg->set_aec_suppression_level(config.aec_suppression_level); |
+ |
+ pb_cfg->set_aecm_enabled(config.aecm_enabled); |
+ pb_cfg->set_aecm_comfort_noise_enabled(config.aecm_comfort_noise_enabled); |
+ pb_cfg->set_aecm_routing_mode(config.aecm_routing_mode); |
+ |
+ pb_cfg->set_agc_enabled(config.agc_enabled); |
+ pb_cfg->set_agc_mode(config.agc_mode); |
+ pb_cfg->set_agc_limiter_enabled(config.agc_limiter_enabled); |
+ pb_cfg->set_noise_robust_agc_enabled(config.noise_robust_agc_enabled); |
+ |
+ pb_cfg->set_hpf_enabled(config.hpf_enabled); |
+ |
+ pb_cfg->set_ns_enabled(config.ns_enabled); |
+ pb_cfg->set_ns_level(config.ns_level); |
-void AecDump::WriteConfig(const InternalAPMConfig& config, bool forced) {} |
+ pb_cfg->set_transient_suppression_enabled( |
+ config.transient_suppression_enabled); |
+ pb_cfg->set_intelligibility_enhancer_enabled( |
+ config.intelligibility_enhancer_enabled); |
-void AecDump::PostTask(std::unique_ptr<audioproc::Event> event) {} |
+ pb_cfg->set_experiments_description(config.experiments_description); |
+} |
+ |
+void AecDump::WriteConfig(const InternalAPMConfig& config, bool forced) { |
+ auto event = std::unique_ptr<audioproc::Event>(new audioproc::Event()); |
peah-webrtc
2017/05/09 07:14:57
I'd prefer to make this part of the WriteToFileTas
aleloi
2017/05/12 13:07:56
That makes everything a little simpler. I like it!
|
+ event->set_type(audioproc::Event::CONFIG); |
+ CopyFromConfigToEvent(config, event->mutable_config()); |
+ |
+ ProtoString serialized_config = event->mutable_config()->SerializeAsString(); |
+ { |
+ rtc::CritScope cs(&config_string_lock_); |
+ if (!forced && serialized_config == last_serialized_capture_config_) { |
+ return; |
+ } |
+ last_serialized_capture_config_ = serialized_config; |
+ } |
+ |
+ PostTask(std::move(event)); |
+} |
+ |
+void AecDump::PostTask(std::unique_ptr<audioproc::Event> event) { |
+ RTC_DCHECK(event); |
+ worker_queue_->PostTask(std::unique_ptr<rtc::QueuedTask>(new WriteToFileTask( |
+ debug_file_.get(), std::move(event), &num_bytes_left_for_log_))); |
+} |
} // namespace webrtc |