shithub: opus

Download patch

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