mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-12 21:30:45 +01:00
Add generic input volume controller test for both AGC1 and AGC2
Make sure that the input volume controller implementations exhibit the adaptive behavior regardless of the sample rate and the number of channels. The newly added tests check that: - a downward adjustment takes place with clipping input - an upward adjustment takes place with a too low speech level - a downward adjustment takes place with a too high speech level Bug: webrtc:14761 Change-Id: I1795e74c5f219e15107e928ebaca2bfa75214526 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/287301 Commit-Queue: Alessio Bazzica <alessiob@webrtc.org> Reviewed-by: Hanna Silen <silen@webrtc.org> Cr-Commit-Position: refs/heads/main@{#38930}
This commit is contained in:
parent
ed0dd8e419
commit
6b7834c14f
2 changed files with 138 additions and 0 deletions
|
@ -43,6 +43,7 @@ constexpr int kMinMicLevel = 12;
|
|||
constexpr int kClippedLevelStep = 15;
|
||||
constexpr float kClippedRatioThreshold = 0.1f;
|
||||
constexpr int kClippedWaitFrames = 300;
|
||||
constexpr float kLowSpeechProbability = 0.1f;
|
||||
constexpr float kHighSpeechProbability = 0.7f;
|
||||
constexpr float kSpeechLevelDbfs = -25.0f;
|
||||
|
||||
|
@ -2113,4 +2114,71 @@ TEST_P(AgcManagerDirectParametrizedTest, NonEmptyRmsErrorOverrideHasEffect) {
|
|||
EXPECT_EQ(manager_1.voice_probability(), manager_2.voice_probability());
|
||||
}
|
||||
|
||||
class AgcManagerDirectChannelSampleRateTest
|
||||
: public ::testing::TestWithParam<std::tuple<int, int>> {
|
||||
protected:
|
||||
int GetNumChannels() const { return std::get<0>(GetParam()); }
|
||||
int GetSampleRateHz() const { return std::get<1>(GetParam()); }
|
||||
};
|
||||
|
||||
TEST_P(AgcManagerDirectChannelSampleRateTest, CheckIsAlive) {
|
||||
const int num_channels = GetNumChannels();
|
||||
const int sample_rate_hz = GetSampleRateHz();
|
||||
|
||||
constexpr AnalogAgcConfig kConfig{.enabled = true,
|
||||
.clipping_predictor{.enabled = true}};
|
||||
AgcManagerDirect manager(num_channels, kConfig);
|
||||
manager.Initialize();
|
||||
AudioBuffer buffer(sample_rate_hz, num_channels, sample_rate_hz, num_channels,
|
||||
sample_rate_hz, num_channels);
|
||||
|
||||
constexpr int kStartupVolume = 100;
|
||||
int applied_initial_volume = kStartupVolume;
|
||||
|
||||
// Trigger a downward adaptation with clipping.
|
||||
WriteAudioBufferSamples(/*samples_value=*/0.0f, /*clipped_ratio=*/0.5f,
|
||||
buffer);
|
||||
const int initial_volume1 = applied_initial_volume;
|
||||
for (int i = 0; i < 400; ++i) {
|
||||
manager.set_stream_analog_level(applied_initial_volume);
|
||||
manager.AnalyzePreProcess(buffer);
|
||||
manager.Process(buffer, kLowSpeechProbability,
|
||||
/*speech_level_dbfs=*/-20.0f);
|
||||
applied_initial_volume = manager.recommended_analog_level();
|
||||
}
|
||||
ASSERT_LT(manager.recommended_analog_level(), initial_volume1);
|
||||
|
||||
// Fill in audio that does not clip.
|
||||
WriteAudioBufferSamples(/*samples_value=*/1234.5f, /*clipped_ratio=*/0.0f,
|
||||
buffer);
|
||||
|
||||
// Trigger an upward adaptation.
|
||||
const int initial_volume2 = manager.recommended_analog_level();
|
||||
for (int i = 0; i < kConfig.clipped_wait_frames; ++i) {
|
||||
manager.set_stream_analog_level(applied_initial_volume);
|
||||
manager.AnalyzePreProcess(buffer);
|
||||
manager.Process(buffer, kHighSpeechProbability,
|
||||
/*speech_level_dbfs=*/-65.0f);
|
||||
applied_initial_volume = manager.recommended_analog_level();
|
||||
}
|
||||
EXPECT_GT(manager.recommended_analog_level(), initial_volume2);
|
||||
|
||||
// Trigger a downward adaptation.
|
||||
const int initial_volume = manager.recommended_analog_level();
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
manager.set_stream_analog_level(applied_initial_volume);
|
||||
manager.AnalyzePreProcess(buffer);
|
||||
manager.Process(buffer, kHighSpeechProbability,
|
||||
/*speech_level_dbfs=*/-5.0f);
|
||||
applied_initial_volume = manager.recommended_analog_level();
|
||||
}
|
||||
EXPECT_LT(manager.recommended_analog_level(), initial_volume);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
,
|
||||
AgcManagerDirectChannelSampleRateTest,
|
||||
::testing::Combine(::testing::Values(1, 2, 3, 6),
|
||||
::testing::Values(8000, 16000, 32000, 48000)));
|
||||
|
||||
} // namespace webrtc
|
||||
|
|
|
@ -325,6 +325,76 @@ class InputVolumeControllerTestHelper {
|
|||
InputVolumeController controller;
|
||||
};
|
||||
|
||||
class InputVolumeControllerChannelSampleRateTest
|
||||
: public ::testing::TestWithParam<std::tuple<int, int>> {
|
||||
protected:
|
||||
int GetNumChannels() const { return std::get<0>(GetParam()); }
|
||||
int GetSampleRateHz() const { return std::get<1>(GetParam()); }
|
||||
};
|
||||
|
||||
TEST_P(InputVolumeControllerChannelSampleRateTest, CheckIsAlive) {
|
||||
const int num_channels = GetNumChannels();
|
||||
const int sample_rate_hz = GetSampleRateHz();
|
||||
|
||||
constexpr InputVolumeController::Config kConfig{.enable_clipping_predictor =
|
||||
true};
|
||||
InputVolumeController controller(num_channels, kConfig);
|
||||
controller.Initialize();
|
||||
AudioBuffer buffer(sample_rate_hz, num_channels, sample_rate_hz, num_channels,
|
||||
sample_rate_hz, num_channels);
|
||||
|
||||
constexpr int kStartupVolume = 100;
|
||||
int applied_initial_volume = kStartupVolume;
|
||||
|
||||
// Trigger a downward adaptation with clipping.
|
||||
constexpr int kLevelWithinTargetDbfs =
|
||||
(kConfig.target_range_min_dbfs + kConfig.target_range_max_dbfs) / 2;
|
||||
WriteAlternatingAudioBufferSamples(/*samples_value=*/kMaxSample, buffer);
|
||||
const int initial_volume1 = applied_initial_volume;
|
||||
for (int i = 0; i < 400; ++i) {
|
||||
controller.AnalyzeInputAudio(applied_initial_volume, buffer);
|
||||
auto recommended_input_volume = controller.RecommendInputVolume(
|
||||
kLowSpeechProbability,
|
||||
/*speech_level_dbfs=*/kLevelWithinTargetDbfs);
|
||||
ASSERT_TRUE(recommended_input_volume.has_value());
|
||||
applied_initial_volume = *recommended_input_volume;
|
||||
}
|
||||
ASSERT_LT(controller.recommended_input_volume(), initial_volume1);
|
||||
|
||||
// Fill in audio that does not clip.
|
||||
WriteAlternatingAudioBufferSamples(/*samples_value=*/1234.5f, buffer);
|
||||
|
||||
// Trigger an upward adaptation.
|
||||
const int initial_volume2 = controller.recommended_input_volume();
|
||||
for (int i = 0; i < kConfig.clipped_wait_frames; ++i) {
|
||||
controller.AnalyzeInputAudio(applied_initial_volume, buffer);
|
||||
auto recommended_input_volume = controller.RecommendInputVolume(
|
||||
kHighSpeechProbability,
|
||||
/*speech_level_dbfs=*/kConfig.target_range_min_dbfs - 5);
|
||||
ASSERT_TRUE(recommended_input_volume.has_value());
|
||||
applied_initial_volume = *recommended_input_volume;
|
||||
}
|
||||
EXPECT_GT(controller.recommended_input_volume(), initial_volume2);
|
||||
|
||||
// Trigger a downward adaptation.
|
||||
const int initial_volume = controller.recommended_input_volume();
|
||||
for (int i = 0; i < kConfig.update_input_volume_wait_frames; ++i) {
|
||||
controller.AnalyzeInputAudio(applied_initial_volume, buffer);
|
||||
auto recommended_input_volume = controller.RecommendInputVolume(
|
||||
kHighSpeechProbability,
|
||||
/*speech_level_dbfs=*/kConfig.target_range_max_dbfs + 5);
|
||||
ASSERT_TRUE(recommended_input_volume.has_value());
|
||||
applied_initial_volume = *recommended_input_volume;
|
||||
}
|
||||
EXPECT_LT(controller.recommended_input_volume(), initial_volume);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
,
|
||||
InputVolumeControllerChannelSampleRateTest,
|
||||
::testing::Combine(::testing::Values(1, 2, 3, 6),
|
||||
::testing::Values(8000, 16000, 32000, 48000)));
|
||||
|
||||
class InputVolumeControllerParametrizedTest
|
||||
: public ::testing::TestWithParam<int> {};
|
||||
|
||||
|
|
Loading…
Reference in a new issue