Unified allocation of fine energy and pulses.
authorJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Sat, 2 Aug 2008 12:14:42 +0000 (08:14 -0400)
committerJean-Marc Valin <jean-marc.valin@usherbrooke.ca>
Sat, 2 Aug 2008 12:14:42 +0000 (08:14 -0400)
libcelt/bands.c
libcelt/bands.h
libcelt/celt.c
libcelt/modes.c
libcelt/quant_bands.c
libcelt/quant_bands.h
libcelt/rate.c
libcelt/rate.h

index c062101..d686f2d 100644 (file)
@@ -329,33 +329,23 @@ void stereo_decision(const CELTMode *m, celt_norm_t * restrict X, int *stereo_mo
 
 
 /* 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 total_bits, int shortBlocks, 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, ec_enc *enc)
 {
-   int i, j, bits;
+   int i, j;
    const celt_int16_t * restrict eBands = m->eBands;
    celt_norm_t * restrict norm;
    VARDECL(celt_norm_t, _norm);
-   VARDECL(int, pulses);
-   VARDECL(int, offsets);
    const int C = CHANNELS(m);
    int B;
    SAVE_STACK;
 
    B = shortBlocks ? m->nbShortMdcts : 1;
    ALLOC(_norm, C*eBands[m->nbEBands+1], celt_norm_t);
-   ALLOC(pulses, m->nbEBands, int);
-   ALLOC(offsets, m->nbEBands, int);
    norm = _norm;
 
-   for (i=0;i<m->nbEBands;i++)
-      offsets[i] = 0;
-   /* Use a single-bit margin to guard against overrunning (make sure it's enough) */
-   bits = total_bits - ec_enc_tell(enc, 0) - 1;
-   compute_allocation(m, offsets, stereo_mode, bits, pulses);
-   
    /*printf("bits left: %d\n", bits);
    for (i=0;i<m->nbEBands;i++)
-      printf ("%d ", pulses[i]);
+      printf ("(%d %d) ", pulses[i], ebits[i]);
    printf ("\n");*/
    /*printf ("%d %d\n", ec_enc_tell(enc, 0), compute_allocation(m, m->nbPulses));*/
    for (i=0;i<m->nbEBands;i++)
@@ -399,31 +389,21 @@ void quant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, ce
 }
 
 /* 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 total_bits, int shortBlocks, 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, ec_dec *dec)
 {
-   int i, j, bits;
+   int i, j;
    const celt_int16_t * restrict eBands = m->eBands;
    celt_norm_t * restrict norm;
    VARDECL(celt_norm_t, _norm);
-   VARDECL(int, pulses);
-   VARDECL(int, offsets);
    const int C = CHANNELS(m);
    int B;
    SAVE_STACK;
 
    B = shortBlocks ? m->nbShortMdcts : 1;
    ALLOC(_norm, C*eBands[m->nbEBands+1], celt_norm_t);
-   ALLOC(pulses, m->nbEBands, int);
-   ALLOC(offsets, m->nbEBands, int);
    norm = _norm;
 
    for (i=0;i<m->nbEBands;i++)
-      offsets[i] = 0;
-   /* Use a single-bit margin to guard against overrunning (make sure it's enough) */
-   bits = total_bits - ec_dec_tell(dec, 0) - 1;
-   compute_allocation(m, offsets, stereo_mode, bits, pulses);
-
-   for (i=0;i<m->nbEBands;i++)
    {
       int q;
       celt_word16_t n;
index 3f3a78b..0f132ae 100644 (file)
@@ -86,7 +86,7 @@ void pitch_quant_bands(const CELTMode *m, celt_norm_t * restrict P, const celt_p
  * @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 total_bits, int time_domain, 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, ec_enc *enc);
 
 /** Decoding of the residual spectrum
  * @param m Mode data 
@@ -95,7 +95,7 @@ void quant_bands(const CELTMode *m, celt_norm_t * restrict X, celt_norm_t *P, ce
  * @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 total_bits, int time_domain, 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, ec_dec *dec);
 
 void stereo_decision(const CELTMode *m, celt_norm_t * restrict X, int *stereo_mode, int len);
 
index 699df1a..8fbaccf 100644 (file)
@@ -370,8 +370,10 @@ int celt_encode(CELTEncoder * restrict st, celt_int16_t * restrict pcm, unsigned
    VARDECL(celt_ener_t, bandE);
    VARDECL(celt_pgain_t, gains);
    VARDECL(int, stereo_mode);
-   VARDECL(celt_int16_t, fine_quant);
+   VARDECL(int, fine_quant);
    VARDECL(celt_word16_t, error);
+   VARDECL(int, pulses);
+   VARDECL(int, offsets);
 #ifdef EXP_PSY
    VARDECL(celt_word32_t, mask);
 #endif
@@ -529,22 +531,34 @@ int celt_encode(CELTEncoder * restrict st, celt_int16_t * restrict pcm, unsigned
          P[i] = 0;
    }
 
-   ALLOC(fine_quant, st->mode->nbEBands, celt_int16_t);
+   ALLOC(fine_quant, st->mode->nbEBands, int);
    ALLOC(error, C*st->mode->nbEBands, celt_word16_t);
-   bits = ec_enc_tell(&st->enc, 0);
    quant_coarse_energy(st->mode, bandE, st->oldBandE, 20*C+nbCompressedBytes*8, st->mode->prob, error, &st->enc);
-   compute_fine_allocation(st->mode, fine_quant, (20*C+nbCompressedBytes*8/5-(ec_enc_tell(&st->enc, 0)-bits))/C);
-   quant_fine_energy(st->mode, bandE, st->oldBandE, error, fine_quant, &st->enc);
-
+   
+   ALLOC(pulses, st->mode->nbEBands, int);
+   ALLOC(offsets, st->mode->nbEBands, int);
    ALLOC(stereo_mode, st->mode->nbEBands, int);
    stereo_decision(st->mode, X, stereo_mode, st->mode->nbEBands);
 
+   for (i=0;i<st->mode->nbEBands;i++)
+      offsets[i] = 0;
+   bits = nbCompressedBytes*8 - ec_enc_tell(&st->enc, 0) - 1;
+   compute_allocation(st->mode, offsets, stereo_mode, bits, pulses, fine_quant);
+   /*for (i=0;i<st->mode->nbEBands;i++)
+      printf("%d ", fine_quant[i]);
+   for (i=0;i<st->mode->nbEBands;i++)
+      printf("%d ", pulses[i]);
+   printf ("\n");*/
+   /*bits = ec_enc_tell(&st->enc, 0);
+   compute_fine_allocation(st->mode, fine_quant, (20*C+nbCompressedBytes*8/5-(ec_enc_tell(&st->enc, 0)-bits))/C);*/
+   quant_fine_energy(st->mode, bandE, st->oldBandE, error, fine_quant, &st->enc);
+
    pitch_quant_bands(st->mode, P, gains);
 
    /*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, nbCompressedBytes*8, shortBlocks, &st->enc);
+   quant_bands(st->mode, X, P, NULL, bandE, stereo_mode, pulses, shortBlocks, &st->enc);
    
    if (C==2)
    {
@@ -741,7 +755,7 @@ static void celt_decode_lost(CELTDecoder * restrict st, short * restrict pcm)
 
 int celt_decode(CELTDecoder * restrict st, unsigned char *data, int len, celt_int16_t * restrict pcm)
 {
-   int c, N, N4;
+   int i, c, N, N4;
    int has_pitch;
    int pitch_index;
    int bits;
@@ -753,7 +767,9 @@ int celt_decode(CELTDecoder * restrict st, unsigned char *data, int len, celt_in
    VARDECL(celt_ener_t, bandE);
    VARDECL(celt_pgain_t, gains);
    VARDECL(int, stereo_mode);
-   VARDECL(celt_int16_t, fine_quant);
+   VARDECL(int, fine_quant);
+   VARDECL(int, pulses);
+   VARDECL(int, offsets);
 
    int shortBlocks;
    int transient_time;
@@ -820,11 +836,23 @@ int celt_decode(CELTDecoder * restrict st, unsigned char *data, int len, celt_in
       pitch_index = 0;
    }
 
-   ALLOC(fine_quant, st->mode->nbEBands, celt_int16_t);
-   bits = ec_dec_tell(&dec, 0);
+   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);
-   compute_fine_allocation(st->mode, fine_quant, (20*C+len*8/5-(ec_dec_tell(&dec, 0)-bits))/C);
+   
+   ALLOC(pulses, st->mode->nbEBands, int);
+   ALLOC(offsets, st->mode->nbEBands, int);
+   ALLOC(stereo_mode, st->mode->nbEBands, int);
+   stereo_decision(st->mode, X, stereo_mode, st->mode->nbEBands);
+
+   for (i=0;i<st->mode->nbEBands;i++)
+      offsets[i] = 0;
+
+   bits = len*8 - ec_dec_tell(&dec, 0) - 1;
+   compute_allocation(st->mode, offsets, stereo_mode, bits, pulses, fine_quant);
+   /*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, bandE, st->oldBandE, fine_quant, &dec);
 
    /* Pitch MDCT */
@@ -837,13 +865,11 @@ int celt_decode(CELTDecoder * restrict st, unsigned char *data, int len, celt_in
       normalise_bands(st->mode, freq, P, bandEp);
    }
 
-   ALLOC(stereo_mode, st->mode->nbEBands, int);
-   stereo_decision(st->mode, X, stereo_mode, st->mode->nbEBands);
    /* Apply pitch gains */
    pitch_quant_bands(st->mode, P, gains);
 
    /* Decode fixed codebook and merge with pitch */
-   unquant_bands(st->mode, X, P, bandE, stereo_mode, len*8, shortBlocks, &dec);
+   unquant_bands(st->mode, X, P, bandE, stereo_mode, pulses, shortBlocks, &dec);
 
    if (C==2)
    {
index 3fc4a87..f791fc7 100644 (file)
@@ -245,6 +245,7 @@ static void compute_energy_allocation_table(CELTMode *mode)
 {
    int i, j;
    celt_int16_t *alloc;
+   const int C = CHANNELS(mode);
    
    alloc = celt_alloc(sizeof(celt_int16_t)*(mode->nbAllocVectors*(mode->nbEBands+1)));
    for (i=0;i<mode->nbAllocVectors;i++)
@@ -258,7 +259,7 @@ static void compute_energy_allocation_table(CELTMode *mode)
       for (j=0;j<mode->nbEBands;j++)
       {
          alloc[i*(mode->nbEBands+1)+j] = mode->allocVectors[i*mode->nbEBands+j]
-                                         / (mode->eBands[j+1]-mode->eBands[j]-1);
+                                         / (C*(mode->eBands[j+1]-mode->eBands[j]));
          if (alloc[i*(mode->nbEBands+1)+j]<min_bits)
             alloc[i*(mode->nbEBands+1)+j] = min_bits;
          if (alloc[i*(mode->nbEBands+1)+j]>7)
index ff9a91b..cdfb07e 100644 (file)
@@ -50,7 +50,7 @@ const celt_word16_t eMeans[24] = {45.f, -8.f, -12.f, -2.5f, 1.f, 0.f, 0.f, 0.f,
 /*const int frac[24] = {4, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};*/
 /*const int frac[24] = {8, 6, 5, 4, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2};*/
 
-void compute_fine_allocation(const CELTMode *m, celt_int16_t *bits, int budget)
+void compute_fine_allocation(const CELTMode *m, int *bits, int budget)
 {
    int i,j;
    int len;
@@ -185,7 +185,7 @@ static void quant_coarse_energy_mono(const CELTMode *m, celt_ener_t *eBands, cel
    }
 }
 
-static void quant_fine_energy_mono(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, celt_word16_t *error, celt_int16_t *fine_quant, ec_enc *enc)
+static void quant_fine_energy_mono(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, celt_word16_t *error, int *fine_quant, ec_enc *enc)
 {
    int i;
    /* Encode finer resolution */
@@ -250,7 +250,7 @@ static void unquant_coarse_energy_mono(const CELTMode *m, celt_ener_t *eBands, c
    }
 }
 
-static void unquant_fine_energy_mono(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, celt_int16_t *fine_quant, ec_dec *dec)
+static void unquant_fine_energy_mono(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int *fine_quant, ec_dec *dec)
 {
    int i;
    /* Decode finer resolution */
@@ -299,7 +299,7 @@ void quant_coarse_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *
    }
 }
 
-void quant_fine_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, celt_word16_t *error, celt_int16_t *fine_quant, ec_enc *enc)
+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)
 {
    int C;
    C = m->nbChannels;
@@ -347,7 +347,7 @@ void unquant_coarse_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t
    }
 }
 
-void unquant_fine_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, celt_int16_t *fine_quant, ec_dec *dec)
+void unquant_fine_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int *fine_quant, ec_dec *dec)
 {
    int C;   
 
index 8d9ae84..c1a2442 100644 (file)
 int *quant_prob_alloc(const CELTMode *m);
 void quant_prob_free(int *freq);
 
-void compute_fine_allocation(const CELTMode *m, celt_int16_t *bits, int budget);
+void compute_fine_allocation(const CELTMode *m, int *bits, int budget);
 
 void quant_coarse_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int budget, int *prob, celt_word16_t *error, ec_enc *enc);
 
