ref: 6775de3eaedad9cff7ad0ba45fdc32236955a273
parent: c890b58b69a340d33b6ee8eceaa617b9535b0bdf
author: Jean-Marc Valin <[email protected]>
date: Sat Aug 2 04:14:42 EDT 2008
Unified allocation of fine energy and pulses.
--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -329,14 +329,12 @@
/* Quantisation of the residual */
-void quant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, celt_mask_t *W, const celt_ener_t *bandE, const int *stereo_mode, int total_bits, int shortBlocks, ec_enc *enc)
+void quant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, celt_mask_t *W, const celt_ener_t *bandE, const int *stereo_mode, int *pulses, int shortBlocks, ec_enc *enc)
{
- int i, j, bits;
+ int i, j;
const celt_int16_t * restrict eBands = m->eBands;
celt_norm_t * restrict norm;
VARDECL(celt_norm_t, _norm);
- VARDECL(int, pulses);
- VARDECL(int, offsets);
const int C = CHANNELS(m);
int B;
SAVE_STACK;
@@ -343,19 +341,11 @@
B = shortBlocks ? m->nbShortMdcts : 1;
ALLOC(_norm, C*eBands[m->nbEBands+1], celt_norm_t);
- ALLOC(pulses, m->nbEBands, int);
- ALLOC(offsets, m->nbEBands, int);
norm = _norm;
- for (i=0;i<m->nbEBands;i++)
- offsets[i] = 0;
- /* Use a single-bit margin to guard against overrunning (make sure it's enough) */
- bits = total_bits - ec_enc_tell(enc, 0) - 1;
- compute_allocation(m, offsets, stereo_mode, bits, pulses);
-
/*printf("bits left: %d\n", bits);
for (i=0;i<m->nbEBands;i++)
- printf ("%d ", pulses[i]);
+ printf ("(%d %d) ", pulses[i], ebits[i]);
printf ("\n");*/
/*printf ("%d %d\n", ec_enc_tell(enc, 0), compute_allocation(m, m->nbPulses));*/
for (i=0;i<m->nbEBands;i++)
@@ -399,14 +389,12 @@
}
/* Decoding of the residual */
-void unquant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, const celt_ener_t *bandE, const int *stereo_mode, int total_bits, int shortBlocks, ec_dec *dec)
+void unquant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, const celt_ener_t *bandE, const int *stereo_mode, int *pulses, int shortBlocks, ec_dec *dec)
{
- int i, j, bits;
+ int i, j;
const celt_int16_t * restrict eBands = m->eBands;
celt_norm_t * restrict norm;
VARDECL(celt_norm_t, _norm);
- VARDECL(int, pulses);
- VARDECL(int, offsets);
const int C = CHANNELS(m);
int B;
SAVE_STACK;
@@ -413,15 +401,7 @@
B = shortBlocks ? m->nbShortMdcts : 1;
ALLOC(_norm, C*eBands[m->nbEBands+1], celt_norm_t);
- ALLOC(pulses, m->nbEBands, int);
- ALLOC(offsets, m->nbEBands, int);
norm = _norm;
-
- for (i=0;i<m->nbEBands;i++)
- offsets[i] = 0;
- /* Use a single-bit margin to guard against overrunning (make sure it's enough) */
- bits = total_bits - ec_dec_tell(dec, 0) - 1;
- compute_allocation(m, offsets, stereo_mode, bits, pulses);
for (i=0;i<m->nbEBands;i++)
{
--- a/libcelt/bands.h
+++ b/libcelt/bands.h
@@ -86,7 +86,7 @@
* @param total_bits Total number of bits that can be used for the frame (including the ones already spent)
* @param enc Entropy encoder
*/
-void quant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, celt_mask_t *W, const celt_ener_t *bandE, const int *stereo_mode, int total_bits, int time_domain, ec_enc *enc);
+void quant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, celt_mask_t *W, const celt_ener_t *bandE, const int *stereo_mode, int *pulses, int time_domain, ec_enc *enc);
/** Decoding of the residual spectrum
* @param m Mode data
@@ -95,7 +95,7 @@
* @param total_bits Total number of bits that can be used for the frame (including the ones already spent)
* @param dec Entropy decoder
*/
-void unquant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, const celt_ener_t *bandE, const int *stereo_mode, int total_bits, int time_domain, ec_dec *dec);
+void unquant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, const celt_ener_t *bandE, const int *stereo_mode, int *pulses, int time_domain, ec_dec *dec);
void stereo_decision(const CELTMode *m, celt_norm_t * restrict X, int *stereo_mode, int len);
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -370,8 +370,10 @@
VARDECL(celt_ener_t, bandE);
VARDECL(celt_pgain_t, gains);
VARDECL(int, stereo_mode);
- VARDECL(celt_int16_t, fine_quant);
+ VARDECL(int, fine_quant);
VARDECL(celt_word16_t, error);
+ VARDECL(int, pulses);
+ VARDECL(int, offsets);
#ifdef EXP_PSY
VARDECL(celt_word32_t, mask);
#endif
@@ -529,22 +531,34 @@
P[i] = 0;
}
- ALLOC(fine_quant, st->mode->nbEBands, celt_int16_t);
+ ALLOC(fine_quant, st->mode->nbEBands, int);
ALLOC(error, C*st->mode->nbEBands, celt_word16_t);
- bits = ec_enc_tell(&st->enc, 0);
quant_coarse_energy(st->mode, bandE, st->oldBandE, 20*C+nbCompressedBytes*8, st->mode->prob, error, &st->enc);
- compute_fine_allocation(st->mode, fine_quant, (20*C+nbCompressedBytes*8/5-(ec_enc_tell(&st->enc, 0)-bits))/C);
- quant_fine_energy(st->mode, bandE, st->oldBandE, error, fine_quant, &st->enc);
-
+
+ ALLOC(pulses, st->mode->nbEBands, int);
+ ALLOC(offsets, st->mode->nbEBands, int);
ALLOC(stereo_mode, st->mode->nbEBands, int);
stereo_decision(st->mode, X, stereo_mode, st->mode->nbEBands);
+ for (i=0;i<st->mode->nbEBands;i++)
+ offsets[i] = 0;
+ bits = nbCompressedBytes*8 - ec_enc_tell(&st->enc, 0) - 1;
+ compute_allocation(st->mode, offsets, stereo_mode, bits, pulses, fine_quant);
+ /*for (i=0;i<st->mode->nbEBands;i++)
+ printf("%d ", fine_quant[i]);
+ for (i=0;i<st->mode->nbEBands;i++)
+ printf("%d ", pulses[i]);
+ printf ("\n");*/
+ /*bits = ec_enc_tell(&st->enc, 0);
+ compute_fine_allocation(st->mode, fine_quant, (20*C+nbCompressedBytes*8/5-(ec_enc_tell(&st->enc, 0)-bits))/C);*/
+ quant_fine_energy(st->mode, bandE, st->oldBandE, error, fine_quant, &st->enc);
+
pitch_quant_bands(st->mode, P, gains);
/*for (i=0;i<B*N;i++) printf("%f ",P[i]);printf("\n");*/
/* Residual quantisation */
- quant_bands(st->mode, X, P, NULL, bandE, stereo_mode, nbCompressedBytes*8, shortBlocks, &st->enc);
+ quant_bands(st->mode, X, P, NULL, bandE, stereo_mode, pulses, shortBlocks, &st->enc);
if (C==2)
{
@@ -741,7 +755,7 @@
int celt_decode(CELTDecoder * restrict st, unsigned char *data, int len, celt_int16_t * restrict pcm)
{
- int c, N, N4;
+ int i, c, N, N4;
int has_pitch;
int pitch_index;
int bits;
@@ -753,7 +767,9 @@
VARDECL(celt_ener_t, bandE);
VARDECL(celt_pgain_t, gains);
VARDECL(int, stereo_mode);
- VARDECL(celt_int16_t, fine_quant);
+ VARDECL(int, fine_quant);
+ VARDECL(int, pulses);
+ VARDECL(int, offsets);
int shortBlocks;
int transient_time;
@@ -820,11 +836,23 @@
pitch_index = 0;
}
- ALLOC(fine_quant, st->mode->nbEBands, celt_int16_t);
- bits = ec_dec_tell(&dec, 0);
+ ALLOC(fine_quant, st->mode->nbEBands, int);
/* Get band energies */
unquant_coarse_energy(st->mode, bandE, st->oldBandE, 20*C+len*8, st->mode->prob, &dec);
- compute_fine_allocation(st->mode, fine_quant, (20*C+len*8/5-(ec_dec_tell(&dec, 0)-bits))/C);
+
+ ALLOC(pulses, st->mode->nbEBands, int);
+ ALLOC(offsets, st->mode->nbEBands, int);
+ ALLOC(stereo_mode, st->mode->nbEBands, int);
+ stereo_decision(st->mode, X, stereo_mode, st->mode->nbEBands);
+
+ for (i=0;i<st->mode->nbEBands;i++)
+ offsets[i] = 0;
+
+ bits = len*8 - ec_dec_tell(&dec, 0) - 1;
+ compute_allocation(st->mode, offsets, stereo_mode, bits, pulses, fine_quant);
+ /*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);*/
+
unquant_fine_energy(st->mode, bandE, st->oldBandE, fine_quant, &dec);
/* Pitch MDCT */
@@ -837,13 +865,11 @@
normalise_bands(st->mode, freq, P, bandEp);
}
- ALLOC(stereo_mode, st->mode->nbEBands, int);
- stereo_decision(st->mode, X, stereo_mode, st->mode->nbEBands);
/* Apply pitch gains */
pitch_quant_bands(st->mode, P, gains);
/* Decode fixed codebook and merge with pitch */
- unquant_bands(st->mode, X, P, bandE, stereo_mode, len*8, shortBlocks, &dec);
+ unquant_bands(st->mode, X, P, bandE, stereo_mode, pulses, shortBlocks, &dec);
if (C==2)
{
--- a/libcelt/modes.c
+++ b/libcelt/modes.c
@@ -245,6 +245,7 @@
{
int i, j;
celt_int16_t *alloc;
+ const int C = CHANNELS(mode);
alloc = celt_alloc(sizeof(celt_int16_t)*(mode->nbAllocVectors*(mode->nbEBands+1)));
for (i=0;i<mode->nbAllocVectors;i++)
@@ -258,7 +259,7 @@
for (j=0;j<mode->nbEBands;j++)
{
alloc[i*(mode->nbEBands+1)+j] = mode->allocVectors[i*mode->nbEBands+j]
- / (mode->eBands[j+1]-mode->eBands[j]-1);
+ / (C*(mode->eBands[j+1]-mode->eBands[j]));
if (alloc[i*(mode->nbEBands+1)+j]<min_bits)
alloc[i*(mode->nbEBands+1)+j] = min_bits;
if (alloc[i*(mode->nbEBands+1)+j]>7)
--- a/libcelt/quant_bands.c
+++ b/libcelt/quant_bands.c
@@ -50,7 +50,7 @@
/*const int frac[24] = {4, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};*/
/*const int frac[24] = {8, 6, 5, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};*/
-void compute_fine_allocation(const CELTMode *m, celt_int16_t *bits, int budget)
+void compute_fine_allocation(const CELTMode *m, int *bits, int budget)
{
int i,j;
int len;
@@ -185,7 +185,7 @@
}
}
-static void quant_fine_energy_mono(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, celt_word16_t *error, celt_int16_t *fine_quant, ec_enc *enc)
+static void quant_fine_energy_mono(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, celt_word16_t *error, int *fine_quant, ec_enc *enc)
{
int i;
/* Encode finer resolution */
@@ -250,7 +250,7 @@
}
}
-static void unquant_fine_energy_mono(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, celt_int16_t *fine_quant, ec_dec *dec)
+static void unquant_fine_energy_mono(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int *fine_quant, ec_dec *dec)
{
int i;
/* Decode finer resolution */
@@ -299,7 +299,7 @@
}
}
-void quant_fine_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, celt_word16_t *error, celt_int16_t *fine_quant, ec_enc *enc)
+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)
{
int C;
C = m->nbChannels;
@@ -347,7 +347,7 @@
}
}
-void unquant_fine_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, celt_int16_t *fine_quant, ec_dec *dec)
+void unquant_fine_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int *fine_quant, ec_dec *dec)
{
int C;
--- a/libcelt/quant_bands.h
+++ b/libcelt/quant_bands.h
@@ -40,14 +40,14 @@
int *quant_prob_alloc(const CELTMode *m);
void quant_prob_free(int *freq);
-void compute_fine_allocation(const CELTMode *m, celt_int16_t *bits, int budget);
+void compute_fine_allocation(const CELTMode *m, int *bits, int budget);
void quant_coarse_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int budget, int *prob, celt_word16_t *error, ec_enc *enc);
-void quant_fine_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, celt_word16_t *error, celt_int16_t *fine_quant, ec_enc *enc);
+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 unquant_coarse_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int budget, int *prob, ec_dec *dec);
-void unquant_fine_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, celt_int16_t *fine_quant, ec_dec *dec);
+void unquant_fine_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int *fine_quant, ec_dec *dec);
#endif /* QUANT_BANDS */
--- a/libcelt/rate.c
+++ b/libcelt/rate.c
@@ -132,11 +132,13 @@
return sum;
}
-static int interp_bits2pulses(const CELTMode *m, const celt_int16_t * const *cache, int *bits1, int *bits2, int total, int *pulses, int len)
+static int interp_bits2pulses(const CELTMode *m, const celt_int16_t * const *cache, int *bits1, int *bits2, int *ebits1, int *ebits2, int total, int *pulses, int *ebits, int len)
{
+ int esum;
int lo, hi, out;
int j;
VARDECL(int, bits);
+ const int C = CHANNELS(m);
SAVE_STACK;
ALLOC(bits, len, int);
lo = 0;
@@ -144,17 +146,30 @@
while (hi-lo != 1)
{
int mid = (lo+hi)>>1;
+ esum = 0;
for (j=0;j<len;j++)
- bits[j] = ((1<<BITRES)-mid)*bits1[j] + mid*bits2[j];
- if (vec_bits2pulses(m, cache, bits, pulses, len) > total<<BITRES)
+ {
+ ebits[j] = (((1<<BITRES)-mid)*ebits1[j] + mid*ebits2[j] + (1<<(BITRES-1)))>>BITRES;
+ esum += C*ebits[j];
+ }
+ for (j=0;j<len;j++)
+ bits[j] = ((1<<BITRES)-mid)*bits1[j] + mid*bits2[j] - C*(ebits[j]<<BITRES);
+ if (vec_bits2pulses(m, cache, bits, pulses, len) > (total-esum)<<BITRES)
hi = mid;
else
lo = mid;
}
+ esum = 0;
/*printf ("interp bisection gave %d\n", lo);*/
for (j=0;j<len;j++)
- bits[j] = ((1<<BITRES)-lo)*bits1[j] + lo*bits2[j];
+ {
+ ebits[j] = (((1<<BITRES)-lo)*ebits1[j] + lo*ebits2[j] + (1<<(BITRES-1)))>>BITRES;
+ esum += C*ebits[j];
+ }
+ for (j=0;j<len;j++)
+ bits[j] = ((1<<BITRES)-lo)*bits1[j] + lo*bits2[j] - C*(ebits[j]<<BITRES);
out = vec_bits2pulses(m, cache, bits, pulses, len);
+ /*printf ("left to allocate: %d\n", total-esum-(out>>BITRES));*/
/* Do some refinement to use up all bits. In the first pass, we can only add pulses to
bands that are under their allocated budget. In the second pass, anything goes */
for (j=0;j<len;j++)
@@ -161,7 +176,7 @@
{
if (cache[j][pulses[j]] < bits[j] && pulses[j]<MAX_PULSES-1)
{
- if (out+cache[j][pulses[j]+1]-cache[j][pulses[j]] <= total<<BITRES)
+ if (out+cache[j][pulses[j]+1]-cache[j][pulses[j]] <= (total-esum)<<BITRES)
{
out = out+cache[j][pulses[j]+1]-cache[j][pulses[j]];
pulses[j] += 1;
@@ -175,7 +190,7 @@
{
if (pulses[j]<MAX_PULSES-1)
{
- if (out+cache[j][pulses[j]+1]-cache[j][pulses[j]] <= total<<BITRES)
+ if (out+cache[j][pulses[j]+1]-cache[j][pulses[j]] <= (total-esum)<<BITRES)
{
out = out+cache[j][pulses[j]+1]-cache[j][pulses[j]];
pulses[j] += 1;
@@ -190,17 +205,22 @@
return (out+BITROUND) >> BITRES;
}
-int compute_allocation(const CELTMode *m, int *offsets, const int *stereo_mode, int total, int *pulses)
+int compute_allocation(const CELTMode *m, int *offsets, const int *stereo_mode, int total, int *pulses, int *ebits)
{
int lo, hi, len, ret, i;
VARDECL(int, bits1);
VARDECL(int, bits2);
+ VARDECL(int, ebits1);
+ VARDECL(int, ebits2);
VARDECL(const celt_int16_t*, cache);
+ const int C = CHANNELS(m);
SAVE_STACK;
len = m->nbEBands;
ALLOC(bits1, len, int);
ALLOC(bits2, len, int);
+ ALLOC(ebits1, len, int);
+ ALLOC(ebits2, len, int);
ALLOC(cache, len, const celt_int16_t*);
if (m->nbChannels==2)
@@ -225,30 +245,33 @@
int mid = (lo+hi) >> 1;
for (j=0;j<len;j++)
{
- bits1[j] = (m->allocVectors[mid*len+j] + offsets[j])<<BITRES;
+ bits1[j] = (m->allocVectors[mid*len+j] - C*m->energy_alloc[mid*(len+1)+j] + offsets[j])<<BITRES;
if (bits1[j] < 0)
bits1[j] = 0;
/*printf ("%d ", bits[j]);*/
}
/*printf ("\n");*/
- if (vec_bits2pulses(m, cache, bits1, pulses, len) > total<<BITRES)
+ if (vec_bits2pulses(m, cache, bits1, pulses, len) > (total-C*m->energy_alloc[mid*(len+1)+len])<<BITRES)
hi = mid;
else
lo = mid;
/*printf ("lo = %d, hi = %d\n", lo, hi);*/
}
+ /*printf ("interp between %d and %d\n", lo, hi);*/
{
int j;
for (j=0;j<len;j++)
{
- bits1[j] = m->allocVectors[lo*len+j] + offsets[j];
- bits2[j] = m->allocVectors[hi*len+j] + offsets[j];
+ ebits1[j] = m->energy_alloc[lo*(len+1)+j];
+ ebits2[j] = m->energy_alloc[hi*(len+1)+j];
+ bits1[j] = m->allocVectors[lo*len+j] + offsets[j] - 0*ebits1[j];
+ bits2[j] = m->allocVectors[hi*len+j] + offsets[j] - 0*ebits2[j];
if (bits1[j] < 0)
bits1[j] = 0;
if (bits2[j] < 0)
bits2[j] = 0;
}
- ret = interp_bits2pulses(m, cache, bits1, bits2, total, pulses, len);
+ ret = interp_bits2pulses(m, cache, bits1, bits2, ebits1, ebits2, total, pulses, ebits, len);
RESTORE_STACK;
return ret;
}
--- a/libcelt/rate.h
+++ b/libcelt/rate.h
@@ -47,7 +47,7 @@
@param pulses Number of pulses per band (returned)
@return Total number of bits allocated
*/
-int compute_allocation(const CELTMode *m, int *offsets, const int *stereo_mode, int total, int *pulses);
+int compute_allocation(const CELTMode *m, int *offsets, const int *stereo_mode, int total, int *pulses, int *ebits);
#endif