ref: 52cb5fb3f6aa897f2e090621f3bc3c260a9d8d16
parent: b469e601f635bf55ce6cdbd16c713638f1c0d4fd
author: Jean-Marc Valin <[email protected]>
date: Wed Jun 10 04:08:55 EDT 2009
Adding extra fine bits only when we have rounded down in the allocation
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -514,6 +514,7 @@
VARDECL(celt_word16_t, error);
VARDECL(int, pulses);
VARDECL(int, offsets);
+ VARDECL(int, fine_priority);
#ifdef EXP_PSY
VARDECL(celt_word32_t, mask);
VARDECL(celt_word32_t, tonality);
@@ -838,6 +839,7 @@
}
ALLOC(offsets, st->mode->nbEBands, int);
+ ALLOC(fine_priority, st->mode->nbEBands, int);
for (i=0;i<st->mode->nbEBands;i++)
offsets[i] = 0;
@@ -845,7 +847,7 @@
if (has_pitch)
bits -= st->mode->nbPBands;
#ifndef STDIN_TUNING
- compute_allocation(st->mode, offsets, bits, pulses, fine_quant);
+ compute_allocation(st->mode, offsets, bits, pulses, fine_quant, fine_priority);
#endif
quant_fine_energy(st->mode, bandE, st->oldBandE, error, fine_quant, &enc);
@@ -858,7 +860,7 @@
quant_bands_stereo(st->mode, X, P, NULL, has_pitch, gains, bandE, pulses, shortBlocks, has_fold, nbCompressedBytes*8, &enc);
#endif
- quant_energy_finalise(st->mode, bandE, st->oldBandE, error, fine_quant, nbCompressedBytes*8-ec_enc_tell(&enc, 0), &enc);
+ quant_energy_finalise(st->mode, bandE, st->oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_enc_tell(&enc, 0), &enc);
/* Re-synthesis of the coded audio if required */
if (st->pitch_available>0 || optional_synthesis!=NULL)
@@ -1277,6 +1279,7 @@
VARDECL(int, fine_quant);
VARDECL(int, pulses);
VARDECL(int, offsets);
+ VARDECL(int, fine_priority);
int shortBlocks;
int intra_ener;
@@ -1351,6 +1354,7 @@
ALLOC(pulses, st->mode->nbEBands, int);
ALLOC(offsets, st->mode->nbEBands, int);
+ ALLOC(fine_priority, st->mode->nbEBands, int);
for (i=0;i<st->mode->nbEBands;i++)
offsets[i] = 0;
@@ -1358,7 +1362,7 @@
bits = len*8 - ec_dec_tell(&dec, 0) - 1;
if (has_pitch)
bits -= st->mode->nbPBands;
- compute_allocation(st->mode, offsets, bits, pulses, fine_quant);
+ compute_allocation(st->mode, offsets, bits, pulses, fine_quant, fine_priority);
/*bits = ec_dec_tell(&dec, 0);
compute_fine_allocation(st->mode, fine_quant, (20*C+len*8/5-(ec_dec_tell(&dec, 0)-bits))/C);*/
@@ -1387,7 +1391,7 @@
else
unquant_bands_stereo(st->mode, X, P, has_pitch, gains, bandE, pulses, shortBlocks, has_fold, len*8, &dec);
#endif
- unquant_energy_finalise(st->mode, bandE, st->oldBandE, fine_quant, len*8-ec_dec_tell(&dec, 0), &dec);
+ unquant_energy_finalise(st->mode, bandE, st->oldBandE, fine_quant, fine_priority, len*8-ec_dec_tell(&dec, 0), &dec);
/* Synthesis */
denormalise_bands(st->mode, X, freq, bandE);
--- a/libcelt/quant_bands.c
+++ b/libcelt/quant_bands.c
@@ -172,7 +172,7 @@
eBands[i] = log2Amp(oldEBands[i]);
}
-static void quant_energy_finalise_mono(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, celt_word16_t *error, int *fine_quant, int bits_left, ec_enc *enc)
+static void quant_energy_finalise_mono(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, celt_word16_t *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc)
{
int i;
/* Use up the remaining bits */
@@ -180,7 +180,7 @@
{
int q2;
celt_word16_t offset;
- if (fine_quant[i] >= 7)
+ if (fine_quant[i] >= 7 || fine_priority[i]==0)
continue;
q2 = error[i]<0 ? 0 : 1;
ec_enc_bits(enc, q2, 1);
@@ -258,7 +258,7 @@
eBands[i] = log2Amp(oldEBands[i]);
}
-static void unquant_energy_finalise_mono(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int *fine_quant, int bits_left, ec_dec *dec)
+static void unquant_energy_finalise_mono(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int *fine_quant, int *fine_priority, int bits_left, ec_dec *dec)
{
int i;
/* Use up the remaining bits */
@@ -266,7 +266,7 @@
{
int q2;
celt_word16_t offset;
- if (fine_quant[i] >= 7)
+ if (fine_quant[i] >= 7 || fine_priority[i]==0)
continue;
q2 = ec_dec_bits(dec, 1);
#ifdef FIXED_POINT
@@ -339,7 +339,7 @@
}
}
-void quant_energy_finalise(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, celt_word16_t *error, int *fine_quant, int bits_left, ec_enc *enc)
+void quant_energy_finalise(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, celt_word16_t *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc)
{
int C;
C = m->nbChannels;
@@ -346,7 +346,7 @@
if (C==1)
{
- quant_energy_finalise_mono(m, eBands, oldEBands, error, fine_quant, bits_left, enc);
+ quant_energy_finalise_mono(m, eBands, oldEBands, error, fine_quant, fine_priority, bits_left, enc);
} else {
int c;
@@ -356,7 +356,7 @@
{
int i;
SAVE_STACK;
- quant_energy_finalise_mono(m, E, oldEBands+c*m->nbEBands, error+c*m->nbEBands, fine_quant, bits_left/C, enc);
+ quant_energy_finalise_mono(m, E, oldEBands+c*m->nbEBands, error+c*m->nbEBands, fine_quant, fine_priority, bits_left/C, enc);
for (i=0;i<m->nbEBands;i++)
eBands[C*i+c] = E[i];
RESTORE_STACK;
@@ -412,7 +412,7 @@
}
}
-void unquant_energy_finalise(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int *fine_quant, int bits_left, ec_dec *dec)
+void unquant_energy_finalise(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int *fine_quant, int *fine_priority, int bits_left, ec_dec *dec)
{
int C;
@@ -420,7 +420,7 @@
if (C==1)
{
- unquant_energy_finalise_mono(m, eBands, oldEBands, fine_quant, bits_left, dec);
+ unquant_energy_finalise_mono(m, eBands, oldEBands, fine_quant, fine_priority, bits_left, dec);
}
else {
int c;
@@ -430,7 +430,7 @@
for (c=0;c<C;c++)
{
int i;
- unquant_energy_finalise_mono(m, E, oldEBands+c*m->nbEBands, fine_quant, bits_left/C, dec);
+ unquant_energy_finalise_mono(m, E, oldEBands+c*m->nbEBands, fine_quant, fine_priority, bits_left/C, dec);
for (i=0;i<m->nbEBands;i++)
eBands[C*i+c] = E[i];
}
--- a/libcelt/quant_bands.h
+++ b/libcelt/quant_bands.h
@@ -59,12 +59,12 @@
void quant_fine_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, celt_word16_t *error, int *fine_quant, ec_enc *enc);
-void quant_energy_finalise(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, celt_word16_t *error, int *fine_quant, int bits_left, ec_enc *enc);
+void quant_energy_finalise(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, celt_word16_t *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc);
void unquant_coarse_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int budget, int intra, int *prob, ec_dec *dec);
void unquant_fine_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int *fine_quant, ec_dec *dec);
-void unquant_energy_finalise(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int *fine_quant, int bits_left, ec_dec *dec);
+void unquant_energy_finalise(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int *fine_quant, int *fine_priority, int bits_left, ec_dec *dec);
#endif /* QUANT_BANDS */
--- a/libcelt/rate.c
+++ b/libcelt/rate.c
@@ -97,7 +97,7 @@
-static void interp_bits2pulses(const CELTMode *m, int *bits1, int *bits2, int total, int *bits, int *ebits, int len)
+static void interp_bits2pulses(const CELTMode *m, int *bits1, int *bits2, int total, int *bits, int *ebits, int *fine_priority, int len)
{
int psum;
int lo, hi;
@@ -144,7 +144,9 @@
d=C*N<<BITRES;
offset = 50 - log2_frac(N, 4);
/* Offset for the number of fine bits compared to their "fair share" of total/N */
- ebits[j] = (bits[j]-offset*N*C+(d>>1))/d;
+ offset = bits[j]-offset*N*C;
+ ebits[j] = (offset+(d>>1))/d;
+ fine_priority[j] = (ebits[j]*d < offset);
/* Make sure not to bust */
if (C*ebits[j] > (bits[j]>>BITRES))
@@ -160,7 +162,7 @@
RESTORE_STACK;
}
-void compute_allocation(const CELTMode *m, int *offsets, int total, int *pulses, int *ebits)
+void compute_allocation(const CELTMode *m, int *offsets, int total, int *pulses, int *ebits, int *fine_priority)
{
int lo, hi, len, j;
VARDECL(int, bits1);
@@ -202,7 +204,7 @@
if (bits2[j] < 0)
bits2[j] = 0;
}
- interp_bits2pulses(m, bits1, bits2, total, pulses, ebits, len);
+ interp_bits2pulses(m, bits1, bits2, total, pulses, ebits, fine_priority, len);
RESTORE_STACK;
}
--- a/libcelt/rate.h
+++ b/libcelt/rate.h
@@ -138,7 +138,7 @@
@param pulses Number of pulses per band (returned)
@return Total number of bits allocated
*/
-void compute_allocation(const CELTMode *m, int *offsets, int total, int *pulses, int *ebits);
+void compute_allocation(const CELTMode *m, int *offsets, int total, int *pulses, int *ebits, int *fine_priority);
#endif