audio_processing/agc: Removed usage of macro WEBRTC_SPL_MUL_16_16 in legacy/agc
The macro is in C defined as
#define WEBRTC_SPL_MUL_16_16(a, b) ((int32_t) (((int16_t)(a)) * ((int16_t)(b))))
(For definition on ARMv7 and MIPS, see common_audio/signal_processing/include/spl_inl_armv7.h and common_audio/signal_processing/include/spl_inl_mips.h)
The replacement consists of
- avoiding casts to int16_t if inputs already are int16_t
- adding explicit cast to <type> if result is assigned to <type> (other than int or int32_t)
BUG=3348, 3353
TESTED=locally on Mac and trybots
R=kwiberg@webrtc.org
Review URL: https://webrtc-codereview.appspot.com/39389004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@8023 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/modules/audio_processing/agc/legacy/analog_agc.c b/webrtc/modules/audio_processing/agc/legacy/analog_agc.c
index eb83115..1559aeb 100644
--- a/webrtc/modules/audio_processing/agc/legacy/analog_agc.c
+++ b/webrtc/modules/audio_processing/agc/legacy/analog_agc.c
@@ -143,7 +143,7 @@
/* Q1 */
tmp16 = (int16_t)(stt->micVol - stt->maxAnalog);
- tmp32 = WEBRTC_SPL_MUL_16_16(GAIN_TBL_LEN - 1, tmp16);
+ tmp32 = (GAIN_TBL_LEN - 1) * tmp16;
tmp16 = (int16_t)(stt->maxLevel - stt->maxAnalog);
targetGainIdx = tmp32 / tmp16;
assert(targetGainIdx < GAIN_TBL_LEN);
@@ -200,8 +200,7 @@
max_nrg = 0;
for (n = 0; n < L; n++)
{
- nrg = WEBRTC_SPL_MUL_16_16(in_mic[0][i * L + n],
- in_mic[0][i * L + n]);
+ nrg = in_mic[0][i * L + n] * in_mic[0][i * L + n];
if (nrg > max_nrg)
{
max_nrg = nrg;
@@ -309,7 +308,7 @@
frameNrgLimit = frameNrgLimit << 1;
}
- frameNrg = WEBRTC_SPL_MUL_16_16(in_near[0][0], in_near[0][0]);
+ frameNrg = (uint32_t)(in_near[0][0] * in_near[0][0]);
for (sampleCntr = 1; sampleCntr < samples; sampleCntr++)
{
@@ -317,9 +316,8 @@
// the correct value of the energy is not important
if (frameNrg < frameNrgLimit)
{
- nrg = WEBRTC_SPL_MUL_16_16(in_near[0][sampleCntr],
- in_near[0][sampleCntr]);
- frameNrg += nrg;
+ nrg = (uint32_t)(in_near[0][sampleCntr] * in_near[0][sampleCntr]);
+ frameNrg += nrg;
}
// Count the zero crossings
@@ -584,8 +582,7 @@
}
/* stt->vadThreshold = (31 * stt->vadThreshold + vadThresh) / 32; */
- tmp32 = (int32_t)vadThresh;
- tmp32 += WEBRTC_SPL_MUL_16_16((int16_t)31, stt->vadThreshold);
+ tmp32 = vadThresh + 31 * stt->vadThreshold;
stt->vadThreshold = (int16_t)(tmp32 >> 5);
}
}
diff --git a/webrtc/modules/audio_processing/agc/legacy/digital_agc.c b/webrtc/modules/audio_processing/agc/legacy/digital_agc.c
index 89a0224..4619b88 100644
--- a/webrtc/modules/audio_processing/agc/legacy/digital_agc.c
+++ b/webrtc/modules/audio_processing/agc/legacy/digital_agc.c
@@ -87,11 +87,11 @@
// kLog10_2 = 49321; // 10*log10(2) in Q14
// Calculate maximum digital gain and zero gain level
- tmp32no1 = WEBRTC_SPL_MUL_16_16(digCompGaindB - analogTarget, kCompRatio - 1);
+ tmp32no1 = (digCompGaindB - analogTarget) * (kCompRatio - 1);
tmp16no1 = analogTarget - targetLevelDbfs;
tmp16no1 += WebRtcSpl_DivW32W16ResW16(tmp32no1 + (kCompRatio >> 1), kCompRatio);
maxGain = WEBRTC_SPL_MAX(tmp16no1, (analogTarget - targetLevelDbfs));
- tmp32no1 = WEBRTC_SPL_MUL_16_16(maxGain, kCompRatio);
+ tmp32no1 = maxGain * kCompRatio;
zeroGainLvl = digCompGaindB;
zeroGainLvl -= WebRtcSpl_DivW32W16ResW16(tmp32no1 + ((kCompRatio - 1) >> 1),
kCompRatio - 1);
@@ -104,7 +104,7 @@
// Calculate the difference between maximum gain and gain at 0dB0v:
// diffGain = maxGain + (compRatio-1)*zeroGainLvl/compRatio
// = (compRatio-1)*digCompGaindB/compRatio
- tmp32no1 = WEBRTC_SPL_MUL_16_16(digCompGaindB, kCompRatio - 1);
+ tmp32no1 = digCompGaindB * (kCompRatio - 1);
diffGain = WebRtcSpl_DivW32W16ResW16(tmp32no1 + (kCompRatio >> 1), kCompRatio);
if (diffGain < 0 || diffGain >= kGenFuncTableSize)
{
@@ -138,7 +138,7 @@
{
// Calculate scaled input level (compressor):
// inLevel = fix((-constLog10_2*(compRatio-1)*(1-i)+fix(compRatio/2))/compRatio)
- tmp16 = (int16_t)WEBRTC_SPL_MUL_16_16(kCompRatio - 1, i - 1); // Q0
+ tmp16 = (int16_t)((kCompRatio - 1) * (i - 1)); // Q0
tmp32 = WEBRTC_SPL_MUL_16_U16(tmp16, kLog10_2) + 1; // Q14
inLevel = WebRtcSpl_DivW32W16(tmp32, kCompRatio); // Q14
@@ -341,7 +341,7 @@
// Account for far end VAD
if (stt->vadFarend.counter > 10)
{
- tmp32 = WEBRTC_SPL_MUL_16_16(3, logratio);
+ tmp32 = 3 * logratio;
logratio = (int16_t)((tmp32 - stt->vadFarend.logRatio) >> 2);
}
@@ -362,7 +362,7 @@
// decay = (int16_t)(((lower_thr - logratio)
// * (2^27/(DecayTime*(upper_thr-lower_thr)))) >> 10);
// SUBSTITUTED: 2^27/(DecayTime*(upper_thr-lower_thr)) -> 65
- tmp32 = WEBRTC_SPL_MUL_16_16((lower_thr - logratio), 65);
+ tmp32 = (lower_thr - logratio) * 65;
decay = (int16_t)(tmp32 >> 10);
}
@@ -376,7 +376,7 @@
} else if (stt->vadNearend.stdLongTerm < 8096)
{
// decay = (int16_t)(((stt->vadNearend.stdLongTerm - 4000) * decay) >> 12);
- tmp32 = WEBRTC_SPL_MUL_16_16((stt->vadNearend.stdLongTerm - 4000), decay);
+ tmp32 = (stt->vadNearend.stdLongTerm - 4000) * decay;
decay = (int16_t)(tmp32 >> 12);
}
@@ -402,8 +402,7 @@
max_nrg = 0;
for (n = 0; n < L; n++)
{
- int32_t nrg = WEBRTC_SPL_MUL_16_16(out[0][k * L + n],
- out[0][k * L + n]);
+ int32_t nrg = out[0][k * L + n] * out[0][k * L + n];
if (nrg > max_nrg)
{
max_nrg = nrg;
@@ -487,7 +486,7 @@
stt->gatePrevious = 0;
} else
{
- tmp32 = WEBRTC_SPL_MUL_16_16(stt->gatePrevious, 7);
+ tmp32 = stt->gatePrevious * 7;
gate = (int16_t)((gate + tmp32) >> 3);
stt->gatePrevious = gate;
}
@@ -714,7 +713,7 @@
}
// update short-term estimate of mean energy level (Q10)
- tmp32 = (WEBRTC_SPL_MUL_16_16(state->meanShortTerm, 15) + (int32_t)dB);
+ tmp32 = state->meanShortTerm * 15 + dB;
state->meanShortTerm = (int16_t)(tmp32 >> 4);
// update short-term estimate of variance in energy level (Q8)
@@ -723,12 +722,12 @@
state->varianceShortTerm = tmp32 / 16;
// update short-term estimate of standard deviation in energy level (Q10)
- tmp32 = WEBRTC_SPL_MUL_16_16(state->meanShortTerm, state->meanShortTerm);
+ tmp32 = state->meanShortTerm * state->meanShortTerm;
tmp32 = (state->varianceShortTerm << 12) - tmp32;
state->stdShortTerm = (int16_t)WebRtcSpl_Sqrt(tmp32);
// update long-term estimate of mean energy level (Q10)
- tmp32 = WEBRTC_SPL_MUL_16_16(state->meanLongTerm, state->counter) + (int32_t)dB;
+ tmp32 = state->meanLongTerm * state->counter + dB;
state->meanLongTerm = WebRtcSpl_DivW32W16ResW16(
tmp32, WebRtcSpl_AddSatW16(state->counter, 1));
@@ -739,13 +738,18 @@
tmp32, WebRtcSpl_AddSatW16(state->counter, 1));
// update long-term estimate of standard deviation in energy level (Q10)
- tmp32 = WEBRTC_SPL_MUL_16_16(state->meanLongTerm, state->meanLongTerm);
+ tmp32 = state->meanLongTerm * state->meanLongTerm;
tmp32 = (state->varianceLongTerm << 12) - tmp32;
state->stdLongTerm = (int16_t)WebRtcSpl_Sqrt(tmp32);
// update voice activity measure (Q10)
tmp16 = 3 << 12;
- tmp32 = WEBRTC_SPL_MUL_16_16(tmp16, (dB - state->meanLongTerm));
+ // TODO(bjornv): (dB - state->meanLongTerm) can overflow, e.g., in
+ // ApmTest.Process unit test. Previously the macro WEBRTC_SPL_MUL_16_16()
+ // was used, which did an intermediate cast to (int16_t), hence losing
+ // significant bits. This cause logRatio to max out positive, rather than
+ // negative. This is a bug, but has very little significance.
+ tmp32 = tmp16 * (int16_t)(dB - state->meanLongTerm);
tmp32 = WebRtcSpl_DivW32W16(tmp32, state->stdLongTerm);
tmpU16 = (13 << 12);
tmp32b = WEBRTC_SPL_MUL_16_U16(state->logRatio, tmpU16);