Commit 6775de3e authored by Jean-Marc Valin's avatar Jean-Marc Valin
Browse files

Unified allocation of fine energy and pulses.

parent c890b58b
......@@ -329,33 +329,23 @@ void stereo_decision(const CELTMode *m, celt_norm_t * restrict X, int *stereo_mo
/* 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;
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,30 +389,20 @@ void quant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, ce
}
/* 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;
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++)
{
int q;
......
......@@ -86,7 +86,7 @@ void pitch_quant_bands(const CELTMode *m, celt_norm_t * restrict P, const celt_p
* @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 @@ void quant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, ce
* @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);
......
......@@ -370,8 +370,10 @@ int celt_encode(CELTEncoder * restrict st, celt_int16_t * restrict pcm, unsigned
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 @@ int celt_encode(CELTEncoder * restrict st, celt_int16_t * restrict pcm, unsigned
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 @@ static void celt_decode_lost(CELTDecoder * restrict st, short * restrict pcm)
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 @@ int celt_decode(CELTDecoder * restrict st, unsigned char *data, int len, celt_in
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 @@ int celt_decode(CELTDecoder * restrict st, unsigned char *data, int len, celt_in
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 @@ int celt_decode(CELTDecoder * restrict st, unsigned char *data, int len, celt_in
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)
{
......
......@@ -245,6 +245,7 @@ static void compute_energy_allocation_table(CELTMode *mode)
{
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 @@ static void compute_energy_allocation_table(CELTMode *mode)
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)
......
......@@ -50,7 +50,7 @@ const celt_word16_t eMeans[24] = {45.f, -8.f, -12.f, -2.5f, 1.f, 0.f, 0.f, 0.f,
/*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_coarse_energy_mono(const CELTMode *m, celt_ener_t *eBands, cel
}
}
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_coarse_energy_mono(const CELTMode *m, celt_ener_t *eBands, c
}
}
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_coarse_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *
}
}
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_coarse_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t
}
}
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;
......
......@@ -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 */
......@@ -132,11 +132,13 @@ static int vec_bits2pulses(const CELTMode *m, const celt_int16_t * const *cache,
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,24 +146,37 @@ static int interp_bits2pulses(const CELTMode *m, const celt_int16_t * const *cac
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++)
{
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 @@ static int interp_bits2pulses(const CELTMode *m, const celt_int16_t * const *cac
{
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 @@ static int interp_bits2pulses(const CELTMode *m, const celt_int16_t * const *cac
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 compute_allocation(const CELTMode *m, int *offsets, const int *stereo_mode,
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;
}
......
......@@ -47,7 +47,7 @@ celt_int16_t **compute_alloc_cache(CELTMode *m, int C);
@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
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment