Commit c493edcc authored by Michael Montvelishsky's avatar Michael Montvelishsky Committed by Commit Bot

Make governed volume linearly increasing.

Change-Id: I1d6967b592fbdbaa682ba85c572e4a6d0576eeec
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1937585
Commit-Queue: Michael Montvelishsky <mont@chromium.org>
Auto-Submit: Michael Montvelishsky <mont@chromium.org>
Reviewed-by: default avatarKenneth MacKay <kmackay@chromium.org>
Cr-Commit-Position: refs/heads/master@{#719491}
parent edc38890
...@@ -21,6 +21,7 @@ namespace { ...@@ -21,6 +21,7 @@ namespace {
const int kNoVolume = -1; const int kNoVolume = -1;
const float kEpsilon = std::numeric_limits<float>::epsilon(); const float kEpsilon = std::numeric_limits<float>::epsilon();
const float kMaxOnSetVolume = 0.989; // -0.1dB
// Configuration strings: // Configuration strings:
const char kOnsetVolumeKey[] = "onset_volume"; const char kOnsetVolumeKey[] = "onset_volume";
...@@ -37,6 +38,8 @@ Governor::Governor(const std::string& config, int input_channels) ...@@ -37,6 +38,8 @@ Governor::Governor(const std::string& config, int input_channels)
CHECK(config_dict) << "Governor config is not valid json: " << config; CHECK(config_dict) << "Governor config is not valid json: " << config;
CHECK(config_dict->GetDouble(kOnsetVolumeKey, &onset_volume_)); CHECK(config_dict->GetDouble(kOnsetVolumeKey, &onset_volume_));
CHECK(config_dict->GetDouble(kClampMultiplierKey, &clamp_multiplier_)); CHECK(config_dict->GetDouble(kClampMultiplierKey, &clamp_multiplier_));
CHECK_LE(onset_volume_, clamp_multiplier_);
CHECK_LE(onset_volume_, kMaxOnSetVolume);
slew_volume_.SetVolume(1.0); slew_volume_.SetVolume(1.0);
LOG(INFO) << "Created a governor: onset_volume = " << onset_volume_ LOG(INFO) << "Created a governor: onset_volume = " << onset_volume_
<< ", clamp_multiplier = " << clamp_multiplier_; << ", clamp_multiplier = " << clamp_multiplier_;
...@@ -71,9 +74,12 @@ void Governor::ProcessFrames(float* data, ...@@ -71,9 +74,12 @@ void Governor::ProcessFrames(float* data,
} }
float Governor::GetGovernorMultiplier() { float Governor::GetGovernorMultiplier() {
// If |volume_| is greater than or "equal" to |onset_volume_|. if (volume_ > onset_volume_) {
if (volume_ > onset_volume_ - kEpsilon) { float effective_volume =
return clamp_multiplier_; onset_volume_ + (volume_ - onset_volume_) *
(clamp_multiplier_ - onset_volume_) /
(1. - onset_volume_);
return effective_volume / volume_;
} }
return 1.0; return 1.0;
} }
......
...@@ -16,13 +16,15 @@ ...@@ -16,13 +16,15 @@
namespace chromecast { namespace chromecast {
namespace media { namespace media {
// Provides a flat reduction in output volume if the input volume is above a // Provides linear reduction in output volume if the input volume is above a
// given threshold. // given threshold.
// Used to protect speakers at high output levels while providing dynamic range // Used to protect speakers at high output levels while providing dynamic range
// at low output level. // at low output level.
// The configuration string for this plugin is: // The configuration string for this plugin is:
// {"onset_volume": |VOLUME_TO_CLAMP|, "clamp_multiplier": |CLAMP_MULTIPLIER|} // {"onset_volume": |VOLUME_TO_CLAMP|, "clamp_multiplier": |CLAMP_MULTIPLIER|}
// Input volumes > |VOLUME_TO_CLAMP| will be attenuated by |CLAMP_MULTIPLIER|. // Input volumes > |VOLUME_TO_CLAMP| will be attenuated by linear approximation,
// changing from 0 (at VOLUME_TO_CLAMP) to |CLAMP_MULTIPLIER| (at 1.0).
// |CLAMP_MULTIPLIER| must be >= |VOLUME_TO_CLAMP|.
class Governor : public AudioPostProcessor2 { class Governor : public AudioPostProcessor2 {
public: public:
Governor(const std::string& config, int input_channels); Governor(const std::string& config, int input_channels);
......
...@@ -81,9 +81,6 @@ class GovernorTest : public ::testing::TestWithParam<float> { ...@@ -81,9 +81,6 @@ class GovernorTest : public ::testing::TestWithParam<float> {
TEST_P(GovernorTest, ZeroVolume) { TEST_P(GovernorTest, ZeroVolume) {
ProcessFrames(0.0f); ProcessFrames(0.0f);
if (onset_volume_ <= 0.0f) {
ScaleData(expected_.data(), kNumFrames * kNumChannels, clamp_);
}
CompareBuffers(); CompareBuffers();
} }
...@@ -95,15 +92,6 @@ TEST_P(GovernorTest, EpsilonBelowOnset) { ...@@ -95,15 +92,6 @@ TEST_P(GovernorTest, EpsilonBelowOnset) {
CompareBuffers(); CompareBuffers();
} }
TEST_P(GovernorTest, EpsilonAboveOnset) {
// Approximately equaling is inclusive, thus needs more than one epsilon to
// make sure triggering volume change.
float volume = onset_volume_ + 2 * std::numeric_limits<float>::epsilon();
ProcessFrames(volume);
ScaleData(expected_.data(), kNumFrames * kNumChannels, clamp_);
CompareBuffers();
}
TEST_P(GovernorTest, MaxVolume) { TEST_P(GovernorTest, MaxVolume) {
ProcessFrames(1.0); ProcessFrames(1.0);
if (onset_volume_ <= 1.0) { if (onset_volume_ <= 1.0) {
...@@ -114,29 +102,23 @@ TEST_P(GovernorTest, MaxVolume) { ...@@ -114,29 +102,23 @@ TEST_P(GovernorTest, MaxVolume) {
INSTANTIATE_TEST_SUITE_P(GovernorClampVolumeTest, INSTANTIATE_TEST_SUITE_P(GovernorClampVolumeTest,
GovernorTest, GovernorTest,
::testing::Values(0.0f, 0.1f, 0.5f, 0.9f, 1.0f, 1.1f)); ::testing::Values(0.0f, 0.1f, 0.5f));
// Default tests from post_processor_test // Default tests from post_processor_test
TEST_P(PostProcessorTest, GovernorDelay) { TEST_P(PostProcessorTest, GovernorDelay) {
std::string config = MakeConfigString(1.0, 1.0); std::string config = MakeConfigString(0.8, 0.9);
auto pp = std::make_unique<Governor>(config, kNumChannels); auto pp = std::make_unique<Governor>(config, kNumChannels);
TestDelay(pp.get(), sample_rate_); TestDelay(pp.get(), sample_rate_);
} }
TEST_P(PostProcessorTest, GovernorRinging) { TEST_P(PostProcessorTest, GovernorRinging) {
std::string config = MakeConfigString(1.0, 1.0); std::string config = MakeConfigString(0.8, 0.9);
auto pp = std::make_unique<Governor>(config, kNumChannels); auto pp = std::make_unique<Governor>(config, kNumChannels);
TestRingingTime(pp.get(), sample_rate_); TestRingingTime(pp.get(), sample_rate_);
} }
TEST_P(PostProcessorTest, GovernorPassthrough) {
std::string config = MakeConfigString(1.0, 1.0);
auto pp = std::make_unique<Governor>(config, kNumChannels);
TestPassthrough(pp.get(), sample_rate_);
}
TEST_P(PostProcessorTest, GovernorBenchmark) { TEST_P(PostProcessorTest, GovernorBenchmark) {
std::string config = MakeConfigString(1.0, 1.0); std::string config = MakeConfigString(0.8, 0.9);
auto pp = std::make_unique<Governor>(config, kNumChannels); auto pp = std::make_unique<Governor>(config, kNumChannels);
AudioProcessorBenchmark(pp.get(), sample_rate_); AudioProcessorBenchmark(pp.get(), sample_rate_);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment