common_audio: Removed macro WEBRTC_SPL_DIV
The macro has no built-in divide by zero check. The only thing that is done is casting to int32_t. In addition a bug was discovered where it was supposed to do a division with rounding, but instead did a division with truncation + addition by 2. This is corrected in this CL. BUG=3348,3353 TESTED=locally on Linux R=kwiberg@webrtc.org, tina.legrand@webrtc.org, turaj@webrtc.org Review URL: https://webrtc-codereview.appspot.com/19129004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@6998 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@@ -46,8 +46,6 @@
|
|||||||
((uint32_t) ((uint32_t)(a) * (uint16_t)(b)))
|
((uint32_t) ((uint32_t)(a) * (uint16_t)(b)))
|
||||||
#define WEBRTC_SPL_MUL_16_U16(a, b) \
|
#define WEBRTC_SPL_MUL_16_U16(a, b) \
|
||||||
((int32_t)(int16_t)(a) * (uint16_t)(b))
|
((int32_t)(int16_t)(a) * (uint16_t)(b))
|
||||||
#define WEBRTC_SPL_DIV(a, b) \
|
|
||||||
((int32_t) ((int32_t)(a) / (int32_t)(b)))
|
|
||||||
|
|
||||||
#ifndef WEBRTC_ARCH_ARM_V7
|
#ifndef WEBRTC_ARCH_ARM_V7
|
||||||
// For ARMv7 platforms, these are inline functions in spl_inl_armv7.h
|
// For ARMv7 platforms, these are inline functions in spl_inl_armv7.h
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ TEST_F(SplTest, MacroTest) {
|
|||||||
|
|
||||||
a = b;
|
a = b;
|
||||||
b = -3;
|
b = -3;
|
||||||
EXPECT_EQ(-5461, WEBRTC_SPL_DIV(a, b));
|
|
||||||
|
|
||||||
EXPECT_EQ(-1, WEBRTC_SPL_MUL_16_32_RSFT16(a, b));
|
EXPECT_EQ(-1, WEBRTC_SPL_MUL_16_32_RSFT16(a, b));
|
||||||
EXPECT_EQ(-1, WEBRTC_SPL_MUL_16_32_RSFT15(a, b));
|
EXPECT_EQ(-1, WEBRTC_SPL_MUL_16_32_RSFT15(a, b));
|
||||||
|
|||||||
@@ -282,11 +282,11 @@ int16_t WebRtcIsacfix_DecLogisticMulti2(int16_t *dataQ7,
|
|||||||
if (inSqrt < 0)
|
if (inSqrt < 0)
|
||||||
inSqrt=-inSqrt;
|
inSqrt=-inSqrt;
|
||||||
|
|
||||||
newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(inSqrt, res) + res, 1);
|
newRes = (inSqrt / res + res) >> 1;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
res = newRes;
|
res = newRes;
|
||||||
newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(inSqrt, res) + res, 1);
|
newRes = (inSqrt / res + res) >> 1;
|
||||||
} while (newRes != res && i-- > 0);
|
} while (newRes != res && i-- > 0);
|
||||||
|
|
||||||
tmpARSpecQ8 = (uint16_t)newRes;
|
tmpARSpecQ8 = (uint16_t)newRes;
|
||||||
|
|||||||
@@ -296,9 +296,9 @@ int32_t WebRtcIsacfix_UpdateUplinkBwImpl(BwEstimatorstr *bweStr,
|
|||||||
bweStr->recBwInv = WEBRTC_SPL_RSHIFT_W32((int32_t)bweStr->recBwInv, 13);
|
bweStr->recBwInv = WEBRTC_SPL_RSHIFT_W32((int32_t)bweStr->recBwInv, 13);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
/* recBwInv = 1 / (INIT_BN_EST + INIT_HDR_RATE) in Q26 (Q30??)*/
|
static const uint32_t kInitRate = INIT_BN_EST + INIT_HDR_RATE;
|
||||||
bweStr->recBwInv = WEBRTC_SPL_DIV((1073741824 +
|
/* recBwInv = 1 / kInitRate in Q26 (Q30??)*/
|
||||||
WEBRTC_SPL_LSHIFT_W32(((int32_t)INIT_BN_EST + INIT_HDR_RATE), 1)), INIT_BN_EST + INIT_HDR_RATE);
|
bweStr->recBwInv = (1073741824 + kInitRate / 2) / kInitRate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reset time-since-update counter */
|
/* reset time-since-update counter */
|
||||||
@@ -854,13 +854,14 @@ uint16_t WebRtcIsacfix_GetMinBytes(RateModel *State,
|
|||||||
} else {
|
} else {
|
||||||
/* handle burst */
|
/* handle burst */
|
||||||
if (State->BurstCounter) {
|
if (State->BurstCounter) {
|
||||||
if (State->StillBuffered < WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL((512 - WEBRTC_SPL_DIV(512, BURST_LEN)), DelayBuildUp), 9)) {
|
if (State->StillBuffered <
|
||||||
|
(((512 - 512 / BURST_LEN) * DelayBuildUp) >> 9)) {
|
||||||
/* max bps derived from BottleNeck and DelayBuildUp values */
|
/* max bps derived from BottleNeck and DelayBuildUp values */
|
||||||
inv_Q12 = WEBRTC_SPL_DIV(4096, WEBRTC_SPL_MUL(BURST_LEN, FrameSamples));
|
inv_Q12 = 4096 / (BURST_LEN * FrameSamples);
|
||||||
MinRate = WEBRTC_SPL_MUL(512 + WEBRTC_SPL_MUL(SAMPLES_PER_MSEC, WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(DelayBuildUp, inv_Q12), 3)), BottleNeck);
|
MinRate = WEBRTC_SPL_MUL(512 + WEBRTC_SPL_MUL(SAMPLES_PER_MSEC, WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(DelayBuildUp, inv_Q12), 3)), BottleNeck);
|
||||||
} else {
|
} else {
|
||||||
/* max bps derived from StillBuffered and DelayBuildUp values */
|
/* max bps derived from StillBuffered and DelayBuildUp values */
|
||||||
inv_Q12 = WEBRTC_SPL_DIV(4096, FrameSamples);
|
inv_Q12 = 4096 / FrameSamples;
|
||||||
if (DelayBuildUp > State->StillBuffered) {
|
if (DelayBuildUp > State->StillBuffered) {
|
||||||
MinRate = WEBRTC_SPL_MUL(512 + WEBRTC_SPL_MUL(SAMPLES_PER_MSEC, WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(DelayBuildUp - State->StillBuffered, inv_Q12), 3)), BottleNeck);
|
MinRate = WEBRTC_SPL_MUL(512 + WEBRTC_SPL_MUL(SAMPLES_PER_MSEC, WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_MUL(DelayBuildUp - State->StillBuffered, inv_Q12), 3)), BottleNeck);
|
||||||
} else if ((den = WEBRTC_SPL_MUL(SAMPLES_PER_MSEC, (State->StillBuffered - DelayBuildUp))) >= FrameSamples) {
|
} else if ((den = WEBRTC_SPL_MUL(SAMPLES_PER_MSEC, (State->StillBuffered - DelayBuildUp))) >= FrameSamples) {
|
||||||
@@ -895,10 +896,10 @@ uint16_t WebRtcIsacfix_GetMinBytes(RateModel *State,
|
|||||||
|
|
||||||
/* keep track of when bottle neck was last exceeded by at least 1% */
|
/* keep track of when bottle neck was last exceeded by at least 1% */
|
||||||
//517/512 ~ 1.01
|
//517/512 ~ 1.01
|
||||||
if (WEBRTC_SPL_DIV(WEBRTC_SPL_MUL(StreamSize, FS8), FrameSamples) > (WEBRTC_SPL_MUL(517, BottleNeck) >> 9)) {
|
if ((StreamSize * (int32_t)FS8) / FrameSamples > (517 * BottleNeck) >> 9) {
|
||||||
if (State->PrevExceed) {
|
if (State->PrevExceed) {
|
||||||
/* bottle_neck exceded twice in a row, decrease ExceedAgo */
|
/* bottle_neck exceded twice in a row, decrease ExceedAgo */
|
||||||
State->ExceedAgo -= WEBRTC_SPL_DIV(BURST_INTERVAL, BURST_LEN - 1);
|
State->ExceedAgo -= BURST_INTERVAL / (BURST_LEN - 1);
|
||||||
if (State->ExceedAgo < 0) {
|
if (State->ExceedAgo < 0) {
|
||||||
State->ExceedAgo = 0;
|
State->ExceedAgo = 0;
|
||||||
}
|
}
|
||||||
@@ -922,7 +923,7 @@ uint16_t WebRtcIsacfix_GetMinBytes(RateModel *State,
|
|||||||
|
|
||||||
|
|
||||||
/* Update buffer delay */
|
/* Update buffer delay */
|
||||||
TransmissionTime = (int16_t)WEBRTC_SPL_DIV(WEBRTC_SPL_MUL(StreamSize, 8000), BottleNeck); /* ms */
|
TransmissionTime = (StreamSize * 8000) / BottleNeck; /* ms */
|
||||||
State->StillBuffered += TransmissionTime;
|
State->StillBuffered += TransmissionTime;
|
||||||
State->StillBuffered -= (int16_t)WEBRTC_SPL_RSHIFT_W16(FrameSamples, 4); //>>4 = SAMPLES_PER_MSEC /* ms */
|
State->StillBuffered -= (int16_t)WEBRTC_SPL_RSHIFT_W16(FrameSamples, 4); //>>4 = SAMPLES_PER_MSEC /* ms */
|
||||||
if (State->StillBuffered < 0) {
|
if (State->StillBuffered < 0) {
|
||||||
@@ -945,13 +946,12 @@ void WebRtcIsacfix_UpdateRateModel(RateModel *State,
|
|||||||
const int16_t FrameSamples, /* samples per frame */
|
const int16_t FrameSamples, /* samples per frame */
|
||||||
const int16_t BottleNeck) /* bottle neck rate; excl headers (bps) */
|
const int16_t BottleNeck) /* bottle neck rate; excl headers (bps) */
|
||||||
{
|
{
|
||||||
int16_t TransmissionTime;
|
const int16_t TransmissionTime = (StreamSize * 8000) / BottleNeck; /* ms */
|
||||||
|
|
||||||
/* avoid the initial "high-rate" burst */
|
/* avoid the initial "high-rate" burst */
|
||||||
State->InitCounter = 0;
|
State->InitCounter = 0;
|
||||||
|
|
||||||
/* Update buffer delay */
|
/* Update buffer delay */
|
||||||
TransmissionTime = (int16_t)WEBRTC_SPL_DIV(WEBRTC_SPL_MUL(WEBRTC_SPL_MUL(StreamSize, 8), 1000), BottleNeck); /* ms */
|
|
||||||
State->StillBuffered += TransmissionTime;
|
State->StillBuffered += TransmissionTime;
|
||||||
State->StillBuffered -= (int16_t)WEBRTC_SPL_RSHIFT_W16(FrameSamples, 4); /* ms */
|
State->StillBuffered -= (int16_t)WEBRTC_SPL_RSHIFT_W16(FrameSamples, 4); /* ms */
|
||||||
if (State->StillBuffered < 0) {
|
if (State->StillBuffered < 0) {
|
||||||
|
|||||||
@@ -59,8 +59,8 @@ int16_t WebRtcIsacfix_DecodeImpl(int16_t *signal_out16,
|
|||||||
|
|
||||||
|
|
||||||
int16_t frame_nb; /* counter */
|
int16_t frame_nb; /* counter */
|
||||||
int16_t frame_mode; /* 0 for 20ms and 30ms, 1 for 60ms */
|
int16_t frame_mode; /* 0 for 30ms, 1 for 60ms */
|
||||||
int16_t processed_samples;
|
static const int16_t kProcessedSamples = 480; /* 480 (for both 30, 60 ms) */
|
||||||
|
|
||||||
/* PLC */
|
/* PLC */
|
||||||
int16_t overlapWin[ 240 ];
|
int16_t overlapWin[ 240 ];
|
||||||
@@ -76,14 +76,14 @@ int16_t WebRtcIsacfix_DecodeImpl(int16_t *signal_out16,
|
|||||||
if (err<0) // error check
|
if (err<0) // error check
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
frame_mode = (int16_t)WEBRTC_SPL_DIV(*current_framesamples, MAX_FRAMESAMPLES); /* 0, or 1 */
|
frame_mode = *current_framesamples / MAX_FRAMESAMPLES; /* 0, or 1 */
|
||||||
processed_samples = (int16_t)WEBRTC_SPL_DIV(*current_framesamples, frame_mode+1); /* either 320 (20ms) or 480 (30, 60 ms) */
|
|
||||||
|
|
||||||
err = WebRtcIsacfix_DecodeSendBandwidth(&ISACdec_obj->bitstr_obj, &BWno);
|
err = WebRtcIsacfix_DecodeSendBandwidth(&ISACdec_obj->bitstr_obj, &BWno);
|
||||||
if (err<0) // error check
|
if (err<0) // error check
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
/* one loop if it's one frame (20 or 30ms), 2 loops if 2 frames bundled together (60ms) */
|
/* one loop if it's one frame (30ms), two loops if two frames bundled together
|
||||||
|
* (60ms) */
|
||||||
for (frame_nb = 0; frame_nb <= frame_mode; frame_nb++) {
|
for (frame_nb = 0; frame_nb <= frame_mode; frame_nb++) {
|
||||||
|
|
||||||
/* decode & dequantize pitch parameters */
|
/* decode & dequantize pitch parameters */
|
||||||
@@ -210,7 +210,10 @@ int16_t WebRtcIsacfix_DecodeImpl(int16_t *signal_out16,
|
|||||||
Vector_Word16_2[k] = tmp_2;
|
Vector_Word16_2[k] = tmp_2;
|
||||||
}
|
}
|
||||||
|
|
||||||
WebRtcIsacfix_FilterAndCombine1(Vector_Word16_1, Vector_Word16_2, signal_out16 + frame_nb * processed_samples, &ISACdec_obj->postfiltbankstr_obj);
|
WebRtcIsacfix_FilterAndCombine1(Vector_Word16_1,
|
||||||
|
Vector_Word16_2,
|
||||||
|
signal_out16 + frame_nb * kProcessedSamples,
|
||||||
|
&ISACdec_obj->postfiltbankstr_obj);
|
||||||
|
|
||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
|
|||||||
@@ -350,11 +350,11 @@ static void CalcRootInvArSpec(const int16_t *ARCoefQ12,
|
|||||||
if(in_sqrt<0)
|
if(in_sqrt<0)
|
||||||
in_sqrt=-in_sqrt;
|
in_sqrt=-in_sqrt;
|
||||||
|
|
||||||
newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(in_sqrt, res) + res, 1);
|
newRes = (in_sqrt / res + res) >> 1;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
res = newRes;
|
res = newRes;
|
||||||
newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(in_sqrt, res) + res, 1);
|
newRes = (in_sqrt / res + res) >> 1;
|
||||||
} while (newRes != res && i-- > 0);
|
} while (newRes != res && i-- > 0);
|
||||||
|
|
||||||
CurveQ8[k] = (int16_t)newRes;
|
CurveQ8[k] = (int16_t)newRes;
|
||||||
@@ -368,11 +368,11 @@ static void CalcRootInvArSpec(const int16_t *ARCoefQ12,
|
|||||||
if(in_sqrt<0)
|
if(in_sqrt<0)
|
||||||
in_sqrt=-in_sqrt;
|
in_sqrt=-in_sqrt;
|
||||||
|
|
||||||
newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(in_sqrt, res) + res, 1);
|
newRes = (in_sqrt / res + res) >> 1;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
res = newRes;
|
res = newRes;
|
||||||
newRes = WEBRTC_SPL_RSHIFT_W32(WEBRTC_SPL_DIV(in_sqrt, res) + res, 1);
|
newRes = (in_sqrt / res + res) >> 1;
|
||||||
} while (newRes != res && i-- > 0);
|
} while (newRes != res && i-- > 0);
|
||||||
|
|
||||||
CurveQ8[k] = (int16_t)newRes;
|
CurveQ8[k] = (int16_t)newRes;
|
||||||
|
|||||||
@@ -208,7 +208,7 @@ int WebRtcAgc_AddMic(void *state, int16_t *in_mic, int16_t *in_mic_H,
|
|||||||
tmp16 = (int16_t)(stt->micVol - stt->maxAnalog);
|
tmp16 = (int16_t)(stt->micVol - stt->maxAnalog);
|
||||||
tmp32 = WEBRTC_SPL_MUL_16_16(GAIN_TBL_LEN - 1, tmp16);
|
tmp32 = WEBRTC_SPL_MUL_16_16(GAIN_TBL_LEN - 1, tmp16);
|
||||||
tmp16 = (int16_t)(stt->maxLevel - stt->maxAnalog);
|
tmp16 = (int16_t)(stt->maxLevel - stt->maxAnalog);
|
||||||
targetGainIdx = (uint16_t)WEBRTC_SPL_DIV(tmp32, tmp16);
|
targetGainIdx = tmp32 / tmp16;
|
||||||
assert(targetGainIdx < GAIN_TBL_LEN);
|
assert(targetGainIdx < GAIN_TBL_LEN);
|
||||||
|
|
||||||
/* Increment through the table towards the target gain.
|
/* Increment through the table towards the target gain.
|
||||||
@@ -1078,8 +1078,7 @@ int32_t WebRtcAgc_ProcessAnalog(void *state, int32_t inMicLevel,
|
|||||||
tmp32 = WEBRTC_SPL_LSHIFT_W32(inMicLevelTmp - stt->minLevel, 14);
|
tmp32 = WEBRTC_SPL_LSHIFT_W32(inMicLevelTmp - stt->minLevel, 14);
|
||||||
if (stt->maxInit != stt->minLevel)
|
if (stt->maxInit != stt->minLevel)
|
||||||
{
|
{
|
||||||
volNormFIX = (int16_t)WEBRTC_SPL_DIV(tmp32,
|
volNormFIX = tmp32 / (stt->maxInit - stt->minLevel);
|
||||||
(stt->maxInit - stt->minLevel));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find correct curve */
|
/* Find correct curve */
|
||||||
@@ -1138,8 +1137,7 @@ int32_t WebRtcAgc_ProcessAnalog(void *state, int32_t inMicLevel,
|
|||||||
tmp32 = WEBRTC_SPL_LSHIFT_W32(inMicLevelTmp - stt->minLevel, 14);
|
tmp32 = WEBRTC_SPL_LSHIFT_W32(inMicLevelTmp - stt->minLevel, 14);
|
||||||
if (stt->maxInit != stt->minLevel)
|
if (stt->maxInit != stt->minLevel)
|
||||||
{
|
{
|
||||||
volNormFIX = (int16_t)WEBRTC_SPL_DIV(tmp32,
|
volNormFIX = tmp32 / (stt->maxInit - stt->minLevel);
|
||||||
(stt->maxInit - stt->minLevel));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find correct curve */
|
/* Find correct curve */
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ int32_t WebRtcAgc_CalculateGainTable(int32_t *gainTable, // Q16
|
|||||||
{
|
{
|
||||||
numFIX += WEBRTC_SPL_RSHIFT_W32(tmp32no1, 1);
|
numFIX += WEBRTC_SPL_RSHIFT_W32(tmp32no1, 1);
|
||||||
}
|
}
|
||||||
y32 = WEBRTC_SPL_DIV(numFIX, tmp32no1); // in Q14
|
y32 = numFIX / tmp32no1; // in Q14
|
||||||
if (limiterEnable && (i < limiterIdx))
|
if (limiterEnable && (i < limiterIdx))
|
||||||
{
|
{
|
||||||
tmp32 = WEBRTC_SPL_MUL_16_U16(i - 1, kLog10_2); // Q14
|
tmp32 = WEBRTC_SPL_MUL_16_U16(i - 1, kLog10_2); // Q14
|
||||||
|
|||||||
@@ -1493,8 +1493,7 @@ void WebRtcNsx_DataSynthesis(NsxInst_t* inst, short* outFrame) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert(inst->energyIn > 0);
|
assert(inst->energyIn > 0);
|
||||||
energyRatio = (int16_t)WEBRTC_SPL_DIV(energyOut
|
energyRatio = (energyOut + inst->energyIn / 2) / inst->energyIn; // Q8
|
||||||
+ WEBRTC_SPL_RSHIFT_W32(inst->energyIn, 1), inst->energyIn); // Q8
|
|
||||||
// Limit the ratio to [0, 1] in Q8, i.e., [0, 256]
|
// Limit the ratio to [0, 1] in Q8, i.e., [0, 256]
|
||||||
energyRatio = WEBRTC_SPL_SAT(256, energyRatio, 0);
|
energyRatio = WEBRTC_SPL_SAT(256, energyRatio, 0);
|
||||||
|
|
||||||
|
|||||||
@@ -258,8 +258,8 @@ void WebRtcNsx_SpeechNoiseProb(NsxInst_t* inst,
|
|||||||
tmp32no1 = WEBRTC_SPL_LSHIFT_W32((int32_t)inst->priorNonSpeechProb,
|
tmp32no1 = WEBRTC_SPL_LSHIFT_W32((int32_t)inst->priorNonSpeechProb,
|
||||||
8); // Q22
|
8); // Q22
|
||||||
|
|
||||||
nonSpeechProbFinal[i] = (uint16_t)WEBRTC_SPL_DIV(tmp32no1,
|
nonSpeechProbFinal[i] = tmp32no1 /
|
||||||
(int32_t)inst->priorNonSpeechProb + invLrtFX); // Q8
|
(inst->priorNonSpeechProb + invLrtFX); // Q8
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user