shithub: opus

Download patch

ref: bc79991742c8e42bf92c6dc50428cb329117fe45
parent: 896471dc3dda1f1a60b8cb176b6dc91589f40c8d
author: Jean-Marc Valin <[email protected]>
date: Fri Nov 7 17:53:13 EST 2008

The fold bit can now be used by the encoder and decoder (encoder still needs
EXP_PSY)

--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -352,7 +352,7 @@
 
 
 /* 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 *pulses, int shortBlocks, int total_bits, 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, int fold, int total_bits, ec_enc *enc)
 {
    int i, j, remaining_bits, balance;
    const celt_int16_t * restrict eBands = m->eBands;
@@ -411,7 +411,7 @@
       n = SHL16(celt_sqrt(C*(eBands[i+1]-eBands[i])),11);
 
       /* If pitch isn't available, use intra-frame prediction */
-      if (eBands[i] >= m->pitchEnd || q<=0)
+      if ((eBands[i] >= m->pitchEnd && fold) || q<=0)
       {
          intra_fold(m, X+C*eBands[i], eBands[i+1]-eBands[i], q, norm, P+C*eBands[i], eBands[i], B);
       }
@@ -440,7 +440,7 @@
 }
 
 /* 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 *pulses, int shortBlocks, int total_bits, 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, int fold, int total_bits, ec_dec *dec)
 {
    int i, j, remaining_bits, balance;
    const celt_int16_t * restrict eBands = m->eBands;
@@ -494,7 +494,7 @@
       n = SHL16(celt_sqrt(C*(eBands[i+1]-eBands[i])),11);
 
       /* If pitch isn't available, use intra-frame prediction */
-      if (eBands[i] >= m->pitchEnd || q<=0)
+      if ((eBands[i] >= m->pitchEnd && fold) || q<=0)
       {
          intra_fold(m, X+C*eBands[i], eBands[i+1]-eBands[i], q, norm, P+C*eBands[i], eBands[i], B);
       }
--- a/libcelt/bands.h
+++ b/libcelt/bands.h
@@ -88,7 +88,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 *pulses, int time_domain, int total_bits, 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, int fold, int total_bits, ec_enc *enc);
 
 /** Decoding of the residual spectrum
  * @param m Mode data 
@@ -97,7 +97,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 *pulses, int time_domain, int total_bits, 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, int fold, int total_bits, 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
@@ -374,7 +374,7 @@
    int has_pitch;
    int pitch_index;
    int bits;
-   int has_fold;
+   int has_fold=1;
    ec_byte_buffer buf;
    ec_enc         enc;
    celt_word32_t curr_power, pitch_power=0;
@@ -545,9 +545,9 @@
          has_fold++;
    /*printf ("%d\n", has_fold);*/
    if (has_fold>=2)
-      has_fold = 1;
-   else
       has_fold = 0;
+   else
+      has_fold = 1;
    for (i=0;i<N;i++)
       mask[i] = sqrt(mask[i]);
    compute_band_energies(st->mode, mask, bandM);
@@ -575,6 +575,7 @@
    /* Check if we can safely use the pitch (i.e. effective gain isn't too high) */
    if (st->pitch_enabled && !shortBlocks && (MULT16_32_Q15(QCONST16(.1f, 15),curr_power) + QCONST32(10.f,ENER_SHIFT) < pitch_power))
    {
+      int id;
       /* Simulates intensity stereo */
       /*for (i=30;i<N*B;i++)
          X[i*C+1] = P[i*C+1] = 0;*/
@@ -581,18 +582,29 @@
 
       /* Pitch prediction */
       compute_pitch_gain(st->mode, X, P, gains);
-      has_pitch = quant_pitch(gains, st->mode->nbPBands, &enc);
+      id = quant_pitch(gains, st->mode->nbPBands, &enc);
+      if (id != -1)
+         has_pitch = 1;
+      else
+         has_pitch = 0;
+      ec_enc_bits(&enc, has_pitch, 1); /* Pitch flag */
       if (has_pitch)
+      {
+         ec_enc_bits(&enc, has_fold, 1); /* Folding flag */
+         ec_enc_bits(&enc, id, 7);
          ec_enc_uint(&enc, pitch_index, MAX_PERIOD-(2*N-2*N4));
-      else if (st->mode->nbShortMdcts > 1)
-         ec_enc_bits(&enc, 0, 1); //Transient off
+      } else if (st->mode->nbShortMdcts > 1) {
+         ec_enc_bits(&enc, 0, 1); /* Transient off */
+         has_fold = 1;
+      }
    } else {
       if (!shortBlocks)
       {
-         ec_enc_bits(&enc, 0, 1); //Pitch off
+         ec_enc_bits(&enc, 0, 1); /* Pitch off */
          if (st->mode->nbShortMdcts > 1)
-           ec_enc_bits(&enc, 0, 1); //Transient off
+           ec_enc_bits(&enc, 0, 1); /* Transient off */
       }
+      has_fold = 1;
       /* No pitch, so we just pretend we found a gain of zero */
       for (i=0;i<st->mode->nbPBands;i++)
          gains[i] = 0;
@@ -643,7 +655,7 @@
    /*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, pulses, shortBlocks, nbCompressedBytes*8, &enc);
+   quant_bands(st->mode, X, P, NULL, bandE, stereo_mode, pulses, shortBlocks, has_fold, nbCompressedBytes*8, &enc);
    
    if (st->pitch_enabled || optional_synthesis!=NULL)
    {
@@ -1047,7 +1059,7 @@
    pitch_quant_bands(st->mode, P, gains);
 
    /* Decode fixed codebook and merge with pitch */
-   unquant_bands(st->mode, X, P, bandE, stereo_mode, pulses, shortBlocks, len*8, &dec);
+   unquant_bands(st->mode, X, P, bandE, stereo_mode, pulses, shortBlocks, has_fold, len*8, &dec);
 
    if (C==2)
    {
--- a/libcelt/quant_pitch.c
+++ b/libcelt/quant_pitch.c
@@ -110,17 +110,12 @@
    } else {
       id = 0;
    }
-   if (id == 0)
-   {
-      ec_enc_bits(enc, 0, 1); //Pitch off
-   } else {
-      ec_enc_bits(enc, 1, 1); //Pitch on
-      ec_enc_bits(enc, 1, 1); //Folding on
-      ec_enc_bits(enc, id, 7);
-   }
    /*for (i=0;i<len;i++) printf ("%f ", pgain_table[id*len+i]);printf ("\n");*/
    id2gains(id, gains, len);
-   return id!=0;
+   if (id != 0)
+      return id;
+   else
+      return -1;
 }
 
 int unquant_pitch(celt_pgain_t *gains, int len, ec_dec *dec)