1885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Copyright (c) 2007-2008 CSIRO
2885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   Copyright (c) 2007-2009 Xiph.Org Foundation
3885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   Copyright (c) 2008-2009 Gregory Maxwell
4885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   Written by Jean-Marc Valin and Gregory Maxwell */
5885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/*
6885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   Redistribution and use in source and binary forms, with or without
7885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   modification, are permitted provided that the following conditions
8885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   are met:
9885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
10885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   - Redistributions of source code must retain the above copyright
11885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   notice, this list of conditions and the following disclaimer.
12885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
13885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   - Redistributions in binary form must reproduce the above copyright
14885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   notice, this list of conditions and the following disclaimer in the
15885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   documentation and/or other materials provided with the distribution.
16885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
17885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org*/
29885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
30885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef HAVE_CONFIG_H
31885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "config.h"
32885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
33885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
34885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include <math.h>
35885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "bands.h"
36885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "modes.h"
37885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "vq.h"
38885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "cwrs.h"
39885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "stack_alloc.h"
40885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "os_support.h"
41885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "mathops.h"
42885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "rate.h"
43e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#include "quant_bands.h"
44e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#include "pitch.h"
45e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
46e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgint hysteresis_decision(opus_val16 val, const opus_val16 *thresholds, const opus_val16 *hysteresis, int N, int prev)
47e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{
48e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int i;
49e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   for (i=0;i<N;i++)
50e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   {
51e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      if (val < thresholds[i])
52e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         break;
53e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   }
54e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   if (i>prev && val < thresholds[prev]+hysteresis[prev])
55e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      i=prev;
56e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   if (i<prev && val > thresholds[prev-1]-hysteresis[prev-1])
57e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      i=prev;
58e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   return i;
59e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org}
60885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
61885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgopus_uint32 celt_lcg_rand(opus_uint32 seed)
62885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
63885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   return 1664525 * seed + 1013904223;
64885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
65885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
66885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* This is a cos() approximation designed to be bit-exact on any platform. Bit exactness
67885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   with this approximation is important because it has an impact on the bit allocation */
68885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic opus_int16 bitexact_cos(opus_int16 x)
69885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
70885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   opus_int32 tmp;
71885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   opus_int16 x2;
72885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   tmp = (4096+((opus_int32)(x)*(x)))>>13;
73885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   celt_assert(tmp<=32767);
74885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   x2 = tmp;
75885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   x2 = (32767-x2) + FRAC_MUL16(x2, (-7651 + FRAC_MUL16(x2, (8277 + FRAC_MUL16(-626, x2)))));
76885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   celt_assert(x2<=32766);
77885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   return 1+x2;
78885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
79885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
80885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic int bitexact_log2tan(int isin,int icos)
81885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
82885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int lc;
83885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int ls;
84885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   lc=EC_ILOG(icos);
85885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   ls=EC_ILOG(isin);
86885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   icos<<=15-lc;
87885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   isin<<=15-ls;
88885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   return (ls-lc)*(1<<11)
89885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         +FRAC_MUL16(isin, FRAC_MUL16(isin, -2597) + 7932)
90885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         -FRAC_MUL16(icos, FRAC_MUL16(icos, -2597) + 7932);
91885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
92885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
93885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT
94885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Compute the amplitude (sqrt energy) in each of the bands */
95885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int M)
96885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
97885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int i, c, N;
98885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   const opus_int16 *eBands = m->eBands;
99885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   N = M*m->shortMdctSize;
100885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   c=0; do {
101885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      for (i=0;i<end;i++)
102885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
103885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         int j;
104885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         opus_val32 maxval=0;
105885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         opus_val32 sum = 0;
106885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
107885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         j=M*eBands[i]; do {
108885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            maxval = MAX32(maxval, X[j+c*N]);
109885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            maxval = MAX32(maxval, -X[j+c*N]);
110885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         } while (++j<M*eBands[i+1]);
111885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
112885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         if (maxval > 0)
113885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         {
114885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            int shift = celt_ilog2(maxval)-10;
115885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            j=M*eBands[i]; do {
116885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               sum = MAC16_16(sum, EXTRACT16(VSHR32(X[j+c*N],shift)),
117885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                                   EXTRACT16(VSHR32(X[j+c*N],shift)));
118885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            } while (++j<M*eBands[i+1]);
119885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            /* We're adding one here to ensure the normalized band isn't larger than unity norm */
120885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            bandE[i+c*m->nbEBands] = EPSILON+VSHR32(EXTEND32(celt_sqrt(sum)),-shift);
121885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         } else {
122885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            bandE[i+c*m->nbEBands] = EPSILON;
123885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         }
124885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         /*printf ("%f ", bandE[i+c*m->nbEBands]);*/
125885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
126885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   } while (++c<C);
127885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /*printf ("\n");*/
128885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
129885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
130885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Normalise each band such that the energy is one. */
131885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid 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)
132885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
133885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int i, c, N;
134885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   const opus_int16 *eBands = m->eBands;
135885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   N = M*m->shortMdctSize;
136885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   c=0; do {
137885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      i=0; do {
138885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         opus_val16 g;
139885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         int j,shift;
140885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         opus_val16 E;
141885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         shift = celt_zlog2(bandE[i+c*m->nbEBands])-13;
142885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         E = VSHR32(bandE[i+c*m->nbEBands], shift);
143885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         g = EXTRACT16(celt_rcp(SHL32(E,3)));
144885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         j=M*eBands[i]; do {
145885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            X[j+c*N] = MULT16_16_Q15(VSHR32(freq[j+c*N],shift-1),g);
146885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         } while (++j<M*eBands[i+1]);
147885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      } while (++i<end);
148885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   } while (++c<C);
149885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
150885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
151885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#else /* FIXED_POINT */
152885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Compute the amplitude (sqrt energy) in each of the bands */
153885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int M)
154885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
155885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int i, c, N;
156885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   const opus_int16 *eBands = m->eBands;
157885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   N = M*m->shortMdctSize;
158885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   c=0; do {
159885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      for (i=0;i<end;i++)
160885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
161885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         int j;
162885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         opus_val32 sum = 1e-27f;
163885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         for (j=M*eBands[i];j<M*eBands[i+1];j++)
164885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            sum += X[j+c*N]*X[j+c*N];
165885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         bandE[i+c*m->nbEBands] = celt_sqrt(sum);
166885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         /*printf ("%f ", bandE[i+c*m->nbEBands]);*/
167885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
168885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   } while (++c<C);
169885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /*printf ("\n");*/
170885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
171885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
172885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Normalise each band such that the energy is one. */
173885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid 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)
174885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
175885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int i, c, N;
176885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   const opus_int16 *eBands = m->eBands;
177885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   N = M*m->shortMdctSize;
178885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   c=0; do {
179885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      for (i=0;i<end;i++)
180885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
181885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         int j;
182885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         opus_val16 g = 1.f/(1e-27f+bandE[i+c*m->nbEBands]);
183885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         for (j=M*eBands[i];j<M*eBands[i+1];j++)
184885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            X[j+c*N] = freq[j+c*N]*g;
185885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
186885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   } while (++c<C);
187885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
188885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
189885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif /* FIXED_POINT */
190885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
191885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* De-normalise the energy to produce the synthesis from the unit-energy bands */
192e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgvoid denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X,
193e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      celt_sig * OPUS_RESTRICT freq, const opus_val16 *bandLogE, int start, int end, int C, int M)
194885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
195885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int i, c, N;
196885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   const opus_int16 *eBands = m->eBands;
197885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   N = M*m->shortMdctSize;
198885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   celt_assert2(C<=2, "denormalise_bands() not implemented for >2 channels");
199885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   c=0; do {
200885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      celt_sig * OPUS_RESTRICT f;
201885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      const celt_norm * OPUS_RESTRICT x;
202885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      f = freq+c*N;
203e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      x = X+c*N+M*eBands[start];
204e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      for (i=0;i<M*eBands[start];i++)
205e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         *f++ = 0;
206e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      for (i=start;i<end;i++)
207885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
208885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         int j, band_end;
209e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         opus_val16 g;
210e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         opus_val16 lg;
211e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#ifdef FIXED_POINT
212e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         int shift;
213e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif
214885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         j=M*eBands[i];
215885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         band_end = M*eBands[i+1];
216e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         lg = ADD16(bandLogE[i+c*m->nbEBands], SHL16((opus_val16)eMeans[i],6));
2173c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com#ifndef FIXED_POINT
2183c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com         g = celt_exp2(lg);
2193c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com#else
220e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         /* Handle the integer part of the log energy */
221e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         shift = 16-(lg>>DB_SHIFT);
222e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         if (shift>31)
223e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         {
224e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            shift=0;
225e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            g=0;
226e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         } else {
227e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            /* Handle the fractional part. */
228e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            g = celt_exp2_frac(lg&((1<<DB_SHIFT)-1));
229e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         }
2303c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com         /* Handle extreme gains with negative shift. */
2313c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com         if (shift<0)
2323c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com         {
2333c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com            /* For shift < -2 we'd be likely to overflow, so we're capping
2343c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com               the gain here. This shouldn't happen unless the bitstream is
2353c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com               already corrupted. */
2363c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com            if (shift < -2)
2373c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com            {
2383c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com               g = 32767;
2393c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com               shift = -2;
2403c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com            }
2413c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com            do {
2423c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com               *f++ = SHL32(MULT16_16(*x++, g), -shift);
2433c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com            } while (++j<band_end);
2443c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com         } else
245e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif
2463c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com         /* Be careful of the fixed-point "else" just above when changing this code */
247885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         do {
248e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            *f++ = SHR32(MULT16_16(*x++, g), shift);
249885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         } while (++j<band_end);
250885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
251e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      celt_assert(start <= end);
252885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      for (i=M*eBands[end];i<N;i++)
253885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         *f++ = 0;
254885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   } while (++c<C);
255885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
256885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
257885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* This prevents energy collapse for transients with multiple short MDCTs */
258885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid anti_collapse(const CELTMode *m, celt_norm *X_, unsigned char *collapse_masks, int LM, int C, int size,
259885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int start, int end, opus_val16 *logE, opus_val16 *prev1logE,
260885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      opus_val16 *prev2logE, int *pulses, opus_uint32 seed)
261885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
262885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int c, i, j, k;
263885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=start;i<end;i++)
264885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
265885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int N0;
266885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      opus_val16 thresh, sqrt_1;
267885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int depth;
268885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT
269885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int shift;
270885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      opus_val32 thresh32;
271885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
272885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
273885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      N0 = m->eBands[i+1]-m->eBands[i];
274885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      /* depth in 1/8 bits */
275885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      depth = (1+pulses[i])/((m->eBands[i+1]-m->eBands[i])<<LM);
276885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
277885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT
278885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      thresh32 = SHR32(celt_exp2(-SHL16(depth, 10-BITRES)),1);
279885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      thresh = MULT16_32_Q15(QCONST16(0.5f, 15), MIN32(32767,thresh32));
280885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
281885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         opus_val32 t;
282885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         t = N0<<LM;
283885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         shift = celt_ilog2(t)>>1;
284885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         t = SHL32(t, (7-shift)<<1);
285885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         sqrt_1 = celt_rsqrt_norm(t);
286885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
287885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#else
288885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      thresh = .5f*celt_exp2(-.125f*depth);
289885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      sqrt_1 = celt_rsqrt(N0<<LM);
290885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
291885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
292885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      c=0; do
293885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
294885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         celt_norm *X;
295885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         opus_val16 prev1;
296885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         opus_val16 prev2;
297885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         opus_val32 Ediff;
298885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         opus_val16 r;
299885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         int renormalize=0;
300885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         prev1 = prev1logE[c*m->nbEBands+i];
301885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         prev2 = prev2logE[c*m->nbEBands+i];
302885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         if (C==1)
303885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         {
304885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            prev1 = MAX16(prev1,prev1logE[m->nbEBands+i]);
305885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            prev2 = MAX16(prev2,prev2logE[m->nbEBands+i]);
306885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         }
307885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Ediff = EXTEND32(logE[c*m->nbEBands+i])-EXTEND32(MIN16(prev1,prev2));
308885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Ediff = MAX32(0, Ediff);
309885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
310885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT
311885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         if (Ediff < 16384)
312885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         {
313885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            opus_val32 r32 = SHR32(celt_exp2(-EXTRACT16(Ediff)),1);
314885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            r = 2*MIN16(16383,r32);
315885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         } else {
316885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            r = 0;
317885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         }
318885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         if (LM==3)
319885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            r = MULT16_16_Q14(23170, MIN32(23169, r));
320885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         r = SHR16(MIN16(thresh, r),1);
321885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         r = SHR32(MULT16_16_Q15(sqrt_1, r),shift);
322885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#else
323885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         /* r needs to be multiplied by 2 or 2*sqrt(2) depending on LM because
324885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            short blocks don't have the same energy as long */
325885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         r = 2.f*celt_exp2(-Ediff);
326885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         if (LM==3)
327885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            r *= 1.41421356f;
328885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         r = MIN16(thresh, r);
329885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         r = r*sqrt_1;
330885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
331885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         X = X_+c*size+(m->eBands[i]<<LM);
332885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         for (k=0;k<1<<LM;k++)
333885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         {
334885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            /* Detect collapse */
335885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if (!(collapse_masks[i*C+c]&1<<k))
336885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            {
337885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               /* Fill with noise */
338885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               for (j=0;j<N0;j++)
339885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               {
340885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  seed = celt_lcg_rand(seed);
341885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  X[(j<<LM)+k] = (seed&0x8000 ? r : -r);
342885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               }
343885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               renormalize = 1;
344885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
345885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         }
346885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         /* We just added some energy, so we need to renormalise */
347885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         if (renormalize)
348885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            renormalise_vector(X, N0<<LM, Q15ONE);
349885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      } while (++c<C);
350885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
351885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
352885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
353885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void intensity_stereo(const CELTMode *m, celt_norm *X, celt_norm *Y, const celt_ener *bandE, int bandID, int N)
354885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
355885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int i = bandID;
356885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int j;
357885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   opus_val16 a1, a2;
358885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   opus_val16 left, right;
359885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   opus_val16 norm;
360885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT
361885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int shift = celt_zlog2(MAX32(bandE[i], bandE[i+m->nbEBands]))-13;
362885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
363885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   left = VSHR32(bandE[i],shift);
364885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   right = VSHR32(bandE[i+m->nbEBands],shift);
365885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   norm = EPSILON + celt_sqrt(EPSILON+MULT16_16(left,left)+MULT16_16(right,right));
366885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   a1 = DIV32_16(SHL32(EXTEND32(left),14),norm);
367885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   a2 = DIV32_16(SHL32(EXTEND32(right),14),norm);
368885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (j=0;j<N;j++)
369885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
370885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      celt_norm r, l;
371885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      l = X[j];
372885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      r = Y[j];
373885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      X[j] = MULT16_16_Q14(a1,l) + MULT16_16_Q14(a2,r);
374885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      /* Side is not encoded, no need to calculate */
375885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
376885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
377885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
378885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void stereo_split(celt_norm *X, celt_norm *Y, int N)
379885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
380885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int j;
381885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (j=0;j<N;j++)
382885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
383885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      celt_norm r, l;
384885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      l = MULT16_16_Q15(QCONST16(.70710678f,15), X[j]);
385885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      r = MULT16_16_Q15(QCONST16(.70710678f,15), Y[j]);
386885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      X[j] = l+r;
387885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      Y[j] = r-l;
388885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
389885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
390885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
391885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void stereo_merge(celt_norm *X, celt_norm *Y, opus_val16 mid, int N)
392885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
393885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int j;
394885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   opus_val32 xp=0, side=0;
395885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   opus_val32 El, Er;
396885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   opus_val16 mid2;
397885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT
398885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int kl, kr;
399885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
400885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   opus_val32 t, lgain, rgain;
401885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
402885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* Compute the norm of X+Y and X-Y as |X|^2 + |Y|^2 +/- sum(xy) */
403e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   dual_inner_prod(Y, X, Y, N, &xp, &side);
404885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* Compensating for the mid normalization */
405885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   xp = MULT16_32_Q15(mid, xp);
406885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* mid and side are in Q15, not Q14 like X and Y */
407885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   mid2 = SHR32(mid, 1);
408885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   El = MULT16_16(mid2, mid2) + side - 2*xp;
409885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   Er = MULT16_16(mid2, mid2) + side + 2*xp;
410885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (Er < QCONST32(6e-4f, 28) || El < QCONST32(6e-4f, 28))
411885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
412885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      for (j=0;j<N;j++)
413885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Y[j] = X[j];
414885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      return;
415885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
416885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
417885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT
418885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   kl = celt_ilog2(El)>>1;
419885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   kr = celt_ilog2(Er)>>1;
420885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
421885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   t = VSHR32(El, (kl-7)<<1);
422885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   lgain = celt_rsqrt_norm(t);
423885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   t = VSHR32(Er, (kr-7)<<1);
424885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   rgain = celt_rsqrt_norm(t);
425885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
426885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT
427885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (kl < 7)
428885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      kl = 7;
429885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (kr < 7)
430885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      kr = 7;
431885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
432885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
433885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (j=0;j<N;j++)
434885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
435885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      celt_norm r, l;
436885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      /* Apply mid scaling (side is already scaled) */
437885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      l = MULT16_16_Q15(mid, X[j]);
438885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      r = Y[j];
439885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      X[j] = EXTRACT16(PSHR32(MULT16_16(lgain, SUB16(l,r)), kl+1));
440885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      Y[j] = EXTRACT16(PSHR32(MULT16_16(rgain, ADD16(l,r)), kr+1));
441885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
442885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
443885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
444885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Decide whether we should spread the pulses in the current frame */
445885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgint spreading_decision(const CELTMode *m, celt_norm *X, int *average,
446885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int last_decision, int *hf_average, int *tapset_decision, int update_hf,
447885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int end, int C, int M)
448885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
449885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int i, c, N0;
450885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int sum = 0, nbBands=0;
451885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   const opus_int16 * OPUS_RESTRICT eBands = m->eBands;
452885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int decision;
453885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int hf_sum=0;
454885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
455885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   celt_assert(end>0);
456885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
457885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   N0 = M*m->shortMdctSize;
458885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
459885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (M*(eBands[end]-eBands[end-1]) <= 8)
460885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      return SPREAD_NONE;
461885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   c=0; do {
462885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      for (i=0;i<end;i++)
463885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
464885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         int j, N, tmp=0;
465885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         int tcount[3] = {0,0,0};
466885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         celt_norm * OPUS_RESTRICT x = X+M*eBands[i]+c*N0;
467885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         N = M*(eBands[i+1]-eBands[i]);
468885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         if (N<=8)
469885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            continue;
470885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         /* Compute rough CDF of |x[j]| */
471885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         for (j=0;j<N;j++)
472885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         {
473885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            opus_val32 x2N; /* Q13 */
474885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
475885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            x2N = MULT16_16(MULT16_16_Q15(x[j], x[j]), N);
476885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if (x2N < QCONST16(0.25f,13))
477885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               tcount[0]++;
478885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if (x2N < QCONST16(0.0625f,13))
479885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               tcount[1]++;
480885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if (x2N < QCONST16(0.015625f,13))
481885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               tcount[2]++;
482885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         }
483885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
484885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         /* Only include four last bands (8 kHz and up) */
485885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         if (i>m->nbEBands-4)
486885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            hf_sum += 32*(tcount[1]+tcount[0])/N;
487885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         tmp = (2*tcount[2] >= N) + (2*tcount[1] >= N) + (2*tcount[0] >= N);
488885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         sum += tmp*256;
489885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         nbBands++;
490885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
491885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   } while (++c<C);
492885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
493885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (update_hf)
494885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
495885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (hf_sum)
496885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         hf_sum /= C*(4-m->nbEBands+end);
497885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      *hf_average = (*hf_average+hf_sum)>>1;
498885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      hf_sum = *hf_average;
499885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (*tapset_decision==2)
500885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         hf_sum += 4;
501885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      else if (*tapset_decision==0)
502885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         hf_sum -= 4;
503885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (hf_sum > 22)
504885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         *tapset_decision=2;
505885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      else if (hf_sum > 18)
506885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         *tapset_decision=1;
507885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      else
508885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         *tapset_decision=0;
509885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
510885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /*printf("%d %d %d\n", hf_sum, *hf_average, *tapset_decision);*/
5113c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com   celt_assert(nbBands>0); /* end has to be non-zero */
512885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   sum /= nbBands;
513885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* Recursive averaging */
514885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   sum = (sum+*average)>>1;
515885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   *average = sum;
516885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* Hysteresis */
517885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   sum = (3*sum + (((3-last_decision)<<7) + 64) + 2)>>2;
518885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (sum < 80)
519885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
520885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      decision = SPREAD_AGGRESSIVE;
521885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   } else if (sum < 256)
522885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
523885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      decision = SPREAD_NORMAL;
524885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   } else if (sum < 384)
525885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
526885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      decision = SPREAD_LIGHT;
527885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   } else {
528885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      decision = SPREAD_NONE;
529885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
530885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FUZZING
531885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   decision = rand()&0x3;
532885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   *tapset_decision=rand()%3;
533885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
534885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   return decision;
535885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
536885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
537885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Indexing table for converting from natural Hadamard to ordery Hadamard
538885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   This is essentially a bit-reversed Gray, on top of which we've added
539885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   an inversion of the order because we want the DC at the end rather than
540885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   the beginning. The lines are for N=2, 4, 8, 16 */
541885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic const int ordery_table[] = {
542885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       1,  0,
543885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       3,  0,  2,  1,
544885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       7,  0,  4,  3,  6,  1,  5,  2,
545885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      15,  0,  8,  7, 12,  3, 11,  4, 14,  1,  9,  6, 13,  2, 10,  5,
546885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org};
547885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
548885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void deinterleave_hadamard(celt_norm *X, int N0, int stride, int hadamard)
549885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
550885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int i,j;
551885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   VARDECL(celt_norm, tmp);
552885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int N;
553885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   SAVE_STACK;
554885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   N = N0*stride;
555885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   ALLOC(tmp, N, celt_norm);
556885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   celt_assert(stride>0);
557885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (hadamard)
558885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
559885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      const int *ordery = ordery_table+stride-2;
560885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      for (i=0;i<stride;i++)
561885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
562885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         for (j=0;j<N0;j++)
563885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            tmp[ordery[i]*N0+j] = X[j*stride+i];
564885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
565885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   } else {
566885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      for (i=0;i<stride;i++)
567885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         for (j=0;j<N0;j++)
568885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            tmp[i*N0+j] = X[j*stride+i];
569885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
570885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (j=0;j<N;j++)
571885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      X[j] = tmp[j];
572885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   RESTORE_STACK;
573885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
574885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
575885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic void interleave_hadamard(celt_norm *X, int N0, int stride, int hadamard)
576885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
577885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int i,j;
578885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   VARDECL(celt_norm, tmp);
579885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int N;
580885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   SAVE_STACK;
581885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   N = N0*stride;
582885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   ALLOC(tmp, N, celt_norm);
583885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (hadamard)
584885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
585885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      const int *ordery = ordery_table+stride-2;
586885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      for (i=0;i<stride;i++)
587885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         for (j=0;j<N0;j++)
588885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            tmp[j*stride+i] = X[ordery[i]*N0+j];
589885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   } else {
590885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      for (i=0;i<stride;i++)
591885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         for (j=0;j<N0;j++)
592885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            tmp[j*stride+i] = X[i*N0+j];
593885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
594885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (j=0;j<N;j++)
595885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      X[j] = tmp[j];
596885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   RESTORE_STACK;
597885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
598885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
599885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid haar1(celt_norm *X, int N0, int stride)
600885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
601885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int i, j;
602885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   N0 >>= 1;
603885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=0;i<stride;i++)
604885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      for (j=0;j<N0;j++)
605885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
606885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         celt_norm tmp1, tmp2;
607885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         tmp1 = MULT16_16_Q15(QCONST16(.70710678f,15), X[stride*2*j+i]);
608885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         tmp2 = MULT16_16_Q15(QCONST16(.70710678f,15), X[stride*(2*j+1)+i]);
609885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         X[stride*2*j+i] = tmp1 + tmp2;
610885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         X[stride*(2*j+1)+i] = tmp1 - tmp2;
611885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
612885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
613885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
614885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic int compute_qn(int N, int b, int offset, int pulse_cap, int stereo)
615885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
616885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   static const opus_int16 exp2_table8[8] =
617885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {16384, 17866, 19483, 21247, 23170, 25267, 27554, 30048};
618885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int qn, qb;
619885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int N2 = 2*N-1;
620885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (stereo && N==2)
621885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      N2--;
622885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* The upper limit ensures that in a stereo split with itheta==16384, we'll
623885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       always have enough bits left over to code at least one pulse in the
624885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       side; otherwise it would collapse, since it doesn't get folded. */
625885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   qb = IMIN(b-pulse_cap-(4<<BITRES), (b+N2*offset)/N2);
626885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
627885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   qb = IMIN(8<<BITRES, qb);
628885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
629885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (qb<(1<<BITRES>>1)) {
630885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      qn = 1;
631885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   } else {
632885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      qn = exp2_table8[qb&0x7]>>(14-(qb>>BITRES));
633885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      qn = (qn+1)>>1<<1;
634885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
635885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   celt_assert(qn <= 256);
636885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   return qn;
637885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
638885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
639e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstruct band_ctx {
640e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int encode;
641e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   const CELTMode *m;
642e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int i;
643e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int intensity;
644e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int spread;
645e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int tf_change;
646e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   ec_ctx *ec;
647e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   opus_int32 remaining_bits;
648e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   const celt_ener *bandE;
649e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   opus_uint32 seed;
650e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org};
651e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
652e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstruct split_ctx {
653e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int inv;
654e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int imid;
655e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int iside;
656e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int delta;
657e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int itheta;
658e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int qalloc;
659e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org};
660e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
661e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstatic void compute_theta(struct band_ctx *ctx, struct split_ctx *sctx,
662e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      celt_norm *X, celt_norm *Y, int N, int *b, int B, int B0,
663e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      int LM,
664e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      int stereo, int *fill)
665885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
666e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int qn;
667e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int itheta=0;
668e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int delta;
669e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int imid, iside;
670e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int qalloc;
671e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int pulse_cap;
672e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int offset;
673e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   opus_int32 tell;
674e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int inv=0;
675e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int encode;
676e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   const CELTMode *m;
677e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int i;
678e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int intensity;
679e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   ec_ctx *ec;
680e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   const celt_ener *bandE;
681e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
682e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   encode = ctx->encode;
683e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   m = ctx->m;
684e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   i = ctx->i;
685e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   intensity = ctx->intensity;
686e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   ec = ctx->ec;
687e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   bandE = ctx->bandE;
688e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
689e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   /* Decide on the resolution to give to the split parameter theta */
690e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   pulse_cap = m->logN[i]+LM*(1<<BITRES);
691e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   offset = (pulse_cap>>1) - (stereo&&N==2 ? QTHETA_OFFSET_TWOPHASE : QTHETA_OFFSET);
692e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   qn = compute_qn(N, *b, offset, pulse_cap, stereo);
693e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   if (stereo && i>=intensity)
694e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      qn = 1;
695e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   if (encode)
696e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   {
697e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      /* theta is the atan() of the ratio between the (normalized)
698e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         side and mid. With just that parameter, we can re-scale both
699e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         mid and side because we know that 1) they have unit norm and
700e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         2) they are orthogonal. */
701e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      itheta = stereo_itheta(X, Y, stereo, N);
702e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   }
703e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   tell = ec_tell_frac(ec);
704e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   if (qn!=1)
705e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   {
706e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      if (encode)
707e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         itheta = (itheta*qn+8192)>>14;
708885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
709e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      /* Entropy coding of the angle. We use a uniform pdf for the
710e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         time split, a step for stereo, and a triangular one for the rest. */
711e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      if (stereo && N>2)
712e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      {
713e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         int p0 = 3;
714e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         int x = itheta;
715e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         int x0 = qn/2;
716e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         int ft = p0*(x0+1) + x0;
717e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         /* Use a probability of p0 up to itheta=8192 and then use 1 after */
718e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         if (encode)
719e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         {
720e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            ec_encode(ec,x<=x0?p0*x:(x-1-x0)+(x0+1)*p0,x<=x0?p0*(x+1):(x-x0)+(x0+1)*p0,ft);
721e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         } else {
722e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            int fs;
723e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            fs=ec_decode(ec,ft);
724e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            if (fs<(x0+1)*p0)
725e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               x=fs/p0;
726e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            else
727e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               x=x0+1+(fs-(x0+1)*p0);
728e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            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);
729e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            itheta = x;
730e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         }
731e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      } else if (B0>1 || stereo) {
732e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         /* Uniform pdf */
733e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         if (encode)
734e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            ec_enc_uint(ec, itheta, qn+1);
735e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         else
736e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            itheta = ec_dec_uint(ec, qn+1);
737e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      } else {
738e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         int fs=1, ft;
739e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         ft = ((qn>>1)+1)*((qn>>1)+1);
740e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         if (encode)
741e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         {
742e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            int fl;
743885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
744e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            fs = itheta <= (qn>>1) ? itheta + 1 : qn + 1 - itheta;
745e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            fl = itheta <= (qn>>1) ? itheta*(itheta + 1)>>1 :
746e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org             ft - ((qn + 1 - itheta)*(qn + 2 - itheta)>>1);
747885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
748e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            ec_encode(ec, fl, fl+fs, ft);
749e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         } else {
750e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            /* Triangular pdf */
751e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            int fl=0;
752e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            int fm;
753e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            fm = ec_decode(ec, ft);
754885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
755e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            if (fm < ((qn>>1)*((qn>>1) + 1)>>1))
756885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            {
757e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               itheta = (isqrt32(8*(opus_uint32)fm + 1) - 1)>>1;
758e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               fs = itheta + 1;
759e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               fl = itheta*(itheta + 1)>>1;
760e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            }
761e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            else
762e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            {
763e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               itheta = (2*(qn + 1)
764e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org                - isqrt32(8*(opus_uint32)(ft - fm - 1) + 1))>>1;
765e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               fs = qn + 1 - itheta;
766e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               fl = ft - ((qn + 1 - itheta)*(qn + 2 - itheta)>>1);
767885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
768885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
769e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            ec_dec_update(ec, fl, fl+fs, ft);
770e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         }
771885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
772e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      itheta = (opus_int32)itheta*16384/qn;
773e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      if (encode && stereo)
774885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
775e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         if (itheta==0)
776e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            intensity_stereo(m, X, Y, bandE, i, N);
777e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         else
778e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            stereo_split(X, Y, N);
779885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
780e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      /* NOTE: Renormalising X and Y *may* help fixed-point a bit at very high rate.
781e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               Let's do that at higher complexity */
782e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   } else if (stereo) {
783e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      if (encode)
784885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
785e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         inv = itheta > 8192;
786e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         if (inv)
787e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         {
788e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            int j;
789e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            for (j=0;j<N;j++)
790e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               Y[j] = -Y[j];
791e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         }
792e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         intensity_stereo(m, X, Y, bandE, i, N);
793885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
794e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      if (*b>2<<BITRES && ctx->remaining_bits > 2<<BITRES)
795885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
796885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         if (encode)
797e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            ec_enc_bit_logp(ec, inv, 2);
798e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         else
799e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            inv = ec_dec_bit_logp(ec, 2);
800e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      } else
801e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         inv = 0;
802e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      itheta = 0;
803885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
804e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   qalloc = ec_tell_frac(ec) - tell;
805e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   *b -= qalloc;
806885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
807e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   if (itheta == 0)
808885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
809e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      imid = 32767;
810e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      iside = 0;
811e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      *fill &= (1<<B)-1;
812e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      delta = -16384;
813e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   } else if (itheta == 16384)
814e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   {
815e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      imid = 0;
816e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      iside = 32767;
817e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      *fill &= ((1<<B)-1)<<B;
818e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      delta = 16384;
819e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   } else {
820e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      imid = bitexact_cos((opus_int16)itheta);
821e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      iside = bitexact_cos((opus_int16)(16384-itheta));
822e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      /* This is the mid vs side allocation that minimizes squared error
823e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         in that band. */
824e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      delta = FRAC_MUL16((N-1)<<7,bitexact_log2tan(iside,imid));
825885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
826885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
827e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   sctx->inv = inv;
828e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   sctx->imid = imid;
829e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   sctx->iside = iside;
830e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   sctx->delta = delta;
831e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   sctx->itheta = itheta;
832e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   sctx->qalloc = qalloc;
833e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org}
834e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstatic unsigned quant_band_n1(struct band_ctx *ctx, celt_norm *X, celt_norm *Y, int b,
835e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      celt_norm *lowband_out)
836e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{
837e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#ifdef RESYNTH
838e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int resynth = 1;
839e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#else
840e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int resynth = !ctx->encode;
841e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif
842e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int c;
843e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int stereo;
844e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   celt_norm *x = X;
845e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int encode;
846e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   ec_ctx *ec;
847885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
848e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   encode = ctx->encode;
849e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   ec = ctx->ec;
850e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
851e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   stereo = Y != NULL;
852e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   c=0; do {
853e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      int sign=0;
854e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      if (ctx->remaining_bits>=1<<BITRES)
855885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
856885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         if (encode)
857885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         {
858e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            sign = x[0]<0;
859e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            ec_enc_bits(ec, sign, 1);
860885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         } else {
861e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            sign = ec_dec_bits(ec, 1);
862e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         }
863e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         ctx->remaining_bits -= 1<<BITRES;
864e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         b-=1<<BITRES;
865e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      }
866e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      if (resynth)
867e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         x[0] = sign ? -NORM_SCALING : NORM_SCALING;
868e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      x = Y;
869e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   } while (++c<1+stereo);
870e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   if (lowband_out)
871e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      lowband_out[0] = SHR16(X[0],4);
872e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   return 1;
873e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org}
874885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
875e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org/* This function is responsible for encoding and decoding a mono partition.
876e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   It can split the band in two and transmit the energy difference with
877e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   the two half-bands. It can be called recursively so bands can end up being
878e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   split in 8 parts. */
879e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstatic unsigned quant_partition(struct band_ctx *ctx, celt_norm *X,
880e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      int N, int b, int B, celt_norm *lowband,
881e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      int LM,
882e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      opus_val16 gain, int fill)
883e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{
884e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   const unsigned char *cache;
885e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int q;
886e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int curr_bits;
887e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int imid=0, iside=0;
888e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int B0=B;
889e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   opus_val16 mid=0, side=0;
890e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   unsigned cm=0;
891e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#ifdef RESYNTH
892e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int resynth = 1;
893e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#else
894e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int resynth = !ctx->encode;
895e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif
896e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   celt_norm *Y=NULL;
897e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int encode;
898e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   const CELTMode *m;
899e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int i;
900e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int spread;
901e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   ec_ctx *ec;
902885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
903e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   encode = ctx->encode;
904e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   m = ctx->m;
905e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   i = ctx->i;
906e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   spread = ctx->spread;
907e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   ec = ctx->ec;
908885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
909e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   /* If we need 1.5 more bit than we can produce, split the band in two. */
910e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   cache = m->cache.bits + m->cache.index[(LM+1)*m->nbEBands+i];
911e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   if (LM != -1 && b > cache[cache[0]]+12 && N>2)
912e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   {
913e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      int mbits, sbits, delta;
914e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      int itheta;
915e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      int qalloc;
916e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      struct split_ctx sctx;
917e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      celt_norm *next_lowband2=NULL;
918e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      opus_int32 rebalance;
919885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
920e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      N >>= 1;
921e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      Y = X+N;
922e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      LM -= 1;
923e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      if (B==1)
924e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         fill = (fill&1)|(fill<<1);
925e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      B = (B+1)>>1;
926885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
927e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      compute_theta(ctx, &sctx, X, Y, N, &b, B, B0,
928e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            LM, 0, &fill);
929e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      imid = sctx.imid;
930e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      iside = sctx.iside;
931e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      delta = sctx.delta;
932e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      itheta = sctx.itheta;
933e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      qalloc = sctx.qalloc;
934885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FIXED_POINT
935885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      mid = imid;
936885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      side = iside;
937885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#else
938885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      mid = (1.f/32768)*imid;
939885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      side = (1.f/32768)*iside;
940885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
941885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
942e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      /* Give more bits to low-energy MDCTs than they would otherwise deserve */
943e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      if (B0>1 && (itheta&0x3fff))
944885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
945e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         if (itheta > 8192)
946e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            /* Rough approximation for pre-echo masking */
947e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            delta -= delta>>(4-LM);
948885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         else
949e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            /* Corresponds to a forward-masking slope of 1.5 dB per 10 ms */
950e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            delta = IMIN(0, delta + (N<<BITRES>>(5-LM)));
951885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
952e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      mbits = IMAX(0, IMIN(b, (b-delta)/2));
953e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      sbits = b-mbits;
954e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      ctx->remaining_bits -= qalloc;
955e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
956e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      if (lowband)
957e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         next_lowband2 = lowband+N; /* >32-bit split case */
958885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
959e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      rebalance = ctx->remaining_bits;
960e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      if (mbits >= sbits)
961e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      {
962e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         cm = quant_partition(ctx, X, N, mbits, B,
963e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               lowband, LM,
964e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               MULT16_16_P15(gain,mid), fill);
965e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         rebalance = mbits - (rebalance-ctx->remaining_bits);
966e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         if (rebalance > 3<<BITRES && itheta!=0)
967e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            sbits += rebalance - (3<<BITRES);
968e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         cm |= quant_partition(ctx, Y, N, sbits, B,
969e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               next_lowband2, LM,
970e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               MULT16_16_P15(gain,side), fill>>B)<<(B0>>1);
971e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      } else {
972e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         cm = quant_partition(ctx, Y, N, sbits, B,
973e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               next_lowband2, LM,
974e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               MULT16_16_P15(gain,side), fill>>B)<<(B0>>1);
975e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         rebalance = sbits - (rebalance-ctx->remaining_bits);
976e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         if (rebalance > 3<<BITRES && itheta!=16384)
977e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            mbits += rebalance - (3<<BITRES);
978e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         cm |= quant_partition(ctx, X, N, mbits, B,
979e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               lowband, LM,
980e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               MULT16_16_P15(gain,mid), fill);
981e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      }
982885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   } else {
983885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      /* This is the basic no-split case */
984885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      q = bits2pulses(m, i, LM, b);
985885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      curr_bits = pulses2bits(m, i, LM, q);
986e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      ctx->remaining_bits -= curr_bits;
987885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
988885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      /* Ensures we can never bust the budget */
989e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      while (ctx->remaining_bits < 0 && q > 0)
990885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
991e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         ctx->remaining_bits += curr_bits;
992885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         q--;
993885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         curr_bits = pulses2bits(m, i, LM, q);
994e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         ctx->remaining_bits -= curr_bits;
995885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
996885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
997885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (q!=0)
998885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
999885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         int K = get_pulses(q);
1000885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
1001885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         /* Finally do the actual quantization */
1002885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         if (encode)
1003885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         {
1004885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            cm = alg_quant(X, N, K, spread, B, ec
1005885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef RESYNTH
1006885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                 , gain
1007885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
1008885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                 );
1009885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         } else {
1010885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            cm = alg_unquant(X, N, K, spread, B, ec, gain);
1011885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         }
1012885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      } else {
1013885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         /* If there's no pulse, fill the band anyway */
1014885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         int j;
1015885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         if (resynth)
1016885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         {
1017885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            unsigned cm_mask;
1018e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            /* B can be as large as 16, so this shift might overflow an int on a
1019885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               16-bit platform; use a long to get defined behavior.*/
1020885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            cm_mask = (unsigned)(1UL<<B)-1;
1021885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            fill &= cm_mask;
1022885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if (!fill)
1023885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            {
1024885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               for (j=0;j<N;j++)
1025885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  X[j] = 0;
1026885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            } else {
1027885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               if (lowband == NULL)
1028885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               {
1029885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  /* Noise */
1030885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  for (j=0;j<N;j++)
1031885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  {
1032e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org                     ctx->seed = celt_lcg_rand(ctx->seed);
1033e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org                     X[j] = (celt_norm)((opus_int32)ctx->seed>>20);
1034885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  }
1035885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  cm = cm_mask;
1036885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               } else {
1037885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  /* Folded spectrum */
1038885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  for (j=0;j<N;j++)
1039885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  {
1040885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     opus_val16 tmp;
1041e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org                     ctx->seed = celt_lcg_rand(ctx->seed);
1042885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     /* About 48 dB below the "normal" folding level */
1043885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     tmp = QCONST16(1.0f/256, 10);
1044e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org                     tmp = (ctx->seed)&0x8000 ? tmp : -tmp;
1045885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     X[j] = lowband[j]+tmp;
1046885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  }
1047885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  cm = fill;
1048885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               }
1049885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               renormalise_vector(X, N, gain);
1050885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
1051885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         }
1052885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
1053885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
1054885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
1055e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   return cm;
1056e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org}
1057e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
1058e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
1059e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org/* This function is responsible for encoding and decoding a band for the mono case. */
1060e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstatic unsigned quant_band(struct band_ctx *ctx, celt_norm *X,
1061e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      int N, int b, int B, celt_norm *lowband,
1062e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      int LM, celt_norm *lowband_out,
1063e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      opus_val16 gain, celt_norm *lowband_scratch, int fill)
1064e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{
1065e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int N0=N;
1066e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int N_B=N;
1067e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int N_B0;
1068e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int B0=B;
1069e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int time_divide=0;
1070e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int recombine=0;
1071e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int longBlocks;
1072e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   unsigned cm=0;
1073e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#ifdef RESYNTH
1074e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int resynth = 1;
1075e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#else
1076e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int resynth = !ctx->encode;
1077e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif
1078e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int k;
1079e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int encode;
1080e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int tf_change;
1081e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
1082e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   encode = ctx->encode;
1083e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   tf_change = ctx->tf_change;
1084e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
1085e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   longBlocks = B0==1;
1086e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
1087e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   N_B /= B;
1088e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
1089e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   /* Special case for one sample */
1090e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   if (N==1)
1091e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   {
1092e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      return quant_band_n1(ctx, X, NULL, b, lowband_out);
1093e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   }
1094e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
1095e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   if (tf_change>0)
1096e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      recombine = tf_change;
1097e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   /* Band recombining to increase frequency resolution */
1098e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
1099e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   if (lowband_scratch && lowband && (recombine || ((N_B&1) == 0 && tf_change<0) || B0>1))
1100e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   {
1101e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      int j;
1102e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      for (j=0;j<N;j++)
1103e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         lowband_scratch[j] = lowband[j];
1104e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      lowband = lowband_scratch;
1105e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   }
1106e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
1107e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   for (k=0;k<recombine;k++)
1108e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   {
1109e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      static const unsigned char bit_interleave_table[16]={
1110e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            0,1,1,1,2,3,3,3,2,3,3,3,2,3,3,3
1111e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      };
1112e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      if (encode)
1113e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         haar1(X, N>>k, 1<<k);
1114e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      if (lowband)
1115e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         haar1(lowband, N>>k, 1<<k);
1116e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      fill = bit_interleave_table[fill&0xF]|bit_interleave_table[fill>>4]<<2;
1117e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   }
1118e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   B>>=recombine;
1119e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   N_B<<=recombine;
1120e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
1121e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   /* Increasing the time resolution */
1122e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   while ((N_B&1) == 0 && tf_change<0)
1123e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   {
1124e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      if (encode)
1125e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         haar1(X, N_B, B);
1126e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      if (lowband)
1127e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         haar1(lowband, N_B, B);
1128e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      fill |= fill<<B;
1129e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      B <<= 1;
1130e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      N_B >>= 1;
1131e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      time_divide++;
1132e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      tf_change++;
1133e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   }
1134e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   B0=B;
1135e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   N_B0 = N_B;
1136e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
1137e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   /* Reorganize the samples in time order instead of frequency order */
1138e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   if (B0>1)
1139e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   {
1140e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      if (encode)
1141e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         deinterleave_hadamard(X, N_B>>recombine, B0<<recombine, longBlocks);
1142e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      if (lowband)
1143e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         deinterleave_hadamard(lowband, N_B>>recombine, B0<<recombine, longBlocks);
1144e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   }
1145e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
1146e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   cm = quant_partition(ctx, X, N, b, B, lowband,
1147e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         LM, gain, fill);
1148e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
1149885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* This code is used by the decoder and by the resynthesis-enabled encoder */
1150885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (resynth)
1151885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
1152e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      /* Undo the sample reorganization going from time order to frequency order */
1153e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      if (B0>1)
1154e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         interleave_hadamard(X, N_B>>recombine, B0<<recombine, longBlocks);
1155e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
1156e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      /* Undo time-freq changes that we did earlier */
1157e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      N_B = N_B0;
1158e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      B = B0;
1159e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      for (k=0;k<time_divide;k++)
1160885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
1161e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         B >>= 1;
1162e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         N_B <<= 1;
1163e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         cm |= cm>>B;
1164e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         haar1(X, N_B, B);
1165e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      }
1166e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
1167e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      for (k=0;k<recombine;k++)
1168885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
1169e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         static const unsigned char bit_deinterleave_table[16]={
1170e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               0x00,0x03,0x0C,0x0F,0x30,0x33,0x3C,0x3F,
1171e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               0xC0,0xC3,0xCC,0xCF,0xF0,0xF3,0xFC,0xFF
1172e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         };
1173e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         cm = bit_deinterleave_table[cm];
1174e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         haar1(X, N0>>k, 1<<k);
1175e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      }
1176e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      B<<=recombine;
1177885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
1178e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      /* Scale output for later folding */
1179e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      if (lowband_out)
1180e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      {
1181e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         int j;
1182e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         opus_val16 n;
1183e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         n = celt_sqrt(SHL32(EXTEND32(N0),22));
1184e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         for (j=0;j<N0;j++)
1185e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            lowband_out[j] = MULT16_16_Q15(n,X[j]);
1186e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      }
1187e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      cm &= (1<<B)-1;
1188e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   }
1189e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   return cm;
1190e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org}
1191885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
1192885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
1193e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org/* This function is responsible for encoding and decoding a band for the stereo case. */
1194e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstatic unsigned quant_band_stereo(struct band_ctx *ctx, celt_norm *X, celt_norm *Y,
1195e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      int N, int b, int B, celt_norm *lowband,
1196e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      int LM, celt_norm *lowband_out,
1197e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      celt_norm *lowband_scratch, int fill)
1198e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{
1199e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int imid=0, iside=0;
1200e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int inv = 0;
1201e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   opus_val16 mid=0, side=0;
1202e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   unsigned cm=0;
1203e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#ifdef RESYNTH
1204e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int resynth = 1;
1205e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#else
1206e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int resynth = !ctx->encode;
1207e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif
1208e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int mbits, sbits, delta;
1209e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int itheta;
1210e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int qalloc;
1211e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   struct split_ctx sctx;
1212e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int orig_fill;
1213e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int encode;
1214e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   ec_ctx *ec;
1215e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
1216e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   encode = ctx->encode;
1217e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   ec = ctx->ec;
1218e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
1219e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   /* Special case for one sample */
1220e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   if (N==1)
1221e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   {
1222e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      return quant_band_n1(ctx, X, Y, b, lowband_out);
1223e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   }
1224e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
1225e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   orig_fill = fill;
1226e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
1227e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   compute_theta(ctx, &sctx, X, Y, N, &b, B, B,
1228e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         LM, 1, &fill);
1229e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   inv = sctx.inv;
1230e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   imid = sctx.imid;
1231e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   iside = sctx.iside;
1232e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   delta = sctx.delta;
1233e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   itheta = sctx.itheta;
1234e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   qalloc = sctx.qalloc;
1235e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#ifdef FIXED_POINT
1236e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   mid = imid;
1237e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   side = iside;
1238e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#else
1239e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   mid = (1.f/32768)*imid;
1240e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   side = (1.f/32768)*iside;
1241e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif
1242885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
1243e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   /* This is a special case for N=2 that only works for stereo and takes
1244e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      advantage of the fact that mid and side are orthogonal to encode
1245e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      the side with just one bit. */
1246e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   if (N==2)
1247e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   {
1248e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      int c;
1249e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      int sign=0;
1250e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      celt_norm *x2, *y2;
1251e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      mbits = b;
1252e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      sbits = 0;
1253e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      /* Only need one bit for the side. */
1254e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      if (itheta != 0 && itheta != 16384)
1255e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         sbits = 1<<BITRES;
1256e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      mbits -= sbits;
1257e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      c = itheta > 8192;
1258e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      ctx->remaining_bits -= qalloc+sbits;
1259e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
1260e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      x2 = c ? Y : X;
1261e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      y2 = c ? X : Y;
1262e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      if (sbits)
1263e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      {
1264e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         if (encode)
1265885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         {
1266e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            /* Here we only need to encode a sign for the side. */
1267e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            sign = x2[0]*y2[1] - x2[1]*y2[0] < 0;
1268e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            ec_enc_bits(ec, sign, 1);
1269e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         } else {
1270e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            sign = ec_dec_bits(ec, 1);
1271885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         }
1272e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      }
1273e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      sign = 1-2*sign;
1274e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      /* We use orig_fill here because we want to fold the side, but if
1275e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         itheta==16384, we'll have cleared the low bits of fill. */
1276e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      cm = quant_band(ctx, x2, N, mbits, B, lowband,
1277e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            LM, lowband_out, Q15ONE, lowband_scratch, orig_fill);
1278e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      /* We don't split N=2 bands, so cm is either 1 or 0 (for a fold-collapse),
1279e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         and there's no need to worry about mixing with the other channel. */
1280e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      y2[0] = -sign*x2[1];
1281e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      y2[1] = sign*x2[0];
1282e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      if (resynth)
1283e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      {
1284e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         celt_norm tmp;
1285e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         X[0] = MULT16_16_Q15(mid, X[0]);
1286e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         X[1] = MULT16_16_Q15(mid, X[1]);
1287e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         Y[0] = MULT16_16_Q15(side, Y[0]);
1288e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         Y[1] = MULT16_16_Q15(side, Y[1]);
1289e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         tmp = X[0];
1290e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         X[0] = SUB16(tmp,Y[0]);
1291e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         Y[0] = ADD16(tmp,Y[0]);
1292e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         tmp = X[1];
1293e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         X[1] = SUB16(tmp,Y[1]);
1294e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         Y[1] = ADD16(tmp,Y[1]);
1295e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      }
1296e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   } else {
1297e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      /* "Normal" split code */
1298e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      opus_int32 rebalance;
1299e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
1300e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      mbits = IMAX(0, IMIN(b, (b-delta)/2));
1301e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      sbits = b-mbits;
1302e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      ctx->remaining_bits -= qalloc;
1303e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
1304e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      rebalance = ctx->remaining_bits;
1305e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      if (mbits >= sbits)
1306e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      {
1307e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         /* In stereo mode, we do not apply a scaling to the mid because we need the normalized
1308e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            mid for folding later. */
1309e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         cm = quant_band(ctx, X, N, mbits, B,
1310e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               lowband, LM, lowband_out,
1311e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               Q15ONE, lowband_scratch, fill);
1312e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         rebalance = mbits - (rebalance-ctx->remaining_bits);
1313e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         if (rebalance > 3<<BITRES && itheta!=0)
1314e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            sbits += rebalance - (3<<BITRES);
1315e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
1316e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         /* For a stereo split, the high bits of fill are always zero, so no
1317e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            folding will be done to the side. */
1318e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         cm |= quant_band(ctx, Y, N, sbits, B,
1319e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               NULL, LM, NULL,
1320e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               side, NULL, fill>>B);
1321e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      } else {
1322e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         /* For a stereo split, the high bits of fill are always zero, so no
1323e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            folding will be done to the side. */
1324e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         cm = quant_band(ctx, Y, N, sbits, B,
1325e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               NULL, LM, NULL,
1326e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               side, NULL, fill>>B);
1327e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         rebalance = sbits - (rebalance-ctx->remaining_bits);
1328e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         if (rebalance > 3<<BITRES && itheta!=16384)
1329e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            mbits += rebalance - (3<<BITRES);
1330e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         /* In stereo mode, we do not apply a scaling to the mid because we need the normalized
1331e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            mid for folding later. */
1332e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         cm |= quant_band(ctx, X, N, mbits, B,
1333e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               lowband, LM, lowband_out,
1334e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               Q15ONE, lowband_scratch, fill);
1335e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      }
1336e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   }
1337e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
1338e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
1339e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   /* This code is used by the decoder and by the resynthesis-enabled encoder */
1340e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   if (resynth)
1341e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   {
1342e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      if (N!=2)
1343e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         stereo_merge(X, Y, mid, N);
1344e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      if (inv)
1345e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      {
1346e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         int j;
1347e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         for (j=0;j<N;j++)
1348e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            Y[j] = -Y[j];
1349885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
1350885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
1351885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   return cm;
1352885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
1353885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
1354e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
1355885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid quant_all_bands(int encode, const CELTMode *m, int start, int end,
1356885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      celt_norm *X_, celt_norm *Y_, unsigned char *collapse_masks, const celt_ener *bandE, int *pulses,
1357885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int shortBlocks, int spread, int dual_stereo, int intensity, int *tf_res,
1358885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      opus_int32 total_bits, opus_int32 balance, ec_ctx *ec, int LM, int codedBands, opus_uint32 *seed)
1359885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
1360885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int i;
1361885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   opus_int32 remaining_bits;
1362885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   const opus_int16 * OPUS_RESTRICT eBands = m->eBands;
1363885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   celt_norm * OPUS_RESTRICT norm, * OPUS_RESTRICT norm2;
1364885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   VARDECL(celt_norm, _norm);
1365e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   celt_norm *lowband_scratch;
1366885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int B;
1367885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int M;
1368885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int lowband_offset;
1369885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int update_lowband = 1;
1370885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int C = Y_ != NULL ? 2 : 1;
1371e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   int norm_offset;
1372885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef RESYNTH
1373885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int resynth = 1;
1374885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#else
1375885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int resynth = !encode;
1376885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
1377e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   struct band_ctx ctx;
1378885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   SAVE_STACK;
1379885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
1380885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   M = 1<<LM;
1381885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   B = shortBlocks ? M : 1;
1382e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   norm_offset = M*eBands[start];
1383e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   /* No need to allocate norm for the last band because we don't need an
1384e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      output in that band. */
1385e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   ALLOC(_norm, C*(M*eBands[m->nbEBands-1]-norm_offset), celt_norm);
1386885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   norm = _norm;
1387e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   norm2 = norm + M*eBands[m->nbEBands-1]-norm_offset;
1388e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   /* We can use the last band as scratch space because we don't need that
1389e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      scratch space for the last band. */
1390e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   lowband_scratch = X_+M*eBands[m->nbEBands-1];
1391885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
1392885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   lowband_offset = 0;
1393e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   ctx.bandE = bandE;
1394e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   ctx.ec = ec;
1395e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   ctx.encode = encode;
1396e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   ctx.intensity = intensity;
1397e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   ctx.m = m;
1398e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   ctx.seed = *seed;
1399e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   ctx.spread = spread;
1400885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=start;i<end;i++)
1401885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
1402885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      opus_int32 tell;
1403885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int b;
1404885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int N;
1405885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      opus_int32 curr_balance;
1406885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int effective_lowband=-1;
1407885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      celt_norm * OPUS_RESTRICT X, * OPUS_RESTRICT Y;
1408885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int tf_change=0;
1409885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      unsigned x_cm;
1410885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      unsigned y_cm;
1411e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      int last;
1412e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
1413e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      ctx.i = i;
1414e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      last = (i==end-1);
1415885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
1416885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      X = X_+M*eBands[i];
1417885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (Y_!=NULL)
1418885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Y = Y_+M*eBands[i];
1419885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      else
1420885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Y = NULL;
1421885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      N = M*eBands[i+1]-M*eBands[i];
1422885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      tell = ec_tell_frac(ec);
1423885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
1424885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      /* Compute how many bits we want to allocate to this band */
1425885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (i != start)
1426885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         balance -= tell;
1427885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      remaining_bits = total_bits-tell-1;
1428e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      ctx.remaining_bits = remaining_bits;
1429885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (i <= codedBands-1)
1430885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
1431885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         curr_balance = balance / IMIN(3, codedBands-i);
1432885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         b = IMAX(0, IMIN(16383, IMIN(remaining_bits+1,pulses[i]+curr_balance)));
1433885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      } else {
1434885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         b = 0;
1435885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
1436885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
1437885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (resynth && M*eBands[i]-N >= M*eBands[start] && (update_lowband || lowband_offset==0))
1438885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            lowband_offset = i;
1439885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
1440885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      tf_change = tf_res[i];
1441e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      ctx.tf_change = tf_change;
1442885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (i>=m->effEBands)
1443885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
1444885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         X=norm;
1445885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         if (Y_!=NULL)
1446885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            Y = norm;
1447e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         lowband_scratch = NULL;
1448885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
1449e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      if (i==end-1)
1450e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         lowband_scratch = NULL;
1451885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
1452885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      /* Get a conservative estimate of the collapse_mask's for the bands we're
1453e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         going to be folding from. */
1454885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (lowband_offset != 0 && (spread!=SPREAD_AGGRESSIVE || B>1 || tf_change<0))
1455885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
1456885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         int fold_start;
1457885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         int fold_end;
1458885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         int fold_i;
1459885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         /* This ensures we never repeat spectral content within one band */
1460e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         effective_lowband = IMAX(0, M*eBands[lowband_offset]-norm_offset-N);
1461885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         fold_start = lowband_offset;
1462e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         while(M*eBands[--fold_start] > effective_lowband+norm_offset);
1463885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         fold_end = lowband_offset-1;
1464e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         while(M*eBands[++fold_end] < effective_lowband+norm_offset+N);
1465885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         x_cm = y_cm = 0;
1466885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         fold_i = fold_start; do {
1467885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org           x_cm |= collapse_masks[fold_i*C+0];
1468885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org           y_cm |= collapse_masks[fold_i*C+C-1];
1469885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         } while (++fold_i<fold_end);
1470885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
1471885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      /* Otherwise, we'll be using the LCG to fold, so all blocks will (almost
1472e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         always) be non-zero. */
1473885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      else
1474885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         x_cm = y_cm = (1<<B)-1;
1475885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
1476885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (dual_stereo && i==intensity)
1477885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
1478885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         int j;
1479885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
1480e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         /* Switch off dual stereo to do intensity. */
1481885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         dual_stereo = 0;
1482885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         if (resynth)
1483e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            for (j=0;j<M*eBands[i]-norm_offset;j++)
1484885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               norm[j] = HALF32(norm[j]+norm2[j]);
1485885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
1486885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (dual_stereo)
1487885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
1488e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         x_cm = quant_band(&ctx, X, N, b/2, B,
1489e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               effective_lowband != -1 ? norm+effective_lowband : NULL, LM,
1490e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               last?NULL:norm+M*eBands[i]-norm_offset, Q15ONE, lowband_scratch, x_cm);
1491e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         y_cm = quant_band(&ctx, Y, N, b/2, B,
1492e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               effective_lowband != -1 ? norm2+effective_lowband : NULL, LM,
1493e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org               last?NULL:norm2+M*eBands[i]-norm_offset, Q15ONE, lowband_scratch, y_cm);
1494885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      } else {
1495e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         if (Y!=NULL)
1496e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         {
1497e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            x_cm = quant_band_stereo(&ctx, X, Y, N, b, B,
1498e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org                  effective_lowband != -1 ? norm+effective_lowband : NULL, LM,
1499e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org                        last?NULL:norm+M*eBands[i]-norm_offset, lowband_scratch, x_cm|y_cm);
1500e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         } else {
1501e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            x_cm = quant_band(&ctx, X, N, b, B,
1502e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org                  effective_lowband != -1 ? norm+effective_lowband : NULL, LM,
1503e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org                        last?NULL:norm+M*eBands[i]-norm_offset, Q15ONE, lowband_scratch, x_cm|y_cm);
1504e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         }
1505885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         y_cm = x_cm;
1506885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
1507885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      collapse_masks[i*C+0] = (unsigned char)x_cm;
1508885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      collapse_masks[i*C+C-1] = (unsigned char)y_cm;
1509885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      balance += pulses[i] + tell;
1510885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
1511e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      /* Update the folding position only as long as we have 1 bit/sample depth. */
1512885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      update_lowband = b>(N<<BITRES);
1513885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
1514e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org   *seed = ctx.seed;
1515e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org
1516885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   RESTORE_STACK;
1517885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
1518885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
1519