-void quant_fine_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, celt_word16_t *error, celt_int16_t *fine_quant, ec_enc *enc);
+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 unquant_coarse_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int budget, int *prob, ec_dec *dec);
 
-void unquant_fine_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, celt_int16_t *fine_quant, ec_dec *dec);
+void unquant_fine_energy(const CELTMode *m, celt_ener_t *eBands, celt_word16_t *oldEBands, int *fine_quant, ec_dec *dec);
 
 #endif /* QUANT_BANDS */
index 3aea466..443146b 100644 (file)
@@ -132,11 +132,13 @@ static int vec_bits2pulses(const CELTMode *m, const celt_int16_t * const *cache,
    return sum;
 }
 
-static int interp_bits2pulses(const CELTMode *m, const celt_int16_t * const *cache, int *bits1, int *bits2, int total, int *pulses, int len)
+static int interp_bits2pulses(const CELTMode *m, const celt_int16_t * const *cache, int *bits1, int *bits2, int *ebits1, int *ebits2, int total, int *pulses, int *ebits, int len)
 {
+   int esum;
    int lo, hi, out;
    int j;
    VARDECL(int, bits);
+   const int C = CHANNELS(m);
    SAVE_STACK;
    ALLOC(bits, len, int);
    lo = 0;
@@ -144,24 +146,37 @@ static int interp_bits2pulses(const CELTMode *m, const celt_int16_t * const *cac
    while (hi-lo != 1)
    {
       int mid = (lo+hi)>>1;
+      esum = 0;
       for (j=0;j<len;j++)
-         bits[j] = ((1<<BITRES)-mid)*bits1[j] + mid*bits2[j];
-      if (vec_bits2pulses(m, cache, bits, pulses, len) > total<<BITRES)
+      {
+         ebits[j] = (((1<<BITRES)-mid)*ebits1[j] + mid*ebits2[j] + (1<<(BITRES-1)))>>BITRES;
+         esum += C*ebits[j];
+      }
+      for (j=0;j<len;j++)
+         bits[j] = ((1<<BITRES)-mid)*bits1[j] + mid*bits2[j] - C*(ebits[j]<<BITRES);
+      if (vec_bits2pulses(m, cache, bits, pulses, len) > (total-esum)<<BITRES)
          hi = mid;
       else
          lo = mid;
    }
+   esum = 0;
    /*printf ("interp bisection gave %d\n", lo);*/
    for (j=0;j<len;j++)
-      bits[j] = ((1<<BITRES)-lo)*bits1[j] + lo*bits2[j];
+   {
+      ebits[j] = (((1<<BITRES)-lo)*ebits1[j] + lo*ebits2[j] + (1<<(BITRES-1)))>>BITRES;
+      esum += C*ebits[j];
+   }
+   for (j=0;j<len;j++)
+      bits[j] = ((1<<BITRES)-lo)*bits1[j] + lo*bits2[j] - C*(ebits[j]<<BITRES);
    out = vec_bits2pulses(m, cache, bits, pulses, len);
+   /*printf ("left to allocate: %d\n", total-esum-(out>>BITRES));*/
    /* Do some refinement to use up all bits. In the first pass, we can only add pulses to 
       bands that are under their allocated budget. In the second pass, anything goes */
    for (j=0;j<len;j++)
    {
       if (cache[j][pulses[j]] < bits[j] && pulses[j]<MAX_PULSES-1)
       {
-         if (out+cache[j][pulses[j]+1]-cache[j][pulses[j]] <= total<<BITRES)
+         if (out+cache[j][pulses[j]+1]-cache[j][pulses[j]] <= (total-esum)<<BITRES)
          {
             out = out+cache[j][pulses[j]+1]-cache[j][pulses[j]];
             pulses[j] += 1;
@@ -175,7 +190,7 @@ static int interp_bits2pulses(const CELTMode *m, const celt_int16_t * const *cac
       {
          if (pulses[j]<MAX_PULSES-1)
          {
-            if (out+cache[j][pulses[j]+1]-cache[j][pulses[j]] <= total<<BITRES)
+            if (out+cache[j][pulses[j]+1]-cache[j][pulses[j]] <= (total-esum)<<BITRES)
             {
                out = out+cache[j][pulses[j]+1]-cache[j][pulses[j]];
                pulses[j] += 1;
@@ -190,17 +205,22 @@ static int interp_bits2pulses(const CELTMode *m, const celt_int16_t * const *cac
    return (out+BITROUND) >> BITRES;
 }
 
-int compute_allocation(const CELTMode *m, int *offsets, const int *stereo_mode, int total, int *pulses)
+int compute_allocation(const CELTMode *m, int *offsets, const int *stereo_mode, int total, int *pulses, int *ebits)
 {
    int lo, hi, len, ret, i;
    VARDECL(int, bits1);
    VARDECL(int, bits2);
+   VARDECL(int, ebits1);
+   VARDECL(int, ebits2);
    VARDECL(const celt_int16_t*, cache);
+   const int C = CHANNELS(m);
    SAVE_STACK;
    
    len = m->nbEBands;
    ALLOC(bits1, len, int);
    ALLOC(bits2, len, int);
+   ALLOC(ebits1, len, int);
+   ALLOC(ebits2, len, int);
    ALLOC(cache, len, const celt_int16_t*);
    
    if (m->nbChannels==2)
@@ -225,30 +245,33 @@ int compute_allocation(const CELTMode *m, int *offsets, const int *stereo_mode,
       int mid = (lo+hi) >> 1;
       for (j=0;j<len;j++)
       {
-         bits1[j] = (m->allocVectors[mid*len+j] + offsets[j])<<BITRES;
+         bits1[j] = (m->allocVectors[mid*len+j] - C*m->energy_alloc[mid*(len+1)+j] + offsets[j])<<BITRES;
          if (bits1[j] < 0)
             bits1[j] = 0;
          /*printf ("%d ", bits[j]);*/
       }
       /*printf ("\n");*/
-      if (vec_bits2pulses(m, cache, bits1, pulses, len) > total<<BITRES)
+      if (vec_bits2pulses(m, cache, bits1, pulses, len) > (total-C*m->energy_alloc[mid*(len+1)+len])<<BITRES)
          hi = mid;
       else
          lo = mid;
       /*printf ("lo = %d, hi = %d\n", lo, hi);*/
    }
+   /*printf ("interp between %d and %d\n", lo, hi);*/
    {
       int j;
       for (j=0;j<len;j++)
       {
-         bits1[j] = m->allocVectors[lo*len+j] + offsets[j];
-         bits2[j] = m->allocVectors[hi*len+j] + offsets[j];
+         ebits1[j] = m->energy_alloc[lo*(len+1)+j];
+         ebits2[j] = m->energy_alloc[hi*(len+1)+j];
+         bits1[j] = m->allocVectors[lo*len+j] + offsets[j] - 0*ebits1[j];
+         bits2[j] = m->allocVectors[hi*len+j] + offsets[j] - 0*ebits2[j];
          if (bits1[j] < 0)
             bits1[j] = 0;
          if (bits2[j] < 0)
             bits2[j] = 0;
       }
-      ret = interp_bits2pulses(m, cache, bits1, bits2, total, pulses, len);
+      ret = interp_bits2pulses(m, cache, bits1, bits2, ebits1, ebits2, total, pulses, ebits, len);
       RESTORE_STACK;
       return ret;
    }
index ff8b05d..6554292 100644 (file)
@@ -47,7 +47,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
 */
-int compute_allocation(const CELTMode *m, int *offsets, const int *stereo_mode, int total, int *pulses);
+int compute_allocation(const CELTMode *m, int *offsets, const int *stereo_mode, int total, int *pulses, int *ebits);
 
 
 #endif