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