Changing the allocation algorithm to better take into account the fixed cost
authorJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Mon, 4 Aug 2008 02:07:06 +0000 (22:07 -0400)
committerJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Mon, 4 Aug 2008 02:07:06 +0000 (22:07 -0400)
per frames for each mode.

libcelt/celt.c
libcelt/modes.c
libcelt/quant_bands.c

index 8fbaccf..1d84809 100644 (file)
@@ -533,7 +533,7 @@ int celt_encode(CELTEncoder * restrict st, celt_int16_t * restrict pcm, unsigned
 
    ALLOC(fine_quant, st->mode->nbEBands, int);
    ALLOC(error, C*st->mode->nbEBands, celt_word16_t);
-   quant_coarse_energy(st->mode, bandE, st->oldBandE, 20*C+nbCompressedBytes*8, st->mode->prob, error, &st->enc);
+   quant_coarse_energy(st->mode, bandE, st->oldBandE, nbCompressedBytes*8/3, st->mode->prob, error, &st->enc);
    
    ALLOC(pulses, st->mode->nbEBands, int);
    ALLOC(offsets, st->mode->nbEBands, int);
@@ -838,7 +838,7 @@ int celt_decode(CELTDecoder * restrict st, unsigned char *data, int len, celt_in
 
    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);
+   unquant_coarse_energy(st->mode, bandE, st->oldBandE, len*8/3, st->mode->prob, &dec);
    
    ALLOC(pulses, st->mode->nbEBands, int);
    ALLOC(offsets, st->mode->nbEBands, int);
index 6530370..22ee988 100644 (file)
@@ -104,9 +104,10 @@ static const celt_int16_t pitch_freq[PBANDS+1] ={0, 345, 689, 1034, 1378, 2067,
 int BITALLOC_SIZE;
 int *band_allocation;
 #else
-#define BITALLOC_SIZE 11
+#define BITALLOC_SIZE 12
 static const int band_allocation[BARK_BANDS*BITALLOC_SIZE] = 
-   {  2,  2,  1,  1,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+   {  4,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+      2,  2,  1,  1,  2,  2,  1,  1,  1,  1,  1,  1,  1,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
       2,  2,  2,  1,  2,  2,  2,  2,  2,  1,  2,  2,  4,  5,  7,  7,  7,  5,  4,  0,  0,  0,  0,  0,  0,
       2,  2,  2,  2,  3,  2,  2,  2,  2,  2,  3,  3,  5,  6,  8,  8,  8,  6,  5,  4,  0,  0,  0,  0,  0,
       3,  2,  2,  2,  3,  3,  2,  3,  2,  3,  4,  4,  6,  7,  9,  9,  9,  7,  6,  5,  5,  5,  0,  0,  0,
@@ -235,22 +236,22 @@ static void compute_allocation_table(CELTMode *mode, int res)
    for (i=0;i<mode->nbAllocVectors;i++)
    {
       int sum = 0;
-      int min_bits = 1;
-      if (allocVectors[i*mode->nbEBands]>12)
-         min_bits = 2;
-      if (allocVectors[i*mode->nbEBands]>24)
-         min_bits = 3;
       for (j=0;j<mode->nbEBands;j++)
       {
-         allocEnergy[i*(mode->nbEBands+1)+j] = allocVectors[i*mode->nbEBands+j]
-                                         / (C*(mode->eBands[j+1]-mode->eBands[j]));
-         if (allocEnergy[i*(mode->nbEBands+1)+j]<min_bits)
-            allocEnergy[i*(mode->nbEBands+1)+j] = min_bits;
-         if (allocEnergy[i*(mode->nbEBands+1)+j]>7)
-            allocEnergy[i*(mode->nbEBands+1)+j] = 7;
+         int ebits;
+         int min_bits=0;
+         if (allocVectors[i*mode->nbEBands+j] >= C)
+            min_bits = 1;
+         ebits = allocVectors[i*mode->nbEBands+j] / (C*(mode->eBands[j+1]-mode->eBands[j]));
+         if (ebits<min_bits)
+            ebits = min_bits;
          /* The bits used for fine allocation can't be used for pulses */
-         allocVectors[i*mode->nbEBands+j] -= C*allocEnergy[i*(mode->nbEBands+1)+j];
-         sum += allocEnergy[i*(mode->nbEBands+1)+j];
+         /* However, we give two "free" bits to all modes to compensate for the fact that some energy
+            resolution is needed regardless of the frame size. */
+         if (ebits>1)
+            allocVectors[i*mode->nbEBands+j] -= C*(ebits-2);
+         sum += ebits;
+         allocEnergy[i*(mode->nbEBands+1)+j] = ebits;
       }
       allocEnergy[i*(mode->nbEBands+1)+mode->nbEBands] = sum;
    }
index bcc35b4..0dd7611 100644 (file)
@@ -129,7 +129,7 @@ static void quant_coarse_energy_mono(const CELTMode *m, celt_ener_t *eBands, cel
 #endif
       /* If we don't have enough bits to encode all the energy, just assume something safe.
          We allow slightly busting the budget here */
-      if (ec_enc_tell(enc, 0) - bits > budget+16)
+      if (ec_enc_tell(enc, 0) - bits > budget)
          qi = -1;
       else
          ec_laplace_encode_start(enc, &qi, prob[2*i], prob[2*i+1]);
@@ -194,7 +194,7 @@ static void unquant_coarse_energy_mono(const CELTMode *m, celt_ener_t *eBands, c
       celt_word16_t mean = MULT16_16_Q15(Q15ONE-coef,eMeans[i]);
       /* If we didn't have enough bits to encode all the energy, just assume something safe.
          We allow slightly busting the budget here */
-      if (ec_dec_tell(dec, 0) - bits > budget+16)
+      if (ec_dec_tell(dec, 0) - bits > budget)
          qi = -1;
       else
          qi = ec_laplace_decode_start(dec, prob[2*i], prob[2*i+1]);