audio_processing/agc: Adds config to set minimum microphone volume at startup

The AGC is currently bumping up the mic volume to 33% at startup if it is below that level. This is to avoid getting stuck in a poor state from which the AGC can not move, simply a too low input audio level. For some users, 33% is instead too loud.

This CL gives the user the possibility to set that level at create time.
- Extends the Config ExperimentalAgc with a startup_mic_volume for the user to set if desired. Note that the bump up does not apply to the legacy AGC and the "regular" AGC is controlled by ExperimentalAgc.
- Without any actions, the same default value as previously is used.
- In addition I removed a return value from InitializeExperimentalAgc() and InitializeTransient()

This has been tested by building Chromium on Mac and verify through apprtc that
1) startup_mic_volume = 128 bumps up to 50%.
2) startup_mic_volume = 500 (out of range) bumps up to 100%.
3) startup_mic_volume = 0 bumps up to 4%, the AGC min level.

BUG=4529
TESTED=locally
R=andrew@webrtc.org, kwiberg@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/43109004

Cr-Commit-Position: refs/heads/master@{#9004}
This commit is contained in:
Bjorn Volcker
2015-04-15 11:42:40 +02:00
parent 19a3807b36
commit adc46c4cf7
6 changed files with 53 additions and 33 deletions

View File

@ -48,7 +48,6 @@ const float kCompressionGainStep = 0.05f;
const int kMaxMicLevel = 255;
static_assert(kGainMapSize > kMaxMicLevel, "gain map too small");
const int kMinMicLevel = 12;
const int kMinInitMicLevel = 85;
// Prevent very large microphone level changes.
const int kMaxResidualGainChange = 15;
@ -57,6 +56,10 @@ const int kMaxResidualGainChange = 15;
// restrictions from clipping events.
const int kSurplusCompressionGain = 6;
int ClampLevel(int mic_level) {
return std::min(std::max(kMinMicLevel, mic_level), kMaxMicLevel);
}
int LevelFromGainError(int gain_error, int level) {
assert(level >= 0 && level <= kMaxMicLevel);
if (gain_error == 0) {
@ -109,7 +112,8 @@ class DebugFile {
};
AgcManagerDirect::AgcManagerDirect(GainControl* gctrl,
VolumeCallbacks* volume_callbacks)
VolumeCallbacks* volume_callbacks,
int startup_min_level)
: agc_(new Agc()),
gctrl_(gctrl),
volume_callbacks_(volume_callbacks),
@ -123,13 +127,15 @@ AgcManagerDirect::AgcManagerDirect(GainControl* gctrl,
capture_muted_(false),
check_volume_on_next_process_(true), // Check at startup.
startup_(true),
startup_min_level_(ClampLevel(startup_min_level)),
file_preproc_(new DebugFile("agc_preproc.pcm")),
file_postproc_(new DebugFile("agc_postproc.pcm")) {
}
AgcManagerDirect::AgcManagerDirect(Agc* agc,
GainControl* gctrl,
VolumeCallbacks* volume_callbacks)
VolumeCallbacks* volume_callbacks,
int startup_min_level)
: agc_(agc),
gctrl_(gctrl),
volume_callbacks_(volume_callbacks),
@ -143,6 +149,7 @@ AgcManagerDirect::AgcManagerDirect(Agc* agc,
capture_muted_(false),
check_volume_on_next_process_(true), // Check at startup.
startup_(true),
startup_min_level_(ClampLevel(startup_min_level)),
file_preproc_(new DebugFile("agc_preproc.pcm")),
file_postproc_(new DebugFile("agc_postproc.pcm")) {
}
@ -336,7 +343,7 @@ int AgcManagerDirect::CheckVolumeAndReset() {
}
LOG(LS_INFO) << "[agc] Initial GetMicVolume()=" << level;
int minLevel = startup_ ? kMinInitMicLevel : kMinMicLevel;
int minLevel = startup_ ? startup_min_level_ : kMinMicLevel;
if (level < minLevel) {
level = minLevel;
LOG(LS_INFO) << "[agc] Initial volume too low, raising to " << level;

View File

@ -41,12 +41,17 @@ class AgcManagerDirect {
public:
// AgcManagerDirect will configure GainControl internally. The user is
// responsible for processing the audio using it after the call to Process.
AgcManagerDirect(GainControl* gctrl, VolumeCallbacks* volume_callbacks);
// The operating range of startup_min_level is [12, 255] and any input value
// outside that range will be clamped.
AgcManagerDirect(GainControl* gctrl,
VolumeCallbacks* volume_callbacks,
int startup_min_level);
// Dependency injection for testing. Don't delete |agc| as the memory is owned
// by the manager.
AgcManagerDirect(Agc* agc,
GainControl* gctrl,
VolumeCallbacks* volume_callbacks);
VolumeCallbacks* volume_callbacks,
int startup_min_level);
~AgcManagerDirect();
int Initialize();
@ -88,6 +93,7 @@ class AgcManagerDirect {
bool capture_muted_;
bool check_volume_on_next_process_;
bool startup_;
int startup_min_level_;
rtc::scoped_ptr<DebugFile> file_preproc_;
rtc::scoped_ptr<DebugFile> file_postproc_;