diff --git a/modules/audio_processing/agc2/input_volume_stats_reporter.cc b/modules/audio_processing/agc2/input_volume_stats_reporter.cc index 4a8b016f45..b2c183157e 100644 --- a/modules/audio_processing/agc2/input_volume_stats_reporter.cc +++ b/modules/audio_processing/agc2/input_volume_stats_reporter.cc @@ -20,9 +20,9 @@ namespace webrtc { namespace { constexpr int kFramesIn60Seconds = 6000; -constexpr int kMinInputVolume = 0; -constexpr int kMaxInputVolume = 255; -constexpr int kMaxUpdate = kMaxInputVolume - kMinInputVolume; +constexpr int kMinGain = 0; +constexpr int kMaxGain = 255; +constexpr int kMaxUpdate = kMaxGain - kMinGain; float ComputeAverageUpdate(int sum_updates, int num_updates) { RTC_DCHECK_GE(sum_updates, 0); @@ -37,50 +37,59 @@ float ComputeAverageUpdate(int sum_updates, int num_updates) { } } // namespace -InputVolumeStatsReporter::InputVolumeStatsReporter() = default; +AnalogGainStatsReporter::AnalogGainStatsReporter() = default; -InputVolumeStatsReporter::~InputVolumeStatsReporter() = default; +AnalogGainStatsReporter::~AnalogGainStatsReporter() = default; -void InputVolumeStatsReporter::UpdateStatistics(int input_volume) { - RTC_DCHECK_GE(input_volume, kMinInputVolume); - RTC_DCHECK_LE(input_volume, kMaxInputVolume); - if (previous_input_volume_.has_value() && - input_volume != previous_input_volume_.value()) { - const int volume_change = input_volume - previous_input_volume_.value(); - if (volume_change < 0) { - ++volume_update_stats_.num_decreases; - volume_update_stats_.sum_decreases -= volume_change; +void AnalogGainStatsReporter::UpdateStatistics(int analog_mic_level) { + RTC_DCHECK_GE(analog_mic_level, kMinGain); + RTC_DCHECK_LE(analog_mic_level, kMaxGain); + if (previous_analog_mic_level_.has_value() && + analog_mic_level != previous_analog_mic_level_.value()) { + const int level_change = + analog_mic_level - previous_analog_mic_level_.value(); + if (level_change < 0) { + ++level_update_stats_.num_decreases; + level_update_stats_.sum_decreases -= level_change; } else { - ++volume_update_stats_.num_increases; - volume_update_stats_.sum_increases += volume_change; + ++level_update_stats_.num_increases; + level_update_stats_.sum_increases += level_change; } } - // Periodically log input volume change metrics. - if (++log_volume_update_stats_counter_ >= kFramesIn60Seconds) { - LogVolumeUpdateStats(); - volume_update_stats_ = {}; - log_volume_update_stats_counter_ = 0; + // Periodically log analog gain change metrics. + if (++log_level_update_stats_counter_ >= kFramesIn60Seconds) { + LogLevelUpdateStats(); + level_update_stats_ = {}; + log_level_update_stats_counter_ = 0; } - previous_input_volume_ = input_volume; + previous_analog_mic_level_ = analog_mic_level; } -void InputVolumeStatsReporter::LogVolumeUpdateStats() const { +void AnalogGainStatsReporter::LogLevelUpdateStats() const { const float average_decrease = ComputeAverageUpdate( - volume_update_stats_.sum_decreases, volume_update_stats_.num_decreases); + level_update_stats_.sum_decreases, level_update_stats_.num_decreases); const float average_increase = ComputeAverageUpdate( - volume_update_stats_.sum_increases, volume_update_stats_.num_increases); + level_update_stats_.sum_increases, level_update_stats_.num_increases); const int num_updates = - volume_update_stats_.num_decreases + volume_update_stats_.num_increases; + level_update_stats_.num_decreases + level_update_stats_.num_increases; const float average_update = ComputeAverageUpdate( - volume_update_stats_.sum_decreases + volume_update_stats_.sum_increases, + level_update_stats_.sum_decreases + level_update_stats_.sum_increases, num_updates); + RTC_DLOG(LS_INFO) << "Analog gain update rate: " + << "num_updates=" << num_updates + << ", num_decreases=" << level_update_stats_.num_decreases + << ", num_increases=" << level_update_stats_.num_increases; + RTC_DLOG(LS_INFO) << "Analog gain update average: " + << "average_update=" << average_update + << ", average_decrease=" << average_decrease + << ", average_increase=" << average_increase; RTC_HISTOGRAM_COUNTS_LINEAR( /*name=*/"WebRTC.Audio.ApmAnalogGainDecreaseRate", - /*sample=*/volume_update_stats_.num_decreases, + /*sample=*/level_update_stats_.num_decreases, /*min=*/1, /*max=*/kFramesIn60Seconds, /*bucket_count=*/50); - if (volume_update_stats_.num_decreases > 0) { + if (level_update_stats_.num_decreases > 0) { RTC_HISTOGRAM_COUNTS_LINEAR( /*name=*/"WebRTC.Audio.ApmAnalogGainDecreaseAverage", /*sample=*/average_decrease, @@ -90,11 +99,11 @@ void InputVolumeStatsReporter::LogVolumeUpdateStats() const { } RTC_HISTOGRAM_COUNTS_LINEAR( /*name=*/"WebRTC.Audio.ApmAnalogGainIncreaseRate", - /*sample=*/volume_update_stats_.num_increases, + /*sample=*/level_update_stats_.num_increases, /*min=*/1, /*max=*/kFramesIn60Seconds, /*bucket_count=*/50); - if (volume_update_stats_.num_increases > 0) { + if (level_update_stats_.num_increases > 0) { RTC_HISTOGRAM_COUNTS_LINEAR( /*name=*/"WebRTC.Audio.ApmAnalogGainIncreaseAverage", /*sample=*/average_increase, diff --git a/modules/audio_processing/agc2/input_volume_stats_reporter.h b/modules/audio_processing/agc2/input_volume_stats_reporter.h index 0040754209..fd048cf3de 100644 --- a/modules/audio_processing/agc2/input_volume_stats_reporter.h +++ b/modules/audio_processing/agc2/input_volume_stats_reporter.h @@ -16,49 +16,51 @@ namespace webrtc { -// Input volume statistics calculator. Computes aggregate stats based on the -// framewise input volume observed by `UpdateStatistics()`. Periodically logs -// the statistics into a histogram. -class InputVolumeStatsReporter { +// Analog gain statistics calculator. Computes aggregate stats based on the +// framewise mic levels processed in `UpdateStatistics()`. Periodically logs the +// statistics into a histogram. +class AnalogGainStatsReporter { public: - InputVolumeStatsReporter(); - InputVolumeStatsReporter(const InputVolumeStatsReporter&) = delete; - InputVolumeStatsReporter operator=(const InputVolumeStatsReporter&) = delete; - ~InputVolumeStatsReporter(); + AnalogGainStatsReporter(); + AnalogGainStatsReporter(const AnalogGainStatsReporter&) = delete; + AnalogGainStatsReporter operator=(const AnalogGainStatsReporter&) = delete; + ~AnalogGainStatsReporter(); - // Updates the stats based on `input_volume`. Periodically logs the stats into - // a histogram. - void UpdateStatistics(int input_volume); + // Updates the stats based on the `analog_mic_level`. Periodically logs the + // stats into a histogram. + void UpdateStatistics(int analog_mic_level); private: - FRIEND_TEST_ALL_PREFIXES(InputVolumeStatsReporterTest, - CheckVolumeUpdateStatsForEmptyStats); - FRIEND_TEST_ALL_PREFIXES(InputVolumeStatsReporterTest, - CheckVolumeUpdateStatsAfterNoVolumeChange); - FRIEND_TEST_ALL_PREFIXES(InputVolumeStatsReporterTest, - CheckVolumeUpdateStatsAfterVolumeIncrease); - FRIEND_TEST_ALL_PREFIXES(InputVolumeStatsReporterTest, - CheckVolumeUpdateStatsAfterVolumeDecrease); - FRIEND_TEST_ALL_PREFIXES(InputVolumeStatsReporterTest, - CheckVolumeUpdateStatsAfterReset); + FRIEND_TEST_ALL_PREFIXES(AnalogGainStatsReporterTest, + CheckLevelUpdateStatsForEmptyStats); + FRIEND_TEST_ALL_PREFIXES(AnalogGainStatsReporterTest, + CheckLevelUpdateStatsAfterNoGainChange); + FRIEND_TEST_ALL_PREFIXES(AnalogGainStatsReporterTest, + CheckLevelUpdateStatsAfterGainIncrease); + FRIEND_TEST_ALL_PREFIXES(AnalogGainStatsReporterTest, + CheckLevelUpdateStatsAfterGainDecrease); + FRIEND_TEST_ALL_PREFIXES(AnalogGainStatsReporterTest, + CheckLevelUpdateStatsAfterReset); - // Stores input volume update stats to enable calculation of update rate and - // average update separately for volume increases and decreases. - struct VolumeUpdateStats { + // Stores analog gain update stats to enable calculation of update rate and + // average update separately for gain increases and decreases. + struct LevelUpdateStats { int num_decreases = 0; int num_increases = 0; int sum_decreases = 0; int sum_increases = 0; - } volume_update_stats_; + } level_update_stats_; // Returns a copy of the stored statistics. Use only for testing. - VolumeUpdateStats volume_update_stats() const { return volume_update_stats_; } + const LevelUpdateStats level_update_stats() const { + return level_update_stats_; + } // Computes aggregate stat and logs them into a histogram. - void LogVolumeUpdateStats() const; + void LogLevelUpdateStats() const; - int log_volume_update_stats_counter_ = 0; - absl::optional previous_input_volume_ = absl::nullopt; + int log_level_update_stats_counter_ = 0; + absl::optional previous_analog_mic_level_ = absl::nullopt; }; } // namespace webrtc diff --git a/modules/audio_processing/agc2/input_volume_stats_reporter_unittest.cc b/modules/audio_processing/agc2/input_volume_stats_reporter_unittest.cc index f8cd010784..196b1e0e36 100644 --- a/modules/audio_processing/agc2/input_volume_stats_reporter_unittest.cc +++ b/modules/audio_processing/agc2/input_volume_stats_reporter_unittest.cc @@ -18,22 +18,22 @@ namespace { constexpr int kFramesIn60Seconds = 6000; -class InputVolumeStatsReporterTest : public ::testing::Test { +class AnalogGainStatsReporterTest : public ::testing::Test { public: - InputVolumeStatsReporterTest() {} + AnalogGainStatsReporterTest() {} protected: void SetUp() override { metrics::Reset(); } }; -TEST_F(InputVolumeStatsReporterTest, CheckLogVolumeUpdateStatsEmpty) { - InputVolumeStatsReporter stats_reporter; - constexpr int kInputVolume = 10; - stats_reporter.UpdateStatistics(kInputVolume); +TEST_F(AnalogGainStatsReporterTest, CheckLogLevelUpdateStatsEmpty) { + AnalogGainStatsReporter stats_reporter; + constexpr int kMicLevel = 10; + stats_reporter.UpdateStatistics(kMicLevel); // Update almost until the periodic logging and reset. for (int i = 0; i < kFramesIn60Seconds - 2; i += 2) { - stats_reporter.UpdateStatistics(kInputVolume + 2); - stats_reporter.UpdateStatistics(kInputVolume); + stats_reporter.UpdateStatistics(kMicLevel + 2); + stats_reporter.UpdateStatistics(kMicLevel); } EXPECT_METRIC_THAT(metrics::Samples("WebRTC.Audio.ApmAnalogGainUpdateRate"), ::testing::ElementsAre()); @@ -52,19 +52,19 @@ TEST_F(InputVolumeStatsReporterTest, CheckLogVolumeUpdateStatsEmpty) { ::testing::ElementsAre()); } -TEST_F(InputVolumeStatsReporterTest, CheckLogVolumeUpdateStatsNotEmpty) { - InputVolumeStatsReporter stats_reporter; - constexpr int kInputVolume = 10; - stats_reporter.UpdateStatistics(kInputVolume); +TEST_F(AnalogGainStatsReporterTest, CheckLogLevelUpdateStatsNotEmpty) { + AnalogGainStatsReporter stats_reporter; + constexpr int kMicLevel = 10; + stats_reporter.UpdateStatistics(kMicLevel); // Update until periodic logging. for (int i = 0; i < kFramesIn60Seconds; i += 2) { - stats_reporter.UpdateStatistics(kInputVolume + 2); - stats_reporter.UpdateStatistics(kInputVolume); + stats_reporter.UpdateStatistics(kMicLevel + 2); + stats_reporter.UpdateStatistics(kMicLevel); } // Update until periodic logging. for (int i = 0; i < kFramesIn60Seconds; i += 2) { - stats_reporter.UpdateStatistics(kInputVolume + 3); - stats_reporter.UpdateStatistics(kInputVolume); + stats_reporter.UpdateStatistics(kMicLevel + 3); + stats_reporter.UpdateStatistics(kMicLevel); } EXPECT_METRIC_THAT( metrics::Samples("WebRTC.Audio.ApmAnalogGainUpdateRate"), @@ -89,80 +89,77 @@ TEST_F(InputVolumeStatsReporterTest, CheckLogVolumeUpdateStatsNotEmpty) { } } // namespace -TEST_F(InputVolumeStatsReporterTest, CheckVolumeUpdateStatsForEmptyStats) { - InputVolumeStatsReporter stats_reporter; - const auto& update_stats = stats_reporter.volume_update_stats(); +TEST_F(AnalogGainStatsReporterTest, CheckLevelUpdateStatsForEmptyStats) { + AnalogGainStatsReporter stats_reporter; + const auto& update_stats = stats_reporter.level_update_stats(); EXPECT_EQ(update_stats.num_decreases, 0); EXPECT_EQ(update_stats.sum_decreases, 0); EXPECT_EQ(update_stats.num_increases, 0); EXPECT_EQ(update_stats.sum_increases, 0); } -TEST_F(InputVolumeStatsReporterTest, - CheckVolumeUpdateStatsAfterNoVolumeChange) { - constexpr int kInputVolume = 10; - InputVolumeStatsReporter stats_reporter; - stats_reporter.UpdateStatistics(kInputVolume); - stats_reporter.UpdateStatistics(kInputVolume); - stats_reporter.UpdateStatistics(kInputVolume); - const auto& update_stats = stats_reporter.volume_update_stats(); +TEST_F(AnalogGainStatsReporterTest, CheckLevelUpdateStatsAfterNoGainChange) { + constexpr int kMicLevel = 10; + AnalogGainStatsReporter stats_reporter; + stats_reporter.UpdateStatistics(kMicLevel); + stats_reporter.UpdateStatistics(kMicLevel); + stats_reporter.UpdateStatistics(kMicLevel); + const auto& update_stats = stats_reporter.level_update_stats(); EXPECT_EQ(update_stats.num_decreases, 0); EXPECT_EQ(update_stats.sum_decreases, 0); EXPECT_EQ(update_stats.num_increases, 0); EXPECT_EQ(update_stats.sum_increases, 0); } -TEST_F(InputVolumeStatsReporterTest, - CheckVolumeUpdateStatsAfterVolumeIncrease) { - constexpr int kInputVolume = 10; - InputVolumeStatsReporter stats_reporter; - stats_reporter.UpdateStatistics(kInputVolume); - stats_reporter.UpdateStatistics(kInputVolume + 4); - stats_reporter.UpdateStatistics(kInputVolume + 5); - const auto& update_stats = stats_reporter.volume_update_stats(); +TEST_F(AnalogGainStatsReporterTest, CheckLevelUpdateStatsAfterGainIncrease) { + constexpr int kMicLevel = 10; + AnalogGainStatsReporter stats_reporter; + stats_reporter.UpdateStatistics(kMicLevel); + stats_reporter.UpdateStatistics(kMicLevel + 4); + stats_reporter.UpdateStatistics(kMicLevel + 5); + const auto& update_stats = stats_reporter.level_update_stats(); EXPECT_EQ(update_stats.num_decreases, 0); EXPECT_EQ(update_stats.sum_decreases, 0); EXPECT_EQ(update_stats.num_increases, 2); EXPECT_EQ(update_stats.sum_increases, 5); } -TEST_F(InputVolumeStatsReporterTest, - CheckVolumeUpdateStatsAfterVolumeDecrease) { - constexpr int kInputVolume = 10; - InputVolumeStatsReporter stats_reporter; - stats_reporter.UpdateStatistics(kInputVolume); - stats_reporter.UpdateStatistics(kInputVolume - 4); - stats_reporter.UpdateStatistics(kInputVolume - 5); - const auto& stats_update = stats_reporter.volume_update_stats(); +TEST_F(AnalogGainStatsReporterTest, CheckLevelUpdateStatsAfterGainDecrease) { + constexpr int kMicLevel = 10; + AnalogGainStatsReporter stats_reporter; + stats_reporter.UpdateStatistics(kMicLevel); + stats_reporter.UpdateStatistics(kMicLevel - 4); + stats_reporter.UpdateStatistics(kMicLevel - 5); + const auto& stats_update = stats_reporter.level_update_stats(); EXPECT_EQ(stats_update.num_decreases, 2); EXPECT_EQ(stats_update.sum_decreases, 5); EXPECT_EQ(stats_update.num_increases, 0); EXPECT_EQ(stats_update.sum_increases, 0); } -TEST_F(InputVolumeStatsReporterTest, CheckVolumeUpdateStatsAfterReset) { - InputVolumeStatsReporter stats_reporter; - constexpr int kInputVolume = 10; - stats_reporter.UpdateStatistics(kInputVolume); +TEST_F(AnalogGainStatsReporterTest, CheckLevelUpdateStatsAfterReset) { + AnalogGainStatsReporter stats_reporter; + constexpr int kMicLevel = 10; + stats_reporter.UpdateStatistics(kMicLevel); // Update until the periodic reset. for (int i = 0; i < kFramesIn60Seconds - 2; i += 2) { - stats_reporter.UpdateStatistics(kInputVolume + 2); - stats_reporter.UpdateStatistics(kInputVolume); + stats_reporter.UpdateStatistics(kMicLevel + 2); + stats_reporter.UpdateStatistics(kMicLevel); } - const auto& stats_before_reset = stats_reporter.volume_update_stats(); + const auto& stats_before_reset = stats_reporter.level_update_stats(); EXPECT_EQ(stats_before_reset.num_decreases, kFramesIn60Seconds / 2 - 1); EXPECT_EQ(stats_before_reset.sum_decreases, kFramesIn60Seconds - 2); EXPECT_EQ(stats_before_reset.num_increases, kFramesIn60Seconds / 2 - 1); EXPECT_EQ(stats_before_reset.sum_increases, kFramesIn60Seconds - 2); - stats_reporter.UpdateStatistics(kInputVolume + 2); - const auto& stats_during_reset = stats_reporter.volume_update_stats(); + stats_reporter.UpdateStatistics(kMicLevel + 2); + const auto& stats_during_reset = stats_reporter.level_update_stats(); EXPECT_EQ(stats_during_reset.num_decreases, 0); EXPECT_EQ(stats_during_reset.sum_decreases, 0); EXPECT_EQ(stats_during_reset.num_increases, 0); EXPECT_EQ(stats_during_reset.sum_increases, 0); - stats_reporter.UpdateStatistics(kInputVolume); - stats_reporter.UpdateStatistics(kInputVolume + 3); - const auto& stats_after_reset = stats_reporter.volume_update_stats(); + stats_reporter.UpdateStatistics(kMicLevel); + stats_reporter.UpdateStatistics(kMicLevel + 3); + const auto& stats_after_reset = stats_reporter.level_update_stats(); EXPECT_EQ(stats_after_reset.num_decreases, 1); EXPECT_EQ(stats_after_reset.sum_decreases, 2); EXPECT_EQ(stats_after_reset.num_increases, 1); diff --git a/modules/audio_processing/audio_processing_impl.cc b/modules/audio_processing/audio_processing_impl.cc index 76e380426f..1d588feb42 100644 --- a/modules/audio_processing/audio_processing_impl.cc +++ b/modules/audio_processing/audio_processing_impl.cc @@ -1131,7 +1131,8 @@ int AudioProcessingImpl::ProcessCaptureStreamLocked() { } if (capture_.applied_input_volume.has_value()) { - applied_input_volume_stats_reporter_.UpdateStatistics( + // Log the applied input volume only when available. + input_volume_stats_reporter_.UpdateStatistics( *capture_.applied_input_volume); } diff --git a/modules/audio_processing/audio_processing_impl.h b/modules/audio_processing/audio_processing_impl.h index bc582b542d..3dfa8cecae 100644 --- a/modules/audio_processing/audio_processing_impl.h +++ b/modules/audio_processing/audio_processing_impl.h @@ -539,7 +539,7 @@ class AudioProcessingImpl : public AudioProcessing { RmsLevel capture_output_rms_ RTC_GUARDED_BY(mutex_capture_); int capture_rms_interval_counter_ RTC_GUARDED_BY(mutex_capture_) = 0; - InputVolumeStatsReporter applied_input_volume_stats_reporter_ + AnalogGainStatsReporter input_volume_stats_reporter_ RTC_GUARDED_BY(mutex_capture_); // Lock protection not needed.