2c76b93c33687dc59fd0bbfad244a4b459dde368
[ffmpeg.git] / libavcodec / libac3 / bit_allocate.c
1 /* 
2  *  bit_allocate.c
3  *
4  *      Copyright (C) Aaron Holtzman - May 1999
5  *
6  *  This file is part of ac3dec, a free Dolby AC-3 stream decoder.
7  *      
8  *  ac3dec is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2, or (at your option)
11  *  any later version.
12  *   
13  *  ac3dec is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *   
18  *  You should have received a copy of the GNU General Public License
19  *  along with GNU Make; see the file COPYING.  If not, write to
20  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
21  *
22  */
23 #include "../common.h"
24 #include "ac3.h"
25 #include "ac3_internal.h"
26
27 static int hthtab[3][50] = {
28     {0x730, 0x730, 0x7c0, 0x800, 0x820, 0x840, 0x850, 0x850, 0x860, 0x860,
29      0x860, 0x860, 0x860, 0x870, 0x870, 0x870, 0x880, 0x880, 0x890, 0x890,
30      0x8a0, 0x8a0, 0x8b0, 0x8b0, 0x8c0, 0x8c0, 0x8d0, 0x8e0, 0x8f0, 0x900,
31      0x910, 0x910, 0x910, 0x910, 0x900, 0x8f0, 0x8c0, 0x870, 0x820, 0x7e0,
32      0x7a0, 0x770, 0x760, 0x7a0, 0x7c0, 0x7c0, 0x6e0, 0x400, 0x3c0, 0x3c0},
33     {0x710, 0x710, 0x7a0, 0x7f0, 0x820, 0x830, 0x840, 0x850, 0x850, 0x860,
34      0x860, 0x860, 0x860, 0x860, 0x870, 0x870, 0x870, 0x880, 0x880, 0x880,
35      0x890, 0x890, 0x8a0, 0x8a0, 0x8b0, 0x8b0, 0x8c0, 0x8c0, 0x8e0, 0x8f0,
36      0x900, 0x910, 0x910, 0x910, 0x910, 0x900, 0x8e0, 0x8b0, 0x870, 0x820,
37      0x7e0, 0x7b0, 0x760, 0x770, 0x7a0, 0x7c0, 0x780, 0x5d0, 0x3c0, 0x3c0},
38     {0x680, 0x680, 0x750, 0x7b0, 0x7e0, 0x810, 0x820, 0x830, 0x840, 0x850,
39      0x850, 0x850, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860,
40      0x870, 0x870, 0x870, 0x870, 0x880, 0x880, 0x880, 0x890, 0x8a0, 0x8b0,
41      0x8c0, 0x8d0, 0x8e0, 0x8f0, 0x900, 0x910, 0x910, 0x910, 0x900, 0x8f0,
42      0x8d0, 0x8b0, 0x840, 0x7f0, 0x790, 0x760, 0x7a0, 0x7c0, 0x7b0, 0x720}
43 };
44
45 static int8_t baptab[305] = {
46     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
47     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
48     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
49     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
50     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
51     16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, // 93 padding entries
52
53     16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 14, 14, 14, 14, 14, 14,
54     14, 12, 12, 12, 12, 11, 11, 11, 11, 10, 10, 10, 10,  9,  9,  9,
55      9,  8,  8,  8,  8,  7,  7,  7,  7,  6,  6,  6,  6,  5,  5,  5,
56      5,  4,  4, -3, -3,  3,  3,  3, -2, -2, -1, -1, -1, -1, -1,  0,
57
58      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
59      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
60      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
61      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
62      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
63      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
64      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
65      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
66      0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
67      0,  0,  0,  0                                      // 148 padding entries
68 };
69
70 static int bndtab[30] = {21, 22,  23,  24,  25,  26,  27,  28,  31,  34,
71                          37, 40,  43,  46,  49,  55,  61,  67,  73,  79,
72                          85, 97, 109, 121, 133, 157, 181, 205, 229, 253};
73
74 static int8_t latab[256] = {
75     -64, -63, -62, -61, -60, -59, -58, -57, -56, -55, -54, -53,
76     -52, -52, -51, -50, -49, -48, -47, -47, -46, -45, -44, -44,
77     -43, -42, -41, -41, -40, -39, -38, -38, -37, -36, -36, -35,
78     -35, -34, -33, -33, -32, -32, -31, -30, -30, -29, -29, -28,
79     -28, -27, -27, -26, -26, -25, -25, -24, -24, -23, -23, -22,
80     -22, -21, -21, -21, -20, -20, -19, -19, -19, -18, -18, -18,
81     -17, -17, -17, -16, -16, -16, -15, -15, -15, -14, -14, -14,
82     -13, -13, -13, -13, -12, -12, -12, -12, -11, -11, -11, -11,
83     -10, -10, -10, -10, -10,  -9,  -9,  -9,  -9,  -9,  -8,  -8,
84      -8,  -8,  -8,  -8,  -7,  -7,  -7,  -7,  -7,  -7,  -6,  -6,
85      -6,  -6,  -6,  -6,  -6,  -6,  -5,  -5,  -5,  -5,  -5,  -5,
86      -5,  -5,  -4,  -4,  -4,  -4,  -4,  -4,  -4,  -4,  -4,  -4,
87      -4,  -3,  -3,  -3,  -3,  -3,  -3,  -3,  -3,  -3,  -3,  -3,
88      -3,  -3,  -3,  -2,  -2,  -2,  -2,  -2,  -2,  -2,  -2,  -2,
89      -2,  -2,  -2,  -2,  -2,  -2,  -2,  -2,  -2,  -2,  -1,  -1,
90      -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
91      -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
92      -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,
93       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
94       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
95       0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
96       0,   0,   0,   0
97 };
98
99 #define UPDATE_LEAK()           \
100 do {                            \
101     fastleak += fdecay;         \
102     if (fastleak > psd + fgain) \
103         fastleak = psd + fgain; \
104     slowleak += sdecay;         \
105     if (slowleak > psd + sgain) \
106         slowleak = psd + sgain; \
107 } while (0)
108
109 #define COMPUTE_MASK()                          \
110 do {                                            \
111     if (psd > dbknee)                           \
112         mask -= (psd - dbknee) >> 2;            \
113     if (mask > hth [i >> halfrate])             \
114         mask = hth [i >> halfrate];             \
115     mask -= snroffset + 128 * deltba[i];        \
116     mask = (mask > 0) ? 0 : ((-mask) >> 5);     \
117     mask -= floor;                              \
118 } while (0)
119
120 void bit_allocate (ac3_state_t * state, ac3_ba_t * ba, int bndstart,
121                    int start, int end, int fastleak, int slowleak,
122                    uint8_t * exp, int8_t * bap)
123 {
124     static int slowgain[4] = {0x540, 0x4d8, 0x478, 0x410};
125     static int dbpbtab[4]  = {0xc00, 0x500, 0x300, 0x100};
126     static int floortab[8] = {0x910, 0x950, 0x990, 0x9d0,
127                               0xa10, 0xa90, 0xb10, 0x1400};
128
129     int i, j;
130     int fdecay, fgain, sdecay, sgain, dbknee, floor, snroffset;
131     int psd, mask;
132     int8_t * deltba;
133     int * hth;
134     int halfrate;
135
136     halfrate = state->halfrate;
137     fdecay = (63 + 20 * state->fdcycod) >> halfrate;
138     fgain = 128 + 128 * ba->fgaincod;
139     sdecay = (15 + 2 * state->sdcycod) >> halfrate;
140     sgain = slowgain[state->sgaincod];
141     dbknee = dbpbtab[state->dbpbcod];
142     hth = hthtab[state->fscod];
143     /*
144      * if there is no delta bit allocation, make deltba point to an area
145      * known to contain zeroes. baptab+156 here.
146      */
147     deltba = (ba->deltbae == DELTA_BIT_NONE) ? baptab + 156 : ba->deltba;
148     floor = floortab[state->floorcod];
149     snroffset = 960 - 64 * state->csnroffst - 4 * ba->fsnroffst + floor;
150     floor >>= 5;
151
152     i = bndstart;
153     j = start;
154     if (start == 0) {   // not the coupling channel
155         int lowcomp;
156
157         lowcomp = 0;
158         j = end - 1;
159         do {
160             if (i < j) {
161                 if (exp[i+1] == exp[i] - 2)
162                     lowcomp = 384;
163                 else if (lowcomp && (exp[i+1] > exp[i]))
164                     lowcomp -= 64;
165             }
166             psd = 128 * exp[i];
167             mask = psd + fgain + lowcomp;
168             COMPUTE_MASK ();
169             bap[i++] = (baptab+156)[mask + 4 * exp[i]];
170         } while ((i < 3) || ((i < 7) && (exp[i] > exp[i-1])));
171         fastleak = psd + fgain;
172         slowleak = psd + sgain;
173
174         while (i < 7) {
175             if (i < j) {
176                 if (exp[i+1] == exp[i] - 2)
177                     lowcomp = 384;
178                 else if (lowcomp && (exp[i+1] > exp[i]))
179                     lowcomp -= 64;
180             }
181             psd = 128 * exp[i];
182             UPDATE_LEAK ();
183             mask = ((fastleak + lowcomp < slowleak) ?
184                     fastleak + lowcomp : slowleak);
185             COMPUTE_MASK ();
186             bap[i++] = (baptab+156)[mask + 4 * exp[i]];
187         }
188
189         if (end == 7)   // lfe channel
190             return;
191
192         do {
193             if (exp[i+1] == exp[i] - 2)
194                 lowcomp = 320;
195             else if (lowcomp && (exp[i+1] > exp[i]))
196                 lowcomp -= 64;
197             psd = 128 * exp[i];
198             UPDATE_LEAK ();
199             mask = ((fastleak + lowcomp < slowleak) ?
200                     fastleak + lowcomp : slowleak);
201             COMPUTE_MASK ();
202             bap[i++] = (baptab+156)[mask + 4 * exp[i]];
203         } while (i < 20);
204
205         while (lowcomp > 128) {         // two iterations maximum
206             lowcomp -= 128;
207             psd = 128 * exp[i];
208             UPDATE_LEAK ();
209             mask = ((fastleak + lowcomp < slowleak) ?
210                     fastleak + lowcomp : slowleak);
211             COMPUTE_MASK ();
212             bap[i++] = (baptab+156)[mask + 4 * exp[i]];
213         }
214         j = i;
215     }
216
217     do {
218         int startband, endband;
219
220         startband = j;
221         endband = ((bndtab-20)[i] < end) ? (bndtab-20)[i] : end;
222         psd = 128 * exp[j++];
223         while (j < endband) {
224             int next, delta;
225
226             next = 128 * exp[j++];
227             delta = next - psd;
228             switch (delta >> 9) {
229             case -6: case -5: case -4: case -3: case -2:
230                 psd = next;
231                 break;
232             case -1:
233                 psd = next + latab[(-delta) >> 1];
234                 break;
235             case 0:
236                 psd += latab[delta >> 1];
237                 break;
238             }
239         }
240         // minpsd = -289
241         UPDATE_LEAK ();
242         mask = (fastleak < slowleak) ? fastleak : slowleak;
243         COMPUTE_MASK ();
244         i++;
245         j = startband;
246         do {
247             // max(mask+4*exp)=147=-(minpsd+fgain-deltba-snroffset)>>5+4*exp
248             // min(mask+4*exp)=-156=-(sgain-deltba-snroffset)>>5
249             bap[j++] = (baptab+156)[mask + 4 * exp[j]];
250         } while (j < endband);
251     } while (j < end);
252 }