InputVolumeController: Restrict the application of min input volume
Only allow the application of min input volume if the applied input volume is above zero. To implement this, add a member variable to store the applied input volume. Rename the related setter to reflect its new functionality. Bug: webrtc:7494 Change-Id: Ia70d5cb4dfd972aad9ef2663a81884f3e5cb0758 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/287680 Reviewed-by: Alessio Bazzica <alessiob@webrtc.org> Commit-Queue: Hanna Silen <silen@webrtc.org> Cr-Commit-Position: refs/heads/main@{#38878}
This commit is contained in:
parent
8d74b28518
commit
cdee165646
@ -551,7 +551,9 @@ void InputVolumeController::HandleCaptureOutputUsedChange(
|
|||||||
capture_output_used_ = capture_output_used;
|
capture_output_used_ = capture_output_used;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputVolumeController::set_stream_analog_level(int input_volume) {
|
void InputVolumeController::SetAppliedInputVolume(int input_volume) {
|
||||||
|
applied_input_volume_ = input_volume;
|
||||||
|
|
||||||
for (auto& controller : channel_controllers_) {
|
for (auto& controller : channel_controllers_) {
|
||||||
controller->set_stream_analog_level(input_volume);
|
controller->set_stream_analog_level(input_volume);
|
||||||
}
|
}
|
||||||
@ -572,7 +574,7 @@ void InputVolumeController::AggregateChannelLevels() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Enforce the minimum input volume when a recommendation is made.
|
// Enforce the minimum input volume when a recommendation is made.
|
||||||
if (new_recommended_input_volume > 0) {
|
if (applied_input_volume_ > 0) {
|
||||||
new_recommended_input_volume =
|
new_recommended_input_volume =
|
||||||
std::max(new_recommended_input_volume, min_input_volume_);
|
std::max(new_recommended_input_volume, min_input_volume_);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -82,7 +82,7 @@ class InputVolumeController final {
|
|||||||
void Initialize();
|
void Initialize();
|
||||||
|
|
||||||
// Sets the applied input volume.
|
// Sets the applied input volume.
|
||||||
void set_stream_analog_level(int level);
|
void SetAppliedInputVolume(int level);
|
||||||
|
|
||||||
// TODO(bugs.webrtc.org/7494): Add argument for the applied input volume and
|
// TODO(bugs.webrtc.org/7494): Add argument for the applied input volume and
|
||||||
// remove `set_stream_analog_level()`.
|
// remove `set_stream_analog_level()`.
|
||||||
@ -101,13 +101,11 @@ class InputVolumeController final {
|
|||||||
void Process(float speech_probability,
|
void Process(float speech_probability,
|
||||||
absl::optional<float> speech_level_dbfs);
|
absl::optional<float> speech_level_dbfs);
|
||||||
|
|
||||||
// TODO(bugs.webrtc.org/7494): Return recommended input volume and remove
|
|
||||||
// `recommended_analog_level()`.
|
|
||||||
// Returns the recommended input volume. If the input volume contoller is
|
// Returns the recommended input volume. If the input volume contoller is
|
||||||
// disabled, returns the input volume set via the latest
|
// disabled, returns the input volume set via the latest
|
||||||
// `set_stream_analog_level()` call. Must be called after
|
// `SetAppliedInputVolume()` call. Must be called after `AnalyzePreProcess()`
|
||||||
// `AnalyzePreProcess()` and `Process()`.
|
// and `Process()`.
|
||||||
int recommended_analog_level() const { return recommended_input_volume_; }
|
int recommended_input_volume() const { return recommended_input_volume_; }
|
||||||
|
|
||||||
// Stores whether the capture output will be used or not. Call when the
|
// Stores whether the capture output will be used or not. Call when the
|
||||||
// capture stream output has been flagged to be used/not-used. If unused, the
|
// capture stream output has been flagged to be used/not-used. If unused, the
|
||||||
@ -144,15 +142,17 @@ class InputVolumeController final {
|
|||||||
// Minimum input volume that can be recommended.
|
// Minimum input volume that can be recommended.
|
||||||
const int min_input_volume_;
|
const int min_input_volume_;
|
||||||
|
|
||||||
// TODO(bugs.webrtc.org/7494): Create a separate member for the applied input
|
|
||||||
// volume.
|
|
||||||
// TODO(bugs.webrtc.org/7494): Once
|
// TODO(bugs.webrtc.org/7494): Once
|
||||||
// `AudioProcessingImpl::recommended_stream_analog_level()` becomes a trivial
|
// `AudioProcessingImpl::recommended_stream_analog_level()` becomes a trivial
|
||||||
// getter, leave uninitialized.
|
// getter, leave uninitialized.
|
||||||
// Recommended input volume. After `set_stream_analog_level()` is called it
|
// Recommended input volume. After `SetAppliedInputVolume()` is called it
|
||||||
// holds the observed input volume. Possibly updated by `AnalyzePreProcess()`
|
// holds holds the observed input volume. Possibly updated by
|
||||||
// and `Process()`; after these calls, holds the recommended input volume.
|
// `AnalyzePreProcess()` and `Process()`; after these calls, holds the
|
||||||
|
// recommended input volume.
|
||||||
int recommended_input_volume_ = 0;
|
int recommended_input_volume_ = 0;
|
||||||
|
// Applied input volume. After `SetAppliedInputVolume()` is called it holds
|
||||||
|
// the current applied volume.
|
||||||
|
int applied_input_volume_ = 0;
|
||||||
|
|
||||||
bool capture_output_used_;
|
bool capture_output_used_;
|
||||||
|
|
||||||
|
|||||||
@ -216,10 +216,10 @@ class SpeechSamplesReader {
|
|||||||
return rtc::SafeClamp(static_cast<float>(v) * gain,
|
return rtc::SafeClamp(static_cast<float>(v) * gain,
|
||||||
kMinSample, kMaxSample);
|
kMinSample, kMaxSample);
|
||||||
});
|
});
|
||||||
controller.set_stream_analog_level(applied_input_volume);
|
controller.SetAppliedInputVolume(applied_input_volume);
|
||||||
controller.AnalyzePreProcess(audio_buffer_);
|
controller.AnalyzePreProcess(audio_buffer_);
|
||||||
controller.Process(speech_probability, speech_level_dbfs);
|
controller.Process(speech_probability, speech_level_dbfs);
|
||||||
applied_input_volume = controller.recommended_analog_level();
|
applied_input_volume = controller.recommended_input_volume();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,14 +232,14 @@ class SpeechSamplesReader {
|
|||||||
|
|
||||||
// Runs the MonoInputVolumeControl processing sequence following the API
|
// Runs the MonoInputVolumeControl processing sequence following the API
|
||||||
// contract. Returns the updated recommended input volume.
|
// contract. Returns the updated recommended input volume.
|
||||||
float UpdateRecommendedInputVolume(MonoInputVolumeController& controller,
|
float UpdateRecommendedInputVolume(MonoInputVolumeController& mono_controller,
|
||||||
int applied_input_volume,
|
int applied_input_volume,
|
||||||
float speech_probability,
|
float speech_probability,
|
||||||
absl::optional<float> rms_error_dbfs) {
|
absl::optional<float> rms_error_dbfs) {
|
||||||
controller.set_stream_analog_level(applied_input_volume);
|
mono_controller.set_stream_analog_level(applied_input_volume);
|
||||||
EXPECT_EQ(controller.recommended_analog_level(), applied_input_volume);
|
EXPECT_EQ(mono_controller.recommended_analog_level(), applied_input_volume);
|
||||||
controller.Process(rms_error_dbfs, speech_probability);
|
mono_controller.Process(rms_error_dbfs, speech_probability);
|
||||||
return controller.recommended_analog_level();
|
return mono_controller.recommended_analog_level();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
@ -297,10 +297,10 @@ class InputVolumeControllerTestHelper {
|
|||||||
int volume = applied_input_volume;
|
int volume = applied_input_volume;
|
||||||
|
|
||||||
for (int i = 0; i < num_calls; ++i) {
|
for (int i = 0; i < num_calls; ++i) {
|
||||||
controller.set_stream_analog_level(volume);
|
controller.SetAppliedInputVolume(volume);
|
||||||
controller.AnalyzePreProcess(audio_buffer);
|
controller.AnalyzePreProcess(audio_buffer);
|
||||||
controller.Process(speech_probability, speech_level_dbfs);
|
controller.Process(speech_probability, speech_level_dbfs);
|
||||||
volume = controller.recommended_analog_level();
|
volume = controller.recommended_input_volume();
|
||||||
}
|
}
|
||||||
return volume;
|
return volume;
|
||||||
}
|
}
|
||||||
@ -356,7 +356,7 @@ TEST_P(InputVolumeControllerParametrizedTest,
|
|||||||
helper.CallAgcSequence(kInitialInputVolume, kHighSpeechProbability,
|
helper.CallAgcSequence(kInitialInputVolume, kHighSpeechProbability,
|
||||||
kSpeechLevel);
|
kSpeechLevel);
|
||||||
|
|
||||||
EXPECT_EQ(kInitialInputVolume, helper.controller.recommended_analog_level());
|
EXPECT_EQ(kInitialInputVolume, helper.controller.recommended_input_volume());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(InputVolumeControllerParametrizedTest, MicVolumeResponseToRmsError) {
|
TEST_P(InputVolumeControllerParametrizedTest, MicVolumeResponseToRmsError) {
|
||||||
@ -372,10 +372,10 @@ TEST_P(InputVolumeControllerParametrizedTest, MicVolumeResponseToRmsError) {
|
|||||||
|
|
||||||
// Above the digital gain's window; volume should be increased.
|
// Above the digital gain's window; volume should be increased.
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -29.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -29.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 128);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 128);
|
||||||
|
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -38.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -38.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 156);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 156);
|
||||||
|
|
||||||
// Inside the digital gain's window; no change of volume.
|
// Inside the digital gain's window; no change of volume.
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -23.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -23.0f);
|
||||||
@ -383,13 +383,13 @@ TEST_P(InputVolumeControllerParametrizedTest, MicVolumeResponseToRmsError) {
|
|||||||
|
|
||||||
// Below the digial gain's window; volume should be decreased.
|
// Below the digial gain's window; volume should be decreased.
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -17.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -17.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 155);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 155);
|
||||||
|
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -17.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -17.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 151);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 151);
|
||||||
|
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -9.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -9.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 119);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 119);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(InputVolumeControllerParametrizedTest, MicVolumeIsLimited) {
|
TEST_P(InputVolumeControllerParametrizedTest, MicVolumeIsLimited) {
|
||||||
@ -399,41 +399,41 @@ TEST_P(InputVolumeControllerParametrizedTest, MicVolumeIsLimited) {
|
|||||||
|
|
||||||
// Maximum upwards change is limited.
|
// Maximum upwards change is limited.
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -48.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -48.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 183);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 183);
|
||||||
|
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -48.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -48.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 243);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 243);
|
||||||
|
|
||||||
// Won't go higher than the maximum.
|
// Won't go higher than the maximum.
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -48.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -48.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 255);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 255);
|
||||||
|
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -17.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -17.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 254);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 254);
|
||||||
|
|
||||||
// Maximum downwards change is limited.
|
// Maximum downwards change is limited.
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, 22.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, 22.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 194);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 194);
|
||||||
|
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, 22.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, 22.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 137);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 137);
|
||||||
|
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, 22.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, 22.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 88);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 88);
|
||||||
|
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, 22.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, 22.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 54);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 54);
|
||||||
|
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, 22.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, 22.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 33);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 33);
|
||||||
|
|
||||||
// Won't go lower than the minimum.
|
// Won't go lower than the minimum.
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, 22.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, 22.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(),
|
EXPECT_EQ(helper.controller.recommended_input_volume(),
|
||||||
std::max(18, GetMinInputVolume()));
|
std::max(18, GetMinInputVolume()));
|
||||||
|
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, 22.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, 22.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(),
|
EXPECT_EQ(helper.controller.recommended_input_volume(),
|
||||||
std::max(12, GetMinInputVolume()));
|
std::max(12, GetMinInputVolume()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -456,11 +456,11 @@ TEST_P(InputVolumeControllerParametrizedTest,
|
|||||||
helper.controller.HandleCaptureOutputUsedChange(true);
|
helper.controller.HandleCaptureOutputUsedChange(true);
|
||||||
|
|
||||||
constexpr int kInputVolume = 127;
|
constexpr int kInputVolume = 127;
|
||||||
helper.controller.set_stream_analog_level(kInputVolume);
|
helper.controller.SetAppliedInputVolume(kInputVolume);
|
||||||
|
|
||||||
// SetMicVolume should not be called.
|
// SetMicVolume should not be called.
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, kSpeechLevel);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, kSpeechLevel);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 127);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 127);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(InputVolumeControllerParametrizedTest, UnmutingRaisesTooLowVolume) {
|
TEST_P(InputVolumeControllerParametrizedTest, UnmutingRaisesTooLowVolume) {
|
||||||
@ -472,10 +472,10 @@ TEST_P(InputVolumeControllerParametrizedTest, UnmutingRaisesTooLowVolume) {
|
|||||||
helper.controller.HandleCaptureOutputUsedChange(true);
|
helper.controller.HandleCaptureOutputUsedChange(true);
|
||||||
|
|
||||||
constexpr int kInputVolume = 11;
|
constexpr int kInputVolume = 11;
|
||||||
helper.controller.set_stream_analog_level(kInputVolume);
|
helper.controller.SetAppliedInputVolume(kInputVolume);
|
||||||
|
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, kSpeechLevel);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, kSpeechLevel);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), GetMinInputVolume());
|
EXPECT_EQ(helper.controller.recommended_input_volume(), GetMinInputVolume());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(InputVolumeControllerParametrizedTest,
|
TEST_P(InputVolumeControllerParametrizedTest,
|
||||||
@ -486,19 +486,19 @@ TEST_P(InputVolumeControllerParametrizedTest,
|
|||||||
|
|
||||||
// GetMicVolume returns a value outside of the quantization slack, indicating
|
// GetMicVolume returns a value outside of the quantization slack, indicating
|
||||||
// a manual volume change.
|
// a manual volume change.
|
||||||
ASSERT_NE(helper.controller.recommended_analog_level(), 154);
|
ASSERT_NE(helper.controller.recommended_input_volume(), 154);
|
||||||
helper.controller.set_stream_analog_level(154);
|
helper.controller.SetAppliedInputVolume(154);
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -29.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -29.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 154);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 154);
|
||||||
|
|
||||||
// Do the same thing, except downwards now.
|
// Do the same thing, except downwards now.
|
||||||
helper.controller.set_stream_analog_level(100);
|
helper.controller.SetAppliedInputVolume(100);
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -17.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -17.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 100);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 100);
|
||||||
|
|
||||||
// And finally verify the AGC continues working without a manual change.
|
// And finally verify the AGC continues working without a manual change.
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -17.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -17.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 99);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 99);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(InputVolumeControllerParametrizedTest,
|
TEST_P(InputVolumeControllerParametrizedTest,
|
||||||
@ -510,21 +510,21 @@ TEST_P(InputVolumeControllerParametrizedTest,
|
|||||||
// Force the mic up to max volume. Takes a few steps due to the residual
|
// Force the mic up to max volume. Takes a few steps due to the residual
|
||||||
// gain limitation.
|
// gain limitation.
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -48.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -48.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 183);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 183);
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -48.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -48.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 243);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 243);
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -48.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -48.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 255);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 255);
|
||||||
|
|
||||||
// Manual change does not result in SetMicVolume call.
|
// Manual change does not result in SetMicVolume call.
|
||||||
helper.controller.set_stream_analog_level(50);
|
helper.controller.SetAppliedInputVolume(50);
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -17.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -17.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 50);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 50);
|
||||||
|
|
||||||
// Continues working as usual afterwards.
|
// Continues working as usual afterwards.
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -38.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -38.0f);
|
||||||
|
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 65);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 65);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks that the minimum input volume is enforced during the upward adjustment
|
// Checks that the minimum input volume is enforced during the upward adjustment
|
||||||
@ -537,20 +537,20 @@ TEST_P(InputVolumeControllerParametrizedTest,
|
|||||||
|
|
||||||
// Manual change below min, but strictly positive, otherwise no action will be
|
// Manual change below min, but strictly positive, otherwise no action will be
|
||||||
// taken.
|
// taken.
|
||||||
helper.controller.set_stream_analog_level(1);
|
helper.controller.SetAppliedInputVolume(1);
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -17.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -17.0f);
|
||||||
|
|
||||||
// Trigger an upward adjustment of the input volume.
|
// Trigger an upward adjustment of the input volume.
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), GetMinInputVolume());
|
EXPECT_EQ(helper.controller.recommended_input_volume(), GetMinInputVolume());
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -29.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -29.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), GetMinInputVolume());
|
EXPECT_EQ(helper.controller.recommended_input_volume(), GetMinInputVolume());
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -48.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -48.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), GetMinInputVolume());
|
EXPECT_EQ(helper.controller.recommended_input_volume(), GetMinInputVolume());
|
||||||
|
|
||||||
// After a number of consistently low speech level observations, the input
|
// After a number of consistently low speech level observations, the input
|
||||||
// volume is eventually raised above the minimum.
|
// volume is eventually raised above the minimum.
|
||||||
helper.CallProcess(/*num_calls=*/10, kHighSpeechProbability, -38.0f);
|
helper.CallProcess(/*num_calls=*/10, kHighSpeechProbability, -38.0f);
|
||||||
EXPECT_GT(helper.controller.recommended_analog_level(), GetMinInputVolume());
|
EXPECT_GT(helper.controller.recommended_input_volume(), GetMinInputVolume());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks that, when the min mic level override is specified, AGC immediately
|
// Checks that, when the min mic level override is specified, AGC immediately
|
||||||
@ -564,9 +564,9 @@ TEST_P(InputVolumeControllerParametrizedTest,
|
|||||||
|
|
||||||
// Manual change below min, but strictly positive, otherwise
|
// Manual change below min, but strictly positive, otherwise
|
||||||
// AGC won't take any action.
|
// AGC won't take any action.
|
||||||
helper.controller.set_stream_analog_level(1);
|
helper.controller.SetAppliedInputVolume(1);
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -17.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -17.0f);
|
||||||
EXPECT_EQ(GetMinInputVolume(), helper.controller.recommended_analog_level());
|
EXPECT_EQ(GetMinInputVolume(), helper.controller.recommended_input_volume());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(InputVolumeControllerParametrizedTest, NoClippingHasNoImpact) {
|
TEST_P(InputVolumeControllerParametrizedTest, NoClippingHasNoImpact) {
|
||||||
@ -575,7 +575,7 @@ TEST_P(InputVolumeControllerParametrizedTest, NoClippingHasNoImpact) {
|
|||||||
kSpeechLevel);
|
kSpeechLevel);
|
||||||
|
|
||||||
helper.CallPreProc(/*num_calls=*/100, /*clipped_ratio=*/0);
|
helper.CallPreProc(/*num_calls=*/100, /*clipped_ratio=*/0);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 128);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 128);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(InputVolumeControllerParametrizedTest,
|
TEST_P(InputVolumeControllerParametrizedTest,
|
||||||
@ -585,7 +585,7 @@ TEST_P(InputVolumeControllerParametrizedTest,
|
|||||||
kSpeechLevel);
|
kSpeechLevel);
|
||||||
|
|
||||||
helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/0.099);
|
helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/0.099);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 128);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 128);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(InputVolumeControllerParametrizedTest, ClippingLowersVolume) {
|
TEST_P(InputVolumeControllerParametrizedTest, ClippingLowersVolume) {
|
||||||
@ -594,7 +594,7 @@ TEST_P(InputVolumeControllerParametrizedTest, ClippingLowersVolume) {
|
|||||||
kSpeechLevel);
|
kSpeechLevel);
|
||||||
|
|
||||||
helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/0.2);
|
helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/0.2);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 240);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 240);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(InputVolumeControllerParametrizedTest,
|
TEST_P(InputVolumeControllerParametrizedTest,
|
||||||
@ -604,14 +604,14 @@ TEST_P(InputVolumeControllerParametrizedTest,
|
|||||||
kSpeechLevel);
|
kSpeechLevel);
|
||||||
|
|
||||||
helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
|
helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 240);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 240);
|
||||||
|
|
||||||
helper.CallPreProc(/*num_calls=*/300,
|
helper.CallPreProc(/*num_calls=*/300,
|
||||||
/*clipped_ratio=*/kAboveClippedThreshold);
|
/*clipped_ratio=*/kAboveClippedThreshold);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 240);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 240);
|
||||||
|
|
||||||
helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
|
helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 225);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 225);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(InputVolumeControllerParametrizedTest, ClippingLoweringIsLimited) {
|
TEST_P(InputVolumeControllerParametrizedTest, ClippingLoweringIsLimited) {
|
||||||
@ -620,11 +620,11 @@ TEST_P(InputVolumeControllerParametrizedTest, ClippingLoweringIsLimited) {
|
|||||||
kSpeechLevel);
|
kSpeechLevel);
|
||||||
|
|
||||||
helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
|
helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), kClippedMin);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), kClippedMin);
|
||||||
|
|
||||||
helper.CallPreProc(/*num_calls=*/1000,
|
helper.CallPreProc(/*num_calls=*/1000,
|
||||||
/*clipped_ratio=*/kAboveClippedThreshold);
|
/*clipped_ratio=*/kAboveClippedThreshold);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), kClippedMin);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), kClippedMin);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(InputVolumeControllerParametrizedTest,
|
TEST_P(InputVolumeControllerParametrizedTest,
|
||||||
@ -634,10 +634,10 @@ TEST_P(InputVolumeControllerParametrizedTest,
|
|||||||
kSpeechLevel);
|
kSpeechLevel);
|
||||||
|
|
||||||
helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
|
helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 240);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 240);
|
||||||
|
|
||||||
helper.CallProcess(/*num_calls=*/10, kHighSpeechProbability, -48.0f);
|
helper.CallProcess(/*num_calls=*/10, kHighSpeechProbability, -48.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 240);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 240);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(InputVolumeControllerParametrizedTest,
|
TEST_P(InputVolumeControllerParametrizedTest,
|
||||||
@ -647,12 +647,12 @@ TEST_P(InputVolumeControllerParametrizedTest,
|
|||||||
kSpeechLevel);
|
kSpeechLevel);
|
||||||
|
|
||||||
helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
|
helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 185);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 185);
|
||||||
|
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -58.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -58.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 240);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 240);
|
||||||
helper.CallProcess(/*num_calls=*/10, kHighSpeechProbability, -58.0f);
|
helper.CallProcess(/*num_calls=*/10, kHighSpeechProbability, -58.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 240);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 240);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(InputVolumeControllerParametrizedTest, UserCanRaiseVolumeAfterClipping) {
|
TEST_P(InputVolumeControllerParametrizedTest, UserCanRaiseVolumeAfterClipping) {
|
||||||
@ -661,22 +661,22 @@ TEST_P(InputVolumeControllerParametrizedTest, UserCanRaiseVolumeAfterClipping) {
|
|||||||
kSpeechLevel);
|
kSpeechLevel);
|
||||||
|
|
||||||
helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
|
helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 210);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 210);
|
||||||
|
|
||||||
// User changed the volume.
|
// User changed the volume.
|
||||||
helper.controller.set_stream_analog_level(250);
|
helper.controller.SetAppliedInputVolume(250);
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -32.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -32.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 250);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 250);
|
||||||
|
|
||||||
// Move down...
|
// Move down...
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -8.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -8.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 210);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 210);
|
||||||
// And back up to the new max established by the user.
|
// And back up to the new max established by the user.
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -58.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -58.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 250);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 250);
|
||||||
// Will not move above new maximum.
|
// Will not move above new maximum.
|
||||||
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -48.0f);
|
helper.CallProcess(/*num_calls=*/1, kHighSpeechProbability, -48.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 250);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 250);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(InputVolumeControllerParametrizedTest,
|
TEST_P(InputVolumeControllerParametrizedTest,
|
||||||
@ -685,9 +685,9 @@ TEST_P(InputVolumeControllerParametrizedTest,
|
|||||||
helper.CallAgcSequence(/*applied_input_volume=*/80, kHighSpeechProbability,
|
helper.CallAgcSequence(/*applied_input_volume=*/80, kHighSpeechProbability,
|
||||||
kSpeechLevel);
|
kSpeechLevel);
|
||||||
|
|
||||||
int initial_volume = helper.controller.recommended_analog_level();
|
int initial_volume = helper.controller.recommended_input_volume();
|
||||||
helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
|
helper.CallPreProc(/*num_calls=*/1, /*clipped_ratio=*/kAboveClippedThreshold);
|
||||||
EXPECT_EQ(initial_volume, helper.controller.recommended_analog_level());
|
EXPECT_EQ(initial_volume, helper.controller.recommended_input_volume());
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(InputVolumeControllerParametrizedTest, TakesNoActionOnZeroMicVolume) {
|
TEST_P(InputVolumeControllerParametrizedTest, TakesNoActionOnZeroMicVolume) {
|
||||||
@ -695,9 +695,9 @@ TEST_P(InputVolumeControllerParametrizedTest, TakesNoActionOnZeroMicVolume) {
|
|||||||
helper.CallAgcSequence(kInitialInputVolume, kHighSpeechProbability,
|
helper.CallAgcSequence(kInitialInputVolume, kHighSpeechProbability,
|
||||||
kSpeechLevel);
|
kSpeechLevel);
|
||||||
|
|
||||||
helper.controller.set_stream_analog_level(0);
|
helper.controller.SetAppliedInputVolume(0);
|
||||||
helper.CallProcess(/*num_calls=*/10, kHighSpeechProbability, -48.0f);
|
helper.CallProcess(/*num_calls=*/10, kHighSpeechProbability, -48.0f);
|
||||||
EXPECT_EQ(helper.controller.recommended_analog_level(), 0);
|
EXPECT_EQ(helper.controller.recommended_input_volume(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(InputVolumeControllerParametrizedTest, ClippingDetectionLowersVolume) {
|
TEST_P(InputVolumeControllerParametrizedTest, ClippingDetectionLowersVolume) {
|
||||||
@ -797,7 +797,7 @@ TEST(InputVolumeControllerTest, MinInputVolumeCheckMinLevelWithClipping) {
|
|||||||
CreateInputVolumeController(kClippedLevelStep, kClippedRatioThreshold,
|
CreateInputVolumeController(kClippedLevelStep, kClippedRatioThreshold,
|
||||||
kClippedWaitFrames);
|
kClippedWaitFrames);
|
||||||
controller->Initialize();
|
controller->Initialize();
|
||||||
controller->set_stream_analog_level(kInitialInputVolume);
|
controller->SetAppliedInputVolume(kInitialInputVolume);
|
||||||
return controller;
|
return controller;
|
||||||
};
|
};
|
||||||
std::unique_ptr<InputVolumeController> controller = factory();
|
std::unique_ptr<InputVolumeController> controller = factory();
|
||||||
@ -825,15 +825,15 @@ TEST(InputVolumeControllerTest, MinInputVolumeCheckMinLevelWithClipping) {
|
|||||||
*controller_with_override);
|
*controller_with_override);
|
||||||
|
|
||||||
// Make sure that an adaptation occurred.
|
// Make sure that an adaptation occurred.
|
||||||
ASSERT_GT(controller->recommended_analog_level(), 0);
|
ASSERT_GT(controller->recommended_input_volume(), 0);
|
||||||
|
|
||||||
// Check that the test signal triggers a larger downward adaptation for
|
// Check that the test signal triggers a larger downward adaptation for
|
||||||
// `controller`, which is allowed to reach a lower gain.
|
// `controller`, which is allowed to reach a lower gain.
|
||||||
EXPECT_GT(controller_with_override->recommended_analog_level(),
|
EXPECT_GT(controller_with_override->recommended_input_volume(),
|
||||||
controller->recommended_analog_level());
|
controller->recommended_input_volume());
|
||||||
// Check that the gain selected by `controller_with_override` equals the
|
// Check that the gain selected by `controller_with_override` equals the
|
||||||
// minimum value overridden via field trial.
|
// minimum value overridden via field trial.
|
||||||
EXPECT_EQ(controller_with_override->recommended_analog_level(),
|
EXPECT_EQ(controller_with_override->recommended_input_volume(),
|
||||||
kMinInputVolume);
|
kMinInputVolume);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -854,7 +854,7 @@ TEST(InputVolumeControllerTest,
|
|||||||
CreateInputVolumeController(kClippedLevelStep, kClippedRatioThreshold,
|
CreateInputVolumeController(kClippedLevelStep, kClippedRatioThreshold,
|
||||||
kClippedWaitFrames);
|
kClippedWaitFrames);
|
||||||
controller->Initialize();
|
controller->Initialize();
|
||||||
controller->set_stream_analog_level(kInitialInputVolume);
|
controller->SetAppliedInputVolume(kInitialInputVolume);
|
||||||
return controller;
|
return controller;
|
||||||
};
|
};
|
||||||
std::unique_ptr<InputVolumeController> controller = factory();
|
std::unique_ptr<InputVolumeController> controller = factory();
|
||||||
@ -881,15 +881,15 @@ TEST(InputVolumeControllerTest,
|
|||||||
/*speech_level_dbfs=*/-18.0f, *controller_with_override);
|
/*speech_level_dbfs=*/-18.0f, *controller_with_override);
|
||||||
|
|
||||||
// Make sure that an adaptation occurred.
|
// Make sure that an adaptation occurred.
|
||||||
ASSERT_GT(controller->recommended_analog_level(), 0);
|
ASSERT_GT(controller->recommended_input_volume(), 0);
|
||||||
|
|
||||||
// Check that the test signal triggers a larger downward adaptation for
|
// Check that the test signal triggers a larger downward adaptation for
|
||||||
// `controller`, which is allowed to reach a lower gain.
|
// `controller`, which is allowed to reach a lower gain.
|
||||||
EXPECT_GT(controller_with_override->recommended_analog_level(),
|
EXPECT_GT(controller_with_override->recommended_input_volume(),
|
||||||
controller->recommended_analog_level());
|
controller->recommended_input_volume());
|
||||||
// Check that the gain selected by `controller_with_override` equals the
|
// Check that the gain selected by `controller_with_override` equals the
|
||||||
// minimum value overridden via field trial.
|
// minimum value overridden via field trial.
|
||||||
EXPECT_EQ(controller_with_override->recommended_analog_level(),
|
EXPECT_EQ(controller_with_override->recommended_input_volume(),
|
||||||
kMinInputVolume);
|
kMinInputVolume);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -910,7 +910,7 @@ TEST(InputVolumeControllerTest, MinInputVolumeCompareMicLevelWithClipping) {
|
|||||||
auto controller = std::make_unique<InputVolumeController>(
|
auto controller = std::make_unique<InputVolumeController>(
|
||||||
/*num_capture_channels=*/1, config);
|
/*num_capture_channels=*/1, config);
|
||||||
controller->Initialize();
|
controller->Initialize();
|
||||||
controller->set_stream_analog_level(kInitialInputVolume);
|
controller->SetAppliedInputVolume(kInitialInputVolume);
|
||||||
return controller;
|
return controller;
|
||||||
};
|
};
|
||||||
std::unique_ptr<InputVolumeController> controller = factory();
|
std::unique_ptr<InputVolumeController> controller = factory();
|
||||||
@ -942,15 +942,15 @@ TEST(InputVolumeControllerTest, MinInputVolumeCompareMicLevelWithClipping) {
|
|||||||
*controller_with_override);
|
*controller_with_override);
|
||||||
|
|
||||||
// Make sure that an adaptation occurred.
|
// Make sure that an adaptation occurred.
|
||||||
ASSERT_GT(controller->recommended_analog_level(), 0);
|
ASSERT_GT(controller->recommended_input_volume(), 0);
|
||||||
|
|
||||||
// Check that the selected analog gain is the same for both controllers and
|
// Check that the selected analog gain is the same for both controllers and
|
||||||
// that it equals the minimum level reached when clipping is handled. That is
|
// that it equals the minimum level reached when clipping is handled. That is
|
||||||
// expected because the minimum microphone level override is less than the
|
// expected because the minimum microphone level override is less than the
|
||||||
// minimum level used when clipping is detected.
|
// minimum level used when clipping is detected.
|
||||||
EXPECT_EQ(controller->recommended_analog_level(),
|
EXPECT_EQ(controller->recommended_input_volume(),
|
||||||
controller_with_override->recommended_analog_level());
|
controller_with_override->recommended_input_volume());
|
||||||
EXPECT_EQ(controller_with_override->recommended_analog_level(),
|
EXPECT_EQ(controller_with_override->recommended_input_volume(),
|
||||||
kDefaultInputVolumeControllerConfig.clipped_level_min);
|
kDefaultInputVolumeControllerConfig.clipped_level_min);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -975,7 +975,7 @@ TEST(InputVolumeControllerTest,
|
|||||||
auto controller = std::make_unique<InputVolumeController>(
|
auto controller = std::make_unique<InputVolumeController>(
|
||||||
/*num_capture_channels=*/1, config);
|
/*num_capture_channels=*/1, config);
|
||||||
controller->Initialize();
|
controller->Initialize();
|
||||||
controller->set_stream_analog_level(kInitialInputVolume);
|
controller->SetAppliedInputVolume(kInitialInputVolume);
|
||||||
return controller;
|
return controller;
|
||||||
};
|
};
|
||||||
std::unique_ptr<InputVolumeController> controller = factory();
|
std::unique_ptr<InputVolumeController> controller = factory();
|
||||||
@ -1006,15 +1006,15 @@ TEST(InputVolumeControllerTest,
|
|||||||
/*speech_level_dbfs=*/-18.0f, *controller_with_override);
|
/*speech_level_dbfs=*/-18.0f, *controller_with_override);
|
||||||
|
|
||||||
// Make sure that an adaptation occurred.
|
// Make sure that an adaptation occurred.
|
||||||
ASSERT_GT(controller->recommended_analog_level(), 0);
|
ASSERT_GT(controller->recommended_input_volume(), 0);
|
||||||
|
|
||||||
// Check that the selected analog gain is the same for both controllers and
|
// Check that the selected analog gain is the same for both controllers and
|
||||||
// that it equals the minimum level reached when clipping is handled. That is
|
// that it equals the minimum level reached when clipping is handled. That is
|
||||||
// expected because the minimum microphone level override is less than the
|
// expected because the minimum microphone level override is less than the
|
||||||
// minimum level used when clipping is detected.
|
// minimum level used when clipping is detected.
|
||||||
EXPECT_EQ(controller->recommended_analog_level(),
|
EXPECT_EQ(controller->recommended_input_volume(),
|
||||||
controller_with_override->recommended_analog_level());
|
controller_with_override->recommended_input_volume());
|
||||||
EXPECT_EQ(controller_with_override->recommended_analog_level(),
|
EXPECT_EQ(controller_with_override->recommended_input_volume(),
|
||||||
kDefaultInputVolumeControllerConfig.clipped_level_min);
|
kDefaultInputVolumeControllerConfig.clipped_level_min);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1264,7 +1264,7 @@ TEST_P(InputVolumeControllerParametrizedTest, EmptyRmsErrorHasNoEffect) {
|
|||||||
absl::nullopt, controller);
|
absl::nullopt, controller);
|
||||||
|
|
||||||
// Check that no adaptation occurs.
|
// Check that no adaptation occurs.
|
||||||
ASSERT_EQ(controller.recommended_analog_level(), kInitialInputVolume);
|
ASSERT_EQ(controller.recommended_input_volume(), kInitialInputVolume);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checks that the recommended input volume is not updated unless enough
|
// Checks that the recommended input volume is not updated unless enough
|
||||||
@ -1294,20 +1294,20 @@ TEST(InputVolumeControllerTest, UpdateInputVolumeWaitFramesIsEffective) {
|
|||||||
/*speech_level_dbfs=*/-42.0f, *controller_wait_100);
|
/*speech_level_dbfs=*/-42.0f, *controller_wait_100);
|
||||||
|
|
||||||
// Check that adaptation only occurs if enough frames have been processed.
|
// Check that adaptation only occurs if enough frames have been processed.
|
||||||
ASSERT_GT(controller_wait_0->recommended_analog_level(), kInputVolume);
|
ASSERT_GT(controller_wait_0->recommended_input_volume(), kInputVolume);
|
||||||
ASSERT_EQ(controller_wait_100->recommended_analog_level(), kInputVolume);
|
ASSERT_EQ(controller_wait_100->recommended_input_volume(), kInputVolume);
|
||||||
|
|
||||||
reader_1.Feed(/*num_frames=*/1, controller_wait_0->recommended_analog_level(),
|
reader_1.Feed(/*num_frames=*/1, controller_wait_0->recommended_input_volume(),
|
||||||
/*gain_db=*/0, kHighSpeechProbability,
|
/*gain_db=*/0, kHighSpeechProbability,
|
||||||
/*speech_level_dbfs=*/-42.0f, *controller_wait_0);
|
/*speech_level_dbfs=*/-42.0f, *controller_wait_0);
|
||||||
reader_2.Feed(/*num_frames=*/1,
|
reader_2.Feed(/*num_frames=*/1,
|
||||||
controller_wait_100->recommended_analog_level(), /*gain_db=*/0,
|
controller_wait_100->recommended_input_volume(), /*gain_db=*/0,
|
||||||
kHighSpeechProbability,
|
kHighSpeechProbability,
|
||||||
/*speech_level_dbfs=*/-42.0f, *controller_wait_100);
|
/*speech_level_dbfs=*/-42.0f, *controller_wait_100);
|
||||||
|
|
||||||
// Check that adaptation only occurs when enough frames have been processed.
|
// Check that adaptation only occurs when enough frames have been processed.
|
||||||
ASSERT_GT(controller_wait_0->recommended_analog_level(), kInputVolume);
|
ASSERT_GT(controller_wait_0->recommended_input_volume(), kInputVolume);
|
||||||
ASSERT_GT(controller_wait_100->recommended_analog_level(), kInputVolume);
|
ASSERT_GT(controller_wait_100->recommended_input_volume(), kInputVolume);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(InputVolumeControllerTest, SpeechRatioThresholdIsEffective) {
|
TEST(InputVolumeControllerTest, SpeechRatioThresholdIsEffective) {
|
||||||
@ -1337,28 +1337,28 @@ TEST(InputVolumeControllerTest, SpeechRatioThresholdIsEffective) {
|
|||||||
/*speech_probability=*/0.4f, /*speech_level_dbfs=*/-42.0f,
|
/*speech_probability=*/0.4f, /*speech_level_dbfs=*/-42.0f,
|
||||||
*controller_2);
|
*controller_2);
|
||||||
|
|
||||||
ASSERT_EQ(controller_1->recommended_analog_level(), kInputVolume);
|
ASSERT_EQ(controller_1->recommended_input_volume(), kInputVolume);
|
||||||
ASSERT_EQ(controller_2->recommended_analog_level(), kInputVolume);
|
ASSERT_EQ(controller_2->recommended_input_volume(), kInputVolume);
|
||||||
|
|
||||||
reader_1.Feed(
|
reader_1.Feed(
|
||||||
/*num_frames=*/2, controller_1->recommended_analog_level(), /*gain_db=*/0,
|
/*num_frames=*/2, controller_1->recommended_input_volume(), /*gain_db=*/0,
|
||||||
/*speech_probability=*/0.4f, /*speech_level_dbfs=*/-42.0f, *controller_1);
|
/*speech_probability=*/0.4f, /*speech_level_dbfs=*/-42.0f, *controller_1);
|
||||||
reader_2.Feed(
|
reader_2.Feed(
|
||||||
/*num_frames=*/2, controller_2->recommended_analog_level(), /*gain_db=*/0,
|
/*num_frames=*/2, controller_2->recommended_input_volume(), /*gain_db=*/0,
|
||||||
/*speech_probability=*/0.4f, /*speech_level_dbfs=*/-42.0f, *controller_2);
|
/*speech_probability=*/0.4f, /*speech_level_dbfs=*/-42.0f, *controller_2);
|
||||||
|
|
||||||
ASSERT_EQ(controller_1->recommended_analog_level(), kInputVolume);
|
ASSERT_EQ(controller_1->recommended_input_volume(), kInputVolume);
|
||||||
ASSERT_EQ(controller_2->recommended_analog_level(), kInputVolume);
|
ASSERT_EQ(controller_2->recommended_input_volume(), kInputVolume);
|
||||||
|
|
||||||
reader_1.Feed(
|
reader_1.Feed(
|
||||||
/*num_frames=*/7, controller_1->recommended_analog_level(), /*gain_db=*/0,
|
/*num_frames=*/7, controller_1->recommended_input_volume(), /*gain_db=*/0,
|
||||||
/*speech_probability=*/0.7f, /*speech_level_dbfs=*/-42.0f, *controller_1);
|
/*speech_probability=*/0.7f, /*speech_level_dbfs=*/-42.0f, *controller_1);
|
||||||
reader_2.Feed(
|
reader_2.Feed(
|
||||||
/*num_frames=*/7, controller_2->recommended_analog_level(), /*gain_db=*/0,
|
/*num_frames=*/7, controller_2->recommended_input_volume(), /*gain_db=*/0,
|
||||||
/*speech_probability=*/0.7f, /*speech_level_dbfs=*/-42.0f, *controller_2);
|
/*speech_probability=*/0.7f, /*speech_level_dbfs=*/-42.0f, *controller_2);
|
||||||
|
|
||||||
ASSERT_GT(controller_1->recommended_analog_level(), kInputVolume);
|
ASSERT_GT(controller_1->recommended_input_volume(), kInputVolume);
|
||||||
ASSERT_EQ(controller_2->recommended_analog_level(), kInputVolume);
|
ASSERT_EQ(controller_2->recommended_input_volume(), kInputVolume);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(InputVolumeControllerTest, SpeechProbabilityThresholdIsEffective) {
|
TEST(InputVolumeControllerTest, SpeechProbabilityThresholdIsEffective) {
|
||||||
@ -1392,30 +1392,30 @@ TEST(InputVolumeControllerTest, SpeechProbabilityThresholdIsEffective) {
|
|||||||
/*speech_probability=*/0.49f, /*speech_level_dbfs=*/-42.0f,
|
/*speech_probability=*/0.49f, /*speech_level_dbfs=*/-42.0f,
|
||||||
*controller_2);
|
*controller_2);
|
||||||
|
|
||||||
ASSERT_EQ(controller_1->recommended_analog_level(), kInputVolume);
|
ASSERT_EQ(controller_1->recommended_input_volume(), kInputVolume);
|
||||||
ASSERT_EQ(controller_2->recommended_analog_level(), kInputVolume);
|
ASSERT_EQ(controller_2->recommended_input_volume(), kInputVolume);
|
||||||
|
|
||||||
reader_1.Feed(/*num_frames=*/2, controller_1->recommended_analog_level(),
|
reader_1.Feed(/*num_frames=*/2, controller_1->recommended_input_volume(),
|
||||||
/*gain_db=*/0,
|
/*gain_db=*/0,
|
||||||
/*speech_probability=*/0.49f, /*speech_level_dbfs=*/-42.0f,
|
/*speech_probability=*/0.49f, /*speech_level_dbfs=*/-42.0f,
|
||||||
*controller_1);
|
*controller_1);
|
||||||
reader_2.Feed(/*num_frames=*/2, controller_2->recommended_analog_level(),
|
reader_2.Feed(/*num_frames=*/2, controller_2->recommended_input_volume(),
|
||||||
/*gain_db=*/0,
|
/*gain_db=*/0,
|
||||||
/*speech_probability=*/0.49f, /*speech_level_dbfs=*/-42.0f,
|
/*speech_probability=*/0.49f, /*speech_level_dbfs=*/-42.0f,
|
||||||
*controller_2);
|
*controller_2);
|
||||||
|
|
||||||
ASSERT_EQ(controller_1->recommended_analog_level(), kInputVolume);
|
ASSERT_EQ(controller_1->recommended_input_volume(), kInputVolume);
|
||||||
ASSERT_EQ(controller_2->recommended_analog_level(), kInputVolume);
|
ASSERT_EQ(controller_2->recommended_input_volume(), kInputVolume);
|
||||||
|
|
||||||
reader_1.Feed(
|
reader_1.Feed(
|
||||||
/*num_frames=*/7, controller_1->recommended_analog_level(), /*gain_db=*/0,
|
/*num_frames=*/7, controller_1->recommended_input_volume(), /*gain_db=*/0,
|
||||||
/*speech_probability=*/0.5f, /*speech_level_dbfs=*/-42.0f, *controller_1);
|
/*speech_probability=*/0.5f, /*speech_level_dbfs=*/-42.0f, *controller_1);
|
||||||
reader_2.Feed(
|
reader_2.Feed(
|
||||||
/*num_frames=*/7, controller_2->recommended_analog_level(), /*gain_db=*/0,
|
/*num_frames=*/7, controller_2->recommended_input_volume(), /*gain_db=*/0,
|
||||||
/*speech_probability=*/0.5f, /*speech_level_dbfs=*/-42.0f, *controller_2);
|
/*speech_probability=*/0.5f, /*speech_level_dbfs=*/-42.0f, *controller_2);
|
||||||
|
|
||||||
ASSERT_GT(controller_1->recommended_analog_level(), kInputVolume);
|
ASSERT_GT(controller_1->recommended_input_volume(), kInputVolume);
|
||||||
ASSERT_EQ(controller_2->recommended_analog_level(), kInputVolume);
|
ASSERT_EQ(controller_2->recommended_input_volume(), kInputVolume);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(InputVolumeControllerTest,
|
TEST(InputVolumeControllerTest,
|
||||||
@ -1432,7 +1432,7 @@ TEST(InputVolumeControllerTest,
|
|||||||
reader.Feed(/*num_frames=*/14, kStartupVolume, /*gain_db=*/50,
|
reader.Feed(/*num_frames=*/14, kStartupVolume, /*gain_db=*/50,
|
||||||
kHighSpeechProbability,
|
kHighSpeechProbability,
|
||||||
/*speech_level_dbfs=*/-20.0f, *controller);
|
/*speech_level_dbfs=*/-20.0f, *controller);
|
||||||
ASSERT_LT(controller->recommended_analog_level(), kStartupVolume);
|
ASSERT_LT(controller->recommended_input_volume(), kStartupVolume);
|
||||||
EXPECT_METRIC_THAT(
|
EXPECT_METRIC_THAT(
|
||||||
metrics::Samples(
|
metrics::Samples(
|
||||||
"WebRTC.Audio.Apm.RecommendedInputVolume.OnChangeToMatchTarget"),
|
"WebRTC.Audio.Apm.RecommendedInputVolume.OnChangeToMatchTarget"),
|
||||||
@ -1452,7 +1452,7 @@ TEST(InputVolumeControllerTest,
|
|||||||
reader.Feed(/*num_frames=*/14, kStartupVolume, /*gain_db=*/-6,
|
reader.Feed(/*num_frames=*/14, kStartupVolume, /*gain_db=*/-6,
|
||||||
kHighSpeechProbability,
|
kHighSpeechProbability,
|
||||||
/*speech_level_dbfs=*/-50.0f, *controller);
|
/*speech_level_dbfs=*/-50.0f, *controller);
|
||||||
ASSERT_GT(controller->recommended_analog_level(), kStartupVolume);
|
ASSERT_GT(controller->recommended_input_volume(), kStartupVolume);
|
||||||
EXPECT_METRIC_THAT(
|
EXPECT_METRIC_THAT(
|
||||||
metrics::Samples(
|
metrics::Samples(
|
||||||
"WebRTC.Audio.Apm.RecommendedInputVolume.OnChangeToMatchTarget"),
|
"WebRTC.Audio.Apm.RecommendedInputVolume.OnChangeToMatchTarget"),
|
||||||
@ -1467,13 +1467,13 @@ TEST(InputVolumeControllerTest,
|
|||||||
auto controller = CreateInputVolumeController();
|
auto controller = CreateInputVolumeController();
|
||||||
controller->Initialize();
|
controller->Initialize();
|
||||||
constexpr int kStartupVolume = 100;
|
constexpr int kStartupVolume = 100;
|
||||||
controller->set_stream_analog_level(kStartupVolume);
|
controller->SetAppliedInputVolume(kStartupVolume);
|
||||||
// Trigger a downward volume change by inputting audio that does not clip and
|
// Trigger a downward volume change by inputting audio that does not clip and
|
||||||
// by passing a speech level above the target range.
|
// by passing a speech level above the target range.
|
||||||
reader.Feed(/*num_frames=*/14, kStartupVolume, /*gain_db=*/-6,
|
reader.Feed(/*num_frames=*/14, kStartupVolume, /*gain_db=*/-6,
|
||||||
kHighSpeechProbability,
|
kHighSpeechProbability,
|
||||||
/*speech_level_dbfs=*/-5.0f, *controller);
|
/*speech_level_dbfs=*/-5.0f, *controller);
|
||||||
ASSERT_LT(controller->recommended_analog_level(), kStartupVolume);
|
ASSERT_LT(controller->recommended_input_volume(), kStartupVolume);
|
||||||
EXPECT_METRIC_THAT(
|
EXPECT_METRIC_THAT(
|
||||||
metrics::Samples(
|
metrics::Samples(
|
||||||
"WebRTC.Audio.Apm.RecommendedInputVolume.OnChangeToMatchTarget"),
|
"WebRTC.Audio.Apm.RecommendedInputVolume.OnChangeToMatchTarget"),
|
||||||
|
|||||||
@ -158,7 +158,7 @@ void GainController2::Analyze(int applied_input_volume,
|
|||||||
|
|
||||||
if (input_volume_controller_) {
|
if (input_volume_controller_) {
|
||||||
// TODO(bugs.webrtc.org/7494): Pass applied volume to `AnalyzePreProcess()`.
|
// TODO(bugs.webrtc.org/7494): Pass applied volume to `AnalyzePreProcess()`.
|
||||||
input_volume_controller_->set_stream_analog_level(applied_input_volume);
|
input_volume_controller_->SetAppliedInputVolume(applied_input_volume);
|
||||||
input_volume_controller_->AnalyzePreProcess(audio_buffer);
|
input_volume_controller_->AnalyzePreProcess(audio_buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -166,7 +166,7 @@ void GainController2::Analyze(int applied_input_volume,
|
|||||||
absl::optional<int> GainController2::GetRecommendedInputVolume() const {
|
absl::optional<int> GainController2::GetRecommendedInputVolume() const {
|
||||||
return input_volume_controller_
|
return input_volume_controller_
|
||||||
? absl::optional<int>(
|
? absl::optional<int>(
|
||||||
input_volume_controller_->recommended_analog_level())
|
input_volume_controller_->recommended_input_volume())
|
||||||
: absl::nullopt;
|
: absl::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user