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