bit_allocate.c

00001 /*
00002  * bit_allocate.c
00003  * Copyright (C) 2000-2002 Michel Lespinasse <[email protected]>
00004  * Copyright (C) 1999-2000 Aaron Holtzman <[email protected]>
00005  *
00006  * This file is part of a52dec, a free ATSC A-52 stream decoder.
00007  * See http://liba52.sourceforge.net/ for updates.
00008  *
00009  * a52dec is free software; you can redistribute it and/or modify
00010  * it under the terms of the GNU General Public License as published by
00011  * the Free Software Foundation; either version 2 of the License, or
00012  * (at your option) any later version.
00013  *
00014  * a52dec is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017  * GNU General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU General Public License
00020  * along with this program; if not, write to the Free Software
00021  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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, /* 93 padding elems */
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                                      /* 148 padding elems */
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;   /* fdcycod */
00144     fgain = 128 + 128 * (ba->bai & 7);                          /* fgaincod */
00145     sdecay = (15 + 2 * (state->bai >> 9)) >> halfrate;          /* sdcycod */
00146     sgain = slowgain[(state->bai >> 5) & 3];                    /* sgaincod */
00147     dbknee = dbpbtab[(state->bai >> 3) & 3];                    /* dbpbcod */
00148     hth = hthtab[state->fscod];
00149     /*
00150      * if there is no delta bit allocation, make deltba point to an area
00151      * known to contain zeroes. baptab+156 here.
00152      */
00153     deltba = (ba->deltbae == DELTA_BIT_NONE) ? baptab + 156 : ba->deltba;
00154     floor = floortab[state->bai & 7];                           /* floorcod */
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) {   /* not the coupling channel */
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)   /* lfe channel */
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) {         /* two iterations maximum */
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         /* minpsd = -289 */
00254         UPDATE_LEAK ();
00255         mask = (fastleak < slowleak) ? fastleak : slowleak;
00256         COMPUTE_MASK ();
00257         i++;
00258         j = startband;
00259         do {
00260             /* max(mask+4*exp)=147=-(minpsd+fgain-deltba-snroffset)>>5+4*exp */
00261             /* min(mask+4*exp)=-156=-(sgain-deltba-snroffset)>>5 */
00262             bap[j] = (baptab+156)[mask + 4 * exp[j]];
00263         } while (++j < endband);
00264     } while (j < end);
00265 }

Generated on Tue Dec 13 14:47:27 2005 for guliverkli by  doxygen 1.4.5