1885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/* Copyright (c) 2007-2008 CSIRO
2885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   Copyright (c) 2007-2009 Xiph.Org Foundation
3885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   Written by Jean-Marc Valin */
4885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/*
5885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   Redistribution and use in source and binary forms, with or without
6885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   modification, are permitted provided that the following conditions
7885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   are met:
8885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
9885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   - Redistributions of source code must retain the above copyright
10885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   notice, this list of conditions and the following disclaimer.
11885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
12885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   - Redistributions in binary form must reproduce the above copyright
13885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   notice, this list of conditions and the following disclaimer in the
14885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   documentation and/or other materials provided with the distribution.
15885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
16885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
20885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org*/
28885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
29885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef HAVE_CONFIG_H
30885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "config.h"
31885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
32885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
33885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include <math.h>
34885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "modes.h"
35885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "cwrs.h"
36885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "arch.h"
37885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "os_support.h"
38885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
39885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "entcode.h"
40885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#include "rate.h"
41885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
42885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic const unsigned char LOG2_FRAC_TABLE[24]={
43885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   0,
44885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   8,13,
45885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  16,19,21,23,
46885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  24,26,27,28,29,30,31,32,
47885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  32,33,34,34,35,36,36,37,37
48885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org};
49885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
50885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef CUSTOM_MODES
51885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
52885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org/*Determines if V(N,K) fits in a 32-bit unsigned integer.
53885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org  N and K are themselves limited to 15 bits.*/
54885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgstatic int fits_in32(int _n, int _k)
55885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
56885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   static const opus_int16 maxN[15] = {
57885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      32767, 32767, 32767, 1476, 283, 109,  60,  40,
58885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       29,  24,  20,  18,  16,  14,  13};
59885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   static const opus_int16 maxK[15] = {
60885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      32767, 32767, 32767, 32767, 1172, 238,  95,  53,
61885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       36,  27,  22,  18,  16,  15,  13};
62885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (_n>=14)
63885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
64885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (_k>=14)
65885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         return 0;
66885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      else
67885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         return _n <= maxN[_k];
68885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   } else {
69885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      return _k <= maxK[_n];
70885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
71885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
72885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
73885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgvoid compute_pulse_cache(CELTMode *m, int LM)
74885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
75885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int C;
76885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int i;
77885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int j;
78885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int curr=0;
79885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int nbEntries=0;
80885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int entryN[100], entryK[100], entryI[100];
81885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   const opus_int16 *eBands = m->eBands;
82885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   PulseCache *cache = &m->cache;
83885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   opus_int16 *cindex;
84885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   unsigned char *bits;
85885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   unsigned char *cap;
86885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
876b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org   cindex = (opus_int16 *)opus_alloc(sizeof(cache->index[0])*m->nbEBands*(LM+2));
88885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   cache->index = cindex;
89885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
90885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* Scan for all unique band sizes */
91885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=0;i<=LM+1;i++)
92885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
93885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      for (j=0;j<m->nbEBands;j++)
94885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
95885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         int k;
96885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         int N = (eBands[j+1]-eBands[j])<<i>>1;
97885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         cindex[i*m->nbEBands+j] = -1;
98885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         /* Find other bands that have the same size */
99885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         for (k=0;k<=i;k++)
100885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         {
101885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            int n;
102885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            for (n=0;n<m->nbEBands && (k!=i || n<j);n++)
103885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            {
104885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               if (N == (eBands[n+1]-eBands[n])<<k>>1)
105885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               {
106885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  cindex[i*m->nbEBands+j] = cindex[k*m->nbEBands+n];
107885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  break;
108885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               }
109885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
110885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         }
111885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         if (cache->index[i*m->nbEBands+j] == -1 && N!=0)
112885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         {
113885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            int K;
114885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            entryN[nbEntries] = N;
115885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            K = 0;
116885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            while (fits_in32(N,get_pulses(K+1)) && K<MAX_PSEUDO)
117885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               K++;
118885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            entryK[nbEntries] = K;
119885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            cindex[i*m->nbEBands+j] = curr;
120885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            entryI[nbEntries] = curr;
121885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
122885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            curr += K+1;
123885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            nbEntries++;
124885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         }
125885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
126885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
1276b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org   bits = (unsigned char *)opus_alloc(sizeof(unsigned char)*curr);
128885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   cache->bits = bits;
129885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   cache->size = curr;
130885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* Compute the cache for all unique sizes */
131885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=0;i<nbEntries;i++)
132885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
133885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      unsigned char *ptr = bits+entryI[i];
134885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      opus_int16 tmp[MAX_PULSES+1];
135885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      get_required_bits(tmp, entryN[i], get_pulses(entryK[i]), BITRES);
136885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      for (j=1;j<=entryK[i];j++)
137885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         ptr[j] = tmp[get_pulses(j)]-1;
138885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      ptr[0] = entryK[i];
139885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
140885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
141885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* Compute the maximum rate for each band at which we'll reliably use as
142885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       many bits as we ask for. */
1436b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org   cache->caps = cap = (unsigned char *)opus_alloc(sizeof(cache->caps[0])*(LM+1)*2*m->nbEBands);
144885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=0;i<=LM;i++)
145885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
146885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      for (C=1;C<=2;C++)
147885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
148885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         for (j=0;j<m->nbEBands;j++)
149885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         {
150885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            int N0;
151885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            int max_bits;
152885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            N0 = m->eBands[j+1]-m->eBands[j];
153885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            /* N=1 bands only have a sign bit and fine bits. */
154885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if (N0<<i == 1)
155885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               max_bits = C*(1+MAX_FINE_BITS)<<BITRES;
156885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            else
157885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            {
158885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               const unsigned char *pcache;
159885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               opus_int32           num;
160885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               opus_int32           den;
161885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               int                  LM0;
162885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               int                  N;
163885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               int                  offset;
164885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               int                  ndof;
165885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               int                  qb;
166885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               int                  k;
167885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               LM0 = 0;
168885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               /* Even-sized bands bigger than N=2 can be split one more time.
169885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  As of commit 44203907 all bands >1 are even, including custom modes.*/
170885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               if (N0 > 2)
171885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               {
172885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  N0>>=1;
173885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  LM0--;
174885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               }
175885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               /* N0=1 bands can't be split down to N<2. */
176885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               else if (N0 <= 1)
177885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               {
178885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  LM0=IMIN(i,1);
179885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  N0<<=LM0;
180885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               }
181885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               /* Compute the cost for the lowest-level PVQ of a fully split
182885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                   band. */
183885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               pcache = bits + cindex[(LM0+1)*m->nbEBands+j];
184885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               max_bits = pcache[pcache[0]]+1;
185885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               /* Add in the cost of coding regular splits. */
186885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               N = N0;
187885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               for(k=0;k<i-LM0;k++){
188885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  max_bits <<= 1;
189885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  /* Offset the number of qtheta bits by log2(N)/2
190885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                      + QTHETA_OFFSET compared to their "fair share" of
191885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                      total/N */
192885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  offset = ((m->logN[j]+((LM0+k)<<BITRES))>>1)-QTHETA_OFFSET;
193885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  /* The number of qtheta bits we'll allocate if the remainder
194885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                      is to be max_bits.
195885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                     The average measured cost for theta is 0.89701 times qb,
196885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                      approximated here as 459/512. */
197885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  num=459*(opus_int32)((2*N-1)*offset+max_bits);
198885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  den=((opus_int32)(2*N-1)<<9)-459;
199885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  qb = IMIN((num+(den>>1))/den, 57);
200885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  celt_assert(qb >= 0);
201885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  max_bits += qb;
202885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  N <<= 1;
203885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               }
204885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               /* Add in the cost of a stereo split, if necessary. */
205885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               if (C==2)
206885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               {
207885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  max_bits <<= 1;
208885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  offset = ((m->logN[j]+(i<<BITRES))>>1)-(N==2?QTHETA_OFFSET_TWOPHASE:QTHETA_OFFSET);
209885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  ndof = 2*N-1-(N==2);
210885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  /* The average measured cost for theta with the step PDF is
211885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                      0.95164 times qb, approximated here as 487/512. */
212885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  num = (N==2?512:487)*(opus_int32)(max_bits+ndof*offset);
213885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  den = ((opus_int32)ndof<<9)-(N==2?512:487);
214885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  qb = IMIN((num+(den>>1))/den, (N==2?64:61));
215885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  celt_assert(qb >= 0);
216885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  max_bits += qb;
217885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               }
218885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               /* Add the fine bits we'll use. */
219885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               /* Compensate for the extra DoF in stereo */
220885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               ndof = C*N + ((C==2 && N>2) ? 1 : 0);
221885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               /* Offset the number of fine bits by log2(N)/2 + FINE_OFFSET
222885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                   compared to their "fair share" of total/N */
223885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               offset = ((m->logN[j] + (i<<BITRES))>>1)-FINE_OFFSET;
224885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               /* N=2 is the only point that doesn't match the curve */
225885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               if (N==2)
226885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                  offset += 1<<BITRES>>2;
227885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               /* The number of fine bits we'll allocate if the remainder is
228885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org                   to be max_bits. */
229885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               num = max_bits+ndof*offset;
230885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               den = (ndof-1)<<BITRES;
231885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               qb = IMIN((num+(den>>1))/den, MAX_FINE_BITS);
232885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               celt_assert(qb >= 0);
233885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               max_bits += C*qb<<BITRES;
234885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
235885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            max_bits = (4*max_bits/(C*((m->eBands[j+1]-m->eBands[j])<<i)))-64;
236885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            celt_assert(max_bits >= 0);
237885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            celt_assert(max_bits < 256);
238885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            *cap++ = (unsigned char)max_bits;
239885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         }
240885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
241885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
242885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
243885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
244885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif /* CUSTOM_MODES */
245885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
246885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#define ALLOC_STEPS 6
247885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
2483c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.comstatic OPUS_INLINE int interp_bits2pulses(const CELTMode *m, int start, int end, int skip_start,
249885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      const int *bits1, const int *bits2, const int *thresh, const int *cap, opus_int32 total, opus_int32 *_balance,
250885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int skip_rsv, int *intensity, int intensity_rsv, int *dual_stereo, int dual_stereo_rsv, int *bits,
251e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev, int signalBandwidth)
252885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
253885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   opus_int32 psum;
254885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int lo, hi;
255885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int i, j;
256885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int logM;
257885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int stereo;
258885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int codedBands=-1;
259885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int alloc_floor;
260885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   opus_int32 left, percoeff;
261885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int done;
2626b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org   opus_int32 balance;
263885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   SAVE_STACK;
264885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
265885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   alloc_floor = C<<BITRES;
266885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   stereo = C>1;
267885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
268885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   logM = LM<<BITRES;
269885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   lo = 0;
270885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   hi = 1<<ALLOC_STEPS;
271885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (i=0;i<ALLOC_STEPS;i++)
272885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
273885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int mid = (lo+hi)>>1;
274885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      psum = 0;
275885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      done = 0;
276885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      for (j=end;j-->start;)
277885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
278885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         int tmp = bits1[j] + (mid*(opus_int32)bits2[j]>>ALLOC_STEPS);
279885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         if (tmp >= thresh[j] || done)
280885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         {
281885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            done = 1;
282885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            /* Don't allocate more than we can actually use */
283885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            psum += IMIN(tmp, cap[j]);
284885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         } else {
285885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if (tmp >= alloc_floor)
286885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               psum += alloc_floor;
287885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         }
288885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
289885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (psum > total)
290885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         hi = mid;
291885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      else
292885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         lo = mid;
293885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
294885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   psum = 0;
295885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /*printf ("interp bisection gave %d\n", lo);*/
296885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   done = 0;
297885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (j=end;j-->start;)
298885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
299885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int tmp = bits1[j] + (lo*bits2[j]>>ALLOC_STEPS);
300885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (tmp < thresh[j] && !done)
301885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
302885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         if (tmp >= alloc_floor)
303885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            tmp = alloc_floor;
304885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         else
305885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            tmp = 0;
306885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      } else
307885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         done = 1;
308885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      /* Don't allocate more than we can actually use */
309885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      tmp = IMIN(tmp, cap[j]);
310885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      bits[j] = tmp;
311885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      psum += tmp;
312885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
313885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
314885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* Decide which bands to skip, working backwards from the end. */
315885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (codedBands=end;;codedBands--)
316885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
317885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int band_width;
318885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int band_bits;
319885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int rem;
320885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      j = codedBands-1;
321885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      /* Never skip the first band, nor a band that has been boosted by
322885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          dynalloc.
323885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         In the first case, we'd be coding a bit to signal we're going to waste
324885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          all the other bits.
325885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         In the second case, we'd be coding a bit to redistribute all the bits
326885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          we just signaled should be cocentrated in this band. */
327885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (j<=skip_start)
328885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
329885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         /* Give the bit we reserved to end skipping back. */
330885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         total += skip_rsv;
331885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         break;
332885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
333885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      /*Figure out how many left-over bits we would be adding to this band.
334885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        This can include bits we've stolen back from higher, skipped bands.*/
335885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      left = total-psum;
336885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      percoeff = left/(m->eBands[codedBands]-m->eBands[start]);
337885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      left -= (m->eBands[codedBands]-m->eBands[start])*percoeff;
338885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      rem = IMAX(left-(m->eBands[j]-m->eBands[start]),0);
339885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      band_width = m->eBands[codedBands]-m->eBands[j];
340885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      band_bits = (int)(bits[j] + percoeff*band_width + rem);
341885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      /*Only code a skip decision if we're above the threshold for this band.
342885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        Otherwise it is force-skipped.
343885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org        This ensures that we have enough bits to code the skip flag.*/
344885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (band_bits >= IMAX(thresh[j], alloc_floor+(1<<BITRES)))
345885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
346885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         if (encode)
347885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         {
348885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            /*This if() block is the only part of the allocation function that
349885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               is not a mandatory part of the bitstream: any bands we choose to
350885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               skip here must be explicitly signaled.*/
351885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            /*Choose a threshold with some hysteresis to keep bands from
352885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               fluctuating in and out.*/
353885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#ifdef FUZZING
354885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if ((rand()&0x1) == 0)
355885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#else
356e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org            if (codedBands<=start+2 || (band_bits > ((j<prev?7:9)*band_width<<LM<<BITRES)>>4 && j<=signalBandwidth))
357885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org#endif
358885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            {
359885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               ec_enc_bit_logp(ec, 1, 1);
360885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               break;
361885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            }
362885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            ec_enc_bit_logp(ec, 0, 1);
363885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         } else if (ec_dec_bit_logp(ec, 1)) {
364885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            break;
365885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         }
366885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         /*We used a bit to skip this band.*/
367885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         psum += 1<<BITRES;
368885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         band_bits -= 1<<BITRES;
369885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
370885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      /*Reclaim the bits originally allocated to this band.*/
371885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      psum -= bits[j]+intensity_rsv;
372885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (intensity_rsv > 0)
373885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         intensity_rsv = LOG2_FRAC_TABLE[j-start];
374885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      psum += intensity_rsv;
375885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (band_bits >= alloc_floor)
376885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
377885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         /*If we have enough for a fine energy bit per channel, use it.*/
378885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         psum += alloc_floor;
379885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         bits[j] = alloc_floor;
380885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      } else {
381885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         /*Otherwise this band gets nothing at all.*/
382885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         bits[j] = 0;
383885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
384885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
385885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
386885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   celt_assert(codedBands > start);
387885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* Code the intensity and dual stereo parameters. */
388885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (intensity_rsv > 0)
389885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
390885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (encode)
391885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
392885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         *intensity = IMIN(*intensity, codedBands);
393885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         ec_enc_uint(ec, *intensity-start, codedBands+1-start);
394885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
395885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      else
396885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         *intensity = start+ec_dec_uint(ec, codedBands+1-start);
397885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
398885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   else
399885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      *intensity = 0;
400885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (*intensity <= start)
401885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
402885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      total += dual_stereo_rsv;
403885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      dual_stereo_rsv = 0;
404885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
405885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (dual_stereo_rsv > 0)
406885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
407885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (encode)
408885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         ec_enc_bit_logp(ec, *dual_stereo, 1);
409885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      else
410885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         *dual_stereo = ec_dec_bit_logp(ec, 1);
411885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
412885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   else
413885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      *dual_stereo = 0;
414885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
415885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* Allocate the remaining bits */
416885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   left = total-psum;
417885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   percoeff = left/(m->eBands[codedBands]-m->eBands[start]);
418885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   left -= (m->eBands[codedBands]-m->eBands[start])*percoeff;
419885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (j=start;j<codedBands;j++)
420885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      bits[j] += ((int)percoeff*(m->eBands[j+1]-m->eBands[j]));
421885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (j=start;j<codedBands;j++)
422885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
423885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int tmp = (int)IMIN(left, m->eBands[j+1]-m->eBands[j]);
424885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      bits[j] += tmp;
425885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      left -= tmp;
426885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
427885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /*for (j=0;j<end;j++)printf("%d ", bits[j]);printf("\n");*/
428885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
429885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   balance = 0;
430885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (j=start;j<codedBands;j++)
431885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
432885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int N0, N, den;
433885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int offset;
434885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int NClogN;
4356b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org      opus_int32 excess, bit;
436885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
437885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      celt_assert(bits[j] >= 0);
438885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      N0 = m->eBands[j+1]-m->eBands[j];
439885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      N=N0<<LM;
4406b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org      bit = (opus_int32)bits[j]+balance;
441885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
442885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (N>1)
443885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
4446b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org         excess = MAX32(bit-cap[j],0);
4456b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org         bits[j] = bit-excess;
446885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
447885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         /* Compensate for the extra DoF in stereo */
448885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         den=(C*N+ ((C==2 && N>2 && !*dual_stereo && j<*intensity) ? 1 : 0));
449885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
450885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         NClogN = den*(m->logN[j] + logM);
451885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
452885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         /* Offset for the number of fine bits by log2(N)/2 + FINE_OFFSET
453885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            compared to their "fair share" of total/N */
454885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         offset = (NClogN>>1)-den*FINE_OFFSET;
455885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
456885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         /* N=2 is the only point that doesn't match the curve */
457885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         if (N==2)
458885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            offset += den<<BITRES>>2;
459885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
460885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         /* Changing the offset for allocating the second and third
461885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org             fine energy bit */
462885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         if (bits[j] + offset < den*2<<BITRES)
463885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            offset += NClogN>>2;
464885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         else if (bits[j] + offset < den*3<<BITRES)
465885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            offset += NClogN>>3;
466885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
467885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         /* Divide with rounding */
468885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         ebits[j] = IMAX(0, (bits[j] + offset + (den<<(BITRES-1))) / (den<<BITRES));
469885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
470885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         /* Make sure not to bust */
471885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         if (C*ebits[j] > (bits[j]>>BITRES))
472885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            ebits[j] = bits[j] >> stereo >> BITRES;
473885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
474885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         /* More than that is useless because that's about as far as PVQ can go */
475885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         ebits[j] = IMIN(ebits[j], MAX_FINE_BITS);
476885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
477885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         /* If we rounded down or capped this band, make it a candidate for the
478885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org             final fine energy pass */
479885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         fine_priority[j] = ebits[j]*(den<<BITRES) >= bits[j]+offset;
480885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
481885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         /* Remove the allocated fine bits; the rest are assigned to PVQ */
482885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         bits[j] -= C*ebits[j]<<BITRES;
483885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
484885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      } else {
485885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         /* For N=1, all bits go to fine energy except for a single sign bit */
4866b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org         excess = MAX32(0,bit-(C<<BITRES));
4876b6bee25314cfac02cc555cddedb9680c63a26d6sergeyu@chromium.org         bits[j] = bit-excess;
488885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         ebits[j] = 0;
489885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         fine_priority[j] = 1;
490885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
491885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
492885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      /* Fine energy can't take advantage of the re-balancing in
493885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org          quant_all_bands().
494885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         Instead, do the re-balancing here.*/
495885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if(excess > 0)
496885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
497885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         int extra_fine;
498885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         int extra_bits;
499885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         extra_fine = IMIN(excess>>(stereo+BITRES),MAX_FINE_BITS-ebits[j]);
500885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         ebits[j] += extra_fine;
501885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         extra_bits = extra_fine*C<<BITRES;
502885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         fine_priority[j] = extra_bits >= excess-balance;
503885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         excess -= extra_bits;
504885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
505885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      balance = excess;
506885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
507885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      celt_assert(bits[j] >= 0);
508885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      celt_assert(ebits[j] >= 0);
509885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
510885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* Save any remaining bits over the cap for the rebalancing in
511885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org       quant_all_bands(). */
512885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   *_balance = balance;
513885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
514885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* The skipped bands use all their bits for fine energy. */
515885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (;j<end;j++)
516885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
517885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      ebits[j] = bits[j] >> stereo >> BITRES;
518885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      celt_assert(C*ebits[j]<<BITRES == bits[j]);
519885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      bits[j] = 0;
520885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      fine_priority[j] = ebits[j]<1;
521885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
522885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   RESTORE_STACK;
523885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   return codedBands;
524885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
525885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
526885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.orgint compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stereo,
527e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org      opus_int32 total, opus_int32 *balance, int *pulses, int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev, int signalBandwidth)
528885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org{
529885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int lo, hi, len, j;
530885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int codedBands;
531885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int skip_start;
532885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int skip_rsv;
533885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int intensity_rsv;
534885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   int dual_stereo_rsv;
535885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   VARDECL(int, bits1);
536885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   VARDECL(int, bits2);
537885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   VARDECL(int, thresh);
538885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   VARDECL(int, trim_offset);
539885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   SAVE_STACK;
540885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
541885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   total = IMAX(total, 0);
542885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   len = m->nbEBands;
543885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   skip_start = start;
544885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* Reserve a bit to signal the end of manually skipped bands. */
545885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   skip_rsv = total >= 1<<BITRES ? 1<<BITRES : 0;
546885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   total -= skip_rsv;
547885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /* Reserve bits for the intensity and dual stereo parameters. */
548885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   intensity_rsv = dual_stereo_rsv = 0;
549885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   if (C==2)
550885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
551885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      intensity_rsv = LOG2_FRAC_TABLE[end-start];
552885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (intensity_rsv>total)
553885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         intensity_rsv = 0;
554885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      else
555885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
556885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         total -= intensity_rsv;
557885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         dual_stereo_rsv = total>=1<<BITRES ? 1<<BITRES : 0;
558885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         total -= dual_stereo_rsv;
559885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
560885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
561885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   ALLOC(bits1, len, int);
562885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   ALLOC(bits2, len, int);
563885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   ALLOC(thresh, len, int);
564885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   ALLOC(trim_offset, len, int);
565885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
566885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (j=start;j<end;j++)
567885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
568885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      /* Below this threshold, we're sure not to allocate any PVQ bits */
569885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      thresh[j] = IMAX((C)<<BITRES, (3*(m->eBands[j+1]-m->eBands[j])<<LM<<BITRES)>>4);
570885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      /* Tilt of the allocation curve */
571885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      trim_offset[j] = C*(m->eBands[j+1]-m->eBands[j])*(alloc_trim-5-LM)*(end-j-1)
572885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            *(1<<(LM+BITRES))>>6;
573885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      /* Giving less resolution to single-coefficient bands because they get
574885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         more benefit from having one coarse value per coefficient*/
575885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if ((m->eBands[j+1]-m->eBands[j])<<LM==1)
576885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         trim_offset[j] -= C<<BITRES;
577885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
578885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   lo = 1;
579885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   hi = m->nbAllocVectors - 1;
580885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   do
581885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
582885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int done = 0;
583885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int psum = 0;
584885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int mid = (lo+hi) >> 1;
585885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      for (j=end;j-->start;)
586885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      {
587885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         int bitsj;
588885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         int N = m->eBands[j+1]-m->eBands[j];
589885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         bitsj = C*N*m->allocVectors[mid*len+j]<<LM>>2;
590885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         if (bitsj > 0)
591885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            bitsj = IMAX(0, bitsj + trim_offset[j]);
592885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         bitsj += offsets[j];
593885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         if (bitsj >= thresh[j] || done)
594885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         {
595885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            done = 1;
596885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            /* Don't allocate more than we can actually use */
597885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            psum += IMIN(bitsj, cap[j]);
598885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         } else {
599885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            if (bitsj >= C<<BITRES)
600885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org               psum += C<<BITRES;
601885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         }
602885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      }
603885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (psum > total)
604885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         hi = mid - 1;
605885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      else
606885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         lo = mid + 1;
607885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      /*printf ("lo = %d, hi = %d\n", lo, hi);*/
608885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
609885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   while (lo <= hi);
610885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   hi = lo--;
611885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   /*printf ("interp between %d and %d\n", lo, hi);*/
612885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   for (j=start;j<end;j++)
613885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   {
614885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int bits1j, bits2j;
615885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      int N = m->eBands[j+1]-m->eBands[j];
616885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      bits1j = C*N*m->allocVectors[lo*len+j]<<LM>>2;
617885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      bits2j = hi>=m->nbAllocVectors ?
618885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org            cap[j] : C*N*m->allocVectors[hi*len+j]<<LM>>2;
619885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (bits1j > 0)
620885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         bits1j = IMAX(0, bits1j + trim_offset[j]);
621885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (bits2j > 0)
622885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         bits2j = IMAX(0, bits2j + trim_offset[j]);
623885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (lo > 0)
624885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         bits1j += offsets[j];
625885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      bits2j += offsets[j];
626885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      if (offsets[j]>0)
627885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         skip_start = j;
628885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      bits2j = IMAX(0,bits2j-bits1j);
629885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      bits1[j] = bits1j;
630885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org      bits2[j] = bits2j;
631885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   }
632885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   codedBands = interp_bits2pulses(m, start, end, skip_start, bits1, bits2, thresh, cap,
633885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org         total, balance, skip_rsv, intensity, intensity_rsv, dual_stereo, dual_stereo_rsv,
634e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org         pulses, ebits, fine_priority, C, LM, ec, encode, prev, signalBandwidth);
635885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   RESTORE_STACK;
636885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org   return codedBands;
637885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org}
638885f2ff5a7a7d6a73432d26a6c0ae9147e6b452sergeyu@chromium.org
639