Move the volume quantization workaround from VoE to AGC.

Voice engine shouldn't really have to manage this. Instead, have AGC
keep track of the last input volume, so that it can avoid getting stuck
under coarsely quantized conditions.

Add a test to verify the behavior.

TESTED=unittests, and observed that AGC didn't get stuck on a MacBook
where this problem can actually occur.

R=bjornv@webrtc.org

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

git-svn-id: http://webrtc.googlecode.com/svn/trunk@5571 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
andrew@webrtc.org
2014-02-18 20:24:56 +00:00
parent 00844d7bef
commit 27c6980239
5 changed files with 161 additions and 91 deletions

View File

@ -822,10 +822,16 @@ int32_t WebRtcAgc_ProcessAnalog(void *state, int32_t inMicLevel,
if (inMicLevelTmp != stt->micVol)
{
// Incoming level mismatch; update our level.
// This could be the case if the volume is changed manually, or if the
// sound device has a low volume resolution.
stt->micVol = inMicLevelTmp;
if (inMicLevel == stt->lastInMicLevel) {
// We requested a volume adjustment, but it didn't occur. This is
// probably due to a coarse quantization of the volume slider.
// Restore the requested value to prevent getting stuck.
inMicLevelTmp = stt->micVol;
}
else {
// As long as the value changed, update to match.
stt->micVol = inMicLevelTmp;
}
}
if (inMicLevelTmp > stt->maxLevel)
@ -835,6 +841,7 @@ int32_t WebRtcAgc_ProcessAnalog(void *state, int32_t inMicLevel,
}
// Store last value here, after we've taken care of manual updates etc.
stt->lastInMicLevel = inMicLevel;
lastMicVol = stt->micVol;
/* Checks if the signal is saturated. Also a check if individual samples
@ -1597,6 +1604,7 @@ int WebRtcAgc_Init(void *agcInst, int32_t minLevel, int32_t maxLevel,
stt->maxInit = stt->maxLevel;
stt->zeroCtrlMax = stt->maxAnalog;
stt->lastInMicLevel = 0;
/* Initialize micVol parameter */
stt->micVol = stt->maxAnalog;

View File

@ -111,6 +111,7 @@ typedef struct
int32_t minLevel; // Minimum possible volume level
int32_t minOutput; // Minimum output volume level
int32_t zeroCtrlMax; // Remember max gain => don't amp low input
int32_t lastInMicLevel;
int16_t scale; // Scale factor for internal volume levels
#ifdef MIC_LEVEL_FEEDBACK