Blame liba52/bit_allocate.c

Packit 64f477
/*
Packit 64f477
 * bit_allocate.c
Packit 64f477
 * Copyright (C) 2000-2002 Michel Lespinasse <walken@zoy.org>
Packit 64f477
 * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
Packit 64f477
 *
Packit 64f477
 * This file is part of a52dec, a free ATSC A-52 stream decoder.
Packit 64f477
 * See http://liba52.sourceforge.net/ for updates.
Packit 64f477
 *
Packit 64f477
 * a52dec is free software; you can redistribute it and/or modify
Packit 64f477
 * it under the terms of the GNU General Public License as published by
Packit 64f477
 * the Free Software Foundation; either version 2 of the License, or
Packit 64f477
 * (at your option) any later version.
Packit 64f477
 *
Packit 64f477
 * a52dec is distributed in the hope that it will be useful,
Packit 64f477
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 64f477
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 64f477
 * GNU General Public License for more details.
Packit 64f477
 *
Packit 64f477
 * You should have received a copy of the GNU General Public License
Packit 64f477
 * along with this program; if not, write to the Free Software
Packit 64f477
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Packit 64f477
 */
Packit 64f477
Packit 64f477
#include "config.h"
Packit 64f477
Packit 64f477
#include <inttypes.h>
Packit 64f477
Packit 64f477
#include "a52.h"
Packit 64f477
#include "a52_internal.h"
Packit 64f477
Packit 64f477
static int hthtab[3][50] = {
Packit 64f477
    {0x730, 0x730, 0x7c0, 0x800, 0x820, 0x840, 0x850, 0x850, 0x860, 0x860,
Packit 64f477
     0x860, 0x860, 0x860, 0x870, 0x870, 0x870, 0x880, 0x880, 0x890, 0x890,
Packit 64f477
     0x8a0, 0x8a0, 0x8b0, 0x8b0, 0x8c0, 0x8c0, 0x8d0, 0x8e0, 0x8f0, 0x900,
Packit 64f477
     0x910, 0x910, 0x910, 0x910, 0x900, 0x8f0, 0x8c0, 0x870, 0x820, 0x7e0,
Packit 64f477
     0x7a0, 0x770, 0x760, 0x7a0, 0x7c0, 0x7c0, 0x6e0, 0x400, 0x3c0, 0x3c0},
Packit 64f477
    {0x710, 0x710, 0x7a0, 0x7f0, 0x820, 0x830, 0x840, 0x850, 0x850, 0x860,
Packit 64f477
     0x860, 0x860, 0x860, 0x860, 0x870, 0x870, 0x870, 0x880, 0x880, 0x880,
Packit 64f477
     0x890, 0x890, 0x8a0, 0x8a0, 0x8b0, 0x8b0, 0x8c0, 0x8c0, 0x8e0, 0x8f0,
Packit 64f477
     0x900, 0x910, 0x910, 0x910, 0x910, 0x900, 0x8e0, 0x8b0, 0x870, 0x820,
Packit 64f477
     0x7e0, 0x7b0, 0x760, 0x770, 0x7a0, 0x7c0, 0x780, 0x5d0, 0x3c0, 0x3c0},
Packit 64f477
    {0x680, 0x680, 0x750, 0x7b0, 0x7e0, 0x810, 0x820, 0x830, 0x840, 0x850,
Packit 64f477
     0x850, 0x850, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860, 0x860,
Packit 64f477
     0x870, 0x870, 0x870, 0x870, 0x880, 0x880, 0x880, 0x890, 0x8a0, 0x8b0,
Packit 64f477
     0x8c0, 0x8d0, 0x8e0, 0x8f0, 0x900, 0x910, 0x910, 0x910, 0x900, 0x8f0,
Packit 64f477
     0x8d0, 0x8b0, 0x840, 0x7f0, 0x790, 0x760, 0x7a0, 0x7c0, 0x7b0, 0x720}
Packit 64f477
};
Packit 64f477
Packit 64f477
static int8_t baptab[305] = {
Packit 64f477
    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
Packit 64f477
    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
Packit 64f477
    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
Packit 64f477
    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
Packit 64f477
    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
Packit 64f477
    16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,	/* 93 padding elems */
Packit 64f477
Packit 64f477
    16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 14, 14, 14, 14, 14, 14,
Packit 64f477
    14, 12, 12, 12, 12, 11, 11, 11, 11, 10, 10, 10, 10,  9,  9,  9,
Packit 64f477
     9,  8,  8,  8,  8,  7,  7,  7,  7,  6,  6,  6,  6,  5,  5,  5,
Packit 64f477
     5,  4,  4, -3, -3,  3,  3,  3, -2, -2, -1, -1, -1, -1, -1,  0,
Packit 64f477
Packit 64f477
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
Packit 64f477
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
Packit 64f477
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
Packit 64f477
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
Packit 64f477
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
Packit 64f477
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
Packit 64f477
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
Packit 64f477
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
Packit 64f477
     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
Packit 64f477
     0,  0,  0,  0					/* 148 padding elems */
Packit 64f477
};
Packit 64f477
Packit 64f477
static int bndtab[30] = {21, 22,  23,  24,  25,  26,  27,  28,  31,  34,
Packit 64f477
			 37, 40,  43,  46,  49,  55,  61,  67,  73,  79,
Packit 64f477
			 85, 97, 109, 121, 133, 157, 181, 205, 229, 253};
