# HG changeset patch # User bellard # Date 1035765545 0 # Node ID dd7d5748d0642d7dca4b09284c5cedb400085d23 # Parent 6f5e87957bcb2d16694a2a9ad24876acd566c3d5 preparing integration of new AC3 decoder diff -r 6f5e87957bcb -r dd7d5748d064 ac3.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ac3.h Mon Oct 28 00:39:05 2002 +0000 @@ -0,0 +1,56 @@ +/* + * Common code between AC3 encoder and decoder + * Copyright (c) 2000, 2001, 2002 Fabrice Bellard. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#define AC3_MAX_CODED_FRAME_SIZE 3840 /* in bytes */ +#define AC3_MAX_CHANNELS 6 /* including LFE channel */ + +#define NB_BLOCKS 6 /* number of PCM blocks inside an AC3 frame */ +#define AC3_FRAME_SIZE (NB_BLOCKS * 256) + +/* exponent encoding strategy */ +#define EXP_REUSE 0 +#define EXP_NEW 1 + +#define EXP_D15 1 +#define EXP_D25 2 +#define EXP_D45 3 + +typedef struct AC3BitAllocParameters { + int fscod; /* frequency */ + int halfratecod; + int sgain, sdecay, fdecay, dbknee, floor; + int cplfleak, cplsleak; +} AC3BitAllocParameters; + +extern const UINT16 ac3_freqs[3]; +extern const UINT16 ac3_bitratetab[19]; +extern const INT16 ac3_window[256]; +extern const UINT8 sdecaytab[4]; +extern const UINT8 fdecaytab[4]; +extern const UINT16 sgaintab[4]; +extern const UINT16 dbkneetab[4]; +extern const UINT16 floortab[8]; +extern const UINT16 fgaintab[8]; + +void ac3_common_init(void); +void ac3_parametric_bit_allocation(AC3BitAllocParameters *s, UINT8 *bap, + INT8 *exp, int start, int end, + int snroffset, int fgain, int is_lfe, + int deltbae,int deltnseg, + UINT8 *deltoffst, UINT8 *deltlen, UINT8 *deltba); diff -r 6f5e87957bcb -r dd7d5748d064 ac3enc.c --- a/ac3enc.c Mon Oct 28 00:34:08 2002 +0000 +++ b/ac3enc.c Mon Oct 28 00:39:05 2002 +0000 @@ -20,25 +20,46 @@ //#define DEBUG_BITALLOC #include "avcodec.h" -#include "ac3enc.h" +#include "ac3.h" + +typedef struct AC3EncodeContext { + PutBitContext pb; + int nb_channels; + int nb_all_channels; + int lfe_channel; + int bit_rate; + int sample_rate; + int bsid; + int frame_size_min; /* minimum frame size in case rounding is necessary */ + int frame_size; /* current frame size in words */ + int halfratecod; + int frmsizecod; + int fscod; /* frequency */ + int acmod; + int lfe; + int bsmod; + short last_samples[AC3_MAX_CHANNELS][256]; + int chbwcod[AC3_MAX_CHANNELS]; + int nb_coefs[AC3_MAX_CHANNELS]; + + /* bitrate allocation control */ + int sgaincod, sdecaycod, fdecaycod, dbkneecod, floorcod; + AC3BitAllocParameters bit_alloc; + int csnroffst; + int fgaincod[AC3_MAX_CHANNELS]; + int fsnroffst[AC3_MAX_CHANNELS]; + /* mantissa encoding */ + int mant1_cnt, mant2_cnt, mant4_cnt; +} AC3EncodeContext; + #include "ac3tab.h" - #define MDCT_NBITS 9 #define N (1 << MDCT_NBITS) -#define NB_BLOCKS 6 /* number of PCM blocks inside an AC3 frame */ /* new exponents are sent if their Norm 1 exceed this number */ #define EXP_DIFF_THRESHOLD 1000 -/* exponent encoding strategy */ -#define EXP_REUSE 0 -#define EXP_NEW 1 - -#define EXP_D15 1 -#define EXP_D25 2 -#define EXP_D45 3 - static void fft_init(int ln); static void ac3_crc_init(void); @@ -88,11 +109,12 @@ } /* AC3 bit allocation. The algorithm is the one described in the AC3 - spec with some optimizations because of our simplified encoding - assumptions. */ -void parametric_bit_allocation(AC3EncodeContext *s, UINT8 *bap, - INT8 *exp, int start, int end, - int snroffset, int fgain, int is_lfe) + spec. */ +void ac3_parametric_bit_allocation(AC3BitAllocParameters *s, UINT8 *bap, + INT8 *exp, int start, int end, + int snroffset, int fgain, int is_lfe, + int deltbae,int deltnseg, + UINT8 *deltoffst, UINT8 *deltlen, UINT8 *deltba) { int bin,i,j,k,end1,v,v1,bndstrt,bndend,lowcomp,begin; int fastleak,slowleak,address,tmp; @@ -138,48 +160,57 @@ bndstrt = masktab[start]; bndend = masktab[end-1] + 1; - lowcomp = 0; - lowcomp = calc_lowcomp1(lowcomp, bndpsd[0], bndpsd[1]) ; - excite[0] = bndpsd[0] - fgain - lowcomp ; - lowcomp = calc_lowcomp1(lowcomp, bndpsd[1], bndpsd[2]) ; - excite[1] = bndpsd[1] - fgain - lowcomp ; - begin = 7 ; - for (bin = 2; bin < 7; bin++) { - if (!(is_lfe && bin == 6)) - lowcomp = calc_lowcomp1(lowcomp, bndpsd[bin], bndpsd[bin+1]) ; - fastleak = bndpsd[bin] - fgain ; - slowleak = bndpsd[bin] - s->sgain ; - excite[bin] = fastleak - lowcomp ; - if (!(is_lfe && bin == 6)) { - if (bndpsd[bin] <= bndpsd[bin+1]) { - begin = bin + 1 ; - break ; - } - } - } + if (bndstrt == 0) { + lowcomp = 0; + lowcomp = calc_lowcomp1(lowcomp, bndpsd[0], bndpsd[1]) ; + excite[0] = bndpsd[0] - fgain - lowcomp ; + lowcomp = calc_lowcomp1(lowcomp, bndpsd[1], bndpsd[2]) ; + excite[1] = bndpsd[1] - fgain - lowcomp ; + begin = 7 ; + for (bin = 2; bin < 7; bin++) { + if (!(is_lfe && bin == 6)) + lowcomp = calc_lowcomp1(lowcomp, bndpsd[bin], bndpsd[bin+1]) ; + fastleak = bndpsd[bin] - fgain ; + slowleak = bndpsd[bin] - s->sgain ; + excite[bin] = fastleak - lowcomp ; + if (!(is_lfe && bin == 6)) { + if (bndpsd[bin] <= bndpsd[bin+1]) { + begin = bin + 1 ; + break ; + } + } + } + + end1=bndend; + if (end1 > 22) end1=22; - end1=bndend; - if (end1 > 22) end1=22; - - for (bin = begin; bin < end1; bin++) { - if (!(is_lfe && bin == 6)) - lowcomp = calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin+1], bin) ; + for (bin = begin; bin < end1; bin++) { + if (!(is_lfe && bin == 6)) + lowcomp = calc_lowcomp(lowcomp, bndpsd[bin], bndpsd[bin+1], bin) ; + + fastleak -= s->fdecay ; + v = bndpsd[bin] - fgain; + if (fastleak < v) fastleak = v; + + slowleak -= s->sdecay ; + v = bndpsd[bin] - s->sgain; + if (slowleak < v) slowleak = v; - fastleak -= s->fdecay ; - v = bndpsd[bin] - fgain; - if (fastleak < v) fastleak = v; + v=fastleak - lowcomp; + if (slowleak > v) v=slowleak; - slowleak -= s->sdecay ; - v = bndpsd[bin] - s->sgain; - if (slowleak < v) slowleak = v; + excite[bin] = v; + } + begin = 22; + } else { + /* coupling channel */ + begin = bndstrt; - v=fastleak - lowcomp; - if (slowleak > v) v=slowleak; - - excite[bin] = v; + fastleak = (s->cplfleak << 8) + 768; + slowleak = (s->cplsleak << 8) + 768; } - for (bin = 22; bin < bndend; bin++) { + for (bin = begin; bin < bndend; bin++) { fastleak -= s->fdecay ; v = bndpsd[bin] - fgain; if (fastleak < v) fastleak = v; @@ -205,6 +236,25 @@ mask[bin] = v; } + /* delta bit allocation */ + + if (deltbae == 0 || deltbae == 1) { + int band, seg, delta; + band = 0 ; + for (seg = 0; seg < deltnseg; seg++) { + band += deltoffst[seg] ; + if (deltba[seg] >= 4) { + delta = (deltba[seg] - 3) << 7; + } else { + delta = (deltba[seg] - 4) << 7; + } + for (k = 0; k < deltlen[seg]; k++) { + mask[band] += delta ; + band++ ; + } + } + } + /* compute bit allocation */ i = start ; @@ -600,12 +650,14 @@ s->mant2_cnt = 0; s->mant4_cnt = 0; for(ch=0;chnb_all_channels;ch++) { - parametric_bit_allocation(s, bap[i][ch], (INT8 *)encoded_exp[i][ch], - 0, s->nb_coefs[ch], - (((csnroffst-15) << 4) + - fsnroffst) << 2, - fgaintab[s->fgaincod[ch]], - ch == s->lfe_channel); + ac3_parametric_bit_allocation(&s->bit_alloc, + bap[i][ch], (INT8 *)encoded_exp[i][ch], + 0, s->nb_coefs[ch], + (((csnroffst-15) << 4) + + fsnroffst) << 2, + fgaintab[s->fgaincod[ch]], + ch == s->lfe_channel, + 2, 0, NULL, NULL, NULL); frame_bits += compute_mantissa_size(s, bap[i][ch], s->nb_coefs[ch]); } @@ -641,12 +693,14 @@ s->fgaincod[ch] = 4; /* compute real values */ - s->sdecay = sdecaytab[s->sdecaycod] >> s->halfratecod; - s->fdecay = fdecaytab[s->fdecaycod] >> s->halfratecod; - s->sgain = sgaintab[s->sgaincod]; - s->dbknee = dbkneetab[s->dbkneecod]; - s->floor = floortab[s->floorcod]; - + s->bit_alloc.fscod = s->fscod; + s->bit_alloc.halfratecod = s->halfratecod; + s->bit_alloc.sdecay = sdecaytab[s->sdecaycod] >> s->halfratecod; + s->bit_alloc.fdecay = fdecaytab[s->fdecaycod] >> s->halfratecod; + s->bit_alloc.sgain = sgaintab[s->sgaincod]; + s->bit_alloc.dbknee = dbkneetab[s->dbkneecod]; + s->bit_alloc.floor = floortab[s->floorcod]; + /* header size */ frame_bits += 65; // if (s->acmod == 2) @@ -738,16 +792,31 @@ return 0; } +void ac3_common_init(void) +{ + int i, j, k, l, v; + /* compute bndtab and masktab from bandsz */ + k = 0; + l = 0; + for(i=0;i<50;i++) { + bndtab[i] = l; + v = bndsz[i]; + for(j=0;jsample_rate; int bitrate = avctx->bit_rate; int channels = avctx->channels; AC3EncodeContext *s = avctx->priv_data; - int i, j, k, l, ch, v; + int i, j, ch; float alpha; - static unsigned short freqs[3] = { 48000, 44100, 32000 }; - static int acmod_defs[6] = { + static const UINT8 acmod_defs[6] = { 0x01, /* C */ 0x02, /* L R */ 0x03, /* L C R */ @@ -771,7 +840,7 @@ /* frequency */ for(i=0;i<3;i++) { for(j=0;j<3;j++) - if ((freqs[j] >> i) == freq) + if ((ac3_freqs[j] >> i) == freq) goto found; } return -1; @@ -785,7 +854,7 @@ /* bitrate & frame size */ bitrate /= 1000; for(i=0;i<19;i++) { - if ((bitratetab[i] >> s->halfratecod) == bitrate) + if ((ac3_bitratetab[i] >> s->halfratecod) == bitrate) break; } if (i == 19) @@ -810,16 +879,7 @@ /* initial snr offset */ s->csnroffst = 40; - /* compute bndtab and masktab from bandsz */ - k = 0; - l = 0; - for(i=0;i<50;i++) { - bndtab[i] = l; - v = bndsz[i]; - for(j=0;jpriv_data; short *samples = data; diff -r 6f5e87957bcb -r dd7d5748d064 ac3enc.h --- a/ac3enc.h Mon Oct 28 00:34:08 2002 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,34 +0,0 @@ - -#define AC3_FRAME_SIZE (6*256) -#define AC3_MAX_CODED_FRAME_SIZE 3840 /* in bytes */ -#define AC3_MAX_CHANNELS 6 - -typedef struct AC3EncodeContext { - PutBitContext pb; - int nb_channels; - int nb_all_channels; - int lfe_channel; - int bit_rate; - int sample_rate; - int bsid; - int frame_size_min; /* minimum frame size in case rounding is necessary */ - int frame_size; /* current frame size in words */ - int halfratecod; - int frmsizecod; - int fscod; /* frequency */ - int acmod; - int lfe; - int bsmod; - short last_samples[AC3_MAX_CHANNELS][256]; - int chbwcod[AC3_MAX_CHANNELS]; - int nb_coefs[AC3_MAX_CHANNELS]; - - /* bitrate allocation control */ - int sgaincod, sdecaycod, fdecaycod, dbkneecod, floorcod; - int sgain, sdecay, fdecay, dbknee, floor; - int csnroffst; - int fgaincod[AC3_MAX_CHANNELS]; - int fsnroffst[AC3_MAX_CHANNELS]; - /* mantissa encoding */ - int mant1_cnt, mant2_cnt, mant4_cnt; -} AC3EncodeContext; diff -r 6f5e87957bcb -r dd7d5748d064 ac3tab.h --- a/ac3tab.h Mon Oct 28 00:34:08 2002 +0000 +++ b/ac3tab.h Mon Oct 28 00:39:05 2002 +0000 @@ -1,7 +1,10 @@ /* tables taken directly from AC3 spec */ +/* possible frequencies */ +const UINT16 ac3_freqs[3] = { 48000, 44100, 32000 }; + /* possible bitrates */ -static const UINT16 bitratetab[19] = { +const UINT16 ac3_bitratetab[19] = { 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 448, 512, 576, 640 }; @@ -9,7 +12,7 @@ /* AC3 MDCT window */ /* MDCT window */ -static const INT16 ac3_window[256]= { +const INT16 ac3_window[256] = { 4, 7, 12, 16, 21, 28, 34, 42, 51, 61, 72, 84, 97, 111, 127, 145, 164, 184, 207, 231, 257, 285, 315, 347, @@ -138,27 +141,27 @@ 15, 15, 15, 15, }; -static const UINT8 sdecaytab[4]={ +const UINT8 sdecaytab[4]={ 0x0f, 0x11, 0x13, 0x15, }; -static const UINT8 fdecaytab[4]={ +const UINT8 fdecaytab[4]={ 0x3f, 0x53, 0x67, 0x7b, }; -static const UINT16 sgaintab[4]= { +const UINT16 sgaintab[4]= { 0x540, 0x4d8, 0x478, 0x410, }; -static const UINT16 dbkneetab[4]= { +const UINT16 dbkneetab[4]= { 0x000, 0x700, 0x900, 0xb00, }; -static const UINT16 floortab[8]= { +const UINT16 floortab[8]= { 0x2f0, 0x2b0, 0x270, 0x230, 0x1f0, 0x170, 0x0f0, 0xf800, }; -static const UINT16 fgaintab[8]= { +const UINT16 fgaintab[8]= { 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0x400, };