ref: 890a9c05e04e3bc837b8544659a5e53e91dcce63
parent: 9a33c5c346c758d430fee33358c3a95b39bd4348
author: Jean-Marc Valin <[email protected]>
date: Sun Jun 13 04:06:28 EDT 2010
Implementing two choices for the tf resolution
--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -931,12 +931,13 @@
} else
lowband = NULL;
- if (shortBlocks)
+ /*if (shortBlocks)
{
tf_change = tf_res[i] ? -1 : 2;
} else {
tf_change = tf_res[i] ? -2 : 0;
- }
+ }*/
+ tf_change = tf_res[i];
quant_band(encode, m, i, X, Y, N, b, spread, tf_change, lowband, resynth, ec, &remaining_bits, LM, norm+M*eBands[i], bandE, 0);
balance += pulses[i] + tell;
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -536,17 +536,25 @@
renormalise_bands(mode, X, C, M);
}
-static void tf_analysis(celt_word16 *bandLogE, celt_word16 *oldBandE, int len, int C, int isTransient, int *tf_res, int nbCompressedBytes)
+static signed char tf_select_table[4][8] = {
+ {0, -1, 0, -1, 0,-1, 0,-1},
+ {0, -1, 0, -2, 1, 0, 1 -1},
+ {0, -2, 0, -3, 2, 0, 1 -1},
+ {0, -2, 0, -3, 2, 0, 1 -1},
+};
+
+static int tf_analysis(celt_word16 *bandLogE, celt_word16 *oldBandE, int len, int C, int isTransient, int *tf_res, int nbCompressedBytes)
{
int i;
celt_word16 threshold;
VARDECL(celt_word32, metric);
+ celt_word32 average=0;
celt_word32 cost0;
celt_word32 cost1;
VARDECL(int, path0);
VARDECL(int, path1);
- /* FIXME: lambda should depend on the bit-rate */
celt_word16 lambda;
+ int tf_select=0;
SAVE_STACK;
if (nbCompressedBytes<40)
@@ -562,16 +570,29 @@
ALLOC(path0, len, int);
ALLOC(path1, len, int);
for (i=0;i<len;i++)
+ {
metric[i] = SUB16(bandLogE[i], oldBandE[i]);
+ average += metric[i];
+ }
if (C==2)
+ {
+ average = 0;
for (i=0;i<len;i++)
+ {
metric[i] = HALF32(metric[i]) + HALF32(SUB16(bandLogE[i+len], oldBandE[i+len]));
-
+ average += metric[i];
+ }
+ }
+ average = DIV32(average, len);
+ /*if (!isTransient)
+ printf ("%f\n", average);*/
if (isTransient)
{
threshold = QCONST16(1.f,DB_SHIFT);
+ tf_select = average > QCONST16(3.f,DB_SHIFT);
} else {
threshold = QCONST16(.5f,DB_SHIFT);
+ tf_select = average > QCONST16(1.f,DB_SHIFT);
}
cost0 = 0;
cost1 = lambda;
@@ -615,9 +636,10 @@
tf_res[i] = path0[i+1];
}
RESTORE_STACK
+ return tf_select;
}
-static void tf_encode(int len, int isTransient, int *tf_res, int nbCompressedBytes, ec_enc *enc)
+static void tf_encode(int len, int isTransient, int *tf_res, int nbCompressedBytes, int LM, int tf_select, ec_enc *enc)
{
int curr, i;
if (8*nbCompressedBytes - ec_enc_tell(enc, 0) < 100)
@@ -633,11 +655,14 @@
curr = tf_res[i];
}
}
+ ec_enc_bits(enc, tf_select, 1);
+ for (i=0;i<len;i++)
+ tf_res[i] = tf_select_table[LM][4*isTransient+2*tf_select+tf_res[i]];
}
-static void tf_decode(int len, int C, int isTransient, int *tf_res, int nbCompressedBytes, ec_dec *dec)
+static void tf_decode(int len, int C, int isTransient, int *tf_res, int nbCompressedBytes, int LM, ec_dec *dec)
{
- int i, curr;
+ int i, curr, tf_select;
if (8*nbCompressedBytes - ec_dec_tell(dec, 0) < 100)
{
for (i=0;i<len;i++)
@@ -651,6 +676,9 @@
curr = tf_res[i];
}
}
+ tf_select = ec_dec_bits(dec, 1);
+ for (i=0;i<len;i++)
+ tf_res[i] = tf_select_table[LM][4*isTransient+2*tf_select+tf_res[i]];
}
#ifdef FIXED_POINT
@@ -692,6 +720,7 @@
int gain_id=0;
int norm_rate;
int LM, M;
+ int tf_select;
celt_int32 vbr_rate=0;
SAVE_STACK;
@@ -921,7 +950,7 @@
}
ALLOC(tf_res, st->mode->nbEBands, int);
- tf_analysis(bandLogE, st->oldBandE, st->mode->nbEBands, C, isTransient, tf_res, nbCompressedBytes);
+ tf_select = tf_analysis(bandLogE, st->oldBandE, st->mode->nbEBands, C, isTransient, tf_res, nbCompressedBytes);
/* Bit allocation */
ALLOC(error, C*st->mode->nbEBands, celt_word16);
@@ -986,7 +1015,7 @@
ec_byte_shrink(&buf, nbCompressedBytes);
}
- tf_encode(st->mode->nbEBands, isTransient, tf_res, nbCompressedBytes, enc);
+ tf_encode(st->mode->nbEBands, isTransient, tf_res, nbCompressedBytes, LM, tf_select, enc);
ALLOC(offsets, st->mode->nbEBands, int);
ALLOC(fine_priority, st->mode->nbEBands, int);
@@ -1715,7 +1744,7 @@
unquant_coarse_energy(st->mode, st->start, bandE, st->oldBandE, len*4-8, intra_ener, st->mode->prob, dec, C);
ALLOC(tf_res, st->mode->nbEBands, int);
- tf_decode(st->mode->nbEBands, C, isTransient, tf_res, len, dec);
+ tf_decode(st->mode->nbEBands, C, isTransient, tf_res, len, LM, dec);
ALLOC(pulses, st->mode->nbEBands, int);
ALLOC(offsets, st->mode->nbEBands, int);