Blame libcelt/bands.c

Packit 664db3
/* (C) 2007-2008 Jean-Marc Valin, CSIRO
Packit 664db3
*/
Packit 664db3
/*
Packit 664db3
   Redistribution and use in source and binary forms, with or without
Packit 664db3
   modification, are permitted provided that the following conditions
Packit 664db3
   are met:
Packit 664db3
   
Packit 664db3
   - Redistributions of source code must retain the above copyright
Packit 664db3
   notice, this list of conditions and the following disclaimer.
Packit 664db3
   
Packit 664db3
   - Redistributions in binary form must reproduce the above copyright
Packit 664db3
   notice, this list of conditions and the following disclaimer in the
Packit 664db3
   documentation and/or other materials provided with the distribution.
Packit 664db3
   
Packit 664db3
   - Neither the name of the Xiph.org Foundation nor the names of its
Packit 664db3
   contributors may be used to endorse or promote products derived from
Packit 664db3
   this software without specific prior written permission.
Packit 664db3
   
Packit 664db3
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Packit 664db3
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Packit 664db3
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
Packit 664db3
   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
Packit 664db3
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
Packit 664db3
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
Packit 664db3
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
Packit 664db3
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
Packit 664db3
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
Packit 664db3
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
Packit 664db3
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit 664db3
*/
Packit 664db3
Packit 664db3
#ifdef HAVE_CONFIG_H
Packit 664db3
#include "config.h"
Packit 664db3
#endif
Packit 664db3
Packit 664db3
#include <math.h>
Packit 664db3
#include "bands.h"
Packit 664db3
#include "modes.h"
Packit 664db3
#include "vq.h"
Packit 664db3
#include "cwrs.h"
Packit 664db3
#include "stack_alloc.h"
Packit 664db3
#include "os_support.h"
Packit 664db3
#include "mathops.h"
Packit 664db3
#include "rate.h"
Packit 664db3
Packit 664db3
const celt_word16_t sqrtC_1[2] = {QCONST16(1.f, 14), QCONST16(1.414214f, 14)};
Packit 664db3
Packit 664db3
#ifdef FIXED_POINT
Packit 664db3
/* Compute the amplitude (sqrt energy) in each of the bands */
Packit 664db3
void compute_band_energies(const CELTMode *m, const celt_sig_t *X, celt_ener_t *bank)
Packit 664db3
{
Packit 664db3
   int i, c;
Packit 664db3
   const celt_int16_t *eBands = m->eBands;
Packit 664db3
   const int C = CHANNELS(m);
Packit 664db3
   for (c=0;c
Packit 664db3
   {
Packit 664db3
      for (i=0;i<m->nbEBands;i++)
Packit 664db3
      {
Packit 664db3
         int j;
Packit 664db3
         celt_word32_t maxval=0;
Packit 664db3
         celt_word32_t sum = 0;
Packit 664db3
         
Packit 664db3
         j=eBands[i]; do {
Packit 664db3
            maxval = MAX32(maxval, X[j*C+c]);
Packit 664db3
            maxval = MAX32(maxval, -X[j*C+c]);
Packit 664db3
         } while (++j
Packit 664db3
         
Packit 664db3
         if (maxval > 0)
Packit 664db3
         {
Packit 664db3
            int shift = celt_ilog2(maxval)-10;
Packit 664db3
            j=eBands[i]; do {
Packit 664db3
               sum = MAC16_16(sum, EXTRACT16(VSHR32(X[j*C+c],shift)),
Packit 664db3
                                   EXTRACT16(VSHR32(X[j*C+c],shift)));
Packit 664db3
            } while (++j
Packit 664db3
            /* We're adding one here to make damn sure we never end up with a pitch vector that's
Packit 664db3
               larger than unity norm */
Packit 664db3
            bank[i*C+c] = EPSILON+VSHR32(EXTEND32(celt_sqrt(sum)),-shift);
Packit 664db3
         } else {
Packit 664db3
            bank[i*C+c] = EPSILON;
Packit 664db3
         }
Packit 664db3
         /*printf ("%f ", bank[i*C+c]);*/
Packit 664db3
      }
Packit 664db3
   }
Packit 664db3
   /*printf ("\n");*/
Packit 664db3
}
Packit 664db3
Packit 664db3
/* Normalise each band such that the energy is one. */
Packit 664db3
void normalise_bands(const CELTMode *m, const celt_sig_t * restrict freq, celt_norm_t * restrict X, const celt_ener_t *bank)
Packit 664db3
{
Packit 664db3
   int i, c;
Packit 664db3
   const celt_int16_t *eBands = m->eBands;
Packit 664db3
   const int C = CHANNELS(m);
Packit 664db3
   for (c=0;c
Packit 664db3
   {
Packit 664db3
      i=0; do {
Packit 664db3
         celt_word16_t g;
Packit 664db3
         int j,shift;
Packit 664db3
         celt_word16_t E;
Packit 664db3
         shift = celt_zlog2(bank[i*C+c])-13;
Packit 664db3
         E = VSHR32(bank[i*C+c], shift);
Packit 664db3
         g = EXTRACT16(celt_rcp(SHR32(MULT16_16(E,sqrtC_1[C-1]),11)));
Packit 664db3
         j=eBands[i]; do {
Packit 664db3
            X[j*C+c] = MULT16_16_Q15(VSHR32(freq[j*C+c],shift-1),g);
Packit 664db3
         } while (++j
Packit 664db3
      } while (++i<m->nbEBands);
Packit 664db3
   }
Packit 664db3
}
Packit 664db3
Packit 664db3
#else /* FIXED_POINT */
Packit 664db3
/* Compute the amplitude (sqrt energy) in each of the bands */
Packit 664db3
void compute_band_energies(const CELTMode *m, const celt_sig_t *X, celt_ener_t *bank)
Packit 664db3
{
Packit 664db3
   int i, c;
Packit 664db3
   const celt_int16_t *eBands = m->eBands;
Packit 664db3
   const int C = CHANNELS(m);
Packit 664db3
   for (c=0;c
Packit 664db3
   {
Packit 664db3
      for (i=0;i<m->nbEBands;i++)
Packit 664db3
      {
Packit 664db3
         int j;
Packit 664db3
         celt_word32_t sum = 1e-10;
Packit 664db3
         for (j=eBands[i];j
Packit 664db3
            sum += X[j*C+c]*X[j*C+c];
Packit 664db3
         bank[i*C+c] = sqrt(sum);
Packit 664db3
         /*printf ("%f ", bank[i*C+c]);*/
Packit 664db3
      }
Packit 664db3
   }
Packit 664db3
   /*printf ("\n");*/
Packit 664db3
}
Packit 664db3
Packit 664db3
#ifdef EXP_PSY
Packit 664db3
void compute_noise_energies(const CELTMode *m, const celt_sig_t *X, const celt_word16_t *tonality, celt_ener_t *bank)
Packit 664db3
{
Packit 664db3
   int i, c;
Packit 664db3
   const celt_int16_t *eBands = m->eBands;
Packit 664db3
   const int C = CHANNELS(m);
Packit 664db3
   for (c=0;c
Packit 664db3
   {
Packit 664db3
      for (i=0;i<m->nbEBands;i++)
Packit 664db3
      {
Packit 664db3
         int j;
Packit 664db3
         celt_word32_t sum = 1e-10;
Packit 664db3
         for (j=eBands[i];j
Packit 664db3
            sum += X[j*C+c]*X[j*C+c]*tonality[j];
Packit 664db3
         bank[i*C+c] = sqrt(sum);
Packit 664db3
         /*printf ("%f ", bank[i*C+c]);*/
Packit 664db3
      }
Packit 664db3
   }
Packit 664db3
   /*printf ("\n");*/
Packit 664db3
}
Packit 664db3
#endif
Packit 664db3
Packit 664db3
/* Normalise each band such that the energy is one. */
Packit 664db3
void normalise_bands(const CELTMode *m, const celt_sig_t * restrict freq, celt_norm_t * restrict X, const celt_ener_t *bank)
Packit 664db3
{
Packit 664db3
   int i, c;
Packit 664db3
   const celt_int16_t *eBands = m->eBands;
Packit 664db3
   const int C = CHANNELS(m);
Packit 664db3
   for (c=0;c
Packit 664db3
   {
Packit 664db3
      for (i=0;i<m->nbEBands;i++)
Packit 664db3
      {
Packit 664db3
         int j;
Packit 664db3
         celt_word16_t g = 1.f/(1e-10+bank[i*C+c]*sqrt(C));
Packit 664db3
         for (j=eBands[i];j
Packit 664db3
            X[j*C+c] = freq[j*C+c]*g;
Packit 664db3
      }
Packit 664db3
   }
Packit 664db3
}
Packit 664db3
Packit 664db3
#endif /* FIXED_POINT */
Packit 664db3
Packit 664db3
#ifndef DISABLE_STEREO
Packit 664db3
void renormalise_bands(const CELTMode *m, celt_norm_t * restrict X)
Packit 664db3
{
Packit 664db3
   int i, c;
Packit 664db3
   const celt_int16_t *eBands = m->eBands;
Packit 664db3
   const int C = CHANNELS(m);
Packit 664db3
   for (c=0;c
Packit 664db3
   {
Packit 664db3
      i=0; do {
Packit 664db3
         renormalise_vector(X+C*eBands[i]+c, QCONST16(0.70711f, 15), eBands[i+1]-eBands[i], C);
Packit 664db3
      } while (++i<m->nbEBands);
Packit 664db3
   }
Packit 664db3
}
Packit 664db3
#endif /* DISABLE_STEREO */
Packit 664db3
Packit 664db3
/* De-normalise the energy to produce the synthesis from the unit-energy bands */
Packit 664db3
void denormalise_bands(const CELTMode *m, const celt_norm_t * restrict X, celt_sig_t * restrict freq, const celt_ener_t *bank)
Packit 664db3
{
Packit 664db3
   int i, c;
Packit 664db3
   const celt_int16_t *eBands = m->eBands;
Packit 664db3
   const int C = CHANNELS(m);
Packit 664db3
   if (C>2)
Packit 664db3
      celt_fatal("denormalise_bands() not implemented for >2 channels");
Packit 664db3
   for (c=0;c
Packit 664db3
   {
Packit 664db3
      for (i=0;i<m->nbEBands;i++)
Packit 664db3
      {
Packit 664db3
         int j;
Packit 664db3
         celt_word32_t g = MULT16_32_Q15(sqrtC_1[C-1],bank[i*C+c]);
Packit 664db3
         j=eBands[i]; do {
Packit 664db3
            freq[j*C+c] = SHL32(MULT16_32_Q15(X[j*C+c], g),2);
Packit 664db3
         } while (++j
Packit 664db3
      }
Packit 664db3
   }
Packit 664db3
   for (i=C*eBands[m->nbEBands];i<C*eBands[m->nbEBands+1];i++)
Packit 664db3
      freq[i] = 0;
Packit 664db3
}
Packit 664db3
Packit 664db3
Packit 664db3
/* Compute the best gain for each "pitch band" */
Packit 664db3
void compute_pitch_gain(const CELTMode *m, const celt_norm_t *X, const celt_norm_t *P, celt_pgain_t *gains)
Packit 664db3
{
Packit 664db3
   int i;
Packit 664db3
   const celt_int16_t *pBands = m->pBands;
Packit 664db3
   const int C = CHANNELS(m);
Packit 664db3
Packit 664db3
   for (i=0;i<m->nbPBands;i++)
Packit 664db3
   {
Packit 664db3
      celt_word32_t Sxy=0, Sxx=0;
Packit 664db3
      int j;
Packit 664db3
      /* We know we're not going to overflow because Sxx can't be more than 1 (Q28) */
Packit 664db3
      for (j=C*pBands[i];j
Packit 664db3
      {
Packit 664db3
         Sxy = MAC16_16(Sxy, X[j], P[j]);
Packit 664db3
         Sxx = MAC16_16(Sxx, X[j], X[j]);
Packit 664db3
      }
Packit 664db3
      /* No negative gain allowed */
Packit 664db3
      if (Sxy < 0)
Packit 664db3
         Sxy = 0;
Packit 664db3
      /* Not sure how that would happen, just making sure */
Packit 664db3
      if (Sxy > Sxx)
Packit 664db3
         Sxy = Sxx;
Packit 664db3
      /* We need to be a bit conservative (multiply gain by 0.9), otherwise the
Packit 664db3
         residual doesn't quantise well */
Packit 664db3
      Sxy = MULT16_32_Q15(QCONST16(.9f, 15), Sxy);
Packit 664db3
      /* gain = Sxy/Sxx */
Packit 664db3
      gains[i] = EXTRACT16(celt_div(Sxy,ADD32(SHR32(Sxx, PGAIN_SHIFT),EPSILON)));
Packit 664db3
      /*printf ("%f ", 1-sqrt(1-gain*gain));*/
Packit 664db3
   }
Packit 664db3
   /*if(rand()%10==0)
Packit 664db3
   {
Packit 664db3
      for (i=0;i<m->nbPBands;i++)
Packit 664db3
         printf ("%f ", 1-sqrt(1-gains[i]*gains[i]));
Packit 664db3
      printf ("\n");
Packit 664db3
   }*/
Packit 664db3
}
Packit 664db3
Packit 664db3
/* Apply the (quantised) gain to each "pitch band" */
Packit 664db3
void pitch_quant_bands(const CELTMode *m, celt_norm_t * restrict P, const celt_pgain_t * restrict gains)
Packit 664db3
{
Packit 664db3
   int i;
Packit 664db3
   const celt_int16_t *pBands = m->pBands;
Packit 664db3
   const int C = CHANNELS(m);
Packit 664db3
   for (i=0;i<m->nbPBands;i++)
Packit 664db3
   {
Packit 664db3
      int j;
Packit 664db3
      for (j=C*pBands[i];j
Packit 664db3
         P[j] = MULT16_16_Q15(gains[i], P[j]);
Packit 664db3
      /*printf ("%f ", gain);*/
Packit 664db3
   }
Packit 664db3
   for (i=C*pBands[m->nbPBands];i<C*pBands[m->nbPBands+1];i++)
Packit 664db3
      P[i] = 0;
Packit 664db3
}
Packit 664db3
Packit 664db3
static void intensity_band(celt_norm_t * restrict X, int len)
Packit 664db3
{
Packit 664db3
   int j;
Packit 664db3
   celt_word32_t E = 1e-15;
Packit 664db3
   celt_word32_t E2 = 1e-15;
Packit 664db3
   for (j=0;j
Packit 664db3
   {
Packit 664db3
      X[j] = X[2*j];
Packit 664db3
      E = MAC16_16(E, X[j],X[j]);
Packit 664db3
      E2 = MAC16_16(E2, X[2*j+1],X[2*j+1]);
Packit 664db3
   }
Packit 664db3
#ifndef FIXED_POINT
Packit 664db3
   E  = celt_sqrt(E+E2)/celt_sqrt(E);
Packit 664db3
   for (j=0;j
Packit 664db3
      X[j] *= E;
Packit 664db3
#endif
Packit 664db3
   for (j=0;j
Packit 664db3
      X[len+j] = 0;
Packit 664db3
Packit 664db3
}
Packit 664db3
Packit 664db3
static void dup_band(celt_norm_t * restrict X, int len)
Packit 664db3
{
Packit 664db3
   int j;
Packit 664db3
   for (j=len-1;j>=0;j--)
Packit 664db3
   {
Packit 664db3
      X[2*j] = MULT16_16_Q15(QCONST16(.70711f,15),X[j]);
Packit 664db3
      X[2*j+1] = MULT16_16_Q15(QCONST16(.70711f,15),X[j]);
Packit 664db3
   }
Packit 664db3
}
Packit 664db3
Packit 664db3
static void stereo_band_mix(const CELTMode *m, celt_norm_t *X, const celt_ener_t *bank, const int *stereo_mode, int bandID, int dir)
Packit 664db3
{
Packit 664db3
   int i = bandID;
Packit 664db3
   const celt_int16_t *eBands = m->eBands;
Packit 664db3
   const int C = CHANNELS(m);
Packit 664db3
   {
Packit 664db3
      int j;
Packit 664db3
      if (stereo_mode[i] && dir <0)
Packit 664db3
      {
Packit 664db3
         dup_band(X+C*eBands[i], eBands[i+1]-eBands[i]);
Packit 664db3
      } else {
Packit 664db3
         celt_word16_t a1, a2;
Packit 664db3
         if (stereo_mode[i]==0)
Packit 664db3
         {
Packit 664db3
            /* Do mid-side when not doing intensity stereo */
Packit 664db3
            a1 = QCONST16(.70711f,14);
Packit 664db3
            a2 = dir*QCONST16(.70711f,14);
Packit 664db3
         } else {
Packit 664db3
            celt_word16_t left, right;
Packit 664db3
            celt_word16_t norm;
Packit 664db3
#ifdef FIXED_POINT
Packit 664db3
            int shift = celt_zlog2(MAX32(bank[i*C], bank[i*C+1]))-13;
Packit 664db3
#endif
Packit 664db3
            left = VSHR32(bank[i*C],shift);
Packit 664db3
            right = VSHR32(bank[i*C+1],shift);
Packit 664db3
            norm = EPSILON + celt_sqrt(EPSILON+MULT16_16(left,left)+MULT16_16(right,right));
Packit 664db3
            a1 = DIV32_16(SHL32(EXTEND32(left),14),norm);
Packit 664db3
            a2 = dir*DIV32_16(SHL32(EXTEND32(right),14),norm);
Packit 664db3
         }
Packit 664db3
         for (j=eBands[i];j
Packit 664db3
         {
Packit 664db3
            celt_norm_t r, l;
Packit 664db3
            l = X[j*C];
Packit 664db3
            r = X[j*C+1];
Packit 664db3
            X[j*C] = MULT16_16_Q14(a1,l) + MULT16_16_Q14(a2,r);
Packit 664db3
            X[j*C+1] = MULT16_16_Q14(a1,r) - MULT16_16_Q14(a2,l);
Packit 664db3
         }
Packit 664db3
      }
Packit 664db3
      if (stereo_mode[i] && dir>0)
Packit 664db3
      {
Packit 664db3
         intensity_band(X+C*eBands[i], eBands[i+1]-eBands[i]);
Packit 664db3
      }
Packit 664db3
   }
Packit 664db3
}
Packit 664db3
Packit 664db3
void stereo_decision(const CELTMode *m, celt_norm_t * restrict X, int *stereo_mode, int len)
Packit 664db3
{
Packit 664db3
   int i;
Packit 664db3
   for (i=0;i
Packit 664db3
      stereo_mode[i] = 0;
Packit 664db3
   for (;i
Packit 664db3
      stereo_mode[i] = 0;
Packit 664db3
}
Packit 664db3
Packit 664db3
Packit 664db3
Packit 664db3
/* Quantisation of the residual */
Packit 664db3
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)
Packit 664db3
{
Packit 664db3
   int i, j, remaining_bits, balance;
Packit 664db3
   const celt_int16_t * restrict eBands = m->eBands;
Packit 664db3
   celt_norm_t * restrict norm;
Packit 664db3
   VARDECL(celt_norm_t, _norm);
Packit 664db3
   const int C = CHANNELS(m);
Packit 664db3
   int B;
Packit 664db3
   SAVE_STACK;
Packit 664db3
Packit 664db3
   B = shortBlocks ? m->nbShortMdcts : 1;
Packit 664db3
   ALLOC(_norm, C*eBands[m->nbEBands+1], celt_norm_t);
Packit 664db3
   norm = _norm;
Packit 664db3
Packit 664db3
   balance = 0;
Packit 664db3
   /*printf("bits left: %d\n", bits);
Packit 664db3
   for (i=0;i<m->nbEBands;i++)
Packit 664db3
      printf ("(%d %d) ", pulses[i], ebits[i]);
Packit 664db3
   printf ("\n");*/
Packit 664db3
   /*printf ("%d %d\n", ec_enc_tell(enc, 0), compute_allocation(m, m->nbPulses));*/
Packit 664db3
   for (i=0;i<m->nbEBands;i++)
Packit 664db3
   {
Packit 664db3
      int tell;
Packit 664db3
      int q;
Packit 664db3
      celt_word16_t n;
Packit 664db3
      const celt_int16_t * const *BPbits;
Packit 664db3
      
Packit 664db3
      int curr_balance, curr_bits;
Packit 664db3
      
Packit 664db3
      if (C>1 && stereo_mode[i]==0)
Packit 664db3
         BPbits = m->bits_stereo;
Packit 664db3
      else
Packit 664db3
         BPbits = m->bits;
Packit 664db3
Packit 664db3
      tell = ec_enc_tell(enc, 4);
Packit 664db3
      if (i != 0)
Packit 664db3
         balance -= tell;
Packit 664db3
      remaining_bits = (total_bits<
Packit 664db3
      curr_balance = (m->nbEBands-i);
Packit 664db3
      if (curr_balance > 3)
Packit 664db3
         curr_balance = 3;
Packit 664db3
      curr_balance = balance / curr_balance;
Packit 664db3
      q = bits2pulses(m, BPbits[i], pulses[i]+curr_balance);
Packit 664db3
      curr_bits = BPbits[i][q];
Packit 664db3
      remaining_bits -= curr_bits;
Packit 664db3
      while (remaining_bits < 0 && q > 0)
Packit 664db3
      {
Packit 664db3
         remaining_bits += curr_bits;
Packit 664db3
         q--;
Packit 664db3
         curr_bits = BPbits[i][q];
Packit 664db3
         remaining_bits -= curr_bits;
Packit 664db3
      }
Packit 664db3
      balance += pulses[i] + tell;
Packit 664db3
      
Packit 664db3
      n = SHL16(celt_sqrt(C*(eBands[i+1]-eBands[i])),11);
Packit 664db3
Packit 664db3
      /* If pitch isn't available, use intra-frame prediction */
Packit 664db3
      if ((eBands[i] >= m->pitchEnd && fold) || q<=0)
Packit 664db3
      {
Packit 664db3
         intra_fold(m, X+C*eBands[i], eBands[i+1]-eBands[i], q, norm, P+C*eBands[i], eBands[i], B);
Packit 664db3
      }
Packit 664db3
      
Packit 664db3
      if (q > 0)
Packit 664db3
      {
Packit 664db3
         int ch=C;
Packit 664db3
         if (C==2 && stereo_mode[i]==1)
Packit 664db3
            ch = 1;
Packit 664db3
         if (C==2)
Packit 664db3
         {
Packit 664db3
            stereo_band_mix(m, X, bandE, stereo_mode, i, 1);
Packit 664db3
            stereo_band_mix(m, P, bandE, stereo_mode, i, 1);
Packit 664db3
         }
Packit 664db3
         alg_quant(X+C*eBands[i], W+C*eBands[i], ch*(eBands[i+1]-eBands[i]), q, P+C*eBands[i], enc);
Packit 664db3
         if (C==2)
Packit 664db3
            stereo_band_mix(m, X, bandE, stereo_mode, i, -1);
Packit 664db3
      } else {
Packit 664db3
         for (j=C*eBands[i];j
Packit 664db3
            X[j] = P[j];
Packit 664db3
      }
Packit 664db3
      for (j=C*eBands[i];j
Packit 664db3
         norm[j] = MULT16_16_Q15(n,X[j]);
Packit 664db3
   }
Packit 664db3
   RESTORE_STACK;
Packit 664db3
}
Packit 664db3
Packit 664db3
/* Decoding of the residual */
Packit 664db3
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)
Packit 664db3
{
Packit 664db3
   int i, j, remaining_bits, balance;
Packit 664db3
   const celt_int16_t * restrict eBands = m->eBands;
Packit 664db3
   celt_norm_t * restrict norm;
Packit 664db3
   VARDECL(celt_norm_t, _norm);
Packit 664db3
   const int C = CHANNELS(m);
Packit 664db3
   int B;
Packit 664db3
   SAVE_STACK;
Packit 664db3
Packit 664db3
   B = shortBlocks ? m->nbShortMdcts : 1;
Packit 664db3
   ALLOC(_norm, C*eBands[m->nbEBands+1], celt_norm_t);
Packit 664db3
   norm = _norm;
Packit 664db3
Packit 664db3
   balance = 0;
Packit 664db3
   for (i=0;i<m->nbEBands;i++)
Packit 664db3
   {
Packit 664db3
      int tell;
Packit 664db3
      int q;
Packit 664db3
      celt_word16_t n;
Packit 664db3
      const celt_int16_t * const *BPbits;
Packit 664db3
      
Packit 664db3
      int curr_balance, curr_bits;
Packit 664db3
      
Packit 664db3
      if (C>1 && stereo_mode[i]==0)
Packit 664db3
         BPbits = m->bits_stereo;
Packit 664db3
      else
Packit 664db3
         BPbits = m->bits;
Packit 664db3
Packit 664db3
      tell = ec_dec_tell(dec, 4);
Packit 664db3
      if (i != 0)
Packit 664db3
         balance -= tell;
Packit 664db3
      remaining_bits = (total_bits<
Packit 664db3
      curr_balance = (m->nbEBands-i);
Packit 664db3
      if (curr_balance > 3)
Packit 664db3
         curr_balance = 3;
Packit 664db3
      curr_balance = balance / curr_balance;
Packit 664db3
      q = bits2pulses(m, BPbits[i], pulses[i]+curr_balance);
Packit 664db3
      curr_bits = BPbits[i][q];
Packit 664db3
      remaining_bits -= curr_bits;
Packit 664db3
      while (remaining_bits < 0 && q > 0)
Packit 664db3
      {
Packit 664db3
         remaining_bits += curr_bits;
Packit 664db3
         q--;
Packit 664db3
         curr_bits = BPbits[i][q];
Packit 664db3
         remaining_bits -= curr_bits;
Packit 664db3
      }
Packit 664db3
      balance += pulses[i] + tell;
Packit 664db3
Packit 664db3
      n = SHL16(celt_sqrt(C*(eBands[i+1]-eBands[i])),11);
Packit 664db3
Packit 664db3
      /* If pitch isn't available, use intra-frame prediction */
Packit 664db3
      if ((eBands[i] >= m->pitchEnd && fold) || q<=0)
Packit 664db3
      {
Packit 664db3
         intra_fold(m, X+C*eBands[i], eBands[i+1]-eBands[i], q, norm, P+C*eBands[i], eBands[i], B);
Packit 664db3
      }
Packit 664db3
      
Packit 664db3
      if (q > 0)
Packit 664db3
      {
Packit 664db3
         int ch=C;
Packit 664db3
         if (C==2 && stereo_mode[i]==1)
Packit 664db3
            ch = 1;
Packit 664db3
         if (C==2)
Packit 664db3
            stereo_band_mix(m, P, bandE, stereo_mode, i, 1);
Packit 664db3
         alg_unquant(X+C*eBands[i], ch*(eBands[i+1]-eBands[i]), q, P+C*eBands[i], dec);
Packit 664db3
         if (C==2)
Packit 664db3
            stereo_band_mix(m, X, bandE, stereo_mode, i, -1);
Packit 664db3
      } else {
Packit 664db3
         for (j=C*eBands[i];j
Packit 664db3
            X[j] = P[j];
Packit 664db3
      }
Packit 664db3
      for (j=C*eBands[i];j
Packit 664db3
         norm[j] = MULT16_16_Q15(n,X[j]);
Packit 664db3
   }
Packit 664db3
   RESTORE_STACK;
Packit 664db3
}
Packit 664db3