shithub: opus

Download patch

ref: 525d7cfdc4489a2ce0a3108a813f54a929aad25d
parent: 41a5593c95d65f7eb3f95be598daba356907123f
author: Jean-Marc Valin <[email protected]>
date: Tue Jul 13 10:14:16 EDT 2010

Support for adjusting the end band

--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -884,7 +884,7 @@
    }
 }
 
-void quant_all_bands(int encode, const CELTMode *m, int start, celt_norm *_X, celt_norm *_Y, const celt_ener *bandE, int *pulses, int shortBlocks, int fold, int *tf_res, int resynth, int total_bits, void *ec, int LM)
+void quant_all_bands(int encode, const CELTMode *m, int start, int end, celt_norm *_X, celt_norm *_Y, const celt_ener *bandE, int *pulses, int shortBlocks, int fold, int *tf_res, int resynth, int total_bits, void *ec, int LM)
 {
    int i, balance;
    celt_int32 remaining_bits;
@@ -907,7 +907,7 @@
 
    balance = 0;
    lowband = NULL;
-   for (i=start;i<m->nbEBands;i++)
+   for (i=start;i<end;i++)
    {
       int tell;
       int b;
@@ -930,7 +930,7 @@
       if (i != start)
          balance -= tell;
       remaining_bits = (total_bits<<BITRES)-tell-1;
-      curr_balance = (m->nbEBands-i);
+      curr_balance = (end-i);
       if (curr_balance > 3)
          curr_balance = 3;
       curr_balance = balance / curr_balance;
--- a/libcelt/bands.h
+++ b/libcelt/bands.h
@@ -85,7 +85,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_all_bands(int encode, const CELTMode *m, int start, celt_norm * X, celt_norm * Y, const celt_ener *bandE, int *pulses, int time_domain, int fold, int *tf_res, int resynth, int total_bits, void *enc, int M);
+void quant_all_bands(int encode, const CELTMode *m, int start, int end, celt_norm * X, celt_norm * Y, const celt_ener *bandE, int *pulses, int time_domain, int fold, int *tf_res, int resynth, int total_bits, void *enc, int M);
 
 
 void stereo_decision(const CELTMode *m, celt_norm * restrict X, int *stereo_mode, int len, int M);
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -963,7 +963,7 @@
 #else
    max_decay = .125*nbAvailableBytes;
 #endif
-   coarse_needed = quant_coarse_energy(st->mode, st->start, bandLogE, st->oldBandE, nbFilledBytes*8+nbAvailableBytes*4-8, intra_ener, st->mode->prob, error, enc, C, max_decay);
+   coarse_needed = quant_coarse_energy(st->mode, st->start, st->end, bandLogE, st->oldBandE, nbFilledBytes*8+nbAvailableBytes*4-8, intra_ener, st->mode->prob, error, enc, C, max_decay);
    coarse_needed -= nbFilledBytes*8;
    coarse_needed = ((coarse_needed*3-1)>>3)+1;
    if (coarse_needed > nbAvailableBytes)
@@ -1035,14 +1035,14 @@
    for (i=0;i<st->mode->nbEBands;i++)
       offsets[i] = 0;
    bits = nbCompressedBytes*8 - ec_enc_tell(enc, 0) - 1;
-   compute_allocation(st->mode, st->start, offsets, bits, pulses, fine_quant, fine_priority, C, M);
+   compute_allocation(st->mode, st->start, st->end, offsets, bits, pulses, fine_quant, fine_priority, C, M);
 
-   quant_fine_energy(st->mode, st->start, bandE, st->oldBandE, error, fine_quant, enc, C);
+   quant_fine_energy(st->mode, st->start, st->end, bandE, st->oldBandE, error, fine_quant, enc, C);
 
    /* Residual quantisation */
-   quant_all_bands(1, st->mode, st->start, X, C==2 ? X+N : NULL, bandE, pulses, shortBlocks, has_fold, tf_res, resynth, nbCompressedBytes*8, enc, LM);
+   quant_all_bands(1, st->mode, st->start, st->end, X, C==2 ? X+N : NULL, bandE, pulses, shortBlocks, has_fold, tf_res, resynth, nbCompressedBytes*8, enc, LM);
 
-   quant_energy_finalise(st->mode, st->start, bandE, st->oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_enc_tell(enc, 0), enc, C);
+   quant_energy_finalise(st->mode, st->start, st->end, bandE, st->oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_enc_tell(enc, 0), enc, C);
 
    /* Re-synthesis of the coded audio if required */
    if (resynth)
@@ -1236,6 +1236,14 @@
          st->start = value;
       }
       break;
+      case CELT_SET_END_BAND_REQUEST:
+      {
+         celt_int32 value = va_arg(ap, celt_int32);
+         if (value<0 || value>=st->mode->nbEBands)
+            goto bad_arg;
+         st->end = value;
+      }
+      break;
       case CELT_SET_PREDICTION_REQUEST:
       {
          int value = va_arg(ap, celt_int32);
@@ -1686,6 +1694,9 @@
    for (c=0;c<C;c++)
       for (i=0;i<M*st->mode->eBands[st->start];i++)
          X[c*N+i] = 0;
+   for (c=0;c<C;c++)
+      for (i=M*st->mode->eBands[st->end];i<N;i++)
+         X[c*N+i] = 0;
 
    if (data == NULL)
    {
@@ -1752,7 +1763,7 @@
 
    ALLOC(fine_quant, st->mode->nbEBands, int);
    /* Get band energies */
-   unquant_coarse_energy(st->mode, st->start, bandE, st->oldBandE, nbFilledBytes*8+nbAvailableBytes*4-8, intra_ener, st->mode->prob, dec, C);
+   unquant_coarse_energy(st->mode, st->start, st->end, bandE, st->oldBandE, nbFilledBytes*8+nbAvailableBytes*4-8, intra_ener, st->mode->prob, dec, C);
 
    ALLOC(tf_res, st->mode->nbEBands, int);
    tf_decode(st->mode->nbEBands, C, isTransient, tf_res, nbAvailableBytes, LM, dec);
@@ -1765,11 +1776,11 @@
       offsets[i] = 0;
 
    bits = len*8 - ec_dec_tell(dec, 0) - 1;
-   compute_allocation(st->mode, st->start, offsets, bits, pulses, fine_quant, fine_priority, C, M);
+   compute_allocation(st->mode, st->start, st->end, offsets, bits, pulses, fine_quant, fine_priority, C, M);
    /*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, st->start, bandE, st->oldBandE, fine_quant, dec, C);
+   unquant_fine_energy(st->mode, st->start, st->end, bandE, st->oldBandE, fine_quant, dec, C);
 
    ALLOC(pitch_freq, C*N, celt_sig); /**< Interleaved signal MDCTs */
    if (has_pitch) 
@@ -1779,9 +1790,9 @@
    }
 
    /* Decode fixed codebook and merge with pitch */
-   quant_all_bands(0, st->mode, st->start, X, C==2 ? X+N : NULL, NULL, pulses, shortBlocks, has_fold, tf_res, 1, len*8, dec, LM);
+   quant_all_bands(0, st->mode, st->start, st->end, X, C==2 ? X+N : NULL, NULL, pulses, shortBlocks, has_fold, tf_res, 1, len*8, dec, LM);
 
-   unquant_energy_finalise(st->mode, st->start, bandE, st->oldBandE, fine_quant, fine_priority, len*8-ec_dec_tell(dec, 0), dec, C);
+   unquant_energy_finalise(st->mode, st->start, st->end, bandE, st->oldBandE, fine_quant, fine_priority, len*8-ec_dec_tell(dec, 0), dec, C);
 
    if (mdct_weight_shift)
    {
@@ -1800,6 +1811,9 @@
    for (c=0;c<C;c++)
       for (i=0;i<M*st->mode->eBands[st->start];i++)
          freq[c*N+i] = 0;
+   for (c=0;c<C;c++)
+      for (i=M*st->mode->eBands[st->end];i<N;i++)
+         freq[c*N+i] = 0;
 
    /* Compute inverse MDCTs */
    compute_inv_mdcts(st->mode, shortBlocks, freq, transient_time, transient_shift, st->out_mem, C, LM);
@@ -1921,6 +1935,14 @@
          if (value<0 || value>=st->mode->nbEBands)
             goto bad_arg;
          st->start = value;
+      }
+      break;
+      case CELT_SET_END_BAND_REQUEST:
+      {
+         celt_int32 value = va_arg(ap, celt_int32);
+         if (value<0 || value>=st->mode->nbEBands)
+            goto bad_arg;
+         st->end = value;
       }
       break;
       case CELT_RESET_STATE:
--- a/libcelt/celt.h
+++ b/libcelt/celt.h
@@ -96,8 +96,10 @@
 #define CELT_RESET_STATE       CELT_RESET_STATE_REQUEST
 
 #define CELT_SET_START_BAND_REQUEST    10000
-/** Controls the complexity from 0-10 (int) */
 #define CELT_SET_START_BAND(x) CELT_SET_START_BAND_REQUEST, _celt_check_int(x)
+
+#define CELT_SET_END_BAND_REQUEST    10001
+#define CELT_SET_END_BAND(x) CELT_SET_END_BAND_REQUEST, _celt_check_int(x)
 
 /** GET the lookahead used in the current mode */
 #define CELT_GET_LOOKAHEAD    1001
--- a/libcelt/quant_bands.c
+++ b/libcelt/quant_bands.c
@@ -84,7 +84,7 @@
    celt_free(freq);
 }
 
-unsigned quant_coarse_energy(const CELTMode *m, int start, const celt_word16 *eBands, celt_word16 *oldEBands, int budget, int intra, int *prob, celt_word16 *error, ec_enc *enc, int _C, celt_word16 max_decay)
+unsigned quant_coarse_energy(const CELTMode *m, int start, int end, const celt_word16 *eBands, celt_word16 *oldEBands, int budget, int intra, int *prob, celt_word16 *error, ec_enc *enc, int _C, celt_word16 max_decay)
 {
    int i, c;
    unsigned bits_used = 0;
@@ -102,7 +102,7 @@
    beta = MULT16_16_P15(QCONST16(.8f,15),coef);
 
    /* Encode at a fixed coarse resolution */
-   for (i=start;i<m->nbEBands;i++)
+   for (i=start;i<end;i++)
    {
       c=0;
       do {
@@ -147,13 +147,13 @@
    return bits_used;
 }
 
-void quant_fine_energy(const CELTMode *m, int start, celt_ener *eBands, celt_word16 *oldEBands, celt_word16 *error, int *fine_quant, ec_enc *enc, int _C)
+void quant_fine_energy(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, celt_word16 *error, int *fine_quant, ec_enc *enc, int _C)
 {
    int i, c;
    const int C = CHANNELS(_C);
 
    /* Encode finer resolution */
-   for (i=start;i<m->nbEBands;i++)
+   for (i=start;i<end;i++)
    {
       celt_int16 frac = 1<<fine_quant[i];
       if (fine_quant[i] <= 0)
@@ -185,7 +185,7 @@
    }
 }
 
-void quant_energy_finalise(const CELTMode *m, int start, celt_ener *eBands, celt_word16 *oldEBands, celt_word16 *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc, int _C)
+void quant_energy_finalise(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, celt_word16 *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc, int _C)
 {
    int i, prio, c;
    const int C = CHANNELS(_C);
@@ -193,7 +193,7 @@
    /* Use up the remaining bits */
    for (prio=0;prio<2;prio++)
    {
-      for (i=start;i<m->nbEBands && bits_left>=C ;i++)
+      for (i=start;i<end && bits_left>=C ;i++)
       {
          if (fine_quant[i] >= 7 || fine_priority[i]!=prio)
             continue;
@@ -224,7 +224,7 @@
    } while (++c < C);
 }
 
-void unquant_coarse_energy(const CELTMode *m, int start, celt_ener *eBands, celt_word16 *oldEBands, int budget, int intra, int *prob, ec_dec *dec, int _C)
+void unquant_coarse_energy(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, int budget, int intra, int *prob, ec_dec *dec, int _C)
 {
    int i, c;
    celt_word32 prev[2] = {0, 0};
@@ -241,7 +241,7 @@
    beta = MULT16_16_P15(QCONST16(.8f,15),coef);
 
    /* Decode at a fixed coarse resolution */
-   for (i=start;i<m->nbEBands;i++)
+   for (i=start;i<end;i++)
    {
       c=0;
       do {
@@ -262,12 +262,12 @@
    }
 }
 
-void unquant_fine_energy(const CELTMode *m, int start, celt_ener *eBands, celt_word16 *oldEBands, int *fine_quant, ec_dec *dec, int _C)
+void unquant_fine_energy(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, int *fine_quant, ec_dec *dec, int _C)
 {
    int i, c;
    const int C = CHANNELS(_C);
    /* Decode finer resolution */
-   for (i=start;i<m->nbEBands;i++)
+   for (i=start;i<end;i++)
    {
       if (fine_quant[i] <= 0)
          continue;
@@ -286,7 +286,7 @@
    }
 }
 
-void unquant_energy_finalise(const CELTMode *m, int start, celt_ener *eBands, celt_word16 *oldEBands, int *fine_quant,  int *fine_priority, int bits_left, ec_dec *dec, int _C)
+void unquant_energy_finalise(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, int *fine_quant,  int *fine_priority, int bits_left, ec_dec *dec, int _C)
 {
    int i, prio, c;
    const int C = CHANNELS(_C);
@@ -294,7 +294,7 @@
    /* Use up the remaining bits */
    for (prio=0;prio<2;prio++)
    {
-      for (i=start;i<m->nbEBands && bits_left>=C ;i++)
+      for (i=start;i<end && bits_left>=C ;i++)
       {
          if (fine_quant[i] >= 7 || fine_priority[i]!=prio)
             continue;
--- a/libcelt/quant_bands.h
+++ b/libcelt/quant_bands.h
@@ -56,16 +56,16 @@
 
 int intra_decision(celt_word16 *eBands, celt_word16 *oldEBands, int len);
 
-unsigned quant_coarse_energy(const CELTMode *m, int start, const celt_word16 *eBands, celt_word16 *oldEBands, int budget, int intra, int *prob, celt_word16 *error, ec_enc *enc, int _C, celt_word16 max_decay);
+unsigned quant_coarse_energy(const CELTMode *m, int start, int end, const celt_word16 *eBands, celt_word16 *oldEBands, int budget, int intra, int *prob, celt_word16 *error, ec_enc *enc, int _C, celt_word16 max_decay);
 
-void quant_fine_energy(const CELTMode *m, int start, celt_ener *eBands, celt_word16 *oldEBands, celt_word16 *error, int *fine_quant, ec_enc *enc, int _C);
+void quant_fine_energy(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, celt_word16 *error, int *fine_quant, ec_enc *enc, int _C);
 
-void quant_energy_finalise(const CELTMode *m, int start, celt_ener *eBands, celt_word16 *oldEBands, celt_word16 *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc, int _C);
+void quant_energy_finalise(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, celt_word16 *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc, int _C);
 
-void unquant_coarse_energy(const CELTMode *m, int start, celt_ener *eBands, celt_word16 *oldEBands, int budget, int intra, int *prob, ec_dec *dec, int _C);
+void unquant_coarse_energy(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, int budget, int intra, int *prob, ec_dec *dec, int _C);
 
-void unquant_fine_energy(const CELTMode *m, int start, celt_ener *eBands, celt_word16 *oldEBands, int *fine_quant, ec_dec *dec, int _C);
+void unquant_fine_energy(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, int *fine_quant, ec_dec *dec, int _C);
 
-void unquant_energy_finalise(const CELTMode *m, int start, celt_ener *eBands, celt_word16 *oldEBands, int *fine_quant, int *fine_priority, int bits_left, ec_dec *dec, int _C);
+void unquant_energy_finalise(const CELTMode *m, int start, int end, celt_ener *eBands, celt_word16 *oldEBands, int *fine_quant, int *fine_priority, int bits_left, ec_dec *dec, int _C);
 
 #endif /* QUANT_BANDS */
--- a/libcelt/rate.c
+++ b/libcelt/rate.c
@@ -111,7 +111,7 @@
 
 
 
-static inline void interp_bits2pulses(const CELTMode *m, int start, int *bits1, int *bits2, int total, int *bits, int *ebits, int *fine_priority, int len, int _C, int M)
+static inline void interp_bits2pulses(const CELTMode *m, int start, int end, int *bits1, int *bits2, int total, int *bits, int *ebits, int *fine_priority, int len, int _C, int M)
 {
    int psum;
    int lo, hi;
@@ -127,7 +127,7 @@
    {
       int mid = (lo+hi)>>1;
       psum = 0;
-      for (j=start;j<len;j++)
+      for (j=start;j<end;j++)
          psum += (((1<<BITRES)-mid)*bits1[j] + mid*bits2[j])>>BITRES;
       if (psum > (total<<BITRES))
          hi = mid;
@@ -136,7 +136,7 @@
    }
    psum = 0;
    /*printf ("interp bisection gave %d\n", lo);*/
-   for (j=start;j<len;j++)
+   for (j=start;j<end;j++)
    {
       bits[j] = (((1<<BITRES)-lo)*bits1[j] + lo*bits2[j])>>BITRES;
       psum += bits[j];
@@ -145,14 +145,14 @@
    {
       int left, perband;
       left = (total<<BITRES)-psum;
-      perband = left/(len-start);
-      for (j=start;j<len;j++)
+      perband = left/(end-start);
+      for (j=start;j<end;j++)
          bits[j] += perband;
-      left = left-len*perband;
+      left = left-end*perband;
       for (j=start;j<start+left;j++)
          bits[j]++;
    }
-   for (j=start;j<len;j++)
+   for (j=start;j<end;j++)
    {
       int N, d;
       int offset;
@@ -187,7 +187,7 @@
    RESTORE_STACK;
 }
 
-void compute_allocation(const CELTMode *m, int start, int *offsets, int total, int *pulses, int *ebits, int *fine_priority, int _C, int M)
+void compute_allocation(const CELTMode *m, int start, int end, int *offsets, int total, int *pulses, int *ebits, int *fine_priority, int _C, int M)
 {
    int lo, hi, len, j;
    const int C = CHANNELS(_C);
@@ -205,7 +205,7 @@
    {
       int psum = 0;
       int mid = (lo+hi) >> 1;
-      for (j=start;j<len;j++)
+      for (j=start;j<end;j++)
       {
          int N = m->eBands[j+1]-m->eBands[j];
          bits1[j] = (C*M*N*m->allocVectors[mid*len+j] + offsets[j]);
@@ -222,7 +222,7 @@
       /*printf ("lo = %d, hi = %d\n", lo, hi);*/
    }
    /*printf ("interp between %d and %d\n", lo, hi);*/
-   for (j=start;j<len;j++)
+   for (j=start;j<end;j++)
    {
       int N = m->eBands[j+1]-m->eBands[j];
       bits1[j] = C*M*N*m->allocVectors[lo*len+j] + offsets[j];
@@ -232,7 +232,7 @@
       if (bits2[j] < 0)
          bits2[j] = 0;
    }
-   interp_bits2pulses(m, start, bits1, bits2, total, pulses, ebits, fine_priority, len, C, M);
+   interp_bits2pulses(m, start, end, bits1, bits2, total, pulses, ebits, fine_priority, len, C, M);
    RESTORE_STACK;
 }
 
--- a/libcelt/rate.h
+++ b/libcelt/rate.h
@@ -166,7 +166,7 @@
  @param pulses Number of pulses per band (returned)
  @return Total number of bits allocated
 */
-void compute_allocation(const CELTMode *m, int start, int *offsets, int total, int *pulses, int *ebits, int *fine_priority, int _C, int M);
+void compute_allocation(const CELTMode *m, int start, int end, int *offsets, int total, int *pulses, int *ebits, int *fine_priority, int _C, int M);
 
 
 #endif
--- a/libcelt/vq.h
+++ b/libcelt/vq.h
@@ -64,17 +64,4 @@
 
 celt_word16 renormalise_vector(celt_norm *X, celt_word16 value, int N, int stride);
 
-/** Intra-frame predictor that matches a section of the current frame (at lower
- * frequencies) to encode the current band.
- * @param x Residual signal to quantise/encode (returns quantised version)
- * @param W Perceptual weight
- * @param N Number of samples to encode
- * @param K Number of pulses to use
- * @param Y Lower frequency spectrum to use, normalised to the same standard deviation
- * @param P Pitch vector (it is assumed that p+x is a unit vector)
- * @param B Stride (number of channels multiplied by the number of MDCTs per frame)
- * @param N0 Number of valid offsets
- */
-void intra_fold(const CELTMode *m, int start, int N, const celt_norm * restrict Y, celt_norm * restrict P, int N0, int B, int M);
-
 #endif /* VQ_H */