📄 ac3dec_bitallocation.cpp
字号:
/*////////////////////////////////////////////////////////////////////////////////// INTEL CORPORATION PROPRIETARY INFORMATION// This software is supplied under the terms of a license agreement or// nondisclosure agreement with Intel Corporation and may not be copied// or disclosed except in accordance with the terms of that agreement.// Copyright(c) 2002-2005 Intel Corporation. All Rights Reserved.//*/#include "umc_ac3_decoder.h"#include "ac3dec_tables.h"#include <math.h>/* In Linux function abs() declared in stdlib.h header*/#ifdef LINUX32#include <stdlib.h>#endif#include "ipps.h"#define min(a,b) (((a) < (b)) ? (a) : (b))#define max(a,b) (((a) > (b)) ? (a) : (b))int UMC::AC3Decoder::BitAllocation(int nblk){ Ipp16u i; short fgain; short snroffset; short start; short end; short fastleak; short slowleak;/* * Only perform bit_allocation if the exponents have changed or we have new * sideband information */ if (audblk[nblk]->chexpstr[0] == 0 && audblk[nblk]->chexpstr[1] == 0 && audblk[nblk]->chexpstr[2] == 0 && audblk[nblk]->chexpstr[3] == 0 && audblk[nblk]->chexpstr[4] == 0 && audblk[nblk]->cplexpstr == 0 && audblk[nblk]->lfeexpstr == 0 && audblk[nblk]->baie == 0 && audblk[nblk]->snroffste == 0 && audblk[nblk]->deltbaie == 0) return 0;/* * Do some setup before we do the bit alloc */ bit_alloc.sdecay = SLOWDEC[audblk[nblk]->sdcycod]; bit_alloc.fdecay = FASTDEC[audblk[nblk]->fdcycod]; bit_alloc.sgain = SLOWGAIN[audblk[nblk]->sgaincod]; bit_alloc.dbknee = DBPBTAB[audblk[nblk]->dbpbcod]; bit_alloc.floor = FLOORTAB[audblk[nblk]->floorcod];/* * if all the SNR offset constants are zero then the whole block is zero */ if (!audblk[nblk]->csnroffst && !audblk[nblk]->fsnroffst[0] && !audblk[nblk]->fsnroffst[1] && !audblk[nblk]->fsnroffst[2] && !audblk[nblk]->fsnroffst[3] && !audblk[nblk]->fsnroffst[4] && !audblk[nblk]->cplfsnroffst && !audblk[nblk]->lfefsnroffst) { ippsZero_8u((Ipp8u *)audblk[nblk]->fbw_bap, sizeof(Ipp16u) * 256 * 5); ippsZero_8u((Ipp8u *)audblk[nblk]->cpl_bap, sizeof(Ipp16u) * 256); ippsZero_8u((Ipp8u *)audblk[nblk]->lfe_bap, sizeof(Ipp16u) * 7); return 0; } for (i = 0; i < bsi.nfchans && i < 7; i++) { start = 0; end = audblk[nblk]->endmant[i];// ------------------ fgain = FASTGAIN[audblk[nblk]->fgaincod[i]]; snroffset = (short)((((audblk[nblk]->csnroffst - 15) << 4) + audblk[nblk]->fsnroffst[i]) << 2); fastleak = 0; slowleak = 0; baComputePsd(start, end, audblk[nblk]->fbw_exp[i], bit_alloc.psd, bit_alloc.bndpsd); baComputeExcitation(start, end, fgain, fastleak, slowleak, 0); baComputeMask(start, end, audblk[nblk]->deltnseg[i], audblk[nblk]->deltoffst[i], audblk[nblk]->deltba[i], audblk[nblk]->deltlen[i]); baComputeBap(start, end, snroffset, audblk[nblk]->fbw_bap[i]); } if (audblk[nblk]->cplinu) { start = audblk[nblk]->cplstrtmant; end = audblk[nblk]->cplendmant; fgain = FASTGAIN[audblk[nblk]->cplfgaincod]; snroffset = (short)((((audblk[nblk]->csnroffst - 15) << 4) + audblk[nblk]->cplfsnroffst) << 2); fastleak = (short)((audblk[nblk]->cplfleak << 8) + 768); slowleak = (short)((audblk[nblk]->cplsleak << 8) + 768); baComputePsd(start, end, audblk[nblk]->cpl_exp, bit_alloc.psd, bit_alloc.bndpsd); baComputeExcitation(start, end, fgain, fastleak, slowleak, 0); baComputeMask(start, end, audblk[nblk]->cpldeltnseg, audblk[nblk]->cpldeltoffst, audblk[nblk]->cpldeltba, audblk[nblk]->cpldeltlen); baComputeBap(start, end, snroffset, audblk[nblk]->cpl_bap); } if (bsi.lfeon) { start = 0; end = 7; fgain = FASTGAIN[audblk[nblk]->lfefgaincod]; snroffset = (short)((((audblk[nblk]->csnroffst - 15) << 4) + audblk[nblk]->lfefsnroffst) << 2); fastleak = 0; slowleak = 0; baComputePsd(start, end, audblk[nblk]->lfe_exp, bit_alloc.psd, bit_alloc.bndpsd); baComputeExcitation(start, end, fgain, fastleak, slowleak, 1);/* * Perform no delta bit allocation for lfe */ baComputeMask(start, end, 0, 0, 0, 0); baComputeBap(start, end, snroffset, audblk[nblk]->lfe_bap); } return 1;}void UMC::AC3Decoder::baComputePsd(short start, short end, Ipp16u *exps, short *psd, short *bndpsd){ int i, j, k; Ipp16s bin; Ipp16s lastbin = 0;/* * This step maps decoded exponents into a 13-bit signed log power-spectral * density function. */ for (bin = start; bin < end; bin++) { psd[bin] = (Ipp16s)(3072 - (exps[bin] << 7)); }/* * Integrate the psd function over each bit allocation band */ j = start; k = MASKTAB[start]; do { lastbin = (short)(min(BNDTAB[k] + BNDSZ[k], end)); bndpsd[k] = psd[j]; j++; for (i = j; i < lastbin; i++) { bndpsd[k] = baLogAdd(bndpsd[k], psd[j]); j++; } k++; } while (end > lastbin);}void UMC::AC3Decoder::baComputeExcitation(short start, short end, short fgain, short fastleak, short slowleak, short is_lfe){ Ipp16s bin; Ipp16s bndstrt; Ipp16s bndend; Ipp16s lowcomp = 0; Ipp16s begin = 0; Ipp16s *bndpsd = bit_alloc.bndpsd; Ipp16s *excite = bit_alloc.excite;/* * Compute excitation function */ bndstrt = MASKTAB[start]; bndend = (Ipp16s)(MASKTAB[end - 1] + 1); if (bndstrt == 0) { /* For fbw and lfe channels */ lowcomp = baCalcLowComp(lowcomp, bndpsd[0], bndpsd[1], 0); excite[0] = (Ipp16s)(bndpsd[0] - fgain - lowcomp); lowcomp = baCalcLowComp(lowcomp, bndpsd[1], bndpsd[2], 1); excite[1] = (Ipp16s)(bndpsd[1] - fgain - lowcomp); begin = 7;/* * Note: Do not call calc_lowcomp() for the last band of the lfe channel, (bin * = 6) */ for (bin = 2; bin < 7; bin++) { if (!(is_lfe && (bin == 6))) lowcomp = baCalcLowComp(lowcomp, bndpsd[bin], bndpsd[bin + 1], bin); fastleak = (Ipp16s)(bit_alloc.bndpsd[bin] - fgain); slowleak = (Ipp16s)(bit_alloc.bndpsd[bin] - bit_alloc.sgain); excite[bin] = (Ipp16s)(fastleak - lowcomp); if (!(is_lfe && (bin == 6))) { if (bndpsd[bin] <= bndpsd[bin + 1]) { begin = (Ipp16s)(bin + 1); break; } } } for (bin = begin; bin < min(bndend, 22); bin++) { if (!(is_lfe && (bin == 6))) lowcomp = baCalcLowComp(lowcomp, bndpsd[bin], bndpsd[bin + 1], bin); fastleak = fastleak - bit_alloc.fdecay; fastleak = (max(fastleak, (bndpsd[bin] - fgain))); slowleak = slowleak - bit_alloc.sdecay; slowleak = (max(slowleak, (bit_alloc.bndpsd[bin] - bit_alloc.sgain))); excite[bin] = (max((fastleak - lowcomp), slowleak)); } begin = 22; } else { /* For coupling channel */ begin = bndstrt; } for (bin = begin; bin < bndend; bin++) { fastleak = fastleak - bit_alloc.fdecay; fastleak = (max(fastleak, (bndpsd[bin] - fgain))); slowleak = slowleak - bit_alloc.sdecay; slowleak = (max(slowleak, (bndpsd[bin] - bit_alloc.sgain))); excite[bin] = (max(fastleak, slowleak)); }}void UMC::AC3Decoder::baComputeMask(short start, short end, Ipp16u deltnseg, Ipp16u *deltoffst, Ipp16u *deltba, Ipp16u *deltlen){ int bin, k, band, seg; Ipp16s bndstrt; Ipp16s bndend; Ipp16s delta; Ipp16u fscod = syncinfo.fscod; Ipp16s *excite = bit_alloc.excite; Ipp16s *mask = bit_alloc.mask; bndstrt = MASKTAB[start]; bndend = (Ipp16s)(MASKTAB[end - 1] + 1); /* Compute the masking curve */ for (bin = bndstrt; bin < bndend; bin++) { if (bit_alloc.bndpsd[bin] < bit_alloc.dbknee) { excite[bin] = excite[bin] + ((bit_alloc.dbknee - bit_alloc.bndpsd[bin]) >> 2); } mask[bin] = (short)(max(excite[bin], HTH[fscod][bin])); } /* Perform delta bit modulation if necessary */ band = bndstrt; for (seg = 0; seg < deltnseg; seg++) { band = band + (deltoffst[seg]); if (deltba[seg] >= 4) { delta = (Ipp16s)((deltba[seg] - 3) << 7); } else { delta = (Ipp16s)((deltba[seg] - 4) << 7); } for (k = 0; k < deltlen[seg]; k++) { mask[band & 0xff] = mask[band & 0xff] + delta; band++; } }}void UMC::AC3Decoder::baComputeBap(Ipp16s start, Ipp16s end, Ipp16s snroffset, Ipp16u *bap){ int i, j, k; Ipp16s lastbin = 0; Ipp16s address = 0; Ipp16s *psd = bit_alloc.psd; Ipp16s *mask = bit_alloc.mask;/* * Compute the bit allocation pointer for each bin */ i = start; j = MASKTAB[start]; do { lastbin = (Ipp16s)(min((BNDTAB[j] + BNDSZ[j]), end)); mask[j] = mask[j] - snroffset; mask[j] = mask[j] - bit_alloc.floor; if (mask[j] < 0) mask[j] = 0; mask[j] &= 0x1fe0; mask[j] = mask[j] + bit_alloc.floor; for (k = i; k < lastbin; k++) { address = (psd[i] - mask[j]) >> 5; address = min(63, max(0, address)); bap[i] = BAPTAB[address]; i++; } j++; } while (end > lastbin);}short UMC::AC3Decoder::baLogAdd(short a, short b){ Ipp16s c; Ipp16s address; c = (a - b); address = (Ipp16s)(min((abs(c) >> 1), 255)); if (c >= 0) return (a + LATAB[address]); return (b + LATAB[address]);}short UMC::AC3Decoder::baCalcLowComp(short a, short b0, short b1, short bin){ if (bin < 7) { if ((b0 + 256) == b1) a = 384; else if (b0 > b1) a = (Ipp16s)max(0, (a - 64)); } else if (bin < 20) { if ((b0 + 256) == b1) a = 320; else if (b0 > b1) a = (Ipp16s)max(0, (a - 64)); } else a = (Ipp16s)max(0, (a - 128)); return a;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -