New implementation of folding_decision()

This commit is contained in:
Jean-Marc Valin 2010-08-31 14:51:58 -04:00
parent 6f6c88bef1
commit 1d17b9ae67
3 changed files with 52 additions and 55 deletions

View file

@ -245,74 +245,66 @@ static void stereo_band_mix(const CELTMode *m, celt_norm *X, celt_norm *Y, const
} }
/* Decide whether we should spread the pulses in the current frame */ /* Decide whether we should spread the pulses in the current frame */
int folding_decision(const CELTMode *m, celt_norm *X, celt_word16 *average, int *last_decision, int end, int _C, int M) int folding_decision(const CELTMode *m, celt_norm *X, int *average, int *last_decision, int end, int _C, int M)
{ {
int i, c, N0; int i, c, N0;
int NR=0; int sum = 0;
celt_word32 ratio = EPSILON;
const int C = CHANNELS(_C); const int C = CHANNELS(_C);
const celt_int16 * restrict eBands = m->eBands; const celt_int16 * restrict eBands = m->eBands;
int decision;
N0 = M*m->shortMdctSize; N0 = M*m->shortMdctSize;
for (c=0;c<C;c++) for (c=0;c<C;c++)
{ {
for (i=0;i<end;i++) for (i=0;i<end;i++)
{
int j, N;
int max_i=0;
celt_word16 max_val=EPSILON;
celt_word32 floor_ener=EPSILON;
celt_norm * restrict x = X+M*eBands[i]+c*N0;
N = M*eBands[i+1]-M*eBands[i];
for (j=0;j<N;j++)
{ {
if (ABS16(x[j])>max_val) int j, N, tmp=0;
int tcount[3] = {0};
celt_norm * restrict x = X+M*eBands[i]+c*N0;
N = M*eBands[i+1]-M*eBands[i];
/* Compute rough CDF of |x[j]| */
for (j=0;j<N;j++)
{ {
max_val = ABS16(x[j]); celt_word32 x2N; /* Q13 */
max_i = j;
x2N = MULT16_16(MULT16_16_Q15(x[j], x[j]), N);
if (x2N < QCONST16(0.25f,13))
tcount[0]++;
if (x2N < QCONST16(0.0625f,13))
tcount[1]++;
if (x2N < QCONST16(0.015625f,13))
tcount[2]++;
} }
}
#if 0 tmp = (2*tcount[2] >= N) + (2*tcount[1] >= N) + (2*tcount[0] >= N);
for (j=0;j<N;j++) sum += tmp*256;
{
if (abs(j-max_i)>2)
floor_ener += x[j]*x[j];
}
#else
floor_ener = QCONST32(1.f,28)-MULT16_16(max_val,max_val);
if (max_i < N-1)
floor_ener -= MULT16_16(x[(max_i+1)], x[(max_i+1)]);
if (max_i < N-2)
floor_ener -= MULT16_16(x[(max_i+2)], x[(max_i+2)]);
if (max_i > 0)
floor_ener -= MULT16_16(x[(max_i-1)], x[(max_i-1)]);
if (max_i > 1)
floor_ener -= MULT16_16(x[(max_i-2)], x[(max_i-2)]);
floor_ener = MAX32(floor_ener, EPSILON);
#endif
if (N>7)
{
celt_word16 r;
celt_word16 den = celt_sqrt(floor_ener);
den = MAX32(QCONST16(.02f, 15), den);
r = DIV32_16(SHL32(EXTEND32(max_val),8),den);
ratio = ADD32(ratio, EXTEND32(r));
NR++;
} }
} }
} sum /= C*end;
if (NR>0) /* Recursive averaging */
ratio = DIV32_16(ratio, NR); sum = (sum+*average)>>1;
ratio = ADD32(HALF32(ratio), HALF32(*average)); *average = sum;
if (!*last_decision) /* Hysteresis */
sum = (3*sum + ((*last_decision<<7) + 64) + 2)>>2;
/* decision and last_decision do not use the same encoding */
if (sum < 128)
{ {
*last_decision = (ratio < QCONST16(1.8f,8)); decision = 2;
*last_decision = 0;
} else if (sum < 256)
{
decision = 1;
*last_decision = 1;
} else if (sum < 384)
{
decision = 3;
*last_decision = 2;
} else { } else {
*last_decision = (ratio < QCONST16(3.f,8)); decision = 0;
*last_decision = 3;
} }
*average = EXTRACT16(ratio); return decision;
return *last_decision;
} }
#ifdef MEASURE_NORM_MSE #ifdef MEASURE_NORM_MSE

View file

@ -66,7 +66,7 @@ void renormalise_bands(const CELTMode *m, celt_norm * restrict X, int end, int _
*/ */
void denormalise_bands(const CELTMode *m, const celt_norm * restrict X, celt_sig * restrict freq, const celt_ener *bands, int end, int _C, int M); void denormalise_bands(const CELTMode *m, const celt_norm * restrict X, celt_sig * restrict freq, const celt_ener *bands, int end, int _C, int M);
int folding_decision(const CELTMode *m, celt_norm *X, celt_word16 *average, int *last_decision, int end, int _C, int M); int folding_decision(const CELTMode *m, celt_norm *X, int *average, int *last_decision, int end, int _C, int M);
#ifdef MEASURE_NORM_MSE #ifdef MEASURE_NORM_MSE
void measure_norm_mse(const CELTMode *m, float *X, float *X0, float *bandE, float *bandE0, int M, int N, int C); void measure_norm_mse(const CELTMode *m, float *X, float *X0, float *bandE, float *bandE0, int M, int N, int C);

View file

@ -84,7 +84,7 @@ struct CELTEncoder {
celt_word32 frame_max; celt_word32 frame_max;
int fold_decision; int fold_decision;
int delayedIntra; int delayedIntra;
celt_word16 tonal_average; int tonal_average;
/* VBR-related parameters */ /* VBR-related parameters */
celt_int32 vbr_reservoir; celt_int32 vbr_reservoir;
@ -754,8 +754,13 @@ int celt_encode_with_ec_float(CELTEncoder * restrict st, const celt_sig * pcm, c
tf_encode(st->start, st->end, isTransient, tf_res, nbAvailableBytes, LM, tf_select, enc); tf_encode(st->start, st->end, isTransient, tf_res, nbAvailableBytes, LM, tf_select, enc);
if (!shortBlocks && !folding_decision(st->mode, X, &st->tonal_average, &st->fold_decision, effEnd, C, M)) if (shortBlocks)
has_fold = 0; {
has_fold = 1;
st->fold_decision = 1;
} else {
has_fold = folding_decision(st->mode, X, &st->tonal_average, &st->fold_decision, effEnd, C, M);
}
ec_enc_bit_prob(enc, has_fold>>1, 8192); ec_enc_bit_prob(enc, has_fold>>1, 8192);
ec_enc_bit_prob(enc, has_fold&1, (has_fold>>1) ? 32768 : 49152); ec_enc_bit_prob(enc, has_fold&1, (has_fold>>1) ? 32768 : 49152);