Packit 64f477
Packit 64f477
static int8_t latab[256] = {
Packit 64f477
    -64, -63, -62, -61, -60, -59, -58, -57, -56, -55, -54, -53,
Packit 64f477
    -52, -52, -51, -50, -49, -48, -47, -47, -46, -45, -44, -44,
Packit 64f477
    -43, -42, -41, -41, -40, -39, -38, -38, -37, -36, -36, -35,
Packit 64f477
    -35, -34, -33, -33, -32, -32, -31, -30, -30, -29, -29, -28,
Packit 64f477
    -28, -27, -27, -26, -26, -25, -25, -24, -24, -23, -23, -22,
Packit 64f477
    -22, -21, -21, -21, -20, -20, -19, -19, -19, -18, -18, -18,
Packit 64f477
    -17, -17, -17, -16, -16, -16, -15, -15, -15, -14, -14, -14,
Packit 64f477
    -13, -13, -13, -13, -12, -12, -12, -12, -11, -11, -11, -11,
Packit 64f477
    -10, -10, -10, -10, -10,  -9,  -9,  -9,  -9,  -9,  -8,  -8,
Packit 64f477
     -8,  -8,  -8,  -8,  -7,  -7,  -7,  -7,  -7,  -7,  -6,  -6,
Packit 64f477
     -6,  -6,  -6,  -6,  -6,  -6,  -5,  -5,  -5,  -5,  -5,  -5,
Packit 64f477
     -5,  -5,  -4,  -4,  -4,  -4,  -4,  -4,  -4,  -4,  -4,  -4,
Packit 64f477
     -4,  -3,  -3,  -3,  -3,  -3,  -3,  -3,  -3,  -3,  -3,  -3,
Packit 64f477
     -3,  -3,  -3,  -2,  -2,  -2,  -2,  -2,  -2,  -2,  -2,  -2,
Packit 64f477
     -2,  -2,  -2,  -2,  -2,  -2,  -2,  -2,  -2,  -2,  -1,  -1,
Packit 64f477
     -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
Packit 64f477
     -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,
Packit 64f477
     -1,  -1,  -1,  -1,  -1,  -1,   0,   0,   0,   0,   0,   0,
Packit 64f477
      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
Packit 64f477
      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
Packit 64f477
      0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,
Packit 64f477
      0,   0,   0,   0
Packit 64f477
};
Packit 64f477
Packit 64f477
#define UPDATE_LEAK() 		\
Packit 64f477
do {				\
Packit 64f477
    fastleak += fdecay;		\
Packit 64f477
    if (fastleak > psd + fgain)	\
Packit 64f477
	fastleak = psd + fgain;	\
Packit 64f477
    slowleak += sdecay;		\
Packit 64f477
    if (slowleak > psd + sgain)	\
Packit 64f477
	slowleak = psd + sgain;	\
Packit 64f477
} while (0)
Packit 64f477
Packit 64f477
#define COMPUTE_MASK()				\
Packit 64f477
do {						\
Packit 64f477
    if (psd > dbknee)				\
Packit 64f477
	mask -= (psd - dbknee) >> 2;		\
Packit 64f477
    if (mask > hth [i >> halfrate])		\
Packit 64f477
	mask = hth [i >> halfrate];		\
Packit 64f477
    mask -= snroffset + 128 * deltba[i];	\
Packit 64f477
    mask = (mask > 0) ? 0 : ((-mask) >> 5);	\
Packit 64f477
    mask -= floor;				\
Packit 64f477
} while (0)
Packit 64f477
Packit 64f477
void a52_bit_allocate (a52_state_t * state, ba_t * ba, int bndstart,
Packit 64f477
		       int start, int end, int fastleak, int slowleak,
Packit 64f477
		       expbap_t * expbap)
