]> git.sesse.net Git - vlc/blob - src/ac3_decoder/ac3_bit_allocate.c
bd59e691f630c6ea4b6f5cc7f51c36e6b4b3bd3b
[vlc] / src / ac3_decoder / ac3_bit_allocate.c
1 /*****************************************************************************
2  * ac3_bit_allocate.c: ac3 allocation tables
3  *****************************************************************************
4  * Copyright (C) 2000 VideoLAN
5  * $Id: ac3_bit_allocate.c,v 1.21 2001/05/14 15:58:03 reno Exp $
6  *
7  * Authors: Michel Kaempf <maxx@via.ecp.fr>
8  *          Aaron Holtzman <aholtzma@engr.uvic.ca>
9  *          Renaud Dartus <reno@videolan.org>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  * 
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
24  *****************************************************************************/
25 #include "defs.h"
26
27 #include <string.h>                                              /* memcpy() */
28
29 #include "config.h"
30 #include "common.h"
31 #include "threads.h"
32 #include "mtime.h"
33
34 #include "intf_msg.h"                        /* intf_DbgMsg(), intf_ErrMsg() */
35
36 #include "stream_control.h"
37 #include "input_ext-dec.h"
38
39 #include "ac3_decoder.h"
40 #include "ac3_internal.h"                                 /* DELTA_BIT_REUSE */
41
42
43 static void ba_compute_psd (bit_allocate_t * p_bit, s16 start, s16 end, s16 exps[]);
44
45 static void ba_compute_excitation (bit_allocate_t * p_bit, s16 start, s16 end, s16 fgain,
46                                    s16 fastleak, s16 slowleak, s16 is_lfe);
47 static void ba_compute_mask (bit_allocate_t * p_bit, s16 start, s16 end, u16 fscod,
48                              u16 deltbae, u16 deltnseg, u16 deltoffst[],
49                              u16 deltba[], u16 deltlen[]);
50 static void ba_compute_bap (bit_allocate_t * p_bit, s16 start, s16 end,
51                             s16 snroffset, s16 bap[]);
52
53 /* Misc LUTs for bit allocation process */
54
55 static const s16 slowdec[]  = { 0x0f,  0x11,  0x13,  0x15  };
56 static const s16 fastdec[]  = { 0x3f,  0x53,  0x67,  0x7b  };
57 static const s16 slowgain[] = { 0x540, 0x4d8, 0x478, 0x410 };
58 static const s16 dbpbtab[]  = { 0x000, 0x700, 0x900, 0xb00 };
59
60 static const u16 floortab[] = { 0x2f0, 0x2b0, 0x270, 0x230, 0x1f0, 0x170, 0x0f0, 0xf800 };
61 static const s16 fastgain[] = { 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0x400  };
62
63 static const s16 bndtab[] = {  0,  1,  2,   3,   4,   5,   6,   7,   8,   9,
64                         10, 11, 12,  13,  14,  15,  16,  17,  18,  19,
65                         20, 21, 22,  23,  24,  25,  26,  27,  28,  31,
66                         34, 37, 40,  43,  46,  49,  55,  61,  67,  73,
67                         79, 85, 97, 109, 121, 133, 157, 181, 205, 229 };
68
69 static const s16 bndsz[]  = { 1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
70                         1,  1,  1,  1,  1,  1,  1,  1,  1,  1,
71                         1,  1,  1,  1,  1,  1,  1,  1,  3,  3,
72                         3,  3,  3,  3,  3,  6,  6,  6,  6,  6,
73                         6, 12, 12, 12, 12, 24, 24, 24, 24, 24 };
74
75 static const s16 masktab[] = { 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
76                      16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 28, 28, 29,
77                      29, 29, 30, 30, 30, 31, 31, 31, 32, 32, 32, 33, 33, 33, 34, 34,
78                      34, 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, 37, 37, 37,
79                      37, 37, 37, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 40,
80                      40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
81                      41, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 43, 43, 43,
82                      43, 43, 43, 43, 43, 43, 43, 43, 43, 44, 44, 44, 44, 44, 44, 44,
83                      44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
84                      45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 46, 46,
85                      46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, 46,
86                      46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
87                      47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 48, 48, 48,
88                      48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48,
89                      48, 48, 48, 48, 48, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,
90                      49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49, 49,  0,  0,  0 };
91
92
93 static const s16 latab[] = { 0x0040, 0x003f, 0x003e, 0x003d, 0x003c, 0x003b, 0x003a, 0x0039,
94                     0x0038, 0x0037, 0x0036, 0x0035, 0x0034, 0x0034, 0x0033, 0x0032,
95                     0x0031, 0x0030, 0x002f, 0x002f, 0x002e, 0x002d, 0x002c, 0x002c,
96                     0x002b, 0x002a, 0x0029, 0x0029, 0x0028, 0x0027, 0x0026, 0x0026,
97                     0x0025, 0x0024, 0x0024, 0x0023, 0x0023, 0x0022, 0x0021, 0x0021,
98                     0x0020, 0x0020, 0x001f, 0x001e, 0x001e, 0x001d, 0x001d, 0x001c,
99                     0x001c, 0x001b, 0x001b, 0x001a, 0x001a, 0x0019, 0x0019, 0x0018,
100                     0x0018, 0x0017, 0x0017, 0x0016, 0x0016, 0x0015, 0x0015, 0x0015,
101                     0x0014, 0x0014, 0x0013, 0x0013, 0x0013, 0x0012, 0x0012, 0x0012,
102                     0x0011, 0x0011, 0x0011, 0x0010, 0x0010, 0x0010, 0x000f, 0x000f,
103                     0x000f, 0x000e, 0x000e, 0x000e, 0x000d, 0x000d, 0x000d, 0x000d,
104                     0x000c, 0x000c, 0x000c, 0x000c, 0x000b, 0x000b, 0x000b, 0x000b,
105                     0x000a, 0x000a, 0x000a, 0x000a, 0x000a, 0x0009, 0x0009, 0x0009,
106                     0x0009, 0x0009, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008, 0x0008,
107                     0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0007, 0x0006, 0x0006,
108                     0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0006, 0x0005, 0x0005,
109                     0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0005, 0x0004, 0x0004,
110                     0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004,
111                     0x0004, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003,
112                     0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0003, 0x0002,
113                     0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
114                     0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002,
115                     0x0002, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
116                     0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
117                     0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
118                     0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001,
119                     0x0001, 0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
120                     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
121                     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
122                     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
123                     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
124                     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
125                     0x0000, 0x0000, 0x0000, 0x0000};
126
127 static const s16 hth[][50] = {{ 0x04d0, 0x04d0, 0x0440, 0x0400, 0x03e0, 0x03c0, 0x03b0, 0x03b0,
128                       0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x0390, 0x0390, 0x0390,
129                       0x0380, 0x0380, 0x0370, 0x0370, 0x0360, 0x0360, 0x0350, 0x0350,
130                       0x0340, 0x0340, 0x0330, 0x0320, 0x0310, 0x0300, 0x02f0, 0x02f0,
131                       0x02f0, 0x02f0, 0x0300, 0x0310, 0x0340, 0x0390, 0x03e0, 0x0420,
132                       0x0460, 0x0490, 0x04a0, 0x0460, 0x0440, 0x0440, 0x0520, 0x0800,
133                       0x0840, 0x0840 },
134
135                     { 0x04f0, 0x04f0, 0x0460, 0x0410, 0x03e0, 0x03d0, 0x03c0, 0x03b0,
136                       0x03b0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x0390, 0x0390,
137                       0x0390, 0x0380, 0x0380, 0x0380, 0x0370, 0x0370, 0x0360, 0x0360,
138                       0x0350, 0x0350, 0x0340, 0x0340, 0x0320, 0x0310, 0x0300, 0x02f0,
139                       0x02f0, 0x02f0, 0x02f0, 0x0300, 0x0320, 0x0350, 0x0390, 0x03e0,
140                       0x0420, 0x0450, 0x04a0, 0x0490, 0x0460, 0x0440, 0x0480, 0x0630,
141                       0x0840, 0x0840 },
142
143                     { 0x0580, 0x0580, 0x04b0, 0x0450, 0x0420, 0x03f0, 0x03e0, 0x03d0,
144                       0x03c0, 0x03b0, 0x03b0, 0x03b0, 0x03a0, 0x03a0, 0x03a0, 0x03a0,
145                       0x03a0, 0x03a0, 0x03a0, 0x03a0, 0x0390, 0x0390, 0x0390, 0x0390,
146                       0x0380, 0x0380, 0x0380, 0x0370, 0x0360, 0x0350, 0x0340, 0x0330,
147                       0x0320, 0x0310, 0x0300, 0x02f0, 0x02f0, 0x02f0, 0x0300, 0x0310,
148                       0x0330, 0x0350, 0x03c0, 0x0410, 0x0470, 0x04a0, 0x0460, 0x0440,
149                       0x0450, 0x04e0 }};
150
151
152 static const s16 baptab[] = { 0,  1,  1,  1,  1,  1,  2,  2,  3,  3,  3,  4,  4,  5,  5,  6,
153                      6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  8,  9,  9,  9,  9, 10,
154                      10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14,
155                      14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15 };
156
157 static __inline__ u16 max_value (s16 a, s16 b)
158 {
159     return (a > b ? a : b);
160 }
161
162 static __inline__ u16 min_value (s16 a, s16 b)
163 {
164     return (a < b ? a : b);
165 }
166
167 static __inline__ s16 logadd (s16 a, s16 b)
168 {
169     s16 c;
170
171     if ((c = a - b) >= 0) {
172         return (a + latab[min_value(((c) >> 1), 255)]);
173     } else {
174         return (b + latab[min_value(((-c) >> 1), 255)]);
175     }
176 }
177
178 static __inline__ s16 calc_lowcomp (s16 a, s16 b0, s16 b1, s16 bin)
179 {
180     if (bin < 7) {
181         if ((b0 + 256) == b1)
182             a = 384;
183         else if (b0 > b1)
184             a = max_value(0, a - 64);
185     } else if (bin < 20) {
186         if ((b0 + 256) == b1)
187             a = 320;
188         else if (b0 > b1)
189             a = max_value(0, a - 64) ;
190     } else
191         a = max_value(0, a - 128);
192
193     return a;
194 }
195
196 void bit_allocate (ac3dec_t * p_ac3dec)
197 {
198     u16 i;
199     s16 fgain;
200     s16 snroffset;
201     s16 start;
202     s16 end;
203     s16 fastleak;
204     s16 slowleak;
205
206     /* Only perform bit_allocation if the exponents have changed or we
207      * have new sideband information */
208     if (p_ac3dec->audblk.chexpstr[0]  == 0 && p_ac3dec->audblk.chexpstr[1] == 0 &&
209         p_ac3dec->audblk.chexpstr[2]  == 0 && p_ac3dec->audblk.chexpstr[3] == 0 &&
210         p_ac3dec->audblk.chexpstr[4]  == 0 && p_ac3dec->audblk.cplexpstr   == 0 &&
211         p_ac3dec->audblk.lfeexpstr    == 0 && p_ac3dec->audblk.baie        == 0 &&
212         p_ac3dec->audblk.snroffste    == 0 && p_ac3dec->audblk.deltbaie    == 0)
213         return;
214
215     /* Do some setup before we do the bit alloc */
216     p_ac3dec->bit_allocate.sdecay = slowdec[p_ac3dec->audblk.sdcycod];
217     p_ac3dec->bit_allocate.fdecay = fastdec[p_ac3dec->audblk.fdcycod];
218     p_ac3dec->bit_allocate.sgain = slowgain[p_ac3dec->audblk.sgaincod];
219     p_ac3dec->bit_allocate.dbknee = dbpbtab[p_ac3dec->audblk.dbpbcod];
220     p_ac3dec->bit_allocate.floor = floortab[p_ac3dec->audblk.floorcod];
221
222     /* if all the SNR offset constants are zero then the whole block is zero */
223     if (!p_ac3dec->audblk.csnroffst    && !p_ac3dec->audblk.fsnroffst[0] &&
224         !p_ac3dec->audblk.fsnroffst[1] && !p_ac3dec->audblk.fsnroffst[2] &&
225         !p_ac3dec->audblk.fsnroffst[3] && !p_ac3dec->audblk.fsnroffst[4] &&
226         !p_ac3dec->audblk.cplfsnroffst && !p_ac3dec->audblk.lfefsnroffst) {
227         memset(p_ac3dec->audblk.fbw_bap,0,sizeof(u16) * 256 * 5);
228         memset(p_ac3dec->audblk.cpl_bap,0,sizeof(u16) * 256);
229         memset(p_ac3dec->audblk.lfe_bap,0,sizeof(u16) * 7);
230         return;
231     }
232
233     for (i = 0; i < p_ac3dec->bsi.nfchans; i++) {
234         start = 0;
235         end = p_ac3dec->audblk.endmant[i] ;
236         fgain = fastgain[p_ac3dec->audblk.fgaincod[i]];
237         snroffset = (((p_ac3dec->audblk.csnroffst - 15) << 4) + p_ac3dec->audblk.fsnroffst[i]) << 2;
238         fastleak = 0;
239         slowleak = 0;
240
241         ba_compute_psd (&p_ac3dec->bit_allocate, start, end, p_ac3dec->audblk.fbw_exp[i]);
242
243         ba_compute_excitation (&p_ac3dec->bit_allocate, start, end , fgain, fastleak, slowleak, 0);
244
245         ba_compute_mask (&p_ac3dec->bit_allocate, start, end, p_ac3dec->syncinfo.fscod,
246                          p_ac3dec->audblk.deltbae[i],
247                          p_ac3dec->audblk.deltnseg[i],
248                          p_ac3dec->audblk.deltoffst[i],
249                          p_ac3dec->audblk.deltba[i],
250                          p_ac3dec->audblk.deltlen[i]);
251
252         ba_compute_bap (&p_ac3dec->bit_allocate, start, end, snroffset, p_ac3dec->audblk.fbw_bap[i]);
253     }
254
255     if (p_ac3dec->audblk.cplinu) {
256         start = p_ac3dec->audblk.cplstrtmant;
257         end = p_ac3dec->audblk.cplendmant;
258         fgain = fastgain[p_ac3dec->audblk.cplfgaincod];
259         snroffset = (((p_ac3dec->audblk.csnroffst - 15) << 4) + p_ac3dec->audblk.cplfsnroffst) << 2 ;
260         fastleak = (p_ac3dec->audblk.cplfleak << 8) + 768;
261         slowleak = (p_ac3dec->audblk.cplsleak << 8) + 768;
262
263         ba_compute_psd (&p_ac3dec->bit_allocate, start, end, p_ac3dec->audblk.cpl_exp);
264
265         ba_compute_excitation (&p_ac3dec->bit_allocate, start, end , fgain, fastleak, slowleak, 0);
266
267         ba_compute_mask (&p_ac3dec->bit_allocate, start, end, p_ac3dec->syncinfo.fscod,
268                          p_ac3dec->audblk.cpldeltbae,
269                          p_ac3dec->audblk.cpldeltnseg,
270                          p_ac3dec->audblk.cpldeltoffst,
271                          p_ac3dec->audblk.cpldeltba,
272                          p_ac3dec->audblk.cpldeltlen);
273
274         ba_compute_bap (&p_ac3dec->bit_allocate, start, end, snroffset, p_ac3dec->audblk.cpl_bap);
275     }
276
277     if (p_ac3dec->bsi.lfeon) {
278         start = 0;
279         end = 7;
280         fgain = fastgain[p_ac3dec->audblk.lfefgaincod];
281         snroffset = (((p_ac3dec->audblk.csnroffst - 15) << 4) + p_ac3dec->audblk.lfefsnroffst) << 2 ;
282         fastleak = 0;
283         slowleak = 0;
284
285         ba_compute_psd (&p_ac3dec->bit_allocate, start, end, p_ac3dec->audblk.lfe_exp);
286
287         ba_compute_excitation (&p_ac3dec->bit_allocate, start, end , fgain, fastleak, slowleak, 1);
288
289         ba_compute_mask (&p_ac3dec->bit_allocate, start, end, p_ac3dec->syncinfo.fscod, 2, 0, 0, 0, 0);
290
291         ba_compute_bap (&p_ac3dec->bit_allocate, start, end, snroffset, p_ac3dec->audblk.lfe_bap);
292     }
293 }
294
295
296 static void ba_compute_psd (bit_allocate_t * p_bit, s16 start, s16 end, s16 exps[])
297 {
298     int bin,j,k;
299     s16 lastbin = 0;
300
301     /* Map the exponents into dBs */
302     for (bin=start; bin<end; bin++) {
303         p_bit->psd[bin] = (3072 - (exps[bin] << 7));
304     }
305
306     /* Integrate the psd function over each bit allocation band */
307     j = start;
308     k = masktab[start];
309
310     do {
311         lastbin = min_value(bndtab[k] + bndsz[k], end);
312         p_bit->bndpsd[k] = p_bit->psd[j];
313         j++;
314
315         for (; j < lastbin; j++) {
316             p_bit->bndpsd[k] = logadd(p_bit->bndpsd[k],p_bit->psd[j]);
317         }
318
319         k++;
320     } while (end > lastbin);
321 }
322
323 static void ba_compute_excitation (bit_allocate_t * p_bit, s16 start, s16 end, 
324                         s16 fgain, s16 fastleak, s16 slowleak, s16 is_lfe)
325 {
326     int bin;
327     s16 bndstrt;
328     s16 bndend;
329     s16 lowcomp = 0;
330     s16 begin = 0;
331
332     /* Compute excitation function */
333     bndstrt = masktab[start];
334     bndend = masktab[end - 1] + 1;
335
336     if (bndstrt == 0) { /* For fbw and lfe channels */
337         lowcomp = calc_lowcomp(lowcomp, p_bit->bndpsd[0], p_bit->bndpsd[1], 0);
338         p_bit->excite[0] = p_bit->bndpsd[0] - fgain - lowcomp;
339         lowcomp = calc_lowcomp(lowcomp, p_bit->bndpsd[1], p_bit->bndpsd[2], 1);
340         p_bit->excite[1] = p_bit->bndpsd[1] - fgain - lowcomp;
341         begin = 7 ;
342
343         /* Note: Do not call calc_lowcomp() for the last band of the lfe channel, (bin = 6) */
344         for (bin = 2; bin < 7; bin++) {
345             if (!(is_lfe && (bin == 6)))
346                 lowcomp = calc_lowcomp (lowcomp, p_bit->bndpsd[bin], p_bit->bndpsd[bin+1], bin);
347             fastleak = p_bit->bndpsd[bin] - fgain;
348             slowleak = p_bit->bndpsd[bin] - p_bit->sgain;
349             p_bit->excite[bin] = fastleak - lowcomp;
350
351             if (!(is_lfe && (bin == 6))) {
352                 if (p_bit->bndpsd[bin] <= 
353                         p_bit->bndpsd[bin+1])
354                 {
355                     begin = bin + 1 ;
356                     break;
357                 }
358             }
359         }
360
361         for (bin = begin; bin < min_value(bndend, 22); bin++) {
362             if (!(is_lfe && (bin == 6)))
363                 lowcomp = calc_lowcomp (lowcomp, p_bit->bndpsd[bin],
364                             p_bit->bndpsd[bin+1], bin);
365             fastleak -= p_bit->fdecay ;
366             fastleak = max_value(fastleak, p_bit->bndpsd[bin] - fgain);
367             slowleak -= p_bit->sdecay ;
368             slowleak = max_value(slowleak, p_bit->bndpsd[bin] - p_bit->sgain);
369             p_bit->excite[bin] = max_value(fastleak - lowcomp, slowleak);
370         }
371         begin = 22;
372     } else { /* For coupling channel */
373         begin = bndstrt;
374     }
375
376     for (bin = begin; bin < bndend; bin++) {
377         fastleak -= p_bit->fdecay;
378         fastleak = max_value(fastleak, p_bit->bndpsd[bin] - fgain);
379         slowleak -= p_bit->sdecay;
380         slowleak = max_value(slowleak, p_bit->bndpsd[bin] - p_bit->sgain);
381         p_bit->excite[bin] = max_value(fastleak, slowleak) ;
382     }
383 }
384
385 static void ba_compute_mask (bit_allocate_t * p_bit, s16 start, s16 end, u16 fscod,
386                              u16 deltbae, u16 deltnseg, u16 deltoffst[],
387                              u16 deltba[], u16 deltlen[])
388 {
389     int bin,k;
390     s16 bndstrt;
391     s16 bndend;
392     s16 delta;
393
394     bndstrt = masktab[start];
395     bndend = masktab[end - 1] + 1;
396
397     /* Compute the masking curve */
398     for (bin = bndstrt; bin < bndend; bin++) {
399         if (p_bit->bndpsd[bin] < p_bit->dbknee) {
400             p_bit->excite[bin] += ((p_bit->dbknee - p_bit->bndpsd[bin]) >> 2);
401         }
402         p_bit->mask[bin] = max_value(p_bit->excite[bin], hth[fscod][bin]);
403     }
404
405     /* Perform delta bit modulation if necessary */
406     if ((deltbae == DELTA_BIT_REUSE) || (deltbae == DELTA_BIT_NEW)) {
407         s16 band = 0;
408         s16 seg = 0;
409
410         for (seg = 0; seg < deltnseg+1; seg++) {
411             band += deltoffst[seg];
412             if (deltba[seg] >= 4) {
413                 delta = (deltba[seg] - 3) << 7;
414             } else {
415                 delta = (deltba[seg] - 4) << 7;
416             }
417             for (k = 0; k < deltlen[seg]; k++) {
418                 p_bit->mask[band] += delta;
419                 band++;
420             }
421         }
422     }
423 }
424
425 static void ba_compute_bap (bit_allocate_t * p_bit, s16 start, s16 end, s16 snroffset,
426                             s16 bap[])
427 {
428     int i,j,k;
429     s16 lastbin = 0;
430     s16 address = 0;
431
432     /* Compute the bit allocation pointer for each bin */
433     i = start;
434     j = masktab[start];
435
436     do {
437         lastbin = min_value(bndtab[j] + bndsz[j], end);
438         p_bit->mask[j] -= snroffset;
439         p_bit->mask[j] -= p_bit->floor;
440
441         if (p_bit->mask[j] < 0)
442             p_bit->mask[j] = 0;
443
444         p_bit->mask[j] &= 0x1fe0;
445         p_bit->mask[j] += p_bit->floor;
446         for (k = i; k < lastbin; k++) {
447             address = (p_bit->psd[i] - p_bit->mask[j]) >> 5;
448             address = min_value(63, max_value(0, address));
449             bap[i] = baptab[address];
450             i++;
451         }
452         j++;
453     } while (end > lastbin);
454 }