Commit 6dc5d71f authored by Justin Ruggles's avatar Justin Ruggles

AC-3 decoder, soc revision 69, Aug 31 07:12:56 2006 UTC by cloud9

Fix the bugs:
1. The quality of output because of incorrect windowing coefficients.
New code for window generation.

2. Dynrng values were reset where dynrng value is present in the first block,
but not in the subsequent block.

Originally committed as revision 9667 to svn://svn.ffmpeg.org/ffmpeg/trunk
parent d7bcc4ad
...@@ -151,6 +151,8 @@ typedef struct { ...@@ -151,6 +151,8 @@ typedef struct {
int nfchans; int nfchans;
int lfeon; int lfeon;
float dynrng;
float dynrng2;
float chcoeffs[6]; float chcoeffs[6];
float cplco[5][18]; float cplco[5][18];
int ncplbnd; int ncplbnd;
...@@ -176,6 +178,7 @@ typedef struct { ...@@ -176,6 +178,7 @@ typedef struct {
DECLARE_ALIGNED_16(float, delay[MAX_CHANNELS][BLOCK_SIZE]); DECLARE_ALIGNED_16(float, delay[MAX_CHANNELS][BLOCK_SIZE]);
DECLARE_ALIGNED_16(float, tmp_imdct[BLOCK_SIZE]); DECLARE_ALIGNED_16(float, tmp_imdct[BLOCK_SIZE]);
DECLARE_ALIGNED_16(float, tmp_output[BLOCK_SIZE * 2]); DECLARE_ALIGNED_16(float, tmp_output[BLOCK_SIZE * 2]);
DECLARE_ALIGNED_16(float, window[BLOCK_SIZE]);
/* Miscellaneous. */ /* Miscellaneous. */
GetBitContext gb; GetBitContext gb;
...@@ -231,49 +234,29 @@ static inline int16_t dither_int16(dither_state *state) ...@@ -231,49 +234,29 @@ static inline int16_t dither_int16(dither_state *state)
/* END Mersenne Twister */ /* END Mersenne Twister */
/**
* Generate a Kaiser Window.
*/
static void
k_window_init(int alpha, float *window, int n, int iter)
{
int j, k;
float a, x;
a = alpha * M_PI / n;
a = a*a;
for(k=0; k<n; k++) {
x = k * (n - k) * a;
window[k] = 1.0;
for(j=iter; j>0; j--) {
window[k] = (window[k] * x / (j*j)) + 1.0;
}
}
}
/** /**
* Generate a Kaiser-Bessel Derived Window. * Generate a Kaiser-Bessel Derived Window.
* @param alpha determines window shape
* @param window array to fill with window values
* @param n length of the window
* @param iter number of iterations to use in BesselI0
*/ */
static void static void
kbd_window_init(int alpha, float *window, int n, int iter) ac3_window_init(float *window)
{ {
int k, n2; int i, j;
float *kwindow; double sum = 0.0, bessel, tmp;
double local_window[256];
n2 = n >> 1; double alpha2 = (5.0 * M_PI / 256.0) * (5.0 * M_PI / 256.0);
kwindow = &window[n2];
k_window_init(alpha, kwindow, n2, iter); for (i = 0; i < 256; i++) {
window[0] = kwindow[0]; tmp = i * (256 - i) * alpha2;
for(k=1; k<n2; k++) { bessel = 1.0;
window[k] = window[k-1] + kwindow[k]; for (j = 100; j > 0; j--) /* defaul to 100 iterations */
} bessel = bessel * tmp / (j * j) + 1;
for(k=0; k<n2; k++) { sum += bessel;
window[k] = sqrt(window[k] / (window[n2-1]+1)); local_window[i] = sum;
window[n-1-k] = window[k]; }
}
sum++;
for (i = 0; i < 256; i++)
window[i] = sqrt(local_window[i] / sum);
} }
static void generate_quantizers_table(int16_t quantizers[], int level, int length) static void generate_quantizers_table(int16_t quantizers[], int level, int length)
...@@ -385,9 +368,6 @@ static void ac3_tables_init(void) ...@@ -385,9 +368,6 @@ static void ac3_tables_init(void)
//for level-15 quantizers //for level-15 quantizers
generate_quantizers_table(l15_quantizers, 15, 15); generate_quantizers_table(l15_quantizers, 15, 15);
/* Kaiser-Bessel derived window. */
kbd_window_init(5, window, 256, 100);
} }
...@@ -398,6 +378,8 @@ static int ac3_decode_init(AVCodecContext *avctx) ...@@ -398,6 +378,8 @@ static int ac3_decode_init(AVCodecContext *avctx)
ac3_tables_init(); ac3_tables_init();
ff_mdct_init(&ctx->imdct_256, 8, 1); ff_mdct_init(&ctx->imdct_256, 8, 1);
ff_mdct_init(&ctx->imdct_512, 9, 1); ff_mdct_init(&ctx->imdct_512, 9, 1);
/* Kaiser-Bessel derived window. */
ac3_window_init(ctx->window);
dsputil_init(&ctx->dsp, avctx); dsputil_init(&ctx->dsp, avctx);
dither_seed(&ctx->dith_state, 0); dither_seed(&ctx->dith_state, 0);
...@@ -469,6 +451,8 @@ static void ac3_parse_bsi(AC3DecodeContext *ctx) ...@@ -469,6 +451,8 @@ static void ac3_parse_bsi(AC3DecodeContext *ctx)
ctx->deltbae[i] = AC3_DBASTR_NONE; ctx->deltbae[i] = AC3_DBASTR_NONE;
ctx->deltnseg[i] = 0; ctx->deltnseg[i] = 0;
} }
ctx->dynrng = 1.0;
ctx->dynrng2 = 1.0;
ctx->acmod = get_bits(gb, 3); ctx->acmod = get_bits(gb, 3);
ctx->nfchans = nfchans_tbl[ctx->acmod]; ctx->nfchans = nfchans_tbl[ctx->acmod];
...@@ -1075,6 +1059,15 @@ static void get_downmix_coeffs(AC3DecodeContext *ctx) ...@@ -1075,6 +1059,15 @@ static void get_downmix_coeffs(AC3DecodeContext *ctx)
float clev = clevs[ctx->cmixlev]; float clev = clevs[ctx->cmixlev];
float slev = slevs[ctx->surmixlev]; float slev = slevs[ctx->surmixlev];
float nf = 1.0; //normalization factor for downmix coeffs float nf = 1.0; //normalization factor for downmix coeffs
int i;
if (!ctx->acmod) {
ctx->chcoeffs[0] = 2 * ctx->dynrng;
ctx->chcoeffs[1] = 2 * ctx->dynrng2;
} else {
for (i = 0; i < ctx->nfchans; i++)
ctx->chcoeffs[i] = 2 * ctx->dynrng;
}
if (to == AC3_OUTPUT_UNMODIFIED) if (to == AC3_OUTPUT_UNMODIFIED)
return; return;
...@@ -1579,9 +1572,9 @@ static void do_imdct_256(AC3DecodeContext *ctx, int chindex) ...@@ -1579,9 +1572,9 @@ static void do_imdct_256(AC3DecodeContext *ctx, int chindex)
ff_imdct_calc(&ctx->imdct_256, ctx->tmp_output + 256, x2, ctx->tmp_imdct); ff_imdct_calc(&ctx->imdct_256, ctx->tmp_output + 256, x2, ctx->tmp_imdct);
ptr = ctx->output[chindex]; ptr = ctx->output[chindex];
ctx->dsp.vector_fmul_add_add(ptr, ctx->tmp_output, window, ctx->delay[chindex], 384, BLOCK_SIZE, 1); ctx->dsp.vector_fmul_add_add(ptr, ctx->tmp_output, ctx->window, ctx->delay[chindex], 384, BLOCK_SIZE, 1);
ptr = ctx->delay[chindex]; ptr = ctx->delay[chindex];
ctx->dsp.vector_fmul_reverse(ptr, ctx->tmp_output + 256, window, BLOCK_SIZE); ctx->dsp.vector_fmul_reverse(ptr, ctx->tmp_output + 256, ctx->window, BLOCK_SIZE);
} }
static void do_imdct_512(AC3DecodeContext *ctx, int chindex) static void do_imdct_512(AC3DecodeContext *ctx, int chindex)
...@@ -1591,9 +1584,9 @@ static void do_imdct_512(AC3DecodeContext *ctx, int chindex) ...@@ -1591,9 +1584,9 @@ static void do_imdct_512(AC3DecodeContext *ctx, int chindex)
ff_imdct_calc(&ctx->imdct_512, ctx->tmp_output, ff_imdct_calc(&ctx->imdct_512, ctx->tmp_output,
ctx->transform_coeffs[chindex], ctx->tmp_imdct); ctx->transform_coeffs[chindex], ctx->tmp_imdct);
ptr = ctx->output[chindex]; ptr = ctx->output[chindex];
ctx->dsp.vector_fmul_add_add(ptr, ctx->tmp_output, window, ctx->delay[chindex], 384, BLOCK_SIZE, 1); ctx->dsp.vector_fmul_add_add(ptr, ctx->tmp_output, ctx->window, ctx->delay[chindex], 384, BLOCK_SIZE, 1);
ptr = ctx->delay[chindex]; ptr = ctx->delay[chindex];
ctx->dsp.vector_fmul_reverse(ptr, ctx->tmp_output + 256, window, BLOCK_SIZE); ctx->dsp.vector_fmul_reverse(ptr, ctx->tmp_output + 256, ctx->window, BLOCK_SIZE);
} }
static inline void do_imdct(AC3DecodeContext *ctx) static inline void do_imdct(AC3DecodeContext *ctx)
...@@ -1623,9 +1616,6 @@ static int ac3_parse_audio_block(AC3DecodeContext * ctx) ...@@ -1623,9 +1616,6 @@ static int ac3_parse_audio_block(AC3DecodeContext * ctx)
int mstrcplco, cplcoexp, cplcomant; int mstrcplco, cplcoexp, cplcomant;
int dynrng, chbwcod, ngrps, cplabsexp, skipl; int dynrng, chbwcod, ngrps, cplabsexp, skipl;
for (i = 0; i < 5; i++)
ctx->chcoeffs[i] = 2.0;
ctx->blksw = 0; ctx->blksw = 0;
for (i = 0; i < nfchans; i++) /*block switch flag */ for (i = 0; i < nfchans; i++) /*block switch flag */
ctx->blksw |= get_bits1(gb) << i; ctx->blksw |= get_bits1(gb) << i;
...@@ -1636,15 +1626,12 @@ static int ac3_parse_audio_block(AC3DecodeContext * ctx) ...@@ -1636,15 +1626,12 @@ static int ac3_parse_audio_block(AC3DecodeContext * ctx)
if (get_bits1(gb)) { /* dynamic range */ if (get_bits1(gb)) { /* dynamic range */
dynrng = get_sbits(gb, 8); dynrng = get_sbits(gb, 8);
drange = ((((dynrng & 0x1f) | 0x20) << 13) * scale_factors[3 - (dynrng >> 5)]); ctx->dynrng = ((((dynrng & 0x1f) | 0x20) << 13) * scale_factors[3 - (dynrng >> 5)]);
for (i = 0; i < nfchans; i++)
ctx->chcoeffs[i] *= drange;
} }
if (acmod == 0x00 && get_bits1(gb)) { /* dynamic range 1+1 mode */ if (acmod == 0x00 && get_bits1(gb)) { /* dynamic range 1+1 mode */
dynrng = get_sbits(gb, 8); dynrng = get_sbits(gb, 8);
drange = ((((dynrng & 0x1f) | 0x20) << 13) * scale_factors[3 - (dynrng >> 5)]); ctx->dynrng2 = ((((dynrng & 0x1f) | 0x20) << 13) * scale_factors[3 - (dynrng >> 5)]);
ctx->chcoeffs[1] *= drange;
} }
get_downmix_coeffs(ctx); get_downmix_coeffs(ctx);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment