Defining MAXG/MING/GCONST for log gain

This commit is contained in:
Jean-Marc Valin 2024-06-26 13:37:24 -04:00
parent be37d86633
commit abd512f7f6
No known key found for this signature in database
GPG key ID: 8D2952BBB52C646D
9 changed files with 150 additions and 138 deletions

View file

@ -105,6 +105,8 @@ void celt_fatal(const char *str, const char *file, int line)
#define IMAX(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum int value. */ #define IMAX(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum int value. */
#define UADD32(a,b) ((a)+(b)) #define UADD32(a,b) ((a)+(b))
#define USUB32(a,b) ((a)-(b)) #define USUB32(a,b) ((a)-(b))
#define MAXG(a,b) MAX16(a, b)
#define MING(a,b) MIN16(a, b)
/* Throughout the code, we use the following scaling for signals: /* Throughout the code, we use the following scaling for signals:
FLOAT: used for float API, normalized to +/-1. FLOAT: used for float API, normalized to +/-1.
@ -270,6 +272,7 @@ static OPUS_INLINE int celt_isnan(float x)
#define QCONST16(x,bits) (x) #define QCONST16(x,bits) (x)
#define QCONST32(x,bits) (x) #define QCONST32(x,bits) (x)
#define GCONST(x) (x)
#define NEG16(x) (-(x)) #define NEG16(x) (-(x))
#define NEG32(x) (-(x)) #define NEG32(x) (-(x))

View file

@ -325,14 +325,14 @@ void anti_collapse(const CELTMode *m, celt_norm *X_, unsigned char *collapse_mas
prev2 = prev2logE[c*m->nbEBands+i]; prev2 = prev2logE[c*m->nbEBands+i];
if (!encode && C==1) if (!encode && C==1)
{ {
prev1 = MAX16(prev1,prev1logE[m->nbEBands+i]); prev1 = MAXG(prev1,prev1logE[m->nbEBands+i]);
prev2 = MAX16(prev2,prev2logE[m->nbEBands+i]); prev2 = MAXG(prev2,prev2logE[m->nbEBands+i]);
} }
Ediff = EXTEND32(logE[c*m->nbEBands+i])-EXTEND32(MIN16(prev1,prev2)); Ediff = EXTEND32(logE[c*m->nbEBands+i])-EXTEND32(MING(prev1,prev2));
Ediff = MAX32(0, Ediff); Ediff = MAX32(0, Ediff);
#ifdef FIXED_POINT #ifdef FIXED_POINT
if (Ediff < 16384) if (Ediff < GCONST(16.f))
{ {
opus_val32 r32 = SHR32(celt_exp2(-EXTRACT16(Ediff)),1); opus_val32 r32 = SHR32(celt_exp2(-EXTRACT16(Ediff)),1);
r = 2*MIN16(16383,r32); r = 2*MIN16(16383,r32);

View file

@ -659,11 +659,11 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM
} }
/* Energy decay */ /* Energy decay */
decay = loss_duration==0 ? QCONST16(1.5f, DB_SHIFT) : QCONST16(.5f, DB_SHIFT); decay = loss_duration==0 ? GCONST(1.5f) : GCONST(.5f);
c=0; do c=0; do
{ {
for (i=start;i<end;i++) for (i=start;i<end;i++)
oldBandE[c*nbEBands+i] = MAX16(backgroundLogE[c*nbEBands+i], oldBandE[c*nbEBands+i] - decay); oldBandE[c*nbEBands+i] = MAXG(backgroundLogE[c*nbEBands+i], oldBandE[c*nbEBands+i] - decay);
} while (++c<C); } while (++c<C);
seed = st->rng; seed = st->rng;
for (c=0;c<C;c++) for (c=0;c<C;c++)
@ -1106,7 +1106,7 @@ int celt_decode_with_ec_dred(CELTDecoder * OPUS_RESTRICT st, const unsigned char
if (C==1) if (C==1)
{ {
for (i=0;i<nbEBands;i++) for (i=0;i<nbEBands;i++)
oldBandE[i]=MAX16(oldBandE[i],oldBandE[nbEBands+i]); oldBandE[i]=MAXG(oldBandE[i],oldBandE[nbEBands+i]);
} }
total_bits = len*8; total_bits = len*8;
@ -1165,11 +1165,11 @@ int celt_decode_with_ec_dred(CELTDecoder * OPUS_RESTRICT st, const unsigned char
{ {
celt_glog safety = 0; celt_glog safety = 0;
int missing = IMIN(10, st->loss_duration>>LM); int missing = IMIN(10, st->loss_duration>>LM);
if (LM==0) safety = QCONST16(1.5f,DB_SHIFT); if (LM==0) safety = GCONST(1.5f);
else if (LM==1) safety = QCONST16(.5f,DB_SHIFT); else if (LM==1) safety = GCONST(.5f);
for (i=start;i<end;i++) for (i=start;i<end;i++)
{ {
if (oldBandE[c*nbEBands+i] < MAX16(oldLogE[c*nbEBands+i], oldLogE2[c*nbEBands+i])) { if (oldBandE[c*nbEBands+i] < MAXG(oldLogE[c*nbEBands+i], oldLogE2[c*nbEBands+i])) {
/* If energy is going down already, continue the trend. */ /* If energy is going down already, continue the trend. */
opus_val32 slope; opus_val32 slope;
opus_val32 E0, E1, E2; opus_val32 E0, E1, E2;
@ -1178,10 +1178,10 @@ int celt_decode_with_ec_dred(CELTDecoder * OPUS_RESTRICT st, const unsigned char
E2 = oldLogE2[c*nbEBands+i]; E2 = oldLogE2[c*nbEBands+i];
slope = MAX32(E1 - E0, HALF32(E2 - E0)); slope = MAX32(E1 - E0, HALF32(E2 - E0));
E0 -= MAX32(0, (1+missing)*slope); E0 -= MAX32(0, (1+missing)*slope);
oldBandE[c*nbEBands+i] = MAX32(-QCONST16(20.f,DB_SHIFT), E0); oldBandE[c*nbEBands+i] = MAX32(-GCONST(20.f), E0);
} else { } else {
/* Otherwise take the min of the last frames. */ /* Otherwise take the min of the last frames. */
oldBandE[c*nbEBands+i] = MIN16(MIN16(oldBandE[c*nbEBands+i], oldLogE[c*nbEBands+i]), oldLogE2[c*nbEBands+i]); oldBandE[c*nbEBands+i] = MING(MING(oldBandE[c*nbEBands+i], oldLogE[c*nbEBands+i]), oldLogE2[c*nbEBands+i]);
} }
/* Shorter frames have more natural fluctuations -- play it safe. */ /* Shorter frames have more natural fluctuations -- play it safe. */
oldBandE[c*nbEBands+i] -= safety; oldBandE[c*nbEBands+i] -= safety;
@ -1283,7 +1283,7 @@ int celt_decode_with_ec_dred(CELTDecoder * OPUS_RESTRICT st, const unsigned char
if (silence) if (silence)
{ {
for (i=0;i<C*nbEBands;i++) for (i=0;i<C*nbEBands;i++)
oldBandE[i] = -QCONST16(28.f,DB_SHIFT); oldBandE[i] = -GCONST(28.f);
} }
if (st->prefilter_and_fold) { if (st->prefilter_and_fold) {
prefilter_and_fold(st, N); prefilter_and_fold(st, N);
@ -1325,26 +1325,26 @@ int celt_decode_with_ec_dred(CELTDecoder * OPUS_RESTRICT st, const unsigned char
OPUS_COPY(oldLogE, oldBandE, 2*nbEBands); OPUS_COPY(oldLogE, oldBandE, 2*nbEBands);
} else { } else {
for (i=0;i<2*nbEBands;i++) for (i=0;i<2*nbEBands;i++)
oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]); oldLogE[i] = MING(oldLogE[i], oldBandE[i]);
} }
/* In normal circumstances, we only allow the noise floor to increase by /* In normal circumstances, we only allow the noise floor to increase by
up to 2.4 dB/second, but when we're in DTX we give the weight of up to 2.4 dB/second, but when we're in DTX we give the weight of
all missing packets to the update packet. */ all missing packets to the update packet. */
max_background_increase = IMIN(160, st->loss_duration+M)*QCONST16(0.001f,DB_SHIFT); max_background_increase = IMIN(160, st->loss_duration+M)*GCONST(0.001f);
for (i=0;i<2*nbEBands;i++) for (i=0;i<2*nbEBands;i++)
backgroundLogE[i] = MIN16(backgroundLogE[i] + max_background_increase, oldBandE[i]); backgroundLogE[i] = MING(backgroundLogE[i] + max_background_increase, oldBandE[i]);
/* In case start or end were to change */ /* In case start or end were to change */
c=0; do c=0; do
{ {
for (i=0;i<start;i++) for (i=0;i<start;i++)
{ {
oldBandE[c*nbEBands+i]=0; oldBandE[c*nbEBands+i]=0;
oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-QCONST16(28.f,DB_SHIFT); oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-GCONST(28.f);
} }
for (i=end;i<nbEBands;i++) for (i=end;i<nbEBands;i++)
{ {
oldBandE[c*nbEBands+i]=0; oldBandE[c*nbEBands+i]=0;
oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-QCONST16(28.f,DB_SHIFT); oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-GCONST(28.f);
} }
} while (++c<2); } while (++c<2);
st->rng = dec->rng; st->rng = dec->rng;
@ -1537,16 +1537,17 @@ int opus_custom_decoder_ctl(CELTDecoder * OPUS_RESTRICT st, int request, ...)
case OPUS_RESET_STATE: case OPUS_RESET_STATE:
{ {
int i; int i;
celt_glog *lpc, *oldBandE, *oldLogE, *oldLogE2; opus_val16 *lpc;
lpc = (celt_glog*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*st->channels); celt_glog *oldBandE, *oldLogE, *oldLogE2;
oldBandE = lpc+st->channels*CELT_LPC_ORDER; lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*st->channels);
oldBandE = (celt_glog*)(lpc+st->channels*CELT_LPC_ORDER);
oldLogE = oldBandE + 2*st->mode->nbEBands; oldLogE = oldBandE + 2*st->mode->nbEBands;
oldLogE2 = oldLogE + 2*st->mode->nbEBands; oldLogE2 = oldLogE + 2*st->mode->nbEBands;
OPUS_CLEAR((char*)&st->DECODER_RESET_START, OPUS_CLEAR((char*)&st->DECODER_RESET_START,
opus_custom_decoder_get_size(st->mode, st->channels)- opus_custom_decoder_get_size(st->mode, st->channels)-
((char*)&st->DECODER_RESET_START - (char*)st)); ((char*)&st->DECODER_RESET_START - (char*)st));
for (i=0;i<2*st->mode->nbEBands;i++) for (i=0;i<2*st->mode->nbEBands;i++)
oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT); oldLogE[i]=oldLogE2[i]=-GCONST(28.f);
st->skip_plc = 1; st->skip_plc = 1;
} }
break; break;

View file

@ -441,28 +441,28 @@ static int patch_transient_decision(celt_glog *newE, celt_glog *oldE, int nbEBan
{ {
spread_old[start] = oldE[start]; spread_old[start] = oldE[start];
for (i=start+1;i<end;i++) for (i=start+1;i<end;i++)
spread_old[i] = MAX16(spread_old[i-1]-QCONST16(1.0f, DB_SHIFT), oldE[i]); spread_old[i] = MAXG(spread_old[i-1]-GCONST(1.0f), oldE[i]);
} else { } else {
spread_old[start] = MAX16(oldE[start],oldE[start+nbEBands]); spread_old[start] = MAXG(oldE[start],oldE[start+nbEBands]);
for (i=start+1;i<end;i++) for (i=start+1;i<end;i++)
spread_old[i] = MAX16(spread_old[i-1]-QCONST16(1.0f, DB_SHIFT), spread_old[i] = MAXG(spread_old[i-1]-GCONST(1.0f),
MAX16(oldE[i],oldE[i+nbEBands])); MAXG(oldE[i],oldE[i+nbEBands]));
} }
for (i=end-2;i>=start;i--) for (i=end-2;i>=start;i--)
spread_old[i] = MAX16(spread_old[i], spread_old[i+1]-QCONST16(1.0f, DB_SHIFT)); spread_old[i] = MAXG(spread_old[i], spread_old[i+1]-GCONST(1.0f));
/* Compute mean increase */ /* Compute mean increase */
c=0; do { c=0; do {
for (i=IMAX(2,start);i<end-1;i++) for (i=IMAX(2,start);i<end-1;i++)
{ {
opus_val16 x1, x2; opus_val16 x1, x2;
x1 = MAX16(0, newE[i + c*nbEBands]); x1 = MAXG(0, newE[i + c*nbEBands]);
x2 = MAX16(0, spread_old[i]); x2 = MAXG(0, spread_old[i]);
mean_diff = ADD32(mean_diff, EXTEND32(MAX16(0, SUB16(x1, x2)))); mean_diff = ADD32(mean_diff, EXTEND32(MAXG(0, SUB16(x1, x2))));
} }
} while (++c<C); } while (++c<C);
mean_diff = DIV32(mean_diff, C*(end-1-IMAX(2,start))); mean_diff = DIV32(mean_diff, C*(end-1-IMAX(2,start)));
/*printf("%f %f %d\n", mean_diff, max_diff, count);*/ /*printf("%f %f %d\n", mean_diff, max_diff, count);*/
return mean_diff > QCONST16(1.f, DB_SHIFT); return mean_diff > GCONST(1.f);
} }
/** Apply window and compute the MDCT for all sub-frames and /** Apply window and compute the MDCT for all sub-frames and
@ -852,8 +852,8 @@ static int alloc_trim_analysis(const CELTMode *m, const celt_norm *X,
logXC2 = MAX16(HALF16(logXC), celt_log2(QCONST32(1.001f, 20)-MULT16_16(minXC, minXC))); logXC2 = MAX16(HALF16(logXC), celt_log2(QCONST32(1.001f, 20)-MULT16_16(minXC, minXC)));
#ifdef FIXED_POINT #ifdef FIXED_POINT
/* Compensate for Q20 vs Q14 input and convert output to Q8 */ /* Compensate for Q20 vs Q14 input and convert output to Q8 */
logXC = PSHR32(logXC-QCONST16(6.f, DB_SHIFT),DB_SHIFT-8); logXC = PSHR32(logXC-QCONST16(6.f, 10),10-8);
logXC2 = PSHR32(logXC2-QCONST16(6.f, DB_SHIFT),DB_SHIFT-8); logXC2 = PSHR32(logXC2-QCONST16(6.f, 10),10-8);
#endif #endif
trim += MAX16(-QCONST16(4.f, 8), MULT16_16_Q15(QCONST16(.75f,15),logXC)); trim += MAX16(-QCONST16(4.f, 8), MULT16_16_Q15(QCONST16(.75f,15),logXC));
@ -869,7 +869,7 @@ static int alloc_trim_analysis(const CELTMode *m, const celt_norm *X,
} while (++c<C); } while (++c<C);
diff /= C*(end-1); diff /= C*(end-1);
/*printf("%f\n", diff);*/ /*printf("%f\n", diff);*/
trim -= MAX32(-QCONST16(2.f, 8), MIN32(QCONST16(2.f, 8), SHR32(diff+QCONST16(1.f, DB_SHIFT),DB_SHIFT-8)/6 )); trim -= MAX32(-QCONST16(2.f, 8), MIN32(QCONST16(2.f, 8), SHR32(diff+GCONST(1.f),DB_SHIFT-8)/6 ));
trim -= SHR16(surround_trim, DB_SHIFT-8); trim -= SHR16(surround_trim, DB_SHIFT-8);
trim -= 2*SHR16(tf_estimate, 14-8); trim -= 2*SHR16(tf_estimate, 14-8);
#ifndef DISABLE_FLOAT_API #ifndef DISABLE_FLOAT_API
@ -956,14 +956,14 @@ static celt_glog median_of_5(const celt_glog *x)
if (t2 > t1) if (t2 > t1)
{ {
if (t1 < t3) if (t1 < t3)
return MIN16(t2, t3); return MING(t2, t3);
else else
return MIN16(t4, t1); return MING(t4, t1);
} else { } else {
if (t2 < t3) if (t2 < t3)
return MIN16(t1, t3); return MING(t1, t3);
else else
return MIN16(t2, t4); return MING(t2, t4);
} }
} }
@ -1005,19 +1005,19 @@ static celt_glog dynalloc_analysis(const celt_glog *bandLogE, const celt_glog *b
ALLOC(bandLogE3, nbEBands, celt_glog); ALLOC(bandLogE3, nbEBands, celt_glog);
OPUS_CLEAR(offsets, nbEBands); OPUS_CLEAR(offsets, nbEBands);
/* Dynamic allocation code */ /* Dynamic allocation code */
maxDepth=-QCONST16(31.9f, DB_SHIFT); maxDepth=-GCONST(31.9f);
for (i=0;i<end;i++) for (i=0;i<end;i++)
{ {
/* Noise floor must take into account eMeans, the depth, the width of the bands /* Noise floor must take into account eMeans, the depth, the width of the bands
and the preemphasis filter (approx. square of bark band ID) */ and the preemphasis filter (approx. square of bark band ID) */
noise_floor[i] = MULT16_16(QCONST16(0.0625f, DB_SHIFT),logN[i]) noise_floor[i] = MULT16_16(GCONST(0.0625f),logN[i])
+QCONST16(.5f,DB_SHIFT)+SHL16(9-lsb_depth,DB_SHIFT)-SHL16(eMeans[i],DB_SHIFT-4) +GCONST(.5f)+SHL16(9-lsb_depth,DB_SHIFT)-SHL16(eMeans[i],DB_SHIFT-4)
+MULT16_16(QCONST16(.0062,DB_SHIFT),(i+5)*(i+5)); +MULT16_16(GCONST(.0062),(i+5)*(i+5));
} }
c=0;do c=0;do
{ {
for (i=0;i<end;i++) for (i=0;i<end;i++)
maxDepth = MAX16(maxDepth, bandLogE[c*nbEBands+i]-noise_floor[i]); maxDepth = MAXG(maxDepth, bandLogE[c*nbEBands+i]-noise_floor[i]);
} while (++c<C); } while (++c<C);
{ {
/* Compute a really simple masking model to avoid taking into account completely masked /* Compute a really simple masking model to avoid taking into account completely masked
@ -1031,21 +1031,21 @@ static celt_glog dynalloc_analysis(const celt_glog *bandLogE, const celt_glog *b
if (C==2) if (C==2)
{ {
for (i=0;i<end;i++) for (i=0;i<end;i++)
mask[i] = MAX16(mask[i], bandLogE[nbEBands+i]-noise_floor[i]); mask[i] = MAXG(mask[i], bandLogE[nbEBands+i]-noise_floor[i]);
} }
OPUS_COPY(sig, mask, end); OPUS_COPY(sig, mask, end);
for (i=1;i<end;i++) for (i=1;i<end;i++)
mask[i] = MAX16(mask[i], mask[i-1] - QCONST16(2.f, DB_SHIFT)); mask[i] = MAXG(mask[i], mask[i-1] - GCONST(2.f));
for (i=end-2;i>=0;i--) for (i=end-2;i>=0;i--)
mask[i] = MAX16(mask[i], mask[i+1] - QCONST16(3.f, DB_SHIFT)); mask[i] = MAXG(mask[i], mask[i+1] - GCONST(3.f));
for (i=0;i<end;i++) for (i=0;i<end;i++)
{ {
/* Compute SMR: Mask is never more than 72 dB below the peak and never below the noise floor.*/ /* Compute SMR: Mask is never more than 72 dB below the peak and never below the noise floor.*/
celt_glog smr = sig[i]-MAX16(MAX16(0, maxDepth-QCONST16(12.f, DB_SHIFT)), mask[i]); celt_glog smr = sig[i]-MAXG(MAXG(0, maxDepth-GCONST(12.f)), mask[i]);
/* Clamp SMR to make sure we're not shifting by something negative or too large. */ /* Clamp SMR to make sure we're not shifting by something negative or too large. */
#ifdef FIXED_POINT #ifdef FIXED_POINT
/* FIXME: Use PSHR16() instead */ /* FIXME: Use PSHR16() instead */
int shift = -PSHR32(MAX16(-QCONST16(5.f, DB_SHIFT), MIN16(0, smr)), DB_SHIFT); int shift = -PSHR32(MAXG(-GCONST(5.f), MING(0, smr)), DB_SHIFT);
#else #else
int shift = IMIN(5, IMAX(0, -(int)floor(.5f + smr))); int shift = IMIN(5, IMAX(0, -(int)floor(.5f + smr)));
#endif #endif
@ -1072,7 +1072,7 @@ static celt_glog dynalloc_analysis(const celt_glog *bandLogE, const celt_glog *b
energy is highly unreliable (high variance). For that reason, energy is highly unreliable (high variance). For that reason,
we take the max with the previous energy so that at least 2 bins we take the max with the previous energy so that at least 2 bins
are getting used. */ are getting used. */
for (i=0;i<IMIN(8,end);i++) bandLogE3[i] = MAX16(bandLogE2[c*nbEBands+i], oldBandE[c*nbEBands+i]); for (i=0;i<IMIN(8,end);i++) bandLogE3[i] = MAXG(bandLogE2[c*nbEBands+i], oldBandE[c*nbEBands+i]);
} }
f = &follower[c*nbEBands]; f = &follower[c*nbEBands];
f[0] = bandLogE3[0]; f[0] = bandLogE3[0];
@ -1081,66 +1081,66 @@ static celt_glog dynalloc_analysis(const celt_glog *bandLogE, const celt_glog *b
/* The last band to be at least 3 dB higher than the previous one /* The last band to be at least 3 dB higher than the previous one
is the last we'll consider. Otherwise, we run into problems on is the last we'll consider. Otherwise, we run into problems on
bandlimited signals. */ bandlimited signals. */
if (bandLogE3[i] > bandLogE3[i-1]+QCONST16(.5f,DB_SHIFT)) if (bandLogE3[i] > bandLogE3[i-1]+GCONST(.5f))
last=i; last=i;
f[i] = MIN16(f[i-1]+QCONST16(1.5f,DB_SHIFT), bandLogE3[i]); f[i] = MING(f[i-1]+GCONST(1.5f), bandLogE3[i]);
} }
for (i=last-1;i>=0;i--) for (i=last-1;i>=0;i--)
f[i] = MIN16(f[i], MIN16(f[i+1]+QCONST16(2.f,DB_SHIFT), bandLogE3[i])); f[i] = MING(f[i], MING(f[i+1]+GCONST(2.f), bandLogE3[i]));
/* Combine with a median filter to avoid dynalloc triggering unnecessarily. /* Combine with a median filter to avoid dynalloc triggering unnecessarily.
The "offset" value controls how conservative we are -- a higher offset The "offset" value controls how conservative we are -- a higher offset
reduces the impact of the median filter and makes dynalloc use more bits. */ reduces the impact of the median filter and makes dynalloc use more bits. */
offset = QCONST16(1.f, DB_SHIFT); offset = GCONST(1.f);
for (i=2;i<end-2;i++) for (i=2;i<end-2;i++)
f[i] = MAX16(f[i], median_of_5(&bandLogE3[i-2])-offset); f[i] = MAXG(f[i], median_of_5(&bandLogE3[i-2])-offset);
tmp = median_of_3(&bandLogE3[0])-offset; tmp = median_of_3(&bandLogE3[0])-offset;
f[0] = MAX16(f[0], tmp); f[0] = MAXG(f[0], tmp);
f[1] = MAX16(f[1], tmp); f[1] = MAXG(f[1], tmp);
tmp = median_of_3(&bandLogE3[end-3])-offset; tmp = median_of_3(&bandLogE3[end-3])-offset;
f[end-2] = MAX16(f[end-2], tmp); f[end-2] = MAXG(f[end-2], tmp);
f[end-1] = MAX16(f[end-1], tmp); f[end-1] = MAXG(f[end-1], tmp);
for (i=0;i<end;i++) for (i=0;i<end;i++)
f[i] = MAX16(f[i], noise_floor[i]); f[i] = MAXG(f[i], noise_floor[i]);
} while (++c<C); } while (++c<C);
if (C==2) if (C==2)
{ {
for (i=start;i<end;i++) for (i=start;i<end;i++)
{ {
/* Consider 24 dB "cross-talk" */ /* Consider 24 dB "cross-talk" */
follower[nbEBands+i] = MAX16(follower[nbEBands+i], follower[ i]-QCONST16(4.f,DB_SHIFT)); follower[nbEBands+i] = MAXG(follower[nbEBands+i], follower[ i]-GCONST(4.f));
follower[ i] = MAX16(follower[ i], follower[nbEBands+i]-QCONST16(4.f,DB_SHIFT)); follower[ i] = MAXG(follower[ i], follower[nbEBands+i]-GCONST(4.f));
follower[i] = HALF16(MAX16(0, bandLogE[i]-follower[i]) + MAX16(0, bandLogE[nbEBands+i]-follower[nbEBands+i])); follower[i] = HALF16(MAXG(0, bandLogE[i]-follower[i]) + MAXG(0, bandLogE[nbEBands+i]-follower[nbEBands+i]));
} }
} else { } else {
for (i=start;i<end;i++) for (i=start;i<end;i++)
{ {
follower[i] = MAX16(0, bandLogE[i]-follower[i]); follower[i] = MAXG(0, bandLogE[i]-follower[i]);
} }
} }
for (i=start;i<end;i++) for (i=start;i<end;i++)
follower[i] = MAX16(follower[i], surround_dynalloc[i]); follower[i] = MAXG(follower[i], surround_dynalloc[i]);
for (i=start;i<end;i++) for (i=start;i<end;i++)
{ {
#ifdef FIXED_POINT #ifdef FIXED_POINT
importance[i] = PSHR32(13*celt_exp2(MIN16(follower[i], QCONST16(4.f, DB_SHIFT))), 16); importance[i] = PSHR32(13*celt_exp2(MING(follower[i], GCONST(4.f))), 16);
#else #else
importance[i] = (int)floor(.5f+13*celt_exp2(MIN16(follower[i], QCONST16(4.f, DB_SHIFT)))); importance[i] = (int)floor(.5f+13*celt_exp2(MING(follower[i], GCONST(4.f))));
#endif #endif
} }
/* For non-transient CBR/CVBR frames, halve the dynalloc contribution */ /* For non-transient CBR/CVBR frames, halve the dynalloc contribution */
if ((!vbr || constrained_vbr)&&!isTransient) if ((!vbr || constrained_vbr)&&!isTransient)
{ {
for (i=start;i<end;i++) for (i=start;i<end;i++)
follower[i] = HALF16(follower[i]); follower[i] = HALF32(follower[i]);
} }
for (i=start;i<end;i++) for (i=start;i<end;i++)
{ {
if (i<8) if (i<8)
follower[i] *= 2; follower[i] *= 2;
if (i>=12) if (i>=12)
follower[i] = HALF16(follower[i]); follower[i] = HALF32(follower[i]);
} }
/* Compensate for Opus' under-allocation on tones. */ /* Compensate for Opus' under-allocation on tones. */
if (toneishness > QCONST32(.98f, 29)) { if (toneishness > QCONST32(.98f, 29)) {
@ -1150,10 +1150,10 @@ static celt_glog dynalloc_analysis(const celt_glog *bandLogE, const celt_glog *b
int freq_bin = (int)floor(.5 + tone_freq*120/M_PI); int freq_bin = (int)floor(.5 + tone_freq*120/M_PI);
#endif #endif
for (i=start;i<end;i++) { for (i=start;i<end;i++) {
if (freq_bin >= eBands[i] && freq_bin <= eBands[i+1]) follower[i] += QCONST16(2., DB_SHIFT); if (freq_bin >= eBands[i] && freq_bin <= eBands[i+1]) follower[i] += GCONST(2.f);
if (freq_bin >= eBands[i]-1 && freq_bin <= eBands[i+1]+1) follower[i] += QCONST16(1., DB_SHIFT); if (freq_bin >= eBands[i]-1 && freq_bin <= eBands[i+1]+1) follower[i] += GCONST(1.f);
if (freq_bin >= eBands[i]-2 && freq_bin <= eBands[i+1]+2) follower[i] += QCONST16(1., DB_SHIFT); if (freq_bin >= eBands[i]-2 && freq_bin <= eBands[i+1]+2) follower[i] += GCONST(1.f);
if (freq_bin >= eBands[i]-3 && freq_bin <= eBands[i+1]+3) follower[i] += QCONST16(.5, DB_SHIFT); if (freq_bin >= eBands[i]-3 && freq_bin <= eBands[i+1]+3) follower[i] += GCONST(.5f);
} }
} }
#ifdef DISABLE_FLOAT_API #ifdef DISABLE_FLOAT_API
@ -1162,7 +1162,7 @@ static celt_glog dynalloc_analysis(const celt_glog *bandLogE, const celt_glog *b
if (analysis->valid) if (analysis->valid)
{ {
for (i=start;i<IMIN(LEAK_BANDS, end);i++) for (i=start;i<IMIN(LEAK_BANDS, end);i++)
follower[i] = follower[i] + QCONST16(1.f/64.f, DB_SHIFT)*analysis->leak_boost[i]; follower[i] = follower[i] + GCONST(1.f/64.f)*analysis->leak_boost[i];
} }
#endif #endif
for (i=start;i<end;i++) for (i=start;i<end;i++)
@ -1171,7 +1171,7 @@ static celt_glog dynalloc_analysis(const celt_glog *bandLogE, const celt_glog *b
int boost; int boost;
int boost_bits; int boost_bits;
follower[i] = MIN16(follower[i], QCONST16(4, DB_SHIFT)); follower[i] = MING(follower[i], GCONST(4));
width = C*(eBands[i+1]-eBands[i])<<LM; width = C*(eBands[i+1]-eBands[i])<<LM;
if (width<6) if (width<6)
@ -1920,7 +1920,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_res * pcm, in
for (c=0;c<C;c++) for (c=0;c<C;c++)
{ {
for (i=0;i<end;i++) for (i=0;i<end;i++)
bandLogE2[nbEBands*c+i] += HALF16(SHL16(LM, DB_SHIFT)); bandLogE2[nbEBands*c+i] += HALF32(SHL32(LM, DB_SHIFT));
} }
} }
@ -1959,10 +1959,10 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_res * pcm, in
for(i=0;i<mask_end;i++) for(i=0;i<mask_end;i++)
{ {
celt_glog mask; celt_glog mask;
mask = MAX16(MIN16(st->energy_mask[nbEBands*c+i], mask = MAXG(MING(st->energy_mask[nbEBands*c+i],
QCONST16(.25f, DB_SHIFT)), -QCONST16(2.0f, DB_SHIFT)); GCONST(.25f)), -GCONST(2.0f));
if (mask > 0) if (mask > 0)
mask = HALF16(mask); mask = HALF32(mask);
mask_avg += MULT16_16(mask, eBands[i+1]-eBands[i]); mask_avg += MULT16_16(mask, eBands[i+1]-eBands[i]);
count += eBands[i+1]-eBands[i]; count += eBands[i+1]-eBands[i];
diff += MULT16_16(mask, 1+2*i-mask_end); diff += MULT16_16(mask, 1+2*i-mask_end);
@ -1970,11 +1970,11 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_res * pcm, in
} }
celt_assert(count>0); celt_assert(count>0);
mask_avg = DIV32_16(mask_avg,count); mask_avg = DIV32_16(mask_avg,count);
mask_avg += QCONST16(.2f, DB_SHIFT); mask_avg += GCONST(.2f);
diff = diff*6/(C*(mask_end-1)*(mask_end+1)*mask_end); diff = diff*6/(C*(mask_end-1)*(mask_end+1)*mask_end);
/* Again, being conservative */ /* Again, being conservative */
diff = HALF32(diff); diff = HALF32(diff);
diff = MAX32(MIN32(diff, QCONST32(.031f, DB_SHIFT)), -QCONST32(.031f, DB_SHIFT)); diff = MAX32(MIN32(diff, GCONST(.031f)), -GCONST(.031f));
/* Find the band that's in the middle of the coded spectrum */ /* Find the band that's in the middle of the coded spectrum */
for (midband=0;eBands[midband+1] < eBands[mask_end]/2;midband++); for (midband=0;eBands[midband+1] < eBands[mask_end]/2;midband++);
count_dynalloc=0; count_dynalloc=0;
@ -1984,14 +1984,14 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_res * pcm, in
celt_glog unmask; celt_glog unmask;
lin = mask_avg + diff*(i-midband); lin = mask_avg + diff*(i-midband);
if (C==2) if (C==2)
unmask = MAX16(st->energy_mask[i], st->energy_mask[nbEBands+i]); unmask = MAXG(st->energy_mask[i], st->energy_mask[nbEBands+i]);
else else
unmask = st->energy_mask[i]; unmask = st->energy_mask[i];
unmask = MIN16(unmask, QCONST16(.0f, DB_SHIFT)); unmask = MING(unmask, GCONST(.0f));
unmask -= lin; unmask -= lin;
if (unmask > QCONST16(.25f, DB_SHIFT)) if (unmask > GCONST(.25f))
{ {
surround_dynalloc[i] = unmask - QCONST16(.25f, DB_SHIFT); surround_dynalloc[i] = unmask - GCONST(.25f);
count_dynalloc++; count_dynalloc++;
} }
} }
@ -1999,7 +1999,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_res * pcm, in
{ {
/* If we need dynalloc in many bands, it's probably because our /* If we need dynalloc in many bands, it's probably because our
initial masking rate was too low. */ initial masking rate was too low. */
mask_avg += QCONST16(.25f, DB_SHIFT); mask_avg += GCONST(.25f);
if (mask_avg>0) if (mask_avg>0)
{ {
/* Something went really wrong in the original calculations, /* Something went really wrong in the original calculations,
@ -2009,10 +2009,10 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_res * pcm, in
OPUS_CLEAR(surround_dynalloc, mask_end); OPUS_CLEAR(surround_dynalloc, mask_end);
} else { } else {
for(i=0;i<mask_end;i++) for(i=0;i<mask_end;i++)
surround_dynalloc[i] = MAX16(0, surround_dynalloc[i]-QCONST16(.25f, DB_SHIFT)); surround_dynalloc[i] = MAXG(0, surround_dynalloc[i]-GCONST(.25f));
} }
} }
mask_avg += QCONST16(.2f, DB_SHIFT); mask_avg += GCONST(.2f);
/* Convert to 1/64th units used for the trim */ /* Convert to 1/64th units used for the trim */
surround_trim = 64*diff; surround_trim = 64*diff;
/*printf("%d %d ", mask_avg, surround_trim);*/ /*printf("%d %d ", mask_avg, surround_trim);*/
@ -2021,19 +2021,19 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_res * pcm, in
/* Temporal VBR (but not for LFE) */ /* Temporal VBR (but not for LFE) */
if (!st->lfe) if (!st->lfe)
{ {
celt_glog follow=-QCONST16(10.0f,DB_SHIFT); celt_glog follow=-GCONST(10.0f);
opus_val32 frame_avg=0; opus_val32 frame_avg=0;
celt_glog offset = shortBlocks?HALF16(SHL16(LM, DB_SHIFT)):0; celt_glog offset = shortBlocks?HALF32(SHL32(LM, DB_SHIFT)):0;
for(i=start;i<end;i++) for(i=start;i<end;i++)
{ {
follow = MAX16(follow-QCONST16(1.f, DB_SHIFT), bandLogE[i]-offset); follow = MAXG(follow-GCONST(1.f), bandLogE[i]-offset);
if (C==2) if (C==2)
follow = MAX16(follow, bandLogE[i+nbEBands]-offset); follow = MAXG(follow, bandLogE[i+nbEBands]-offset);
frame_avg += follow; frame_avg += follow;
} }
frame_avg /= (end-start); frame_avg /= (end-start);
temporal_vbr = SUB16(frame_avg,st->spec_avg); temporal_vbr = SUB16(frame_avg,st->spec_avg);
temporal_vbr = MIN16(QCONST16(3.f, DB_SHIFT), MAX16(-QCONST16(1.5f, DB_SHIFT), temporal_vbr)); temporal_vbr = MING(GCONST(3.f), MAXG(-GCONST(1.5f), temporal_vbr));
st->spec_avg += MULT16_16_Q15(QCONST16(.02f, 15), temporal_vbr); st->spec_avg += MULT16_16_Q15(QCONST16(.02f, 15), temporal_vbr);
} }
/*for (i=0;i<21;i++) /*for (i=0;i<21;i++)
@ -2060,7 +2060,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_res * pcm, in
for (c=0;c<C;c++) for (c=0;c<C;c++)
{ {
for (i=0;i<end;i++) for (i=0;i<end;i++)
bandLogE2[nbEBands*c+i] += HALF16(SHL16(LM, DB_SHIFT)); bandLogE2[nbEBands*c+i] += HALF32(SHL32(LM, DB_SHIFT));
} }
tf_estimate = QCONST16(.2f,14); tf_estimate = QCONST16(.2f,14);
} }
@ -2121,7 +2121,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_res * pcm, in
/* When the energy is stable, slightly bias energy quantization towards /* When the energy is stable, slightly bias energy quantization towards
the previous error to make the gain more stable (a constant offset is the previous error to make the gain more stable (a constant offset is
better than fluctuations). */ better than fluctuations). */
if (ABS32(SUB32(bandLogE[i+c*nbEBands], oldBandE[i+c*nbEBands])) < QCONST16(2.f, DB_SHIFT)) if (ABS32(SUB32(bandLogE[i+c*nbEBands], oldBandE[i+c*nbEBands])) < GCONST(2.f))
{ {
bandLogE[i+c*nbEBands] -= MULT16_16_Q15(energyError[i+c*nbEBands], QCONST16(0.25f, 15)); bandLogE[i+c*nbEBands] -= MULT16_16_Q15(energyError[i+c*nbEBands], QCONST16(0.25f, 15));
} }
@ -2428,14 +2428,14 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_res * pcm, in
do { do {
for (i=start;i<end;i++) for (i=start;i<end;i++)
{ {
energyError[i+c*nbEBands] = MAX16(-QCONST16(0.5f, 15), MIN16(QCONST16(0.5f, 15), error[i+c*nbEBands])); energyError[i+c*nbEBands] = MAXG(-GCONST(0.5f), MING(GCONST(0.5f), error[i+c*nbEBands]));
} }
} while (++c < C); } while (++c < C);
if (silence) if (silence)
{ {
for (i=0;i<C*nbEBands;i++) for (i=0;i<C*nbEBands;i++)
oldBandE[i] = -QCONST16(28.f,DB_SHIFT); oldBandE[i] = -GCONST(28.f);
} }
#ifdef RESYNTH #ifdef RESYNTH
@ -2502,7 +2502,7 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_res * pcm, in
OPUS_COPY(oldLogE, oldBandE, CC*nbEBands); OPUS_COPY(oldLogE, oldBandE, CC*nbEBands);
} else { } else {
for (i=0;i<CC*nbEBands;i++) for (i=0;i<CC*nbEBands;i++)
oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]); oldLogE[i] = MING(oldLogE[i], oldBandE[i]);
} }
/* In case start or end were to change */ /* In case start or end were to change */
c=0; do c=0; do
@ -2510,12 +2510,12 @@ int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_res * pcm, in
for (i=0;i<start;i++) for (i=0;i<start;i++)
{ {
oldBandE[c*nbEBands+i]=0; oldBandE[c*nbEBands+i]=0;
oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-QCONST16(28.f,DB_SHIFT); oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-GCONST(28.f);
} }
for (i=end;i<nbEBands;i++) for (i=end;i<nbEBands;i++)
{ {
oldBandE[c*nbEBands+i]=0; oldBandE[c*nbEBands+i]=0;
oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-QCONST16(28.f,DB_SHIFT); oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-GCONST(28.f);
} }
} while (++c<CC); } while (++c<CC);
@ -2770,7 +2770,7 @@ int opus_custom_encoder_ctl(CELTEncoder * OPUS_RESTRICT st, int request, ...)
opus_custom_encoder_get_size(st->mode, st->channels)- opus_custom_encoder_get_size(st->mode, st->channels)-
((char*)&st->ENCODER_RESET_START - (char*)st)); ((char*)&st->ENCODER_RESET_START - (char*)st));
for (i=0;i<st->channels*st->mode->nbEBands;i++) for (i=0;i<st->channels*st->mode->nbEBands;i++)
oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT); oldLogE[i]=oldLogE2[i]=-GCONST(28.f);
st->vbr_offset = 0; st->vbr_offset = 0;
st->delayedIntra = 1; st->delayedIntra = 1;
st->spread_decision = SPREAD_NORMAL; st->spread_decision = SPREAD_NORMAL;

View file

@ -51,6 +51,8 @@ extern opus_int64 celt_mips;
#define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits)))) #define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits))))
#define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val32)1)<<(bits)))) #define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val32)1)<<(bits))))
#define GCONST2(x,bits) ((celt_glog)(.5+(x)*(((celt_glog)1)<<(bits))))
#define GCONST(x) GCONST2((x),DB_SHIFT)
#define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768) #define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768)
#define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL) #define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL)

View file

@ -77,6 +77,12 @@
/** Compile-time conversion of float constant to 32-bit value */ /** Compile-time conversion of float constant to 32-bit value */
#define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val32)1)<<(bits)))) #define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val32)1)<<(bits))))
/** Compile-time conversion of float constant to log gain value */
#define GCONST2(x,bits) ((celt_glog)(.5+(x)*(((celt_glog)1)<<(bits))))
/** Compile-time conversion of float constant to DB_SHFIT log gain value */
#define GCONST(x) GCONST2((x),DB_SHIFT)
/** Negate a 16-bit value */ /** Negate a 16-bit value */
#define NEG16(x) (-(x)) #define NEG16(x) (-(x))
/** Negate a 32-bit value */ /** Negate a 32-bit value */

View file

@ -146,7 +146,7 @@ static opus_val32 loss_distortion(const celt_glog *eBands, celt_glog *oldEBands,
c=0; do { c=0; do {
for (i=start;i<end;i++) for (i=start;i<end;i++)
{ {
celt_glog d = SUB16(SHR16(eBands[i+c*len], 3), SHR16(oldEBands[i+c*len], 3)); celt_glog d = SUB32(SHR32(eBands[i+c*len], 3), SHR32(oldEBands[i+c*len], 3));
dist = MAC16_16(dist, d,d); dist = MAC16_16(dist, d,d);
} }
} while (++c<C); } while (++c<C);
@ -189,24 +189,24 @@ static int quant_coarse_energy_impl(const CELTMode *m, int start, int end,
celt_glog oldE; celt_glog oldE;
celt_glog decay_bound; celt_glog decay_bound;
x = eBands[i+c*m->nbEBands]; x = eBands[i+c*m->nbEBands];
oldE = MAX16(-QCONST16(9.f,DB_SHIFT), oldEBands[i+c*m->nbEBands]); oldE = MAXG(-GCONST(9.f), oldEBands[i+c*m->nbEBands]);
#ifdef FIXED_POINT #ifdef FIXED_POINT
f = SHL32(EXTEND32(x),7) - PSHR32(MULT16_16(coef,oldE), 8) - prev[c]; f = SHL32(EXTEND32(x),7) - PSHR32(MULT16_16(coef,oldE), 8) - prev[c];
/* Rounding to nearest integer here is really important! */ /* Rounding to nearest integer here is really important! */
qi = (f+QCONST32(.5f,DB_SHIFT+7))>>(DB_SHIFT+7); qi = (f+QCONST32(.5f,DB_SHIFT+7))>>(DB_SHIFT+7);
decay_bound = EXTRACT16(MAX32(-QCONST16(28.f,DB_SHIFT), decay_bound = EXTRACT16(MAX32(-GCONST(28.f),
SUB32((opus_val32)oldEBands[i+c*m->nbEBands],max_decay))); SUB32((opus_val32)oldEBands[i+c*m->nbEBands],max_decay)));
#else #else
f = x-coef*oldE-prev[c]; f = x-coef*oldE-prev[c];
/* Rounding to nearest integer here is really important! */ /* Rounding to nearest integer here is really important! */
qi = (int)floor(.5f+f); qi = (int)floor(.5f+f);
decay_bound = MAX16(-QCONST16(28.f,DB_SHIFT), oldEBands[i+c*m->nbEBands]) - max_decay; decay_bound = MAXG(-GCONST(28.f), oldEBands[i+c*m->nbEBands]) - max_decay;
#endif #endif
/* Prevent the energy from going down too quickly (e.g. for bands /* Prevent the energy from going down too quickly (e.g. for bands
that have just one bin) */ that have just one bin) */
if (qi < 0 && x < decay_bound) if (qi < 0 && x < decay_bound)
{ {
qi += (int)SHR16(SUB16(decay_bound,x), DB_SHIFT); qi += (int)SHR32(SUB32(decay_bound,x), DB_SHIFT);
if (qi > 0) if (qi > 0)
qi = 0; qi = 0;
} }
@ -243,7 +243,7 @@ static int quant_coarse_energy_impl(const CELTMode *m, int start, int end,
} }
else else
qi = -1; qi = -1;
error[i+c*m->nbEBands] = PSHR32(f,7) - SHL16(qi,DB_SHIFT); error[i+c*m->nbEBands] = PSHR32(f,7) - SHL32(qi,DB_SHIFT);
badness += abs(qi0-qi); badness += abs(qi0-qi);
q = (opus_val32)SHL32(EXTEND32(qi),DB_SHIFT); q = (opus_val32)SHL32(EXTEND32(qi),DB_SHIFT);
@ -282,7 +282,7 @@ void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd,
if (tell+3 > budget) if (tell+3 > budget)
two_pass = intra = 0; two_pass = intra = 0;
max_decay = QCONST16(16.f,DB_SHIFT); max_decay = GCONST(16.f);
if (end-start>10) if (end-start>10)
{ {
#ifdef FIXED_POINT #ifdef FIXED_POINT
@ -292,7 +292,7 @@ void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd,
#endif #endif
} }
if (lfe) if (lfe)
max_decay = QCONST16(3.f,DB_SHIFT); max_decay = GCONST(3.f);
enc_start_state = *enc; enc_start_state = *enc;
ALLOC(oldEBands_intra, C*m->nbEBands, celt_glog); ALLOC(oldEBands_intra, C*m->nbEBands, celt_glog);
@ -374,7 +374,7 @@ void quant_fine_energy(const CELTMode *m, int start, int end, celt_glog *oldEBan
celt_glog offset; celt_glog offset;
#ifdef FIXED_POINT #ifdef FIXED_POINT
/* Has to be without rounding */ /* Has to be without rounding */
q2 = (error[i+c*m->nbEBands]+QCONST16(.5f,DB_SHIFT))>>(DB_SHIFT-fine_quant[i]); q2 = (error[i+c*m->nbEBands]+GCONST(.5f))>>(DB_SHIFT-fine_quant[i]);
#else #else
q2 = (int)floor((error[i+c*m->nbEBands]+.5f)*frac); q2 = (int)floor((error[i+c*m->nbEBands]+.5f)*frac);
#endif #endif
@ -384,7 +384,7 @@ void quant_fine_energy(const CELTMode *m, int start, int end, celt_glog *oldEBan
q2 = 0; q2 = 0;
ec_enc_bits(enc, q2, fine_quant[i]); ec_enc_bits(enc, q2, fine_quant[i]);
#ifdef FIXED_POINT #ifdef FIXED_POINT
offset = SUB16(SHR32(SHL32(EXTEND32(q2),DB_SHIFT)+QCONST16(.5f,DB_SHIFT),fine_quant[i]),QCONST16(.5f,DB_SHIFT)); offset = SUB32(SHR32(SHL32(EXTEND32(q2),DB_SHIFT)+GCONST(.5f),fine_quant[i]),GCONST(.5f));
#else #else
offset = (q2+.5f)*(1<<(14-fine_quant[i]))*(1.f/16384) - .5f; offset = (q2+.5f)*(1<<(14-fine_quant[i]))*(1.f/16384) - .5f;
#endif #endif
@ -413,7 +413,7 @@ void quant_energy_finalise(const CELTMode *m, int start, int end, celt_glog *old
q2 = error[i+c*m->nbEBands]<0 ? 0 : 1; q2 = error[i+c*m->nbEBands]<0 ? 0 : 1;
ec_enc_bits(enc, q2, 1); ec_enc_bits(enc, q2, 1);
#ifdef FIXED_POINT #ifdef FIXED_POINT
offset = SHR16(SHL16(q2,DB_SHIFT)-QCONST16(.5f,DB_SHIFT),fine_quant[i]+1); offset = SHR32(SHL32(q2,DB_SHIFT)-GCONST(.5f),fine_quant[i]+1);
#else #else
offset = (q2-.5f)*(1<<(14-fine_quant[i]-1))*(1.f/16384); offset = (q2-.5f)*(1<<(14-fine_quant[i]-1))*(1.f/16384);
#endif #endif
@ -479,7 +479,7 @@ void unquant_coarse_energy(const CELTMode *m, int start, int end, celt_glog *old
qi = -1; qi = -1;
q = (opus_val32)SHL32(EXTEND32(qi),DB_SHIFT); q = (opus_val32)SHL32(EXTEND32(qi),DB_SHIFT);
oldEBands[i+c*m->nbEBands] = MAX16(-QCONST16(9.f,DB_SHIFT), oldEBands[i+c*m->nbEBands]); oldEBands[i+c*m->nbEBands] = MAXG(-GCONST(9.f), oldEBands[i+c*m->nbEBands]);
tmp = PSHR32(MULT16_16(coef,oldEBands[i+c*m->nbEBands]),8) + prev[c] + SHL32(q,7); tmp = PSHR32(MULT16_16(coef,oldEBands[i+c*m->nbEBands]),8) + prev[c] + SHL32(q,7);
#ifdef FIXED_POINT #ifdef FIXED_POINT
tmp = MAX32(-QCONST32(28.f, DB_SHIFT+7), tmp); tmp = MAX32(-QCONST32(28.f, DB_SHIFT+7), tmp);
@ -504,7 +504,7 @@ void unquant_fine_energy(const CELTMode *m, int start, int end, celt_glog *oldEB
celt_glog offset; celt_glog offset;
q2 = ec_dec_bits(dec, fine_quant[i]); q2 = ec_dec_bits(dec, fine_quant[i]);
#ifdef FIXED_POINT #ifdef FIXED_POINT
offset = SUB16(SHR32(SHL32(EXTEND32(q2),DB_SHIFT)+QCONST16(.5f,DB_SHIFT),fine_quant[i]),QCONST16(.5f,DB_SHIFT)); offset = SUB32(SHR32(SHL32(EXTEND32(q2),DB_SHIFT)+GCONST(.5f),fine_quant[i]),GCONST(.5f));
#else #else
offset = (q2+.5f)*(1<<(14-fine_quant[i]))*(1.f/16384) - .5f; offset = (q2+.5f)*(1<<(14-fine_quant[i]))*(1.f/16384) - .5f;
#endif #endif
@ -530,7 +530,7 @@ void unquant_energy_finalise(const CELTMode *m, int start, int end, celt_glog *o
celt_glog offset; celt_glog offset;
q2 = ec_dec_bits(dec, 1); q2 = ec_dec_bits(dec, 1);
#ifdef FIXED_POINT #ifdef FIXED_POINT
offset = SHR16(SHL16(q2,DB_SHIFT)-QCONST16(.5f,DB_SHIFT),fine_quant[i]+1); offset = SHR32(SHL32(q2,DB_SHIFT)-GCONST(.5f),fine_quant[i]+1);
#else #else
offset = (q2-.5f)*(1<<(14-fine_quant[i]-1))*(1.f/16384); offset = (q2-.5f)*(1<<(14-fine_quant[i]-1))*(1.f/16384);
#endif #endif
@ -551,13 +551,13 @@ void amp2Log2(const CELTMode *m, int effEnd, int end,
{ {
bandLogE[i+c*m->nbEBands] = bandLogE[i+c*m->nbEBands] =
celt_log2(bandE[i+c*m->nbEBands]) celt_log2(bandE[i+c*m->nbEBands])
- SHL16((celt_glog)eMeans[i],DB_SHIFT-4); - SHL32((celt_glog)eMeans[i],DB_SHIFT-4);
#ifdef FIXED_POINT #ifdef FIXED_POINT
/* Compensate for bandE[] being Q12 but celt_log2() taking a Q14 input. */ /* Compensate for bandE[] being Q12 but celt_log2() taking a Q14 input. */
bandLogE[i+c*m->nbEBands] += QCONST16(2.f, DB_SHIFT); bandLogE[i+c*m->nbEBands] += GCONST(2.f);
#endif #endif
} }
for (i=effEnd;i<end;i++) for (i=effEnd;i<end;i++)
bandLogE[c*m->nbEBands+i] = -QCONST16(14.f,DB_SHIFT); bandLogE[c*m->nbEBands+i] = -GCONST(14.f);
} while (++c < C); } while (++c < C);
} }

View file

@ -1952,7 +1952,7 @@ static opus_int32 opus_encode_frame_native(OpusEncoder *st, const opus_res *pcm,
if (st->energy_masking && st->use_vbr && !st->lfe) if (st->energy_masking && st->use_vbr && !st->lfe)
{ {
opus_val32 mask_sum=0; opus_val32 mask_sum=0;
opus_val16 masking_depth; celt_glog masking_depth;
opus_int32 rate_offset; opus_int32 rate_offset;
int c; int c;
int end = 17; int end = 17;
@ -1970,17 +1970,17 @@ static opus_int32 opus_encode_frame_native(OpusEncoder *st, const opus_res *pcm,
{ {
for(i=0;i<end;i++) for(i=0;i<end;i++)
{ {
opus_val16 mask; celt_glog mask;
mask = MAX16(MIN16(st->energy_masking[21*c+i], mask = MAXG(MING(st->energy_masking[21*c+i],
QCONST16(.5f, DB_SHIFT)), -QCONST16(2.0f, DB_SHIFT)); GCONST(.5f)), -GCONST(2.0f));
if (mask > 0) if (mask > 0)
mask = HALF16(mask); mask = HALF32(mask);
mask_sum += mask; mask_sum += mask;
} }
} }
/* Conservative rate reduction, we cut the masking in half */ /* Conservative rate reduction, we cut the masking in half */
masking_depth = mask_sum / end*st->channels; masking_depth = mask_sum / end*st->channels;
masking_depth += QCONST16(.2f, DB_SHIFT); masking_depth += GCONST(.2f);
rate_offset = (opus_int32)PSHR32(MULT16_16(srate, masking_depth), DB_SHIFT); rate_offset = (opus_int32)PSHR32(MULT16_16(srate, masking_depth), DB_SHIFT);
rate_offset = MAX32(rate_offset, -2*st->silk_mode.bitRate/3); rate_offset = MAX32(rate_offset, -2*st->silk_mode.bitRate/3);
/* Split the rate change between the SILK and CELT part for hybrid. */ /* Split the rate change between the SILK and CELT part for hybrid. */

View file

@ -184,15 +184,15 @@ static void channel_pos(int channels, int pos[8])
#if 1 #if 1
/* Computes a rough approximation of log2(2^a + 2^b) */ /* Computes a rough approximation of log2(2^a + 2^b) */
static opus_val16 logSum(opus_val16 a, opus_val16 b) static opus_val16 logSum(celt_glog a, celt_glog b)
{ {
opus_val16 max; celt_glog max;
opus_val32 diff; celt_glog diff;
opus_val16 frac; celt_glog frac;
static const opus_val16 diff_table[17] = { static const opus_val16 diff_table[17] = {
QCONST16(0.5000000f, DB_SHIFT), QCONST16(0.2924813f, DB_SHIFT), QCONST16(0.1609640f, DB_SHIFT), QCONST16(0.0849625f, DB_SHIFT), GCONST(0.5000000f), GCONST(0.2924813f), GCONST(0.1609640f), GCONST(0.0849625f),
QCONST16(0.0437314f, DB_SHIFT), QCONST16(0.0221971f, DB_SHIFT), QCONST16(0.0111839f, DB_SHIFT), QCONST16(0.0056136f, DB_SHIFT), GCONST(0.0437314f), GCONST(0.0221971f), GCONST(0.0111839f), GCONST(0.0056136f),
QCONST16(0.0028123f, DB_SHIFT) GCONST(0.0028123f)
}; };
int low; int low;
if (a>b) if (a>b)
@ -203,16 +203,16 @@ static opus_val16 logSum(opus_val16 a, opus_val16 b)
max = b; max = b;
diff = SUB32(EXTEND32(b),EXTEND32(a)); diff = SUB32(EXTEND32(b),EXTEND32(a));
} }
if (!(diff < QCONST16(8.f, DB_SHIFT))) /* inverted to catch NaNs */ if (!(diff < GCONST(8.f))) /* inverted to catch NaNs */
return max; return max;
#ifdef FIXED_POINT #ifdef FIXED_POINT
low = SHR32(diff, DB_SHIFT-1); low = SHR32(diff, DB_SHIFT-1);
frac = SHL16(diff - SHL16(low, DB_SHIFT-1), 16-DB_SHIFT); frac = SHL32(diff - SHL32(low, DB_SHIFT-1), 16-DB_SHIFT);
#else #else
low = (int)floor(2*diff); low = (int)floor(2*diff);
frac = 2*diff - low; frac = 2*diff - low;
#endif #endif
return max + diff_table[low] + MULT16_16_Q15(frac, SUB16(diff_table[low+1], diff_table[low])); return max + diff_table[low] + MULT16_16_Q15(frac, SUB32(diff_table[low+1], diff_table[low]));
} }
#else #else
opus_val16 logSum(opus_val16 a, opus_val16 b) opus_val16 logSum(opus_val16 a, opus_val16 b)
@ -257,7 +257,7 @@ void surround_analysis(const CELTMode *celt_mode, const void *pcm, celt_glog *ba
for (c=0;c<3;c++) for (c=0;c<3;c++)
for (i=0;i<21;i++) for (i=0;i<21;i++)
maskLogE[c][i] = -QCONST16(28.f, DB_SHIFT); maskLogE[c][i] = -GCONST(28.f);
for (c=0;c<channels;c++) for (c=0;c<channels;c++)
{ {
@ -303,9 +303,9 @@ void surround_analysis(const CELTMode *celt_mode, const void *pcm, celt_glog *ba
amp2Log2(celt_mode, 21, 21, bandE, bandLogE+21*c, 1); amp2Log2(celt_mode, 21, 21, bandE, bandLogE+21*c, 1);
/* Apply spreading function with -6 dB/band going up and -12 dB/band going down. */ /* Apply spreading function with -6 dB/band going up and -12 dB/band going down. */
for (i=1;i<21;i++) for (i=1;i<21;i++)
bandLogE[21*c+i] = MAX16(bandLogE[21*c+i], bandLogE[21*c+i-1]-QCONST16(1.f, DB_SHIFT)); bandLogE[21*c+i] = MAXG(bandLogE[21*c+i], bandLogE[21*c+i-1]-GCONST(1.f));
for (i=19;i>=0;i--) for (i=19;i>=0;i--)
bandLogE[21*c+i] = MAX16(bandLogE[21*c+i], bandLogE[21*c+i+1]-QCONST16(2.f, DB_SHIFT)); bandLogE[21*c+i] = MAXG(bandLogE[21*c+i], bandLogE[21*c+i+1]-GCONST(2.f));
if (pos[c]==1) if (pos[c]==1)
{ {
for (i=0;i<21;i++) for (i=0;i<21;i++)
@ -318,8 +318,8 @@ void surround_analysis(const CELTMode *celt_mode, const void *pcm, celt_glog *ba
{ {
for (i=0;i<21;i++) for (i=0;i<21;i++)
{ {
maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]-QCONST16(.5f, DB_SHIFT)); maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]-GCONST(.5f));
maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]-QCONST16(.5f, DB_SHIFT)); maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]-GCONST(.5f));
} }
} }
#if 0 #if 0