00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "config.h"
00025
00026 #include <inttypes.h>
00027
00028 #include "a52.h"
00029 #include "a52_internal.h"
00030
00031 static int hthtab[3][50] = {
00032 {0x730, 0x730, 0x7c0, 0x800, 0x820, 0x840, 0x850, 0x850, 0x860, 0x860,
00033 0x860, 0x860, 0x860, 0x870, 0x870, 0x870, 0x880, 0x880, 0x890, 0x890,
00034 0x8a0, 0x8a0, 0x8b0, 0x8b0, 0x8c0, 0x8c0, 0x8d0, 0x8e0, 0x8f0, 0x900,
00035 0x910, 0x910, 0x910, 0x910, 0x900, 0x8f0, 0x8c0, 0x870, 0x820, 0x7e0,
00036 0x7a0, 0x770, 0x760, 0x7a0, 0x7c0, 0x7c0, 0x6e0, 0x400, 0x3c0, 0x3c0},
00037 {0x710, 0x710, 0x7a0, 0x7f0, 0x820, 0x830, 0x840, 0x850, 0x850, 0x860,
00038 0x860, 0x860, 0x860, 0x860, 0x870, 0x870, 0x870, 0x880, 0x880, 0x880,
00039 0x890, 0x890, 0x8a0, 0x8a0, 0x8b0, 0x8b0, 0x8c0, 0x8c0, 0x8e0, 0x8f0,
00040 0x900, 0x910, 0x910, 0x910, 0x910, 0x900, 0x8e0, 0x8b0, 0x870, 0x820,
00041 0x7e0, 0x7b0, 0x760, 0x770, 0x7a0, 0x7c0, 0x780, 0x5d0, 0x3c0, 0x3c0},
00042 {0x680, 0x680, 0x750, 0x7b0, 0x7e0, 0x810, 0x820, 0x830, 0x840, 0x850,
00043 0x850, 0x850, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860,
00044 0x870, 0x870, 0x870, 0x870, 0x880, 0x880, 0x880, 0x890, 0x8a0, 0x8b0,
00045 0x8c0, 0x8d0, 0x8e0, 0x8f0, 0x900, 0x910, 0x910, 0x910, 0x900, 0x8f0,
00046 0x8d0, 0x8b0, 0x840, 0x7f0, 0x790, 0x760, 0x7a0, 0x7c0, 0x7b0, 0x720}
00047 };
00048
00049 static int8_t baptab[305] = {
00050 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
00051 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
00052 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
00053 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
00054 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
00055 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
00056
00057 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 14, 14, 14, 14, 14, 14,
00058 14, 12, 12, 12, 12, 11, 11, 11, 11, 10, 10, 10, 10, 9, 9, 9,
00059 9, 8, 8, 8, 8, 7, 7, 7, 7, 6, 6, 6, 6, 5, 5, 5,
00060 5, 4, 4, -3, -3, 3, 3, 3, -2, -2, -1, -1, -1, -1, -1, 0,
00061
00062 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00063 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00064 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00065 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00066 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00067 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00068 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00069 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00070 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00071 0, 0, 0, 0
00072 };
00073
00074 static int bndtab[30] = {21, 22, 23, 24, 25, 26, 27, 28, 31, 34,
00075 37, 40, 43, 46, 49, 55, 61, 67, 73, 79,
00076 85, 97, 109, 121, 133, 157, 181, 205, 229, 253};
00077
00078 static int8_t latab[256] = {
00079 -64, -63, -62, -61, -60, -59, -58, -57, -56, -55, -54, -53,
00080 -52, -52, -51, -50, -49, -48, -47, -47, -46, -45, -44, -44,
00081 -43, -42, -41, -41, -40, -39, -38, -38, -37, -36, -36, -35,
00082 -35, -34, -33, -33, -32, -32, -31, -30, -30, -29, -29, -28,
00083 -28, -27, -27, -26, -26, -25, -25, -24, -24, -23, -23, -22,
00084 -22, -21, -21, -21, -20, -20, -19, -19, -19, -18, -18, -18,
00085 -17, -17, -17, -16, -16, -16, -15, -15, -15, -14, -14, -14,
00086 -13, -13, -13, -13, -12, -12, -12, -12, -11, -11, -11, -11,
00087 -10, -10, -10, -10, -10, -9, -9, -9, -9, -9, -8, -8,
00088 -8, -8, -8, -8, -7, -7, -7, -7, -7, -7, -6, -6,
00089 -6, -6, -6, -6, -6, -6, -5, -5, -5, -5, -5, -5,
00090 -5, -5, -4, -4, -4, -4, -4, -4, -4, -4, -4, -4,
00091 -4, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3, -3,
00092 -3, -3, -3, -2, -2, -2, -2, -2, -2, -2, -2, -2,
00093 -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -1,
00094 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00095 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
00096 -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0,
00097 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00098 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00099 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00100 0, 0, 0, 0
00101 };
00102
00103 #define UPDATE_LEAK() \
00104 do { \
00105 fastleak += fdecay; \
00106 if (fastleak > psd + fgain) \
00107 fastleak = psd + fgain; \
00108 slowleak += sdecay; \
00109 if (slowleak > psd + sgain) \
00110 slowleak = psd + sgain; \
00111 } while (0)
00112
00113 #define COMPUTE_MASK() \
00114 do { \
00115 if (psd > dbknee) \
00116 mask -= (psd - dbknee) >> 2; \
00117 if (mask > hth [i >> halfrate]) \
00118 mask = hth [i >> halfrate]; \
00119 mask -= snroffset + 128 * deltba[i]; \
00120 mask = (mask > 0) ? 0 : ((-mask) >> 5); \
00121 mask -= floor; \
00122 } while (0)
00123
00124 void a52_bit_allocate (a52_state_t * state, ba_t * ba, int bndstart,
00125 int start, int end, int fastleak, int slowleak,
00126 expbap_t * expbap)
00127 {
00128 static int slowgain[4] = {0x540, 0x4d8, 0x478, 0x410};
00129 static int dbpbtab[4] = {0xc00, 0x500, 0x300, 0x100};
00130 static int floortab[8] = {0x910, 0x950, 0x990, 0x9d0,
00131 0xa10, 0xa90, 0xb10, 0x1400};
00132
00133 int i, j;
00134 uint8_t * exp;
00135 int8_t * bap;
00136 int fdecay, fgain, sdecay, sgain, dbknee, floor, snroffset;
00137 int psd, mask;
00138 int8_t * deltba;
00139 int * hth;
00140 int halfrate;
00141
00142 halfrate = state->halfrate;
00143 fdecay = (63 + 20 * ((state->bai >> 7) & 3)) >> halfrate;
00144 fgain = 128 + 128 * (ba->bai & 7);
00145 sdecay = (15 + 2 * (state->bai >> 9)) >> halfrate;
00146 sgain = slowgain[(state->bai >> 5) & 3];
00147 dbknee = dbpbtab[(state->bai >> 3) & 3];
00148 hth = hthtab[state->fscod];
00149
00150
00151
00152
00153 deltba = (ba->deltbae == DELTA_BIT_NONE) ? baptab + 156 : ba->deltba;
00154 floor = floortab[state->bai & 7];
00155 snroffset = 960 - 64 * state->csnroffst - 4 * (ba->bai >> 3) + floor;
00156 floor >>= 5;
00157
00158 exp = expbap->exp;
00159 bap = expbap->bap;
00160
00161 i = bndstart;
00162 j = start;
00163 if (start == 0) {
00164 int lowcomp;
00165
00166 lowcomp = 0;
00167 j = end - 1;
00168 do {
00169 if (i < j) {
00170 if (exp[i+1] == exp[i] - 2)
00171 lowcomp = 384;
00172 else if (lowcomp && (exp[i+1] > exp[i]))
00173 lowcomp -= 64;
00174 }
00175 psd = 128 * exp[i];
00176 mask = psd + fgain + lowcomp;
00177 COMPUTE_MASK ();
00178 bap[i] = (baptab+156)[mask + 4 * exp[i]];
00179 i++;
00180 } while ((i < 3) || ((i < 7) && (exp[i] > exp[i-1])));
00181 fastleak = psd + fgain;
00182 slowleak = psd + sgain;
00183
00184 while (i < 7) {
00185 if (i < j) {
00186 if (exp[i+1] == exp[i] - 2)
00187 lowcomp = 384;
00188 else if (lowcomp && (exp[i+1] > exp[i]))
00189 lowcomp -= 64;
00190 }
00191 psd = 128 * exp[i];
00192 UPDATE_LEAK ();
00193 mask = ((fastleak + lowcomp < slowleak) ?
00194 fastleak + lowcomp : slowleak);
00195 COMPUTE_MASK ();
00196 bap[i] = (baptab+156)[mask + 4 * exp[i]];
00197 i++;
00198 }
00199
00200 if (end == 7)
00201 return;
00202
00203 do {
00204 if (exp[i+1] == exp[i] - 2)
00205 lowcomp = 320;
00206 else if (lowcomp && (exp[i+1] > exp[i]))
00207 lowcomp -= 64;
00208 psd = 128 * exp[i];
00209 UPDATE_LEAK ();
00210 mask = ((fastleak + lowcomp < slowleak) ?
00211 fastleak + lowcomp : slowleak);
00212 COMPUTE_MASK ();
00213 bap[i] = (baptab+156)[mask + 4 * exp[i]];
00214 i++;
00215 } while (i < 20);
00216
00217 while (lowcomp > 128) {
00218 lowcomp -= 128;
00219 psd = 128 * exp[i];
00220 UPDATE_LEAK ();
00221 mask = ((fastleak + lowcomp < slowleak) ?
00222 fastleak + lowcomp : slowleak);
00223 COMPUTE_MASK ();
00224 bap[i] = (baptab+156)[mask + 4 * exp[i]];
00225 i++;
00226 }
00227 j = i;
00228 }
00229
00230 do {
00231 int startband, endband;
00232
00233 startband = j;
00234 endband = ((bndtab-20)[i] < end) ? (bndtab-20)[i] : end;
00235 psd = 128 * exp[j++];
00236 while (j < endband) {
00237 int next, delta;
00238
00239 next = 128 * exp[j++];
00240 delta = next - psd;
00241 switch (delta >> 9) {
00242 case -6: case -5: case -4: case -3: case -2:
00243 psd = next;
00244 break;
00245 case -1:
00246 psd = next + latab[(-delta) >> 1];
00247 break;
00248 case 0:
00249 psd += latab[delta >> 1];
00250 break;
00251 }
00252 }
00253
00254 UPDATE_LEAK ();
00255 mask = (fastleak < slowleak) ? fastleak : slowleak;
00256 COMPUTE_MASK ();
00257 i++;
00258 j = startband;
00259 do {
00260
00261
00262 bap[j] = (baptab+156)[mask + 4 * exp[j]];
00263 } while (++j < endband);
00264 } while (j < end);
00265 }