12bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian/* Copyright (c) 2007-2008 CSIRO
22bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   Copyright (c) 2007-2009 Xiph.Org Foundation
32bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   Copyright (c) 2008-2009 Gregory Maxwell
42bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   Written by Jean-Marc Valin and Gregory Maxwell */
52bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian/*
62bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   Redistribution and use in source and binary forms, with or without
72bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   modification, are permitted provided that the following conditions
82bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   are met:
92bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   - Redistributions of source code must retain the above copyright
112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   notice, this list of conditions and the following disclaimer.
122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   - Redistributions in binary form must reproduce the above copyright
142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   notice, this list of conditions and the following disclaimer in the
152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   documentation and/or other materials provided with the distribution.
162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian*/
292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef HAVE_CONFIG_H
312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include "config.h"
322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include <math.h>
352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include "bands.h"
362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include "modes.h"
372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include "vq.h"
382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include "cwrs.h"
392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include "stack_alloc.h"
402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include "os_support.h"
412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include "mathops.h"
422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include "rate.h"
432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include "quant_bands.h"
442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include "pitch.h"
452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianint hysteresis_decision(opus_val16 val, const opus_val16 *thresholds, const opus_val16 *hysteresis, int N, int prev)
472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int i;
492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   for (i=0;i<N;i++)
502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (val < thresholds[i])
522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         break;
532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (i>prev && val < thresholds[prev]+hysteresis[prev])
552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      i=prev;
562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (i<prev && val > thresholds[prev-1]-hysteresis[prev-1])
572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      i=prev;
582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   return i;
592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianopus_uint32 celt_lcg_rand(opus_uint32 seed)
622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   return 1664525 * seed + 1013904223;
642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian/* This is a cos() approximation designed to be bit-exact on any platform. Bit exactness
672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   with this approximation is important because it has an impact on the bit allocation */
682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic opus_int16 bitexact_cos(opus_int16 x)
692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_int32 tmp;
712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_int16 x2;
722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   tmp = (4096+((opus_int32)(x)*(x)))>>13;
732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   celt_assert(tmp<=32767);
742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   x2 = tmp;
752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   x2 = (32767-x2) + FRAC_MUL16(x2, (-7651 + FRAC_MUL16(x2, (8277 + FRAC_MUL16(-626, x2)))));
762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   celt_assert(x2<=32766);
772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   return 1+x2;
782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic int bitexact_log2tan(int isin,int icos)
812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int lc;
832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int ls;
842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   lc=EC_ILOG(icos);
852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ls=EC_ILOG(isin);
862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   icos<<=15-lc;
872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   isin<<=15-ls;
882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   return (ls-lc)*(1<<11)
892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         +FRAC_MUL16(isin, FRAC_MUL16(isin, -2597) + 7932)
902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         -FRAC_MUL16(icos, FRAC_MUL16(icos, -2597) + 7932);
912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef FIXED_POINT
942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian/* Compute the amplitude (sqrt energy) in each of the bands */
952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianvoid compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int M)
962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int i, c, N;
982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   const opus_int16 *eBands = m->eBands;
992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   N = M*m->shortMdctSize;
1002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   c=0; do {
1012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      for (i=0;i<end;i++)
1022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
1032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         int j;
1042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         opus_val32 maxval=0;
1052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         opus_val32 sum = 0;
1062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
1072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         j=M*eBands[i]; do {
1082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            maxval = MAX32(maxval, X[j+c*N]);
1092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            maxval = MAX32(maxval, -X[j+c*N]);
1102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         } while (++j<M*eBands[i+1]);
1112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
1122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         if (maxval > 0)
1132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         {
1142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            int shift = celt_ilog2(maxval)-10;
1152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            j=M*eBands[i]; do {
1162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               sum = MAC16_16(sum, EXTRACT16(VSHR32(X[j+c*N],shift)),
1172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                                   EXTRACT16(VSHR32(X[j+c*N],shift)));
1182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            } while (++j<M*eBands[i+1]);
1192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            /* We're adding one here to ensure the normalized band isn't larger than unity norm */
1202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            bandE[i+c*m->nbEBands] = EPSILON+VSHR32(EXTEND32(celt_sqrt(sum)),-shift);
1212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         } else {
1222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            bandE[i+c*m->nbEBands] = EPSILON;
1232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         }
1242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         /*printf ("%f ", bandE[i+c*m->nbEBands]);*/
1252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
1262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   } while (++c<C);
1272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /*printf ("\n");*/
1282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
1292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
1302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian/* Normalise each band such that the energy is one. */
1312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianvoid normalise_bands(const CELTMode *m, const celt_sig * OPUS_RESTRICT freq, celt_norm * OPUS_RESTRICT X, const celt_ener *bandE, int end, int C, int M)
1322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
1332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int i, c, N;
1342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   const opus_int16 *eBands = m->eBands;
1352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   N = M*m->shortMdctSize;
1362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   c=0; do {
1372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      i=0; do {
1382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         opus_val16 g;
1392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         int j,shift;
1402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         opus_val16 E;
1412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         shift = celt_zlog2(bandE[i+c*m->nbEBands])-13;
1422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         E = VSHR32(bandE[i+c*m->nbEBands], shift);
1432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         g = EXTRACT16(celt_rcp(SHL32(E,3)));
1442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         j=M*eBands[i]; do {
1452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            X[j+c*N] = MULT16_16_Q15(VSHR32(freq[j+c*N],shift-1),g);
1462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         } while (++j<M*eBands[i+1]);
1472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      } while (++i<end);
1482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   } while (++c<C);
1492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
1502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
1512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#else /* FIXED_POINT */
1522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian/* Compute the amplitude (sqrt energy) in each of the bands */
1532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianvoid compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int M)
1542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
1552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int i, c, N;
1562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   const opus_int16 *eBands = m->eBands;
1572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   N = M*m->shortMdctSize;
1582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   c=0; do {
1592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      for (i=0;i<end;i++)
1602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
1612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         int j;
1622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         opus_val32 sum = 1e-27f;
1632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         for (j=M*eBands[i];j<M*eBands[i+1];j++)
1642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            sum += X[j+c*N]*X[j+c*N];
1652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         bandE[i+c*m->nbEBands] = celt_sqrt(sum);
1662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         /*printf ("%f ", bandE[i+c*m->nbEBands]);*/
1672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
1682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   } while (++c<C);
1692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /*printf ("\n");*/
1702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
1712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
1722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian/* Normalise each band such that the energy is one. */
1732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianvoid normalise_bands(const CELTMode *m, const celt_sig * OPUS_RESTRICT freq, celt_norm * OPUS_RESTRICT X, const celt_ener *bandE, int end, int C, int M)
1742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
1752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int i, c, N;
1762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   const opus_int16 *eBands = m->eBands;
1772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   N = M*m->shortMdctSize;
1782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   c=0; do {
1792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      for (i=0;i<end;i++)
1802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
1812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         int j;
1822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         opus_val16 g = 1.f/(1e-27f+bandE[i+c*m->nbEBands]);
1832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         for (j=M*eBands[i];j<M*eBands[i+1];j++)
1842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            X[j+c*N] = freq[j+c*N]*g;
1852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
1862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   } while (++c<C);
1872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
1882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
1892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif /* FIXED_POINT */
1902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
1912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian/* De-normalise the energy to produce the synthesis from the unit-energy bands */
1922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianvoid denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X,
1932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      celt_sig * OPUS_RESTRICT freq, const opus_val16 *bandLogE, int start, int end, int C, int M)
1942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
1952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int i, c, N;
1962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   const opus_int16 *eBands = m->eBands;
1972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   N = M*m->shortMdctSize;
1982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   celt_assert2(C<=2, "denormalise_bands() not implemented for >2 channels");
1992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   c=0; do {
2002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      celt_sig * OPUS_RESTRICT f;
2012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      const celt_norm * OPUS_RESTRICT x;
2022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      f = freq+c*N;
2032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      x = X+c*N+M*eBands[start];
2042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      for (i=0;i<M*eBands[start];i++)
2052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         *f++ = 0;
2062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      for (i=start;i<end;i++)
2072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
2082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         int j, band_end;
2092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         opus_val16 g;
2102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         opus_val16 lg;
2112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef FIXED_POINT
2122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         int shift;
2132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
2142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         j=M*eBands[i];
2152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         band_end = M*eBands[i+1];
2162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         lg = ADD16(bandLogE[i+c*m->nbEBands], SHL16((opus_val16)eMeans[i],6));
2172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifndef FIXED_POINT
2182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         g = celt_exp2(lg);
2192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#else
2202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         /* Handle the integer part of the log energy */
2212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         shift = 16-(lg>>DB_SHIFT);
2222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         if (shift>31)
2232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         {
2242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            shift=0;
2252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            g=0;
2262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         } else {
2272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            /* Handle the fractional part. */
2282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            g = celt_exp2_frac(lg&((1<<DB_SHIFT)-1));
2292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         }
2302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         /* Handle extreme gains with negative shift. */
2312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         if (shift<0)
2322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         {
2332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            /* For shift < -2 we'd be likely to overflow, so we're capping
2342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               the gain here. This shouldn't happen unless the bitstream is
2352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               already corrupted. */
2362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (shift < -2)
2372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
2382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               g = 32767;
2392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               shift = -2;
2402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
2412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            do {
2422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               *f++ = SHL32(MULT16_16(*x++, g), -shift);
2432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            } while (++j<band_end);
2442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         } else
2452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
2462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         /* Be careful of the fixed-point "else" just above when changing this code */
2472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         do {
2482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            *f++ = SHR32(MULT16_16(*x++, g), shift);
2492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         } while (++j<band_end);
2502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
2512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      celt_assert(start <= end);
2522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      for (i=M*eBands[end];i<N;i++)
2532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         *f++ = 0;
2542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   } while (++c<C);
2552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
2562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
2572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian/* This prevents energy collapse for transients with multiple short MDCTs */
2582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianvoid anti_collapse(const CELTMode *m, celt_norm *X_, unsigned char *collapse_masks, int LM, int C, int size,
2592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int start, int end, opus_val16 *logE, opus_val16 *prev1logE,
2602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      opus_val16 *prev2logE, int *pulses, opus_uint32 seed)
2612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
2622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int c, i, j, k;
2632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   for (i=start;i<end;i++)
2642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
2652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int N0;
2662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      opus_val16 thresh, sqrt_1;
2672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int depth;
2682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef FIXED_POINT
2692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int shift;
2702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      opus_val32 thresh32;
2712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
2722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
2732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      N0 = m->eBands[i+1]-m->eBands[i];
2742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* depth in 1/8 bits */
2752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      depth = (1+pulses[i])/((m->eBands[i+1]-m->eBands[i])<<LM);
2762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
2772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef FIXED_POINT
2782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      thresh32 = SHR32(celt_exp2(-SHL16(depth, 10-BITRES)),1);
2792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      thresh = MULT16_32_Q15(QCONST16(0.5f, 15), MIN32(32767,thresh32));
2802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
2812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         opus_val32 t;
2822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         t = N0<<LM;
2832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         shift = celt_ilog2(t)>>1;
2842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         t = SHL32(t, (7-shift)<<1);
2852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         sqrt_1 = celt_rsqrt_norm(t);
2862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
2872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#else
2882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      thresh = .5f*celt_exp2(-.125f*depth);
2892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      sqrt_1 = celt_rsqrt(N0<<LM);
2902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
2912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
2922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      c=0; do
2932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
2942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         celt_norm *X;
2952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         opus_val16 prev1;
2962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         opus_val16 prev2;
2972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         opus_val32 Ediff;
2982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         opus_val16 r;
2992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         int renormalize=0;
3002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         prev1 = prev1logE[c*m->nbEBands+i];
3012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         prev2 = prev2logE[c*m->nbEBands+i];
3022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         if (C==1)
3032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         {
3042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            prev1 = MAX16(prev1,prev1logE[m->nbEBands+i]);
3052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            prev2 = MAX16(prev2,prev2logE[m->nbEBands+i]);
3062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         }
3072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         Ediff = EXTEND32(logE[c*m->nbEBands+i])-EXTEND32(MIN16(prev1,prev2));
3082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         Ediff = MAX32(0, Ediff);
3092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
3102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef FIXED_POINT
3112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         if (Ediff < 16384)
3122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         {
3132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_val32 r32 = SHR32(celt_exp2(-EXTRACT16(Ediff)),1);
3142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            r = 2*MIN16(16383,r32);
3152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         } else {
3162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            r = 0;
3172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         }
3182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         if (LM==3)
3192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            r = MULT16_16_Q14(23170, MIN32(23169, r));
3202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         r = SHR16(MIN16(thresh, r),1);
3212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         r = SHR32(MULT16_16_Q15(sqrt_1, r),shift);
3222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#else
3232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         /* r needs to be multiplied by 2 or 2*sqrt(2) depending on LM because
3242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            short blocks don't have the same energy as long */
3252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         r = 2.f*celt_exp2(-Ediff);
3262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         if (LM==3)
3272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            r *= 1.41421356f;
3282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         r = MIN16(thresh, r);
3292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         r = r*sqrt_1;
3302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
3312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         X = X_+c*size+(m->eBands[i]<<LM);
3322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         for (k=0;k<1<<LM;k++)
3332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         {
3342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            /* Detect collapse */
3352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (!(collapse_masks[i*C+c]&1<<k))
3362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
3372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               /* Fill with noise */
3382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               for (j=0;j<N0;j++)
3392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               {
3402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                  seed = celt_lcg_rand(seed);
3412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                  X[(j<<LM)+k] = (seed&0x8000 ? r : -r);
3422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               }
3432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               renormalize = 1;
3442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
3452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         }
3462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         /* We just added some energy, so we need to renormalise */
3472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         if (renormalize)
3482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            renormalise_vector(X, N0<<LM, Q15ONE);
3492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      } while (++c<C);
3502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
3512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
3522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
3532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic void intensity_stereo(const CELTMode *m, celt_norm *X, celt_norm *Y, const celt_ener *bandE, int bandID, int N)
3542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
3552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int i = bandID;
3562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int j;
3572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_val16 a1, a2;
3582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_val16 left, right;
3592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_val16 norm;
3602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef FIXED_POINT
3612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int shift = celt_zlog2(MAX32(bandE[i], bandE[i+m->nbEBands]))-13;
3622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
3632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   left = VSHR32(bandE[i],shift);
3642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   right = VSHR32(bandE[i+m->nbEBands],shift);
3652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   norm = EPSILON + celt_sqrt(EPSILON+MULT16_16(left,left)+MULT16_16(right,right));
3662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   a1 = DIV32_16(SHL32(EXTEND32(left),14),norm);
3672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   a2 = DIV32_16(SHL32(EXTEND32(right),14),norm);
3682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   for (j=0;j<N;j++)
3692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
3702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      celt_norm r, l;
3712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      l = X[j];
3722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      r = Y[j];
3732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      X[j] = MULT16_16_Q14(a1,l) + MULT16_16_Q14(a2,r);
3742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* Side is not encoded, no need to calculate */
3752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
3762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
3772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
3782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic void stereo_split(celt_norm *X, celt_norm *Y, int N)
3792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
3802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int j;
3812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   for (j=0;j<N;j++)
3822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
3832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      celt_norm r, l;
3842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      l = MULT16_16_Q15(QCONST16(.70710678f,15), X[j]);
3852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      r = MULT16_16_Q15(QCONST16(.70710678f,15), Y[j]);
3862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      X[j] = l+r;
3872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      Y[j] = r-l;
3882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
3892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
3902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
3912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic void stereo_merge(celt_norm *X, celt_norm *Y, opus_val16 mid, int N)
3922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
3932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int j;
3942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_val32 xp=0, side=0;
3952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_val32 El, Er;
3962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_val16 mid2;
3972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef FIXED_POINT
3982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int kl, kr;
3992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
4002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_val32 t, lgain, rgain;
4012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
4022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /* Compute the norm of X+Y and X-Y as |X|^2 + |Y|^2 +/- sum(xy) */
4032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   dual_inner_prod(Y, X, Y, N, &xp, &side);
4042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /* Compensating for the mid normalization */
4052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   xp = MULT16_32_Q15(mid, xp);
4062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /* mid and side are in Q15, not Q14 like X and Y */
4072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   mid2 = SHR32(mid, 1);
4082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   El = MULT16_16(mid2, mid2) + side - 2*xp;
4092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   Er = MULT16_16(mid2, mid2) + side + 2*xp;
4102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (Er < QCONST32(6e-4f, 28) || El < QCONST32(6e-4f, 28))
4112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
4122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      for (j=0;j<N;j++)
4132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         Y[j] = X[j];
4142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      return;
4152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
4162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
4172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef FIXED_POINT
4182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   kl = celt_ilog2(El)>>1;
4192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   kr = celt_ilog2(Er)>>1;
4202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
4212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   t = VSHR32(El, (kl-7)<<1);
4222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   lgain = celt_rsqrt_norm(t);
4232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   t = VSHR32(Er, (kr-7)<<1);
4242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   rgain = celt_rsqrt_norm(t);
4252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
4262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef FIXED_POINT
4272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (kl < 7)
4282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      kl = 7;
4292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (kr < 7)
4302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      kr = 7;
4312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
4322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
4332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   for (j=0;j<N;j++)
4342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
4352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      celt_norm r, l;
4362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* Apply mid scaling (side is already scaled) */
4372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      l = MULT16_16_Q15(mid, X[j]);
4382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      r = Y[j];
4392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      X[j] = EXTRACT16(PSHR32(MULT16_16(lgain, SUB16(l,r)), kl+1));
4402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      Y[j] = EXTRACT16(PSHR32(MULT16_16(rgain, ADD16(l,r)), kr+1));
4412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
4422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
4432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
4442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian/* Decide whether we should spread the pulses in the current frame */
4452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianint spreading_decision(const CELTMode *m, celt_norm *X, int *average,
4462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int last_decision, int *hf_average, int *tapset_decision, int update_hf,
4472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int end, int C, int M)
4482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
4492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int i, c, N0;
4502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int sum = 0, nbBands=0;
4512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   const opus_int16 * OPUS_RESTRICT eBands = m->eBands;
4522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int decision;
4532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int hf_sum=0;
4542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
4552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   celt_assert(end>0);
4562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
4572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   N0 = M*m->shortMdctSize;
4582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
4592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (M*(eBands[end]-eBands[end-1]) <= 8)
4602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      return SPREAD_NONE;
4612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   c=0; do {
4622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      for (i=0;i<end;i++)
4632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
4642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         int j, N, tmp=0;
4652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         int tcount[3] = {0,0,0};
4662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         celt_norm * OPUS_RESTRICT x = X+M*eBands[i]+c*N0;
4672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         N = M*(eBands[i+1]-eBands[i]);
4682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         if (N<=8)
4692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            continue;
4702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         /* Compute rough CDF of |x[j]| */
4712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         for (j=0;j<N;j++)
4722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         {
4732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_val32 x2N; /* Q13 */
4742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
4752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            x2N = MULT16_16(MULT16_16_Q15(x[j], x[j]), N);
4762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (x2N < QCONST16(0.25f,13))
4772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               tcount[0]++;
4782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (x2N < QCONST16(0.0625f,13))
4792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               tcount[1]++;
4802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (x2N < QCONST16(0.015625f,13))
4812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               tcount[2]++;
4822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         }
4832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
4842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         /* Only include four last bands (8 kHz and up) */
4852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         if (i>m->nbEBands-4)
4862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            hf_sum += 32*(tcount[1]+tcount[0])/N;
4872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         tmp = (2*tcount[2] >= N) + (2*tcount[1] >= N) + (2*tcount[0] >= N);
4882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         sum += tmp*256;
4892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         nbBands++;
4902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
4912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   } while (++c<C);
4922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
4932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (update_hf)
4942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
4952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (hf_sum)
4962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         hf_sum /= C*(4-m->nbEBands+end);
4972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      *hf_average = (*hf_average+hf_sum)>>1;
4982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      hf_sum = *hf_average;
4992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (*tapset_decision==2)
5002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         hf_sum += 4;
5012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      else if (*tapset_decision==0)
5022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         hf_sum -= 4;
5032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (hf_sum > 22)
5042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         *tapset_decision=2;
5052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      else if (hf_sum > 18)
5062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         *tapset_decision=1;
5072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      else
5082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         *tapset_decision=0;
5092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
5102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /*printf("%d %d %d\n", hf_sum, *hf_average, *tapset_decision);*/
5112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   celt_assert(nbBands>0); /* end has to be non-zero */
5122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   sum /= nbBands;
5132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /* Recursive averaging */
5142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   sum = (sum+*average)>>1;
5152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   *average = sum;
5162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /* Hysteresis */
5172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   sum = (3*sum + (((3-last_decision)<<7) + 64) + 2)>>2;
5182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (sum < 80)
5192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
5202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      decision = SPREAD_AGGRESSIVE;
5212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   } else if (sum < 256)
5222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
5232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      decision = SPREAD_NORMAL;
5242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   } else if (sum < 384)
5252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
5262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      decision = SPREAD_LIGHT;
5272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   } else {
5282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      decision = SPREAD_NONE;
5292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
5302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef FUZZING
5312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   decision = rand()&0x3;
5322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   *tapset_decision=rand()%3;
5332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
5342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   return decision;
5352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
5362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
5372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian/* Indexing table for converting from natural Hadamard to ordery Hadamard
5382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   This is essentially a bit-reversed Gray, on top of which we've added
5392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   an inversion of the order because we want the DC at the end rather than
5402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   the beginning. The lines are for N=2, 4, 8, 16 */
5412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic const int ordery_table[] = {
5422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       1,  0,
5432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       3,  0,  2,  1,
5442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       7,  0,  4,  3,  6,  1,  5,  2,
5452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      15,  0,  8,  7, 12,  3, 11,  4, 14,  1,  9,  6, 13,  2, 10,  5,
5462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian};
5472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
5482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic void deinterleave_hadamard(celt_norm *X, int N0, int stride, int hadamard)
5492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
5502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int i,j;
5512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   VARDECL(celt_norm, tmp);
5522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int N;
5532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   SAVE_STACK;
5542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   N = N0*stride;
5552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ALLOC(tmp, N, celt_norm);
5562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   celt_assert(stride>0);
5572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (hadamard)
5582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
5592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      const int *ordery = ordery_table+stride-2;
5602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      for (i=0;i<stride;i++)
5612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
5622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         for (j=0;j<N0;j++)
5632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            tmp[ordery[i]*N0+j] = X[j*stride+i];
5642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
5652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   } else {
5662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      for (i=0;i<stride;i++)
5672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         for (j=0;j<N0;j++)
5682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            tmp[i*N0+j] = X[j*stride+i];
5692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
5702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   for (j=0;j<N;j++)
5712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      X[j] = tmp[j];
5722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   RESTORE_STACK;
5732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
5742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
5752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic void interleave_hadamard(celt_norm *X, int N0, int stride, int hadamard)
5762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
5772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int i,j;
5782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   VARDECL(celt_norm, tmp);
5792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int N;
5802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   SAVE_STACK;
5812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   N = N0*stride;
5822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ALLOC(tmp, N, celt_norm);
5832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (hadamard)
5842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
5852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      const int *ordery = ordery_table+stride-2;
5862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      for (i=0;i<stride;i++)
5872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         for (j=0;j<N0;j++)
5882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            tmp[j*stride+i] = X[ordery[i]*N0+j];
5892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   } else {
5902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      for (i=0;i<stride;i++)
5912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         for (j=0;j<N0;j++)
5922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            tmp[j*stride+i] = X[i*N0+j];
5932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
5942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   for (j=0;j<N;j++)
5952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      X[j] = tmp[j];
5962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   RESTORE_STACK;
5972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
5982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
5992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianvoid haar1(celt_norm *X, int N0, int stride)
6002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
6012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int i, j;
6022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   N0 >>= 1;
6032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   for (i=0;i<stride;i++)
6042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      for (j=0;j<N0;j++)
6052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
6062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         celt_norm tmp1, tmp2;
6072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         tmp1 = MULT16_16_Q15(QCONST16(.70710678f,15), X[stride*2*j+i]);
6082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         tmp2 = MULT16_16_Q15(QCONST16(.70710678f,15), X[stride*(2*j+1)+i]);
6092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         X[stride*2*j+i] = tmp1 + tmp2;
6102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         X[stride*(2*j+1)+i] = tmp1 - tmp2;
6112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
6122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
6132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
6142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic int compute_qn(int N, int b, int offset, int pulse_cap, int stereo)
6152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
6162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   static const opus_int16 exp2_table8[8] =
6172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {16384, 17866, 19483, 21247, 23170, 25267, 27554, 30048};
6182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int qn, qb;
6192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int N2 = 2*N-1;
6202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (stereo && N==2)
6212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      N2--;
6222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /* The upper limit ensures that in a stereo split with itheta==16384, we'll
6232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       always have enough bits left over to code at least one pulse in the
6242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       side; otherwise it would collapse, since it doesn't get folded. */
6252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   qb = IMIN(b-pulse_cap-(4<<BITRES), (b+N2*offset)/N2);
6262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
6272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   qb = IMIN(8<<BITRES, qb);
6282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
6292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (qb<(1<<BITRES>>1)) {
6302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      qn = 1;
6312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   } else {
6322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      qn = exp2_table8[qb&0x7]>>(14-(qb>>BITRES));
6332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      qn = (qn+1)>>1<<1;
6342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
6352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   celt_assert(qn <= 256);
6362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   return qn;
6372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
6382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
6392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstruct band_ctx {
6402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int encode;
6412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   const CELTMode *m;
6422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int i;
6432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int intensity;
6442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int spread;
6452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int tf_change;
6462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ec_ctx *ec;
6472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_int32 remaining_bits;
6482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   const celt_ener *bandE;
6492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_uint32 seed;
6502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian};
6512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
6522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstruct split_ctx {
6532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int inv;
6542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int imid;
6552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int iside;
6562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int delta;
6572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int itheta;
6582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int qalloc;
6592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian};
6602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
6612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic void compute_theta(struct band_ctx *ctx, struct split_ctx *sctx,
6622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      celt_norm *X, celt_norm *Y, int N, int *b, int B, int B0,
6632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int LM,
6642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int stereo, int *fill)
6652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
6662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int qn;
6672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int itheta=0;
6682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int delta;
6692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int imid, iside;
6702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int qalloc;
6712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int pulse_cap;
6722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int offset;
6732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_int32 tell;
6742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int inv=0;
6752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int encode;
6762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   const CELTMode *m;
6772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int i;
6782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int intensity;
6792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ec_ctx *ec;
6802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   const celt_ener *bandE;
6812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
6822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   encode = ctx->encode;
6832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   m = ctx->m;
6842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   i = ctx->i;
6852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   intensity = ctx->intensity;
6862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ec = ctx->ec;
6872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   bandE = ctx->bandE;
6882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
6892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /* Decide on the resolution to give to the split parameter theta */
6902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   pulse_cap = m->logN[i]+LM*(1<<BITRES);
6912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   offset = (pulse_cap>>1) - (stereo&&N==2 ? QTHETA_OFFSET_TWOPHASE : QTHETA_OFFSET);
6922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   qn = compute_qn(N, *b, offset, pulse_cap, stereo);
6932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (stereo && i>=intensity)
6942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      qn = 1;
6952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (encode)
6962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
6972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* theta is the atan() of the ratio between the (normalized)
6982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         side and mid. With just that parameter, we can re-scale both
6992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         mid and side because we know that 1) they have unit norm and
7002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         2) they are orthogonal. */
7012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      itheta = stereo_itheta(X, Y, stereo, N);
7022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
7032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   tell = ec_tell_frac(ec);
7042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (qn!=1)
7052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
7062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (encode)
7072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         itheta = (itheta*qn+8192)>>14;
7082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
7092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* Entropy coding of the angle. We use a uniform pdf for the
7102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         time split, a step for stereo, and a triangular one for the rest. */
7112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (stereo && N>2)
7122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
7132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         int p0 = 3;
7142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         int x = itheta;
7152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         int x0 = qn/2;
7162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         int ft = p0*(x0+1) + x0;
7172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         /* Use a probability of p0 up to itheta=8192 and then use 1 after */
7182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         if (encode)
7192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         {
7202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            ec_encode(ec,x<=x0?p0*x:(x-1-x0)+(x0+1)*p0,x<=x0?p0*(x+1):(x-x0)+(x0+1)*p0,ft);
7212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         } else {
7222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            int fs;
7232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            fs=ec_decode(ec,ft);
7242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (fs<(x0+1)*p0)
7252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               x=fs/p0;
7262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            else
7272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               x=x0+1+(fs-(x0+1)*p0);
7282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            ec_dec_update(ec,x<=x0?p0*x:(x-1-x0)+(x0+1)*p0,x<=x0?p0*(x+1):(x-x0)+(x0+1)*p0,ft);
7292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            itheta = x;
7302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         }
7312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      } else if (B0>1 || stereo) {
7322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         /* Uniform pdf */
7332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         if (encode)
7342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            ec_enc_uint(ec, itheta, qn+1);
7352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         else
7362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            itheta = ec_dec_uint(ec, qn+1);
7372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      } else {
7382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         int fs=1, ft;
7392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         ft = ((qn>>1)+1)*((qn>>1)+1);
7402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         if (encode)
7412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         {
7422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            int fl;
7432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
7442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            fs = itheta <= (qn>>1) ? itheta + 1 : qn + 1 - itheta;
7452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            fl = itheta <= (qn>>1) ? itheta*(itheta + 1)>>1 :
7462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian             ft - ((qn + 1 - itheta)*(qn + 2 - itheta)>>1);
7472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
7482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            ec_encode(ec, fl, fl+fs, ft);
7492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         } else {
7502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            /* Triangular pdf */
7512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            int fl=0;
7522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            int fm;
7532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            fm = ec_decode(ec, ft);
7542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
7552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (fm < ((qn>>1)*((qn>>1) + 1)>>1))
7562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
7572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               itheta = (isqrt32(8*(opus_uint32)fm + 1) - 1)>>1;
7582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               fs = itheta + 1;
7592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               fl = itheta*(itheta + 1)>>1;
7602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
7612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            else
7622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
7632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               itheta = (2*(qn + 1)
7642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                - isqrt32(8*(opus_uint32)(ft - fm - 1) + 1))>>1;
7652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               fs = qn + 1 - itheta;
7662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               fl = ft - ((qn + 1 - itheta)*(qn + 2 - itheta)>>1);
7672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
7682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
7692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            ec_dec_update(ec, fl, fl+fs, ft);
7702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         }
7712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
7722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      itheta = (opus_int32)itheta*16384/qn;
7732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (encode && stereo)
7742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
7752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         if (itheta==0)
7762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            intensity_stereo(m, X, Y, bandE, i, N);
7772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         else
7782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            stereo_split(X, Y, N);
7792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
7802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* NOTE: Renormalising X and Y *may* help fixed-point a bit at very high rate.
7812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               Let's do that at higher complexity */
7822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   } else if (stereo) {
7832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (encode)
7842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
7852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         inv = itheta > 8192;
7862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         if (inv)
7872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         {
7882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            int j;
7892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            for (j=0;j<N;j++)
7902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               Y[j] = -Y[j];
7912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         }
7922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         intensity_stereo(m, X, Y, bandE, i, N);
7932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
7942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (*b>2<<BITRES && ctx->remaining_bits > 2<<BITRES)
7952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
7962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         if (encode)
7972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            ec_enc_bit_logp(ec, inv, 2);
7982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         else
7992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            inv = ec_dec_bit_logp(ec, 2);
8002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      } else
8012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         inv = 0;
8022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      itheta = 0;
8032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
8042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   qalloc = ec_tell_frac(ec) - tell;
8052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   *b -= qalloc;
8062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
8072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (itheta == 0)
8082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
8092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      imid = 32767;
8102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      iside = 0;
8112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      *fill &= (1<<B)-1;
8122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      delta = -16384;
8132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   } else if (itheta == 16384)
8142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
8152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      imid = 0;
8162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      iside = 32767;
8172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      *fill &= ((1<<B)-1)<<B;
8182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      delta = 16384;
8192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   } else {
8202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      imid = bitexact_cos((opus_int16)itheta);
8212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      iside = bitexact_cos((opus_int16)(16384-itheta));
8222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* This is the mid vs side allocation that minimizes squared error
8232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         in that band. */
8242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      delta = FRAC_MUL16((N-1)<<7,bitexact_log2tan(iside,imid));
8252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
8262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
8272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   sctx->inv = inv;
8282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   sctx->imid = imid;
8292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   sctx->iside = iside;
8302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   sctx->delta = delta;
8312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   sctx->itheta = itheta;
8322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   sctx->qalloc = qalloc;
8332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
8342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic unsigned quant_band_n1(struct band_ctx *ctx, celt_norm *X, celt_norm *Y, int b,
8352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      celt_norm *lowband_out)
8362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
8372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef RESYNTH
8382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int resynth = 1;
8392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#else
8402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int resynth = !ctx->encode;
8412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
8422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int c;
8432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int stereo;
8442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   celt_norm *x = X;
8452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int encode;
8462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ec_ctx *ec;
8472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
8482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   encode = ctx->encode;
8492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ec = ctx->ec;
8502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
8512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   stereo = Y != NULL;
8522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   c=0; do {
8532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int sign=0;
8542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (ctx->remaining_bits>=1<<BITRES)
8552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
8562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         if (encode)
8572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         {
8582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            sign = x[0]<0;
8592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            ec_enc_bits(ec, sign, 1);
8602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         } else {
8612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            sign = ec_dec_bits(ec, 1);
8622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         }
8632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         ctx->remaining_bits -= 1<<BITRES;
8642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         b-=1<<BITRES;
8652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
8662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (resynth)
8672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         x[0] = sign ? -NORM_SCALING : NORM_SCALING;
8682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      x = Y;
8692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   } while (++c<1+stereo);
8702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (lowband_out)
8712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      lowband_out[0] = SHR16(X[0],4);
8722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   return 1;
8732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
8742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
8752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian/* This function is responsible for encoding and decoding a mono partition.
8762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   It can split the band in two and transmit the energy difference with
8772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   the two half-bands. It can be called recursively so bands can end up being
8782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   split in 8 parts. */
8792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic unsigned quant_partition(struct band_ctx *ctx, celt_norm *X,
8802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int N, int b, int B, celt_norm *lowband,
8812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int LM,
8822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      opus_val16 gain, int fill)
8832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
8842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   const unsigned char *cache;
8852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int q;
8862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int curr_bits;
8872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int imid=0, iside=0;
8882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int B0=B;
8892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_val16 mid=0, side=0;
8902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   unsigned cm=0;
8912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef RESYNTH
8922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int resynth = 1;
8932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#else
8942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int resynth = !ctx->encode;
8952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
8962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   celt_norm *Y=NULL;
8972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int encode;
8982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   const CELTMode *m;
8992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int i;
9002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int spread;
9012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ec_ctx *ec;
9022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
9032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   encode = ctx->encode;
9042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   m = ctx->m;
9052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   i = ctx->i;
9062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   spread = ctx->spread;
9072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ec = ctx->ec;
9082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
9092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /* If we need 1.5 more bit than we can produce, split the band in two. */
9102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   cache = m->cache.bits + m->cache.index[(LM+1)*m->nbEBands+i];
9112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (LM != -1 && b > cache[cache[0]]+12 && N>2)
9122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
9132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int mbits, sbits, delta;
9142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int itheta;
9152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int qalloc;
9162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      struct split_ctx sctx;
9172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      celt_norm *next_lowband2=NULL;
9182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      opus_int32 rebalance;
9192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
9202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      N >>= 1;
9212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      Y = X+N;
9222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      LM -= 1;
9232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (B==1)
9242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         fill = (fill&1)|(fill<<1);
9252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      B = (B+1)>>1;
9262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
9272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      compute_theta(ctx, &sctx, X, Y, N, &b, B, B0,
9282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            LM, 0, &fill);
9292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      imid = sctx.imid;
9302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      iside = sctx.iside;
9312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      delta = sctx.delta;
9322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      itheta = sctx.itheta;
9332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      qalloc = sctx.qalloc;
9342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef FIXED_POINT
9352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      mid = imid;
9362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      side = iside;
9372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#else
9382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      mid = (1.f/32768)*imid;
9392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      side = (1.f/32768)*iside;
9402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
9412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
9422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* Give more bits to low-energy MDCTs than they would otherwise deserve */
9432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (B0>1 && (itheta&0x3fff))
9442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
9452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         if (itheta > 8192)
9462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            /* Rough approximation for pre-echo masking */
9472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            delta -= delta>>(4-LM);
9482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         else
9492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            /* Corresponds to a forward-masking slope of 1.5 dB per 10 ms */
9502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            delta = IMIN(0, delta + (N<<BITRES>>(5-LM)));
9512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
9522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      mbits = IMAX(0, IMIN(b, (b-delta)/2));
9532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      sbits = b-mbits;
9542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      ctx->remaining_bits -= qalloc;
9552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
9562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (lowband)
9572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         next_lowband2 = lowband+N; /* >32-bit split case */
9582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
9592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      rebalance = ctx->remaining_bits;
9602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (mbits >= sbits)
9612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
9622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         cm = quant_partition(ctx, X, N, mbits, B,
9632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               lowband, LM,
9642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               MULT16_16_P15(gain,mid), fill);
9652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         rebalance = mbits - (rebalance-ctx->remaining_bits);
9662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         if (rebalance > 3<<BITRES && itheta!=0)
9672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            sbits += rebalance - (3<<BITRES);
9682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         cm |= quant_partition(ctx, Y, N, sbits, B,
9692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               next_lowband2, LM,
9702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               MULT16_16_P15(gain,side), fill>>B)<<(B0>>1);
9712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      } else {
9722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         cm = quant_partition(ctx, Y, N, sbits, B,
9732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               next_lowband2, LM,
9742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               MULT16_16_P15(gain,side), fill>>B)<<(B0>>1);
9752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         rebalance = sbits - (rebalance-ctx->remaining_bits);
9762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         if (rebalance > 3<<BITRES && itheta!=16384)
9772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            mbits += rebalance - (3<<BITRES);
9782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         cm |= quant_partition(ctx, X, N, mbits, B,
9792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               lowband, LM,
9802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               MULT16_16_P15(gain,mid), fill);
9812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
9822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   } else {
9832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* This is the basic no-split case */
9842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      q = bits2pulses(m, i, LM, b);
9852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      curr_bits = pulses2bits(m, i, LM, q);
9862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      ctx->remaining_bits -= curr_bits;
9872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
9882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* Ensures we can never bust the budget */
9892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      while (ctx->remaining_bits < 0 && q > 0)
9902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
9912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         ctx->remaining_bits += curr_bits;
9922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         q--;
9932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         curr_bits = pulses2bits(m, i, LM, q);
9942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         ctx->remaining_bits -= curr_bits;
9952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
9962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
9972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (q!=0)
9982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
9992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         int K = get_pulses(q);
10002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
10012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         /* Finally do the actual quantization */
10022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         if (encode)
10032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         {
10042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            cm = alg_quant(X, N, K, spread, B, ec
10052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef RESYNTH
10062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                 , gain
10072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
10082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                 );
10092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         } else {
10102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            cm = alg_unquant(X, N, K, spread, B, ec, gain);
10112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         }
10122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      } else {
10132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         /* If there's no pulse, fill the band anyway */
10142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         int j;
10152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         if (resynth)
10162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         {
10172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            unsigned cm_mask;
10182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            /* B can be as large as 16, so this shift might overflow an int on a
10192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               16-bit platform; use a long to get defined behavior.*/
10202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            cm_mask = (unsigned)(1UL<<B)-1;
10212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            fill &= cm_mask;
10222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (!fill)
10232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
10242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               for (j=0;j<N;j++)
10252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                  X[j] = 0;
10262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            } else {
10272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               if (lowband == NULL)
10282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               {
10292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                  /* Noise */
10302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                  for (j=0;j<N;j++)
10312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                  {
10322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                     ctx->seed = celt_lcg_rand(ctx->seed);
10332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                     X[j] = (celt_norm)((opus_int32)ctx->seed>>20);
10342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                  }
10352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                  cm = cm_mask;
10362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               } else {
10372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                  /* Folded spectrum */
10382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                  for (j=0;j<N;j++)
10392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                  {
10402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                     opus_val16 tmp;
10412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                     ctx->seed = celt_lcg_rand(ctx->seed);
10422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                     /* About 48 dB below the "normal" folding level */
10432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                     tmp = QCONST16(1.0f/256, 10);
10442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                     tmp = (ctx->seed)&0x8000 ? tmp : -tmp;
10452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                     X[j] = lowband[j]+tmp;
10462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                  }
10472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                  cm = fill;
10482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               }
10492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               renormalise_vector(X, N, gain);
10502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
10512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         }
10522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
10532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
10542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
10552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   return cm;
10562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
10572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
10582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
10592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian/* This function is responsible for encoding and decoding a band for the mono case. */
10602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic unsigned quant_band(struct band_ctx *ctx, celt_norm *X,
10612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int N, int b, int B, celt_norm *lowband,
10622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int LM, celt_norm *lowband_out,
10632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      opus_val16 gain, celt_norm *lowband_scratch, int fill)
10642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
10652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int N0=N;
10662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int N_B=N;
10672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int N_B0;
10682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int B0=B;
10692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int time_divide=0;
10702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int recombine=0;
10712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int longBlocks;
10722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   unsigned cm=0;
10732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef RESYNTH
10742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int resynth = 1;
10752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#else
10762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int resynth = !ctx->encode;
10772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
10782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int k;
10792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int encode;
10802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int tf_change;
10812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
10822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   encode = ctx->encode;
10832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   tf_change = ctx->tf_change;
10842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
10852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   longBlocks = B0==1;
10862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
10872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   N_B /= B;
10882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
10892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /* Special case for one sample */
10902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (N==1)
10912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
10922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      return quant_band_n1(ctx, X, NULL, b, lowband_out);
10932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
10942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
10952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (tf_change>0)
10962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      recombine = tf_change;
10972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /* Band recombining to increase frequency resolution */
10982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
10992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (lowband_scratch && lowband && (recombine || ((N_B&1) == 0 && tf_change<0) || B0>1))
11002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
11012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int j;
11022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      for (j=0;j<N;j++)
11032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         lowband_scratch[j] = lowband[j];
11042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      lowband = lowband_scratch;
11052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
11062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
11072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   for (k=0;k<recombine;k++)
11082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
11092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      static const unsigned char bit_interleave_table[16]={
11102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            0,1,1,1,2,3,3,3,2,3,3,3,2,3,3,3
11112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      };
11122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (encode)
11132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         haar1(X, N>>k, 1<<k);
11142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (lowband)
11152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         haar1(lowband, N>>k, 1<<k);
11162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      fill = bit_interleave_table[fill&0xF]|bit_interleave_table[fill>>4]<<2;
11172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
11182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   B>>=recombine;
11192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   N_B<<=recombine;
11202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
11212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /* Increasing the time resolution */
11222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   while ((N_B&1) == 0 && tf_change<0)
11232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
11242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (encode)
11252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         haar1(X, N_B, B);
11262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (lowband)
11272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         haar1(lowband, N_B, B);
11282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      fill |= fill<<B;
11292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      B <<= 1;
11302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      N_B >>= 1;
11312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      time_divide++;
11322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      tf_change++;
11332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
11342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   B0=B;
11352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   N_B0 = N_B;
11362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
11372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /* Reorganize the samples in time order instead of frequency order */
11382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (B0>1)
11392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
11402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (encode)
11412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         deinterleave_hadamard(X, N_B>>recombine, B0<<recombine, longBlocks);
11422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (lowband)
11432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         deinterleave_hadamard(lowband, N_B>>recombine, B0<<recombine, longBlocks);
11442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
11452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
11462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   cm = quant_partition(ctx, X, N, b, B, lowband,
11472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         LM, gain, fill);
11482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
11492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /* This code is used by the decoder and by the resynthesis-enabled encoder */
11502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (resynth)
11512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
11522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* Undo the sample reorganization going from time order to frequency order */
11532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (B0>1)
11542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         interleave_hadamard(X, N_B>>recombine, B0<<recombine, longBlocks);
11552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
11562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* Undo time-freq changes that we did earlier */
11572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      N_B = N_B0;
11582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      B = B0;
11592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      for (k=0;k<time_divide;k++)
11602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
11612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         B >>= 1;
11622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         N_B <<= 1;
11632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         cm |= cm>>B;
11642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         haar1(X, N_B, B);
11652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
11662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
11672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      for (k=0;k<recombine;k++)
11682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
11692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         static const unsigned char bit_deinterleave_table[16]={
11702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               0x00,0x03,0x0C,0x0F,0x30,0x33,0x3C,0x3F,
11712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               0xC0,0xC3,0xCC,0xCF,0xF0,0xF3,0xFC,0xFF
11722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         };
11732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         cm = bit_deinterleave_table[cm];
11742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         haar1(X, N0>>k, 1<<k);
11752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
11762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      B<<=recombine;
11772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
11782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* Scale output for later folding */
11792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (lowband_out)
11802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
11812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         int j;
11822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         opus_val16 n;
11832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         n = celt_sqrt(SHL32(EXTEND32(N0),22));
11842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         for (j=0;j<N0;j++)
11852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            lowband_out[j] = MULT16_16_Q15(n,X[j]);
11862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
11872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      cm &= (1<<B)-1;
11882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
11892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   return cm;
11902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
11912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
11922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
11932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian/* This function is responsible for encoding and decoding a band for the stereo case. */
11942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic unsigned quant_band_stereo(struct band_ctx *ctx, celt_norm *X, celt_norm *Y,
11952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int N, int b, int B, celt_norm *lowband,
11962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int LM, celt_norm *lowband_out,
11972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      celt_norm *lowband_scratch, int fill)
11982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
11992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int imid=0, iside=0;
12002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int inv = 0;
12012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_val16 mid=0, side=0;
12022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   unsigned cm=0;
12032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef RESYNTH
12042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int resynth = 1;
12052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#else
12062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int resynth = !ctx->encode;
12072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
12082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int mbits, sbits, delta;
12092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int itheta;
12102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int qalloc;
12112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   struct split_ctx sctx;
12122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int orig_fill;
12132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int encode;
12142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ec_ctx *ec;
12152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
12162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   encode = ctx->encode;
12172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ec = ctx->ec;
12182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
12192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /* Special case for one sample */
12202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (N==1)
12212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
12222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      return quant_band_n1(ctx, X, Y, b, lowband_out);
12232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
12242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
12252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   orig_fill = fill;
12262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
12272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   compute_theta(ctx, &sctx, X, Y, N, &b, B, B,
12282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         LM, 1, &fill);
12292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   inv = sctx.inv;
12302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   imid = sctx.imid;
12312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   iside = sctx.iside;
12322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   delta = sctx.delta;
12332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   itheta = sctx.itheta;
12342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   qalloc = sctx.qalloc;
12352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef FIXED_POINT
12362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   mid = imid;
12372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   side = iside;
12382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#else
12392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   mid = (1.f/32768)*imid;
12402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   side = (1.f/32768)*iside;
12412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
12422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
12432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /* This is a special case for N=2 that only works for stereo and takes
12442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      advantage of the fact that mid and side are orthogonal to encode
12452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      the side with just one bit. */
12462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (N==2)
12472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
12482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int c;
12492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int sign=0;
12502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      celt_norm *x2, *y2;
12512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      mbits = b;
12522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      sbits = 0;
12532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* Only need one bit for the side. */
12542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (itheta != 0 && itheta != 16384)
12552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         sbits = 1<<BITRES;
12562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      mbits -= sbits;
12572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      c = itheta > 8192;
12582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      ctx->remaining_bits -= qalloc+sbits;
12592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
12602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      x2 = c ? Y : X;
12612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      y2 = c ? X : Y;
12622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (sbits)
12632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
12642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         if (encode)
12652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         {
12662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            /* Here we only need to encode a sign for the side. */
12672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            sign = x2[0]*y2[1] - x2[1]*y2[0] < 0;
12682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            ec_enc_bits(ec, sign, 1);
12692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         } else {
12702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            sign = ec_dec_bits(ec, 1);
12712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         }
12722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
12732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      sign = 1-2*sign;
12742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* We use orig_fill here because we want to fold the side, but if
12752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         itheta==16384, we'll have cleared the low bits of fill. */
12762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      cm = quant_band(ctx, x2, N, mbits, B, lowband,
12772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            LM, lowband_out, Q15ONE, lowband_scratch, orig_fill);
12782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* We don't split N=2 bands, so cm is either 1 or 0 (for a fold-collapse),
12792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         and there's no need to worry about mixing with the other channel. */
12802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      y2[0] = -sign*x2[1];
12812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      y2[1] = sign*x2[0];
12822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (resynth)
12832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
12842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         celt_norm tmp;
12852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         X[0] = MULT16_16_Q15(mid, X[0]);
12862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         X[1] = MULT16_16_Q15(mid, X[1]);
12872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         Y[0] = MULT16_16_Q15(side, Y[0]);
12882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         Y[1] = MULT16_16_Q15(side, Y[1]);
12892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         tmp = X[0];
12902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         X[0] = SUB16(tmp,Y[0]);
12912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         Y[0] = ADD16(tmp,Y[0]);
12922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         tmp = X[1];
12932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         X[1] = SUB16(tmp,Y[1]);
12942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         Y[1] = ADD16(tmp,Y[1]);
12952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
12962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   } else {
12972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* "Normal" split code */
12982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      opus_int32 rebalance;
12992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
13002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      mbits = IMAX(0, IMIN(b, (b-delta)/2));
13012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      sbits = b-mbits;
13022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      ctx->remaining_bits -= qalloc;
13032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
13042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      rebalance = ctx->remaining_bits;
13052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (mbits >= sbits)
13062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
13072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         /* In stereo mode, we do not apply a scaling to the mid because we need the normalized
13082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            mid for folding later. */
13092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         cm = quant_band(ctx, X, N, mbits, B,
13102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               lowband, LM, lowband_out,
13112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               Q15ONE, lowband_scratch, fill);
13122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         rebalance = mbits - (rebalance-ctx->remaining_bits);
13132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         if (rebalance > 3<<BITRES && itheta!=0)
13142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            sbits += rebalance - (3<<BITRES);
13152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
13162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         /* For a stereo split, the high bits of fill are always zero, so no
13172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            folding will be done to the side. */
13182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         cm |= quant_band(ctx, Y, N, sbits, B,
13192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               NULL, LM, NULL,
13202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               side, NULL, fill>>B);
13212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      } else {
13222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         /* For a stereo split, the high bits of fill are always zero, so no
13232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            folding will be done to the side. */
13242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         cm = quant_band(ctx, Y, N, sbits, B,
13252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               NULL, LM, NULL,
13262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               side, NULL, fill>>B);
13272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         rebalance = sbits - (rebalance-ctx->remaining_bits);
13282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         if (rebalance > 3<<BITRES && itheta!=16384)
13292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            mbits += rebalance - (3<<BITRES);
13302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         /* In stereo mode, we do not apply a scaling to the mid because we need the normalized
13312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            mid for folding later. */
13322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         cm |= quant_band(ctx, X, N, mbits, B,
13332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               lowband, LM, lowband_out,
13342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               Q15ONE, lowband_scratch, fill);
13352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
13362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
13372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
13382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
13392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /* This code is used by the decoder and by the resynthesis-enabled encoder */
13402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (resynth)
13412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
13422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (N!=2)
13432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         stereo_merge(X, Y, mid, N);
13442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (inv)
13452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
13462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         int j;
13472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         for (j=0;j<N;j++)
13482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            Y[j] = -Y[j];
13492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
13502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
13512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   return cm;
13522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
13532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
13542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
13552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianvoid quant_all_bands(int encode, const CELTMode *m, int start, int end,
13562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      celt_norm *X_, celt_norm *Y_, unsigned char *collapse_masks, const celt_ener *bandE, int *pulses,
13572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int shortBlocks, int spread, int dual_stereo, int intensity, int *tf_res,
13582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      opus_int32 total_bits, opus_int32 balance, ec_ctx *ec, int LM, int codedBands, opus_uint32 *seed)
13592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
13602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int i;
13612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_int32 remaining_bits;
13622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   const opus_int16 * OPUS_RESTRICT eBands = m->eBands;
13632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   celt_norm * OPUS_RESTRICT norm, * OPUS_RESTRICT norm2;
13642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   VARDECL(celt_norm, _norm);
13652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   celt_norm *lowband_scratch;
13662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int B;
13672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int M;
13682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int lowband_offset;
13692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int update_lowband = 1;
13702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int C = Y_ != NULL ? 2 : 1;
13712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int norm_offset;
13722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef RESYNTH
13732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int resynth = 1;
13742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#else
13752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int resynth = !encode;
13762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
13772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   struct band_ctx ctx;
13782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   SAVE_STACK;
13792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
13802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   M = 1<<LM;
13812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   B = shortBlocks ? M : 1;
13822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   norm_offset = M*eBands[start];
13832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /* No need to allocate norm for the last band because we don't need an
13842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      output in that band. */
13852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ALLOC(_norm, C*(M*eBands[m->nbEBands-1]-norm_offset), celt_norm);
13862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   norm = _norm;
13872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   norm2 = norm + M*eBands[m->nbEBands-1]-norm_offset;
13882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /* We can use the last band as scratch space because we don't need that
13892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      scratch space for the last band. */
13902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   lowband_scratch = X_+M*eBands[m->nbEBands-1];
13912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
13922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   lowband_offset = 0;
13932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ctx.bandE = bandE;
13942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ctx.ec = ec;
13952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ctx.encode = encode;
13962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ctx.intensity = intensity;
13972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ctx.m = m;
13982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ctx.seed = *seed;
13992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ctx.spread = spread;
14002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   for (i=start;i<end;i++)
14012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
14022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      opus_int32 tell;
14032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int b;
14042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int N;
14052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      opus_int32 curr_balance;
14062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int effective_lowband=-1;
14072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      celt_norm * OPUS_RESTRICT X, * OPUS_RESTRICT Y;
14082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int tf_change=0;
14092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      unsigned x_cm;
14102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      unsigned y_cm;
14112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int last;
14122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
14132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      ctx.i = i;
14142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      last = (i==end-1);
14152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
14162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      X = X_+M*eBands[i];
14172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (Y_!=NULL)
14182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         Y = Y_+M*eBands[i];
14192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      else
14202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         Y = NULL;
14212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      N = M*eBands[i+1]-M*eBands[i];
14222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      tell = ec_tell_frac(ec);
14232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
14242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* Compute how many bits we want to allocate to this band */
14252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (i != start)
14262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         balance -= tell;
14272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      remaining_bits = total_bits-tell-1;
14282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      ctx.remaining_bits = remaining_bits;
14292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (i <= codedBands-1)
14302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
14312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         curr_balance = balance / IMIN(3, codedBands-i);
14322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         b = IMAX(0, IMIN(16383, IMIN(remaining_bits+1,pulses[i]+curr_balance)));
14332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      } else {
14342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         b = 0;
14352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
14362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
14372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (resynth && M*eBands[i]-N >= M*eBands[start] && (update_lowband || lowband_offset==0))
14382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            lowband_offset = i;
14392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
14402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      tf_change = tf_res[i];
14412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      ctx.tf_change = tf_change;
14422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (i>=m->effEBands)
14432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
14442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         X=norm;
14452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         if (Y_!=NULL)
14462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            Y = norm;
14472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         lowband_scratch = NULL;
14482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
14492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (i==end-1)
14502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         lowband_scratch = NULL;
14512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
14522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* Get a conservative estimate of the collapse_mask's for the bands we're
14532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         going to be folding from. */
14542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (lowband_offset != 0 && (spread!=SPREAD_AGGRESSIVE || B>1 || tf_change<0))
14552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
14562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         int fold_start;
14572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         int fold_end;
14582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         int fold_i;
14592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         /* This ensures we never repeat spectral content within one band */
14602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         effective_lowband = IMAX(0, M*eBands[lowband_offset]-norm_offset-N);
14612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         fold_start = lowband_offset;
14622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         while(M*eBands[--fold_start] > effective_lowband+norm_offset);
14632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         fold_end = lowband_offset-1;
14642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         while(M*eBands[++fold_end] < effective_lowband+norm_offset+N);
14652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         x_cm = y_cm = 0;
14662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         fold_i = fold_start; do {
14672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           x_cm |= collapse_masks[fold_i*C+0];
14682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           y_cm |= collapse_masks[fold_i*C+C-1];
14692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         } while (++fold_i<fold_end);
14702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
14712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* Otherwise, we'll be using the LCG to fold, so all blocks will (almost
14722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         always) be non-zero. */
14732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      else
14742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         x_cm = y_cm = (1<<B)-1;
14752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
14762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (dual_stereo && i==intensity)
14772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
14782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         int j;
14792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
14802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         /* Switch off dual stereo to do intensity. */
14812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         dual_stereo = 0;
14822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         if (resynth)
14832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            for (j=0;j<M*eBands[i]-norm_offset;j++)
14842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               norm[j] = HALF32(norm[j]+norm2[j]);
14852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
14862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (dual_stereo)
14872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
14882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         x_cm = quant_band(&ctx, X, N, b/2, B,
14892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               effective_lowband != -1 ? norm+effective_lowband : NULL, LM,
14902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               last?NULL:norm+M*eBands[i]-norm_offset, Q15ONE, lowband_scratch, x_cm);
14912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         y_cm = quant_band(&ctx, Y, N, b/2, B,
14922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               effective_lowband != -1 ? norm2+effective_lowband : NULL, LM,
14932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               last?NULL:norm2+M*eBands[i]-norm_offset, Q15ONE, lowband_scratch, y_cm);
14942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      } else {
14952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         if (Y!=NULL)
14962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         {
14972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            x_cm = quant_band_stereo(&ctx, X, Y, N, b, B,
14982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                  effective_lowband != -1 ? norm+effective_lowband : NULL, LM,
14992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                        last?NULL:norm+M*eBands[i]-norm_offset, lowband_scratch, x_cm|y_cm);
15002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         } else {
15012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            x_cm = quant_band(&ctx, X, N, b, B,
15022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                  effective_lowband != -1 ? norm+effective_lowband : NULL, LM,
15032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                        last?NULL:norm+M*eBands[i]-norm_offset, Q15ONE, lowband_scratch, x_cm|y_cm);
15042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         }
15052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         y_cm = x_cm;
15062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
15072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      collapse_masks[i*C+0] = (unsigned char)x_cm;
15082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      collapse_masks[i*C+C-1] = (unsigned char)y_cm;
15092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      balance += pulses[i] + tell;
15102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
15112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* Update the folding position only as long as we have 1 bit/sample depth. */
15122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      update_lowband = b>(N<<BITRES);
15132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
15142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   *seed = ctx.seed;
15152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
15162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   RESTORE_STACK;
15172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
15182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
1519