blob: 5d85f557ad6ca203ce8c8f28b3d410e885d64b7c [file] [log] [blame]
Jean-Marc Valin8b2ff0d2009-10-17 21:40:10 -04001/* Copyright (c) 2007-2008 CSIRO
2 Copyright (c) 2007-2009 Xiph.Org Foundation
3 Written by Jean-Marc Valin */
Jean-Marc Valin33ddd792008-01-14 17:39:01 +11004/*
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
15
16 - Neither the name of the Xiph.org Foundation nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
24 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*/
32
Jean-Marc Valin02fa9132008-02-20 12:09:29 +110033#ifdef HAVE_CONFIG_H
34#include "config.h"
35#endif
36
Jean-Marc Valin33ddd792008-01-14 17:39:01 +110037#include <math.h>
38#include "modes.h"
39#include "cwrs.h"
40#include "arch.h"
Jean-Marc Valina6631742008-01-16 17:16:04 +110041#include "os_support.h"
Jean-Marc Valin33ddd792008-01-14 17:39:01 +110042
43#include "entcode.h"
Jean-Marc Valinf51ca492008-01-17 10:58:38 +110044#include "rate.h"
Jean-Marc Valin33ddd792008-01-14 17:39:01 +110045
Jean-Marc Valina6631742008-01-16 17:16:04 +110046
Timothy B. Terriberry76469c62011-01-07 09:18:34 -080047static const unsigned char LOG2_FRAC_TABLE[24]={
48 0,
49 8,13,
50 16,19,21,23,
51 24,26,27,28,29,30,31,32,
52 32,33,34,34,35,36,36,37,37
53};
54
Jean-Marc Valinb76ee702008-03-10 15:42:35 +110055#ifndef STATIC_MODES
Jean-Marc Valin33ddd792008-01-14 17:39:01 +110056
Jean-Marc Valin3ad8db42010-08-25 13:11:09 -040057/*Determines if V(N,K) fits in a 32-bit unsigned integer.
58 N and K are themselves limited to 15 bits.*/
59static int fits_in32(int _n, int _k)
Jean-Marc Valina6631742008-01-16 17:16:04 +110060{
Jean-Marc Valin3ad8db42010-08-25 13:11:09 -040061 static const celt_int16 maxN[15] = {
62 32767, 32767, 32767, 1476, 283, 109, 60, 40,
63 29, 24, 20, 18, 16, 14, 13};
64 static const celt_int16 maxK[15] = {
65 32767, 32767, 32767, 32767, 1172, 238, 95, 53,
66 36, 27, 22, 18, 16, 15, 13};
67 if (_n>=14)
Jean-Marc Valina6631742008-01-16 17:16:04 +110068 {
Jean-Marc Valin3ad8db42010-08-25 13:11:09 -040069 if (_k>=14)
70 return 0;
Jean-Marc Valincae30df2010-05-21 00:26:03 -040071 else
Jean-Marc Valin3ad8db42010-08-25 13:11:09 -040072 return _n <= maxN[_k];
73 } else {
74 return _k <= maxK[_n];
Jean-Marc Valina6631742008-01-16 17:16:04 +110075 }
Jean-Marc Valin3ad8db42010-08-25 13:11:09 -040076}
77
78void compute_pulse_cache(CELTMode *m, int LM)
79{
80 int i;
81 int curr=0;
82 int nbEntries=0;
83 int entryN[100], entryK[100], entryI[100];
84 const celt_int16 *eBands = m->eBands;
85 PulseCache *cache = &m->cache;
Jean-Marc Valin732ea382010-08-25 13:52:27 -040086 celt_int16 *cindex;
87 unsigned char *bits;
Jean-Marc Valin3ad8db42010-08-25 13:11:09 -040088
Jean-Marc Valin732ea382010-08-25 13:52:27 -040089 cindex = celt_alloc(sizeof(cache->index[0])*m->nbEBands*(LM+2));
90 cache->index = cindex;
Jean-Marc Valin3ad8db42010-08-25 13:11:09 -040091
Jean-Marc Valin7fff5722010-10-18 16:20:00 -040092 /* Scan for all unique band sizes */
Jean-Marc Valin3ad8db42010-08-25 13:11:09 -040093 for (i=0;i<=LM+1;i++)
Gregory Maxwelldc67fa92009-06-04 17:17:35 -040094 {
Jean-Marc Valin3ad8db42010-08-25 13:11:09 -040095 int j;
Jean-Marc Valin732ea382010-08-25 13:52:27 -040096 for (j=0;j<m->nbEBands;j++)
Gregory Maxwelldc67fa92009-06-04 17:17:35 -040097 {
Jean-Marc Valin3ad8db42010-08-25 13:11:09 -040098 int k;
99 int N = (eBands[j+1]-eBands[j])<<i>>1;
Jean-Marc Valin732ea382010-08-25 13:52:27 -0400100 cindex[i*m->nbEBands+j] = -1;
Jean-Marc Valin7fff5722010-10-18 16:20:00 -0400101 /* Find other bands that have the same size */
Jean-Marc Valin3ad8db42010-08-25 13:11:09 -0400102 for (k=0;k<=i;k++)
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400103 {
Jean-Marc Valin3ad8db42010-08-25 13:11:09 -0400104 int n;
Jean-Marc Valin732ea382010-08-25 13:52:27 -0400105 for (n=0;n<m->nbEBands && (k!=i || n<j);n++)
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400106 {
Jean-Marc Valin3ad8db42010-08-25 13:11:09 -0400107 if (N == (eBands[n+1]-eBands[n])<<k>>1)
108 {
Jean-Marc Valin732ea382010-08-25 13:52:27 -0400109 cindex[i*m->nbEBands+j] = cindex[k*m->nbEBands+n];
Jean-Marc Valin3ad8db42010-08-25 13:11:09 -0400110 break;
111 }
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400112 }
113 }
Jean-Marc Valin732ea382010-08-25 13:52:27 -0400114 if (cache->index[i*m->nbEBands+j] == -1 && N!=0)
Jean-Marc Valin3ad8db42010-08-25 13:11:09 -0400115 {
116 int K;
117 entryN[nbEntries] = N;
118 K = 0;
Jean-Marc Valin7fff5722010-10-18 16:20:00 -0400119 while (fits_in32(N,get_pulses(K+1)) && K<MAX_PSEUDO)
Jean-Marc Valin3ad8db42010-08-25 13:11:09 -0400120 K++;
121 entryK[nbEntries] = K;
Jean-Marc Valin732ea382010-08-25 13:52:27 -0400122 cindex[i*m->nbEBands+j] = curr;
Jean-Marc Valin3ad8db42010-08-25 13:11:09 -0400123 entryI[nbEntries] = curr;
124
125 curr += K+1;
126 nbEntries++;
127 }
128 }
Gregory Maxwelldc67fa92009-06-04 17:17:35 -0400129 }
Jean-Marc Valin732ea382010-08-25 13:52:27 -0400130 bits = celt_alloc(sizeof(unsigned char)*curr);
131 cache->bits = bits;
132 cache->size = curr;
Jean-Marc Valin7fff5722010-10-18 16:20:00 -0400133 /* Compute the cache for all unique sizes */
Jean-Marc Valin3ad8db42010-08-25 13:11:09 -0400134 for (i=0;i<nbEntries;i++)
135 {
136 int j;
Jean-Marc Valin732ea382010-08-25 13:52:27 -0400137 unsigned char *ptr = bits+entryI[i];
Jean-Marc Valin7fff5722010-10-18 16:20:00 -0400138 celt_int16 tmp[MAX_PULSES+1];
Jean-Marc Valin3ad8db42010-08-25 13:11:09 -0400139 get_required_bits(tmp, entryN[i], get_pulses(entryK[i]), BITRES);
140 for (j=1;j<=entryK[i];j++)
141 ptr[j] = tmp[get_pulses(j)]-1;
142 ptr[0] = entryK[i];
143 }
Jean-Marc Valina6631742008-01-16 17:16:04 +1100144}
145
Jean-Marc Valinb76ee702008-03-10 15:42:35 +1100146#endif /* !STATIC_MODES */
Jean-Marc Valin33ddd792008-01-14 17:39:01 +1100147
Jean-Marc Valin7b0cb4b2008-09-11 00:20:08 -0400148
Jean-Marc Valinae319fe2010-09-13 09:46:54 -0400149#define ALLOC_STEPS 6
Jean-Marc Valin33ddd792008-01-14 17:39:01 +1100150
Gregory Maxwell8e447672010-12-16 14:22:51 -0500151static inline int interp_bits2pulses(const CELTMode *m, int start, int end, int skip_start,
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800152 const int *bits1, const int *bits2, const int *thresh, int total, int skip_rsv,
153 int *intensity, int intensity_rsv, int *dual_stereo, int dual_stereo_rsv, int *bits,
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -0500154 int *ebits, int *fine_priority, int _C, int LM, void *ec, int encode, int prev)
Jean-Marc Valinc6b43902008-01-16 22:04:17 +1100155{
Jean-Marc Valin9a6c4962009-02-09 00:45:48 -0500156 int psum;
Jean-Marc Valinebf72da2008-09-09 23:21:36 -0400157 int lo, hi;
Jean-Marc Valina6a53ab2010-08-31 16:46:40 -0400158 int i, j;
Jean-Marc Valinaead79b2010-05-11 07:34:24 -0400159 int logM;
Jean-Marc Valinbf2398b2009-10-15 07:28:19 -0400160 const int C = CHANNELS(_C);
Gregory Maxwell9b98aaa2010-12-19 02:50:12 -0500161 int stereo;
Jean-Marc Valinb801da52010-09-28 14:56:20 -0400162 int codedBands=-1;
Jean-Marc Valin9651ffd2010-12-14 16:41:03 -0500163 int alloc_floor;
Jean-Marc Valinffe10572010-12-15 00:36:41 -0500164 int left, percoeff;
Jean-Marc Valinffe10572010-12-15 00:36:41 -0500165 int done;
Timothy B. Terriberry66c5ab42010-12-16 08:39:37 -0800166 int balance;
Jean-Marc Valin8600f692008-02-29 15:14:12 +1100167 SAVE_STACK;
Jean-Marc Valinaead79b2010-05-11 07:34:24 -0400168
Jean-Marc Valin9651ffd2010-12-14 16:41:03 -0500169 alloc_floor = C<<BITRES;
Gregory Maxwell9b98aaa2010-12-19 02:50:12 -0500170 stereo = C>1;
Jean-Marc Valin9651ffd2010-12-14 16:41:03 -0500171
Jean-Marc Valin5c0c9362010-08-31 10:11:11 -0400172 logM = LM<<BITRES;
Jean-Marc Valinc6b43902008-01-16 22:04:17 +1100173 lo = 0;
Jean-Marc Valina6a53ab2010-08-31 16:46:40 -0400174 hi = 1<<ALLOC_STEPS;
175 for (i=0;i<ALLOC_STEPS;i++)
Jean-Marc Valinc6b43902008-01-16 22:04:17 +1100176 {
177 int mid = (lo+hi)>>1;
Jean-Marc Valinb801da52010-09-28 14:56:20 -0400178 psum = 0;
Jean-Marc Valinffe10572010-12-15 00:36:41 -0500179 done = 0;
Timothy B. Terriberry405e6a92010-12-15 20:46:09 -0800180 for (j=end;j-->start;)
Jean-Marc Valinb801da52010-09-28 14:56:20 -0400181 {
182 int tmp = bits1[j] + (mid*bits2[j]>>ALLOC_STEPS);
Timothy B. Terriberry405e6a92010-12-15 20:46:09 -0800183 if (tmp >= thresh[j] || done)
Jean-Marc Valinffe10572010-12-15 00:36:41 -0500184 {
Jean-Marc Valinffe10572010-12-15 00:36:41 -0500185 done = 1;
Timothy B. Terriberry405e6a92010-12-15 20:46:09 -0800186 /* Don't allocate more than we can actually use */
187 psum += IMIN(tmp, 64*C<<BITRES<<LM);
188 } else {
Jean-Marc Valinffe10572010-12-15 00:36:41 -0500189 if (tmp >= alloc_floor)
190 psum += alloc_floor;
191 }
Jean-Marc Valinb801da52010-09-28 14:56:20 -0400192 }
Timothy B. Terriberry4777f062010-12-15 06:56:00 -0800193 if (psum > total)
Jean-Marc Valinc6b43902008-01-16 22:04:17 +1100194 hi = mid;
195 else
196 lo = mid;
197 }
Jean-Marc Valin825ead82008-09-09 00:15:40 -0400198 psum = 0;
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100199 /*printf ("interp bisection gave %d\n", lo);*/
Jean-Marc Valinffe10572010-12-15 00:36:41 -0500200 done = 0;
Timothy B. Terriberry405e6a92010-12-15 20:46:09 -0800201 for (j=end;j-->start;)
Jean-Marc Valin6775de32008-08-02 08:14:42 -0400202 {
Jean-Marc Valinb801da52010-09-28 14:56:20 -0400203 int tmp = bits1[j] + (lo*bits2[j]>>ALLOC_STEPS);
Timothy B. Terriberry405e6a92010-12-15 20:46:09 -0800204 if (tmp < thresh[j] && !done)
Jean-Marc Valinb801da52010-09-28 14:56:20 -0400205 {
Jean-Marc Valinffe10572010-12-15 00:36:41 -0500206 if (tmp >= alloc_floor)
207 tmp = alloc_floor;
Jean-Marc Valin9651ffd2010-12-14 16:41:03 -0500208 else
209 tmp = 0;
Timothy B. Terriberry405e6a92010-12-15 20:46:09 -0800210 } else
211 done = 1;
Jean-Marc Valin52dc66b2010-12-06 21:31:15 -0500212 /* Don't allocate more than we can actually use */
Jean-Marc Valin9651ffd2010-12-14 16:41:03 -0500213 tmp = IMIN(tmp, 64*C<<BITRES<<LM);
214 bits[j] = tmp;
215 psum += tmp;
Jean-Marc Valin825ead82008-09-09 00:15:40 -0400216 }
Jean-Marc Valin9651ffd2010-12-14 16:41:03 -0500217
Timothy B. Terriberry7627b9f2010-12-15 08:22:14 -0800218 /* Decide which bands to skip, working backwards from the end. */
219 for (codedBands=end;;codedBands--)
Jean-Marc Valindfd6e712010-12-09 23:23:34 -0500220 {
Jean-Marc Valinffe10572010-12-15 00:36:41 -0500221 int band_width;
222 int band_bits;
223 int rem;
Timothy B. Terriberry7627b9f2010-12-15 08:22:14 -0800224 j = codedBands-1;
Timothy B. Terriberry76ea41e2010-12-16 14:39:58 -0800225 /* Never skip the first band, nor a band that has been boosted by
226 dynalloc.
227 In the first case, we'd be coding a bit to signal we're going to waste
228 all the other bits.
229 In the second case, we'd be coding a bit to redistribute all the bits
230 we just signaled should be cocentrated in this band. */
Gregory Maxwell8e447672010-12-16 14:22:51 -0500231 if (j<=skip_start)
Timothy B. Terriberry76ea41e2010-12-16 14:39:58 -0800232 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800233 /* Give the bit we reserved to end skipping back. */
234 total += skip_rsv;
Timothy B. Terriberry7627b9f2010-12-15 08:22:14 -0800235 break;
Timothy B. Terriberry76ea41e2010-12-16 14:39:58 -0800236 }
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800237 /*Figure out how many left-over bits we would be adding to this band.
238 This can include bits we've stolen back from higher, skipped bands.*/
239 left = total-psum;
240 percoeff = left/(m->eBands[codedBands]-m->eBands[start]);
241 left -= (m->eBands[codedBands]-m->eBands[start])*percoeff;
Timothy B. Terriberry4777f062010-12-15 06:56:00 -0800242 rem = IMAX(left-(m->eBands[j]-m->eBands[start]),0);
Jean-Marc Valinffe10572010-12-15 00:36:41 -0500243 band_width = m->eBands[codedBands]-m->eBands[j];
244 band_bits = bits[j] + percoeff*band_width + rem;
Timothy B. Terriberry283a9b62010-12-15 05:35:54 -0800245 /*Only code a skip decision if we're above the threshold for this band.
246 Otherwise it is force-skipped.
Timothy B. Terriberry405e6a92010-12-15 20:46:09 -0800247 This ensures that we have enough bits to code the skip flag.*/
248 if (band_bits >= IMAX(thresh[j], alloc_floor+(1<<BITRES)))
Jean-Marc Valindfd6e712010-12-09 23:23:34 -0500249 {
Timothy B. Terriberryb2f59002010-12-15 05:12:43 -0800250 if (encode)
Jean-Marc Valinffe10572010-12-15 00:36:41 -0500251 {
Timothy B. Terriberry7cbf1682010-12-14 21:55:49 -0800252 /*This if() block is the only part of the allocation function that
253 is not a mandatory part of the bitstream: any bands we choose to
254 skip here must be explicitly signaled.*/
Jean-Marc Valinffe10572010-12-15 00:36:41 -0500255 /*Choose a threshold with some hysteresis to keep bands from
256 fluctuating in and out.*/
257 if (band_bits > ((j<prev?7:9)*band_width<<LM<<BITRES)>>4)
Timothy B. Terriberryb2f59002010-12-15 05:12:43 -0800258 {
Timothy B. Terriberrye86fb262010-12-17 14:50:19 -0800259 ec_enc_bit_logp((ec_enc *)ec, 1, 1);
Jean-Marc Valinffe10572010-12-15 00:36:41 -0500260 break;
Timothy B. Terriberryb2f59002010-12-15 05:12:43 -0800261 }
Timothy B. Terriberrye86fb262010-12-17 14:50:19 -0800262 ec_enc_bit_logp((ec_enc *)ec, 0, 1);
263 } else if (ec_dec_bit_logp((ec_dec *)ec, 1)) {
Jean-Marc Valinffe10572010-12-15 00:36:41 -0500264 break;
Timothy B. Terriberryb2f59002010-12-15 05:12:43 -0800265 }
266 /*We used a bit to skip this band.*/
Jean-Marc Valinffe10572010-12-15 00:36:41 -0500267 psum += 1<<BITRES;
268 band_bits -= 1<<BITRES;
Jean-Marc Valindfd6e712010-12-09 23:23:34 -0500269 }
Jean-Marc Valinffe10572010-12-15 00:36:41 -0500270 /*Reclaim the bits originally allocated to this band.*/
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800271 psum -= bits[j]+intensity_rsv;
272 if (intensity_rsv > 0)
273 intensity_rsv = LOG2_FRAC_TABLE[j-start];
274 psum += intensity_rsv;
Timothy B. Terriberry7cbf1682010-12-14 21:55:49 -0800275 if (band_bits >= alloc_floor)
Jean-Marc Valindcacb732010-12-14 13:39:30 -0500276 {
Jean-Marc Valinffe10572010-12-15 00:36:41 -0500277 /*If we have enough for a fine energy bit per channel, use it.*/
Jean-Marc Valin9651ffd2010-12-14 16:41:03 -0500278 psum += alloc_floor;
Timothy B. Terriberry7cbf1682010-12-14 21:55:49 -0800279 bits[j] = alloc_floor;
Jean-Marc Valin9651ffd2010-12-14 16:41:03 -0500280 } else {
Jean-Marc Valinffe10572010-12-15 00:36:41 -0500281 /*Otherwise this band gets nothing at all.*/
Timothy B. Terriberry7cbf1682010-12-14 21:55:49 -0800282 bits[j] = 0;
Jean-Marc Valindcacb732010-12-14 13:39:30 -0500283 }
Jean-Marc Valindfd6e712010-12-09 23:23:34 -0500284 }
Jean-Marc Valinffe10572010-12-15 00:36:41 -0500285
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800286 celt_assert(codedBands > start);
287 /* Code the intensity and dual stereo parameters. */
288 if (intensity_rsv > 0)
289 {
290 if (encode)
Jean-Marc Valinfb031112010-11-25 16:32:54 -0500291 {
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800292 *intensity = IMIN(*intensity, codedBands);
293 ec_enc_uint((ec_enc *)ec, *intensity-start, codedBands+1-start);
Jean-Marc Valinfb031112010-11-25 16:32:54 -0500294 }
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800295 else
296 *intensity = start+ec_dec_uint((ec_dec *)ec, codedBands+1-start);
297 }
298 else
299 *intensity = 0;
300 if (*intensity <= start)
301 {
302 total += dual_stereo_rsv;
303 dual_stereo_rsv = 0;
304 }
305 if (dual_stereo_rsv > 0)
306 {
307 if (encode)
308 ec_enc_bit_logp((ec_enc *)ec, *dual_stereo, 1);
309 else
310 *dual_stereo = ec_dec_bit_logp((ec_dec *)ec, 1);
311 }
312 else
313 *dual_stereo = 0;
314
315 /* Allocate the remaining bits */
316 left = total-psum;
317 percoeff = left/(m->eBands[codedBands]-m->eBands[start]);
318 left -= (m->eBands[codedBands]-m->eBands[start])*percoeff;
319 for (j=start;j<codedBands;j++)
320 bits[j] += percoeff*(m->eBands[j+1]-m->eBands[j]);
321 for (j=start;j<codedBands;j++)
322 {
323 int tmp = IMIN(left, m->eBands[j+1]-m->eBands[j]);
324 bits[j] += tmp;
325 left -= tmp;
Jean-Marc Valinebf72da2008-09-09 23:21:36 -0400326 }
Jean-Marc Valin54d84c02010-11-19 11:45:37 -0500327 /*for (j=0;j<end;j++)printf("%d ", bits[j]);printf("\n");*/
Timothy B. Terriberry66c5ab42010-12-16 08:39:37 -0800328
329 balance = 0;
Timothy B. Terriberry7627b9f2010-12-15 08:22:14 -0800330 for (j=start;j<codedBands;j++)
Jean-Marc Valin9a6c4962009-02-09 00:45:48 -0500331 {
Jean-Marc Valin3f9857b2010-08-13 21:20:37 -0400332 int N0, N, den;
Jean-Marc Valin9a6c4962009-02-09 00:45:48 -0500333 int offset;
Jean-Marc Valin5c0c9362010-08-31 10:11:11 -0400334 int NClogN;
335
Jean-Marc Valin9651ffd2010-12-14 16:41:03 -0500336 celt_assert(bits[j] >= 0);
Jean-Marc Valin36034282010-08-06 14:42:43 -0400337 N0 = m->eBands[j+1]-m->eBands[j];
Jean-Marc Valin5c0c9362010-08-31 10:11:11 -0400338 N=N0<<LM;
Jean-Marc Valin5c0c9362010-08-31 10:11:11 -0400339
Timothy B. Terriberry66c5ab42010-12-16 08:39:37 -0800340 if (N>1)
Jean-Marc Valindcacb732010-12-14 13:39:30 -0500341 {
Timothy B. Terriberry66c5ab42010-12-16 08:39:37 -0800342 NClogN = N*C*(m->logN[j] + logM);
Jean-Marc Valin9a6c4962009-02-09 00:45:48 -0500343
Timothy B. Terriberry66c5ab42010-12-16 08:39:37 -0800344 /* Compensate for the extra DoF in stereo */
345 den=(C*N+ ((C==2 && N>2) ? 1 : 0));
346
347 /* Offset for the number of fine bits by log2(N)/2 + FINE_OFFSET
348 compared to their "fair share" of total/N */
349 offset = (NClogN>>1)-N*C*FINE_OFFSET;
350
351 /* N=2 is the only point that doesn't match the curve */
352 if (N==2)
353 offset += N*C<<BITRES>>2;
354
355 /* Changing the offset for allocating the second and third
356 fine energy bit */
357 if (bits[j] + offset < den*2<<BITRES)
358 offset += NClogN>>2;
359 else if (bits[j] + offset < den*3<<BITRES)
360 offset += NClogN>>3;
361
362 /* Divide with rounding */
363 ebits[j] = IMAX(0, (bits[j] + offset + (den<<(BITRES-1))) / (den<<BITRES));
364
Timothy B. Terriberry66c5ab42010-12-16 08:39:37 -0800365 /* Make sure not to bust */
366 if (C*ebits[j] > (bits[j]>>BITRES))
Gregory Maxwell9b98aaa2010-12-19 02:50:12 -0500367 ebits[j] = bits[j] >> stereo >> BITRES;
Timothy B. Terriberry66c5ab42010-12-16 08:39:37 -0800368
Jean-Marc Valina66b7572011-01-10 13:21:04 -0500369 /* More than that is useless because that's about as far as PVQ can go */
370 ebits[j] = IMIN(ebits[j], MAX_FINE_BITS);
Timothy B. Terriberry66c5ab42010-12-16 08:39:37 -0800371
Timothy B. Terriberry949f1802010-12-30 08:38:48 -0800372 /* If we rounded down or capped this band, make it a candidate for the
373 final fine energy pass */
374 fine_priority[j] = ebits[j]*(den<<BITRES) >= bits[j]+offset;
375
Timothy B. Terriberry66c5ab42010-12-16 08:39:37 -0800376 } else {
377 /* For N=1, all bits go to fine energy except for a single sign bit */
Jean-Marc Valina66b7572011-01-10 13:21:04 -0500378 ebits[j] = IMIN(IMAX(0,(bits[j] >> stereo >> BITRES)-1),MAX_FINE_BITS);
Timothy B. Terriberry66c5ab42010-12-16 08:39:37 -0800379 fine_priority[j] = (ebits[j]+1)*C<<BITRES >= (bits[j]-balance);
380 /* N=1 bands can't take advantage of the re-balancing in
381 quant_all_bands() because they don't have shape, only fine energy.
382 Instead, do the re-balancing here.*/
383 balance = IMAX(0,bits[j] - ((ebits[j]+1)*C<<BITRES));
384 if (j+1<codedBands)
385 {
386 bits[j] -= balance;
387 bits[j+1] += balance;
388 }
389 }
Jean-Marc Valin3f9857b2010-08-13 21:20:37 -0400390
Jean-Marc Valin5c0c9362010-08-31 10:11:11 -0400391 /* The other bits are assigned to PVQ */
Jean-Marc Valin9a6c4962009-02-09 00:45:48 -0500392 bits[j] -= C*ebits[j]<<BITRES;
Jean-Marc Valin6cbfbc32010-12-14 11:53:39 -0500393 celt_assert(bits[j] >= 0);
Jean-Marc Valin9651ffd2010-12-14 16:41:03 -0500394 celt_assert(ebits[j] >= 0);
Jean-Marc Valin9a6c4962009-02-09 00:45:48 -0500395 }
Timothy B. Terriberry7627b9f2010-12-15 08:22:14 -0800396 /* The skipped bands use all their bits for fine energy. */
397 for (;j<end;j++)
398 {
Gregory Maxwell9b98aaa2010-12-19 02:50:12 -0500399 ebits[j] = bits[j] >> stereo >> BITRES;
Timothy B. Terriberry7627b9f2010-12-15 08:22:14 -0800400 celt_assert(C*ebits[j]<<BITRES == bits[j]);
401 bits[j] = 0;
Jean-Marc Valindf6620e2010-12-16 13:07:29 -0500402 fine_priority[j] = ebits[j]<1;
Timothy B. Terriberry7627b9f2010-12-15 08:22:14 -0800403 }
Jean-Marc Valin8600f692008-02-29 15:14:12 +1100404 RESTORE_STACK;
Jean-Marc Valinb801da52010-09-28 14:56:20 -0400405 return codedBands;
Jean-Marc Valinc6b43902008-01-16 22:04:17 +1100406}
Jean-Marc Valinf51ca492008-01-17 10:58:38 +1100407
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800408int compute_allocation(const CELTMode *m, int start, int end, const int *offsets, int alloc_trim, int *intensity, int *dual_stereo,
Timothy B. Terriberryb2f59002010-12-15 05:12:43 -0800409 int total, int *pulses, int *ebits, int *fine_priority, int _C, int LM, void *ec, int encode, int prev)
Jean-Marc Valinf51ca492008-01-17 10:58:38 +1100410{
Jean-Marc Valin54aab422008-12-06 07:52:48 -0500411 int lo, hi, len, j;
Jean-Marc Valinbf2398b2009-10-15 07:28:19 -0400412 const int C = CHANNELS(_C);
Jean-Marc Valinb801da52010-09-28 14:56:20 -0400413 int codedBands;
Gregory Maxwell8e447672010-12-16 14:22:51 -0500414 int skip_start;
Timothy B. Terriberry76ea41e2010-12-16 14:39:58 -0800415 int skip_rsv;
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800416 int intensity_rsv;
417 int dual_stereo_rsv;
Jean-Marc Valin31b79d12008-03-12 17:17:23 +1100418 VARDECL(int, bits1);
419 VARDECL(int, bits2);
Jean-Marc Valinc40addc2010-10-22 14:57:07 -0400420 VARDECL(int, thresh);
421 VARDECL(int, trim_offset);
Jean-Marc Valin8600f692008-02-29 15:14:12 +1100422 SAVE_STACK;
Jean-Marc Valin0bb05bc2008-02-20 13:43:40 +1100423
Jean-Marc Valin9651ffd2010-12-14 16:41:03 -0500424 total = IMAX(total, 0);
Jean-Marc Valinf51ca492008-01-17 10:58:38 +1100425 len = m->nbEBands;
Gregory Maxwell8e447672010-12-16 14:22:51 -0500426 skip_start = start;
Timothy B. Terriberry76ea41e2010-12-16 14:39:58 -0800427 /* Reserve a bit to signal the end of manually skipped bands. */
428 skip_rsv = total >= 1<<BITRES ? 1<<BITRES : 0;
429 total -= skip_rsv;
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800430 /* Reserve bits for the intensity and dual stereo parameters. */
431 intensity_rsv = dual_stereo_rsv = 0;
432 if (C==2)
433 {
434 intensity_rsv = LOG2_FRAC_TABLE[end-start];
435 if (intensity_rsv>total)
436 intensity_rsv = 0;
437 else
438 {
439 total -= intensity_rsv;
440 dual_stereo_rsv = total>=1<<BITRES ? 1<<BITRES : 0;
441 total -= dual_stereo_rsv;
442 }
443 }
Jean-Marc Valin9a0bba12008-02-20 14:08:50 +1100444 ALLOC(bits1, len, int);
445 ALLOC(bits2, len, int);
Jean-Marc Valinc40addc2010-10-22 14:57:07 -0400446 ALLOC(thresh, len, int);
447 ALLOC(trim_offset, len, int);
448
449 for (j=start;j<end;j++)
Jean-Marc Valin3fed34a2010-12-17 14:17:27 -0500450 {
451 /* Below this threshold, we're sure not to allocate any PVQ bits */
Jean-Marc Valin9651ffd2010-12-14 16:41:03 -0500452 thresh[j] = IMAX((C)<<BITRES, (3*(m->eBands[j+1]-m->eBands[j])<<LM<<BITRES)>>4);
Jean-Marc Valin3fed34a2010-12-17 14:17:27 -0500453 /* Tilt of the allocation curve */
Jean-Marc Valinbad42a72010-12-01 14:54:10 -0500454 trim_offset[j] = C*(m->eBands[j+1]-m->eBands[j])*(alloc_trim-5-LM)*(m->nbEBands-j-1)
Jean-Marc Valin35095c62010-11-04 13:24:44 -0400455 <<(LM+BITRES)>>6;
Jean-Marc Valin3fed34a2010-12-17 14:17:27 -0500456 /* Giving less resolution to single-coefficient bands because they get
457 more benefit from having one coarse value per coefficient*/
458 if ((m->eBands[j+1]-m->eBands[j])<<LM==1)
459 trim_offset[j] -= C<<BITRES;
460 }
Timothy B. Terriberry428a77d2010-12-16 16:50:16 -0800461 lo = 1;
462 hi = m->nbAllocVectors - 2;
463 do
Jean-Marc Valinf51ca492008-01-17 10:58:38 +1100464 {
Gregory Maxwell7c673cf2010-12-19 02:26:56 -0500465 int done = 0;
Jean-Marc Valin825ead82008-09-09 00:15:40 -0400466 int psum = 0;
Jean-Marc Valinf51ca492008-01-17 10:58:38 +1100467 int mid = (lo+hi) >> 1;
Gregory Maxwell7c673cf2010-12-19 02:26:56 -0500468 for (j=end;j-->start;)
Jean-Marc Valinf51ca492008-01-17 10:58:38 +1100469 {
Jean-Marc Valinbb8fa1f2010-06-03 00:33:42 -0400470 int N = m->eBands[j+1]-m->eBands[j];
Jean-Marc Valinc40addc2010-10-22 14:57:07 -0400471 bits1[j] = C*N*m->allocVectors[mid*len+j]<<LM>>2;
472 if (bits1[j] > 0)
Timothy B. Terriberry428a77d2010-12-16 16:50:16 -0800473 bits1[j] = IMAX(0, bits1[j] + trim_offset[j]);
Jean-Marc Valinc40addc2010-10-22 14:57:07 -0400474 bits1[j] += offsets[j];
Gregory Maxwell7c673cf2010-12-19 02:26:56 -0500475 if (bits1[j] >= thresh[j] || done)
476 {
477 done = 1;
478 /* Don't allocate more than we can actually use */
Timothy B. Terriberry428a77d2010-12-16 16:50:16 -0800479 psum += IMIN(bits1[j], 64*C<<BITRES<<LM);
Gregory Maxwell7c673cf2010-12-19 02:26:56 -0500480 } else {
481 if (bits1[j] >= C<<BITRES)
482 psum += C<<BITRES;
483 }
Jean-Marc Valinf51ca492008-01-17 10:58:38 +1100484 }
Timothy B. Terriberry4777f062010-12-15 06:56:00 -0800485 if (psum > total)
Timothy B. Terriberry428a77d2010-12-16 16:50:16 -0800486 hi = mid - 1;
Jean-Marc Valinf51ca492008-01-17 10:58:38 +1100487 else
Timothy B. Terriberry428a77d2010-12-16 16:50:16 -0800488 lo = mid + 1;
Jean-Marc Valina85657b2008-02-20 11:59:30 +1100489 /*printf ("lo = %d, hi = %d\n", lo, hi);*/
Jean-Marc Valinf51ca492008-01-17 10:58:38 +1100490 }
Timothy B. Terriberry428a77d2010-12-16 16:50:16 -0800491 while (lo <= hi);
492 hi = lo--;
Jean-Marc Valin6775de32008-08-02 08:14:42 -0400493 /*printf ("interp between %d and %d\n", lo, hi);*/
Jean-Marc Valin525d7cf2010-07-13 14:14:16 -0400494 for (j=start;j<end;j++)
Jean-Marc Valinf51ca492008-01-17 10:58:38 +1100495 {
Jean-Marc Valinbb8fa1f2010-06-03 00:33:42 -0400496 int N = m->eBands[j+1]-m->eBands[j];
Timothy B. Terriberry428a77d2010-12-16 16:50:16 -0800497 bits1[j] = C*N*m->allocVectors[lo*len+j]<<LM>>2;
498 bits2[j] = C*N*m->allocVectors[hi*len+j]<<LM>>2;
Jean-Marc Valinc40addc2010-10-22 14:57:07 -0400499 if (bits1[j] > 0)
Timothy B. Terriberry428a77d2010-12-16 16:50:16 -0800500 bits1[j] = IMAX(0, bits1[j] + trim_offset[j]);
501 if (bits2[j] > 0)
502 bits2[j] = IMAX(0, bits2[j] + trim_offset[j]);
503 if (lo > 0)
504 bits1[j] += offsets[j];
505 bits2[j] += offsets[j];
Gregory Maxwell8e447672010-12-16 14:22:51 -0500506 if (offsets[j]>0)
507 skip_start = j;
Timothy B. Terriberry428a77d2010-12-16 16:50:16 -0800508 bits2[j] -= bits1[j];
Jean-Marc Valinf51ca492008-01-17 10:58:38 +1100509 }
Gregory Maxwell8e447672010-12-16 14:22:51 -0500510 codedBands = interp_bits2pulses(m, start, end, skip_start, bits1, bits2, thresh,
Timothy B. Terriberry76469c62011-01-07 09:18:34 -0800511 total, skip_rsv, intensity, intensity_rsv, dual_stereo, dual_stereo_rsv,
Jean-Marc Valinc39bb8a2011-01-26 10:50:55 -0500512 pulses, ebits, fine_priority, C, LM, ec, encode, prev);
Jean-Marc Valin825ead82008-09-09 00:15:40 -0400513 RESTORE_STACK;
Jean-Marc Valinb801da52010-09-28 14:56:20 -0400514 return codedBands;
Jean-Marc Valinf51ca492008-01-17 10:58:38 +1100515}
Jean-Marc Valinb86ed072008-01-15 16:33:21 +1100516