Add a new UMA metric in APM to track incoming capture-side audio level

This CL adds WebRTC.Audio.ApmCaptureInputLevelAverage and
WebRTC.Audio.ApmCaptureInputLevelPeak. The metrics are updated once
every 10 seconds.

BUG=webrtc:6622

Review-Url: https://codereview.webrtc.org/2534473004
Cr-Commit-Position: refs/heads/master@{#15300}
This commit is contained in:
henrik.lundin
2016-11-29 08:09:09 -08:00
committed by Commit bot
parent 939e08f5f4
commit 290d43aa14
4 changed files with 22 additions and 5 deletions

View File

@ -1095,6 +1095,18 @@ int AudioProcessingImpl::ProcessCaptureStreamLocked() {
AudioBuffer* capture_buffer = capture_.capture_audio.get(); // For brevity. AudioBuffer* capture_buffer = capture_.capture_audio.get(); // For brevity.
rms_.Analyze(rtc::ArrayView<const int16_t>(
capture_buffer->channels_const()[0],
capture_nonlocked_.capture_processing_format.num_frames()));
if (++rms_interval_counter_ >= 1000) {
rms_interval_counter_ = 0;
RmsLevel::Levels levels = rms_.AverageAndPeak();
RTC_HISTOGRAM_COUNTS("WebRTC.Audio.ApmCaptureInputLevelAverage",
levels.average, 1, RmsLevel::kMinLevelDb, 100);
RTC_HISTOGRAM_COUNTS("WebRTC.Audio.ApmCaptureInputLevelPeak", levels.peak,
1, RmsLevel::kMinLevelDb, 100);
}
if (constants_.use_experimental_agc && if (constants_.use_experimental_agc &&
public_submodules_->gain_control->is_enabled()) { public_submodules_->gain_control->is_enabled()) {
private_submodules_->agc_manager->AnalyzePreProcess( private_submodules_->agc_manager->AnalyzePreProcess(

View File

@ -25,6 +25,7 @@
#include "webrtc/modules/audio_processing/audio_buffer.h" #include "webrtc/modules/audio_processing/audio_buffer.h"
#include "webrtc/modules/audio_processing/include/audio_processing.h" #include "webrtc/modules/audio_processing/include/audio_processing.h"
#include "webrtc/modules/audio_processing/render_queue_item_verifier.h" #include "webrtc/modules/audio_processing/render_queue_item_verifier.h"
#include "webrtc/modules/audio_processing/rms_level.h"
#include "webrtc/system_wrappers/include/file_wrapper.h" #include "webrtc/system_wrappers/include/file_wrapper.h"
#ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP
@ -406,6 +407,9 @@ class AudioProcessingImpl : public AudioProcessing {
std::vector<float> red_render_queue_buffer_ GUARDED_BY(crit_render_); std::vector<float> red_render_queue_buffer_ GUARDED_BY(crit_render_);
std::vector<float> red_capture_queue_buffer_ GUARDED_BY(crit_capture_); std::vector<float> red_capture_queue_buffer_ GUARDED_BY(crit_capture_);
RmsLevel rms_ GUARDED_BY(crit_capture_);
int rms_interval_counter_ GUARDED_BY(crit_capture_) = 0;
// Lock protection not needed. // Lock protection not needed.
std::unique_ptr<SwapQueue<std::vector<float>, RenderQueueItemVerifier<float>>> std::unique_ptr<SwapQueue<std::vector<float>, RenderQueueItemVerifier<float>>>
aec_render_signal_queue_; aec_render_signal_queue_;

View File

@ -19,7 +19,6 @@
namespace webrtc { namespace webrtc {
namespace { namespace {
static constexpr float kMaxSquaredLevel = 32768 * 32768; static constexpr float kMaxSquaredLevel = 32768 * 32768;
static constexpr int kMinLevelDb = 127;
// kMinLevel is the level corresponding to kMinLevelDb, that is 10^(-127/10). // kMinLevel is the level corresponding to kMinLevelDb, that is 10^(-127/10).
static constexpr float kMinLevel = 1.995262314968883e-13f; static constexpr float kMinLevel = 1.995262314968883e-13f;
@ -31,7 +30,7 @@ static constexpr float kMinLevel = 1.995262314968883e-13f;
int ComputeRms(float mean_square) { int ComputeRms(float mean_square) {
if (mean_square <= kMinLevel * kMaxSquaredLevel) { if (mean_square <= kMinLevel * kMaxSquaredLevel) {
// Very faint; simply return the minimum value. // Very faint; simply return the minimum value.
return kMinLevelDb; return RmsLevel::kMinLevelDb;
} }
// Normalize by the max level. // Normalize by the max level.
const float mean_square_norm = mean_square / kMaxSquaredLevel; const float mean_square_norm = mean_square / kMaxSquaredLevel;
@ -39,7 +38,7 @@ int ComputeRms(float mean_square) {
// 20log_10(x^0.5) = 10log_10(x) // 20log_10(x^0.5) = 10log_10(x)
const float rms = 10.f * log10(mean_square_norm); const float rms = 10.f * log10(mean_square_norm);
RTC_DCHECK_LE(rms, 0.f); RTC_DCHECK_LE(rms, 0.f);
RTC_DCHECK_GT(rms, -kMinLevelDb); RTC_DCHECK_GT(rms, -RmsLevel::kMinLevelDb);
// Return the negated value. // Return the negated value.
return static_cast<int>(-rms + 0.5f); return static_cast<int>(-rms + 0.5f);
} }
@ -81,7 +80,7 @@ void RmsLevel::AnalyzeMuted(size_t length) {
} }
int RmsLevel::Average() { int RmsLevel::Average() {
int rms = (sample_count_ == 0) ? kMinLevelDb int rms = (sample_count_ == 0) ? RmsLevel::kMinLevelDb
: ComputeRms(sum_square_ / sample_count_); : ComputeRms(sum_square_ / sample_count_);
Reset(); Reset();
return rms; return rms;
@ -92,7 +91,7 @@ RmsLevel::Levels RmsLevel::AverageAndPeak() {
// sample_count_ != 0. Also, the * operator of rtc::Optional enforces this // sample_count_ != 0. Also, the * operator of rtc::Optional enforces this
// with a DCHECK. // with a DCHECK.
Levels levels = (sample_count_ == 0) Levels levels = (sample_count_ == 0)
? Levels{kMinLevelDb, kMinLevelDb} ? Levels{RmsLevel::kMinLevelDb, RmsLevel::kMinLevelDb}
: Levels{ComputeRms(sum_square_ / sample_count_), : Levels{ComputeRms(sum_square_ / sample_count_),
ComputeRms(max_sum_square_ / *block_size_)}; ComputeRms(max_sum_square_ / *block_size_)};
Reset(); Reset();

View File

@ -32,6 +32,8 @@ class RmsLevel {
int peak; int peak;
}; };
static constexpr int kMinLevelDb = 127;
RmsLevel(); RmsLevel();
~RmsLevel(); ~RmsLevel();