Packit 64f477
{
Packit 64f477
    static int slowgain[4] = {0x540, 0x4d8, 0x478, 0x410};
Packit 64f477
    static int dbpbtab[4]  = {0xc00, 0x500, 0x300, 0x100};
Packit 64f477
    static int floortab[8] = {0x910, 0x950, 0x990, 0x9d0,
Packit 64f477
			      0xa10, 0xa90, 0xb10, 0x1400};
Packit 64f477
Packit 64f477
    int i, j;
Packit 64f477
    uint8_t * exp;
Packit 64f477
    int8_t * bap;
Packit 64f477
    int fdecay, fgain, sdecay, sgain, dbknee, floor, snroffset;
Packit 64f477
    int psd, mask;
Packit 64f477
    int8_t * deltba;
Packit 64f477
    int * hth;
Packit 64f477
    int halfrate;
Packit 64f477
Packit 64f477
    halfrate = state->halfrate;
Packit 64f477
    fdecay = (63 + 20 * ((state->bai >> 7) & 3)) >> halfrate;	/* fdcycod */
Packit 64f477
    fgain = 128 + 128 * (ba->bai & 7);				/* fgaincod */
Packit 64f477
    sdecay = (15 + 2 * (state->bai >> 9)) >> halfrate;		/* sdcycod */
Packit 64f477
    sgain = slowgain[(state->bai >> 5) & 3];			/* sgaincod */
Packit 64f477
    dbknee = dbpbtab[(state->bai >> 3) & 3];			/* dbpbcod */
Packit 64f477
    hth = hthtab[state->fscod];
Packit 64f477
    /*
Packit 64f477
     * if there is no delta bit allocation, make deltba point to an area
Packit 64f477
     * known to contain zeroes. baptab+156 here.
Packit 64f477
     */
Packit 64f477
    deltba = (ba->deltbae == DELTA_BIT_NONE) ? baptab + 156 : ba->deltba;
Packit 64f477
    floor = floortab[state->bai & 7];				/* floorcod */
Packit 64f477
    snroffset = 960 - 64 * state->csnroffst - 4 * (ba->bai >> 3) + floor;
Packit 64f477
    floor >>= 5;
Packit 64f477
Packit 64f477
    exp = expbap->exp;
Packit 64f477
    bap = expbap->bap;
Packit 64f477
Packit 64f477
    i = bndstart;
Packit 64f477
    j = start;
Packit 64f477
    if (start == 0) {	/* not the coupling channel */
Packit 64f477
	int lowcomp;
Packit 64f477
Packit 64f477
	lowcomp = 0;
Packit 64f477
	j = end - 1;
Packit 64f477
	do {
Packit 64f477
	    if (i < j) {
Packit 64f477
		if (exp[i+1] == exp[i] - 2)
Packit 64f477
		    lowcomp = 384;
Packit 64f477
		else if (lowcomp && (exp[i+1] > exp[i]))
Packit 64f477
		    lowcomp -= 64;
Packit 64f477
	    }
Packit 64f477
	    psd = 128 * exp[i];
Packit 64f477
	    mask = psd + fgain + lowcomp;
Packit 64f477
	    COMPUTE_MASK ();
Packit 64f477
	    bap[i] = (baptab+156)[mask + 4 * exp[i]];
Packit 64f477
	    i++;
Packit 64f477
	} while ((i < 3) || ((i < 7) && (exp[i] > exp[i-1])));
Packit 64f477
	fastleak = psd + fgain;
Packit 64f477
	slowleak = psd + sgain;
Packit 64f477
Packit 64f477
	while (i < 7) {
Packit 64f477
	    if (i < j) {
Packit 64f477
		if (exp[i+1] == exp[i] - 2)
Packit 64f477
		    lowcomp = 384;
Packit 64f477
		else if (lowcomp && (exp[i+1] > exp[i]))
Packit 64f477
		    lowcomp -= 64;
Packit 64f477
	    }
Packit 64f477
	    psd = 128 * exp[i];
Packit 64f477
	    UPDATE_LEAK ();
Packit 64f477
	    mask = ((fastleak + lowcomp < slowleak) ?
Packit 64f477
		    fastleak + lowcomp : slowleak);
Packit 64f477
	    COMPUTE_MASK ();
Packit 64f477
	    bap[i] = (baptab+156)[mask + 4 * exp[i]];
Packit 64f477
	    i++;
Packit 64f477
	}
Packit 64f477
Packit 64f477
	if (end == 7)	/* lfe channel */
Packit 64f477
	    return;
Packit 64f477
Packit 64f477
	do {
Packit 64f477
	    if (exp[i+1] == exp[i] - 2)
Packit 64f477
		lowcomp = 320;
Packit 64f477
	    else if (lowcomp && (exp[i+1] > exp[i]))
Packit 64f477
		lowcomp -= 64;
Packit 64f477
	    psd = 128 * exp[i];
Packit 64f477
	    UPDATE_LEAK ();
Packit 64f477
	    mask = ((fastleak + lowcomp < slowleak) ?
Packit 64f477
		    fastleak + lowcomp : slowleak);
Packit 64f477
	    COMPUTE_MASK ();
Packit 64f477
	    bap[i] = (baptab+156)[mask + 4 * exp[i]];
Packit 64f477
	    i++;
Packit 64f477
	} while (i < 20);
Packit 64f477
Packit 64f477
	while (lowcomp > 128) {		/* two iterations maximum */
Packit 64f477
	    lowcomp -= 128;
Packit 64f477
	    psd = 128 * exp[i];
Packit 64f477
	    UPDATE_LEAK ();
Packit 64f477
	    mask = ((fastleak + lowcomp < slowleak) ?
Packit 64f477
		    fastleak + lowcomp : slowleak);
Packit 64f477
	    COMPUTE_MASK ();
Packit 64f477
	    bap[i] = (baptab+156)[mask + 4 * exp[i]];
Packit 64f477
	    i++;
Packit 64f477
	}
Packit 64f477
	j = i;
Packit 64f477
    }
Packit 64f477
Packit 64f477
    do {
Packit 64f477
	int startband, endband;
Packit 64f477
Packit 64f477
	startband = j;
Packit 64f477
	endband = ((bndtab-20)[i] < end) ? (bndtab-20)[i] : end;
Packit 64f477
	psd = 128 * exp[j++];
Packit 64f477
	while (j < endband) {
Packit 64f477
	    int next, delta;
Packit 64f477
Packit 64f477
	    next = 128 * exp[j++];
Packit 64f477
	    delta = next - psd;
Packit 64f477
	    switch (delta >> 9) {
Packit 64f477
	    case -6: case -5: case -4: case -3: case -2:
Packit 64f477
		psd = next;
Packit 64f477
		break;
Packit 64f477
	    case -1:
Packit 64f477
		psd = next + latab[(-delta) >> 1];
Packit 64f477
		break;
Packit 64f477
	    case 0:
Packit 64f477
		psd += latab[delta >> 1];
Packit 64f477
		break;
Packit 64f477
	    }
Packit 64f477
	}
Packit 64f477
	/* minpsd = -289 */
Packit 64f477
	UPDATE_LEAK ();
Packit 64f477
	mask = (fastleak < slowleak) ? fastleak : slowleak;
Packit 64f477
	COMPUTE_MASK ();
Packit 64f477
	i++;
Packit 64f477
	j = startband;
Packit 64f477
	do {
Packit 64f477
	    /* max(mask+4*exp)=147=-(minpsd+fgain-deltba-snroffset)>>5+4*exp */
Packit 64f477
	    /* min(mask+4*exp)=-156=-(sgain-deltba-snroffset)>>5 */
Packit 64f477
	    bap[j] = (baptab+156)[mask + 4 * exp[j]];
Packit 64f477
	} while (++j < endband);
Packit 64f477
    } while (j < end);
Packit 64f477
}