Adding extra fine bits only when we have rounded down in the allocation
authorJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Wed, 10 Jun 2009 12:08:55 +0000 (08:08 -0400)
committerJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Wed, 10 Jun 2009 12:08:55 +0000 (08:08 -0400)
libcelt/celt.c
libcelt/quant_bands.c
libcelt/quant_bands.h
libcelt/rate.c
libcelt/rate.h

index 779a086..785a246 100644 (file)
@@ -514,6 +514,7 @@ int celt_encode_float(CELTEncoder * restrict st, const celt_sig_t * pcm, celt_si
    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 @@ int celt_encode_float(CELTEncoder * restrict st, const celt_sig_t * pcm, celt_si
    }
 
    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 @@ int celt_encode_float(CELTEncoder * restrict st, const celt_sig_t * pcm, celt_si
    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 @@ int celt_encode_float(CELTEncoder * restrict st, const celt_sig_t * pcm, celt_si
       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 @@ int celt_decode_float(CELTDecoder * restrict st, const unsigned char *data, int
    VARDECL(int, fine_quant);
    VARDECL(int, pulses);
    VARDECL(int, offsets);
+   VARDECL(int, fine_priority);
 
    int shortBlocks;
    int intra_ener;
@@ -1351,6 +1354,7 @@ int celt_decode_float(CELTDecoder * restrict st, const unsigned char *data, int
    
    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 @@ int celt_decode_float(CELTDecoder * restrict st, const unsigned char *data, int
    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 @@ int celt_decode_float(CELTDecoder * restrict st, const unsigned char *data, int
    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);
index ac907ac..4fe6a1d 100644 (file)
@@ -172,7 +172,7 @@ static void quant_fine_energy_mono(const CELTMode *m, celt_ener_t *eBands, celt_
       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 @@ static void quant_energy_finalise_mono(const CELTMode *m, celt_ener_t *eBands, c
    {
       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 @@ static void unquant_fine_energy_mono(const CELTMode *m, celt_ener_t *eBands, cel
       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 @@ static void unquant_energy_finalise_mono(const CELTMode *m, celt_ener_t *eBands,
    {
       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,14 +339,14 @@ void quant_fine_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *ol
    }
 }
 
-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;
 
    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 @@ void quant_energy_finalise(const CELTMode *m, celt_ener_t *eBands, celt_word16_t
       {
          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_fine_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *
    }
 }
 
-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 @@ void unquant_energy_finalise(const CELTMode *m, celt_ener_t *eBands, celt_word16
 
    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 @@ void unquant_energy_finalise(const CELTMode *m, celt_ener_t *eBands, celt_word16
       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];
       }
index 0c43707..9528210 100644 (file)
@@ -59,12 +59,12 @@ unsigned quant_coarse_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16
 
 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 */
index a85984e..061f3e7 100644 (file)
@@ -97,7 +97,7 @@ celt_int16_t **compute_alloc_cache(CELTMode *m, int C)
 
 
 
-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 @@ static void interp_bits2pulses(const CELTMode *m, int *bits1, int *bits2, int to
       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 @@ static void interp_bits2pulses(const CELTMode *m, int *bits1, int *bits2, int to
    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 @@ void compute_allocation(const CELTMode *m, int *offsets, int total, int *pulses,
       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;
 }
 
index 52cd343..bc69037 100644 (file)
@@ -138,7 +138,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
 */
-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