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