mirror of https://git.ffmpeg.org/ffmpeg.git
AC-3 decoder, soc revision 48, Aug 16 11:27:49 2006 UTC by cloud9
I realized that the bug was not in the imdct routine but in the get_transform_coeffs. Fixed it. Code now uses the ffmpeg's imdct routines. All the mplayer's ac3 samples are decoded successfully. Also improved downmixing. Now all the downmixing coeffcients for channels are normalized such that the sum of coefficients used to construct the output for single channel never exceeds 1.0. Originally committed as revision 9659 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
2fbbd087bb
commit
45b0ed13a8
|
@ -34,6 +34,7 @@
|
|||
#include "avutil.h"
|
||||
#include "common.h"
|
||||
#include "math.h"
|
||||
#include "crc.h"
|
||||
|
||||
#define N 512 /* constant for IMDCT Block size */
|
||||
|
||||
|
@ -158,8 +159,8 @@ typedef struct {
|
|||
DECLARE_ALIGNED_16(float, transform_coeffs[MAX_CHANNELS][BLOCK_SIZE]);
|
||||
|
||||
/* For IMDCT. */
|
||||
FFTContext fft_64; //N/8 point IFFT context
|
||||
FFTContext fft_128; //N/4 point IFFT context
|
||||
MDCTContext imdct_512; //N/8 point IFFT context
|
||||
MDCTContext imdct_256; //N/4 point IFFT context
|
||||
DECLARE_ALIGNED_16(float, output[MAX_CHANNELS][BLOCK_SIZE]);
|
||||
DECLARE_ALIGNED_16(float, delay[MAX_CHANNELS][BLOCK_SIZE]);
|
||||
DECLARE_ALIGNED_16(float, tmp_imdct[BLOCK_SIZE]);
|
||||
|
@ -398,8 +399,8 @@ static int ac3_decode_init(AVCodecContext *avctx)
|
|||
AC3DecodeContext *ctx = avctx->priv_data;
|
||||
|
||||
ac3_tables_init();
|
||||
ff_fft_init(&ctx->fft_64, 6, 1);
|
||||
ff_fft_init(&ctx->fft_128, 7, 1);
|
||||
ff_mdct_init(&ctx->imdct_256, 8, 1);
|
||||
ff_mdct_init(&ctx->imdct_512, 9, 1);
|
||||
dither_seed(&ctx->dith_state, 0);
|
||||
|
||||
return 0;
|
||||
|
@ -838,9 +839,9 @@ static int get_transform_coeffs_cpling(AC3DecodeContext *ctx, mant_groups *m)
|
|||
case 0:
|
||||
for (ch = 0; ch < ctx->nfchans; ch++)
|
||||
if (((ctx->chincpl) >> ch) & 1) {
|
||||
if (!(((ctx->dithflag) >> ch) & 1)) {
|
||||
if ((ctx->dithflag >> ch) & 1) {
|
||||
TRANSFORM_COEFF(cplcoeff, dither_int16(&ctx->dith_state), exps[start], scale_factors);
|
||||
ctx->transform_coeffs[ch + 1][start] = cplcoeff * cplcos[ch];
|
||||
ctx->transform_coeffs[ch + 1][start] = cplcoeff * cplcos[ch] * LEVEL_MINUS_3DB;
|
||||
} else
|
||||
ctx->transform_coeffs[ch + 1][start] = 0;
|
||||
}
|
||||
|
@ -887,7 +888,7 @@ static int get_transform_coeffs_cpling(AC3DecodeContext *ctx, mant_groups *m)
|
|||
break;
|
||||
|
||||
default:
|
||||
TRANSFORM_COEFF(cplcoeff, get_bits(gb, qntztab[tbap]) << (16 - qntztab[tbap]),
|
||||
TRANSFORM_COEFF(cplcoeff, get_sbits(gb, qntztab[tbap]) << (16 - qntztab[tbap]),
|
||||
exps[start], scale_factors);
|
||||
}
|
||||
for (ch = 0; ch < ctx->nfchans; ch++)
|
||||
|
@ -932,13 +933,13 @@ static int get_transform_coeffs_ch(AC3DecodeContext *ctx, int ch_index, mant_gro
|
|||
tbap = bap[i];
|
||||
switch (tbap) {
|
||||
case 0:
|
||||
if (dithflag) {
|
||||
if (!dithflag) {
|
||||
coeffs[i] = 0;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
TRANSFORM_COEFF(coeffs[i], dither_int16(&ctx->dith_state), exps[i], factors);
|
||||
coeffs[i] *= LEVEL_PLUS_3DB;
|
||||
coeffs[i] *= LEVEL_MINUS_3DB;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -983,7 +984,7 @@ static int get_transform_coeffs_ch(AC3DecodeContext *ctx, int ch_index, mant_gro
|
|||
continue;
|
||||
|
||||
default:
|
||||
TRANSFORM_COEFF(coeffs[i], get_bits(gb, qntztab[tbap]) << (16 - qntztab[tbap]), exps[i], factors);
|
||||
TRANSFORM_COEFF(coeffs[i], get_sbits(gb, qntztab[tbap]) << (16 - qntztab[tbap]), exps[i], factors);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -1075,6 +1076,7 @@ static void get_downmix_coeffs(AC3DecodeContext *ctx)
|
|||
int to = ctx->blkoutput;
|
||||
float clev = clevs[ctx->cmixlev];
|
||||
float slev = slevs[ctx->surmixlev];
|
||||
float nf = 1.0; //normalization factor for downmix coeffs
|
||||
|
||||
if (to == AC3_OUTPUT_UNMODIFIED)
|
||||
return;
|
||||
|
@ -1084,107 +1086,142 @@ static void get_downmix_coeffs(AC3DecodeContext *ctx)
|
|||
switch (to) {
|
||||
case AC3_OUTPUT_MONO:
|
||||
case AC3_OUTPUT_STEREO: /* We Assume that sum of both mono channels is requested */
|
||||
ctx->chcoeffs[0] *= LEVEL_MINUS_6DB;
|
||||
ctx->chcoeffs[1] *= LEVEL_MINUS_6DB;
|
||||
nf = 0.5;
|
||||
ctx->chcoeffs[0] *= nf;
|
||||
ctx->chcoeffs[1] *= nf;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AC3_INPUT_MONO:
|
||||
switch (to) {
|
||||
case AC3_OUTPUT_STEREO:
|
||||
ctx->chcoeffs[0] *= LEVEL_MINUS_3DB;
|
||||
nf = LEVEL_MINUS_3DB;
|
||||
ctx->chcoeffs[0] *= nf;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AC3_INPUT_STEREO:
|
||||
switch (to) {
|
||||
case AC3_OUTPUT_MONO:
|
||||
ctx->chcoeffs[0] *= LEVEL_MINUS_3DB;
|
||||
ctx->chcoeffs[1] *= LEVEL_MINUS_3DB;
|
||||
nf = LEVEL_MINUS_3DB;
|
||||
ctx->chcoeffs[0] *= nf;
|
||||
ctx->chcoeffs[1] *= nf;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AC3_INPUT_3F:
|
||||
switch (to) {
|
||||
case AC3_OUTPUT_MONO:
|
||||
ctx->chcoeffs[0] *= LEVEL_MINUS_3DB;
|
||||
ctx->chcoeffs[2] *= LEVEL_MINUS_3DB;
|
||||
ctx->chcoeffs[1] *= (clev * LEVEL_PLUS_3DB);
|
||||
nf = LEVEL_MINUS_3DB / (1.0 + clev);
|
||||
ctx->chcoeffs[0] *= (nf * LEVEL_MINUS_3DB);
|
||||
ctx->chcoeffs[2] *= (nf * LEVEL_MINUS_3DB);
|
||||
ctx->chcoeffs[1] *= ((nf * clev * LEVEL_MINUS_3DB) / 2.0);
|
||||
break;
|
||||
case AC3_OUTPUT_STEREO:
|
||||
ctx->chcoeffs[1] *= clev;
|
||||
nf = 1.0 / (1.0 + clev);
|
||||
ctx->chcoeffs[0] *= nf;
|
||||
ctx->chcoeffs[2] *= nf;
|
||||
ctx->chcoeffs[1] *= (nf * clev);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AC3_INPUT_2F_1R:
|
||||
switch (to) {
|
||||
case AC3_OUTPUT_MONO:
|
||||
ctx->chcoeffs[0] *= LEVEL_MINUS_3DB;
|
||||
ctx->chcoeffs[1] *= LEVEL_MINUS_3DB;
|
||||
ctx->chcoeffs[2] *= slev * LEVEL_MINUS_3DB;
|
||||
nf = 2.0 * LEVEL_MINUS_3DB / (2.0 + slev);
|
||||
ctx->chcoeffs[0] *= (nf * LEVEL_MINUS_3DB);
|
||||
ctx->chcoeffs[1] *= (nf * LEVEL_MINUS_3DB);
|
||||
ctx->chcoeffs[2] *= (nf * slev * LEVEL_MINUS_3DB);
|
||||
break;
|
||||
case AC3_OUTPUT_STEREO:
|
||||
ctx->chcoeffs[2] *= slev * LEVEL_MINUS_3DB;
|
||||
nf = 1.0 / (1.0 + (slev * LEVEL_MINUS_3DB));
|
||||
ctx->chcoeffs[0] *= nf;
|
||||
ctx->chcoeffs[1] *= nf;
|
||||
ctx->chcoeffs[2] *= (nf * slev * LEVEL_MINUS_3DB);
|
||||
break;
|
||||
case AC3_OUTPUT_DOLBY:
|
||||
ctx->chcoeffs[2] *= LEVEL_MINUS_3DB;
|
||||
nf = 1.0 / (1.0 + LEVEL_MINUS_3DB);
|
||||
ctx->chcoeffs[0] *= nf;
|
||||
ctx->chcoeffs[1] *= nf;
|
||||
ctx->chcoeffs[2] *= (nf * LEVEL_MINUS_3DB);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AC3_INPUT_3F_1R:
|
||||
switch (to) {
|
||||
case AC3_OUTPUT_MONO:
|
||||
ctx->chcoeffs[0] *= LEVEL_MINUS_3DB;
|
||||
ctx->chcoeffs[2] *= LEVEL_MINUS_3DB;
|
||||
ctx->chcoeffs[1] *= clev * LEVEL_PLUS_3DB;
|
||||
ctx->chcoeffs[3] *= slev * LEVEL_MINUS_3DB;
|
||||
nf = LEVEL_MINUS_3DB / (1.0 + clev + (slev / 2.0));
|
||||
ctx->chcoeffs[0] *= (nf * LEVEL_MINUS_3DB);
|
||||
ctx->chcoeffs[2] *= (nf * LEVEL_MINUS_3DB);
|
||||
ctx->chcoeffs[1] *= (nf * clev * LEVEL_PLUS_3DB);
|
||||
ctx->chcoeffs[3] *= (nf * slev * LEVEL_MINUS_3DB);
|
||||
break;
|
||||
case AC3_OUTPUT_STEREO:
|
||||
ctx->chcoeffs[1] *= clev;
|
||||
ctx->chcoeffs[3] *= slev * LEVEL_MINUS_3DB;
|
||||
nf = 1.0 / (1.0 + clev + (slev * LEVEL_MINUS_3DB));
|
||||
ctx->chcoeffs[0] *= nf;
|
||||
ctx->chcoeffs[2] *= nf;
|
||||
ctx->chcoeffs[1] *= (nf * clev);
|
||||
ctx->chcoeffs[3] *= (nf * slev * LEVEL_MINUS_3DB);
|
||||
break;
|
||||
case AC3_OUTPUT_DOLBY:
|
||||
ctx->chcoeffs[1] *= LEVEL_MINUS_3DB;
|
||||
ctx->chcoeffs[3] *= LEVEL_MINUS_3DB;
|
||||
nf = 1.0 / (1.0 + (2.0 * LEVEL_MINUS_3DB));
|
||||
ctx->chcoeffs[0] *= nf;
|
||||
ctx->chcoeffs[1] *= nf;
|
||||
ctx->chcoeffs[1] *= (nf * LEVEL_MINUS_3DB);
|
||||
ctx->chcoeffs[3] *= (nf * LEVEL_MINUS_3DB);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AC3_INPUT_2F_2R:
|
||||
switch (to) {
|
||||
case AC3_OUTPUT_MONO:
|
||||
ctx->chcoeffs[0] *= LEVEL_MINUS_3DB;
|
||||
ctx->chcoeffs[1] *= LEVEL_MINUS_3DB;
|
||||
ctx->chcoeffs[2] *= slev * LEVEL_MINUS_3DB;
|
||||
ctx->chcoeffs[3] *= slev * LEVEL_MINUS_3DB;
|
||||
nf = LEVEL_MINUS_3DB / (1.0 + slev);
|
||||
ctx->chcoeffs[0] *= (nf * LEVEL_MINUS_3DB);
|
||||
ctx->chcoeffs[1] *= (nf * LEVEL_MINUS_3DB);
|
||||
ctx->chcoeffs[2] *= (nf * slev * LEVEL_MINUS_3DB);
|
||||
ctx->chcoeffs[3] *= (nf * slev * LEVEL_MINUS_3DB);
|
||||
break;
|
||||
case AC3_OUTPUT_STEREO:
|
||||
ctx->chcoeffs[2] *= slev;
|
||||
ctx->chcoeffs[3] *= slev;
|
||||
nf = 1.0 / (1.0 + slev);
|
||||
ctx->chcoeffs[0] *= nf;
|
||||
ctx->chcoeffs[1] *= nf;
|
||||
ctx->chcoeffs[2] *= (nf * slev);
|
||||
ctx->chcoeffs[3] *= (nf * slev);
|
||||
break;
|
||||
case AC3_OUTPUT_DOLBY:
|
||||
ctx->chcoeffs[2] *= LEVEL_MINUS_3DB;
|
||||
ctx->chcoeffs[3] *= LEVEL_MINUS_3DB;
|
||||
nf = 1.0 / (1.0 + (2.0 * LEVEL_MINUS_3DB));
|
||||
ctx->chcoeffs[0] *= nf;
|
||||
ctx->chcoeffs[1] *= nf;
|
||||
ctx->chcoeffs[2] *= (nf * LEVEL_MINUS_3DB);
|
||||
ctx->chcoeffs[3] *= (nf * LEVEL_MINUS_3DB);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case AC3_INPUT_3F_2R:
|
||||
switch (to) {
|
||||
case AC3_OUTPUT_MONO:
|
||||
ctx->chcoeffs[0] *= LEVEL_MINUS_3DB;
|
||||
ctx->chcoeffs[2] *= LEVEL_MINUS_3DB;
|
||||
ctx->chcoeffs[1] *= clev * LEVEL_PLUS_3DB;
|
||||
ctx->chcoeffs[3] *= slev * LEVEL_MINUS_3DB;
|
||||
ctx->chcoeffs[4] *= slev * LEVEL_MINUS_3DB;
|
||||
nf = LEVEL_MINUS_3DB / (1.0 + clev + slev);
|
||||
ctx->chcoeffs[0] *= (nf * LEVEL_MINUS_3DB);
|
||||
ctx->chcoeffs[2] *= (nf * LEVEL_MINUS_3DB);
|
||||
ctx->chcoeffs[1] *= (nf * clev * LEVEL_PLUS_3DB);
|
||||
ctx->chcoeffs[3] *= (nf * slev * LEVEL_MINUS_3DB);
|
||||
ctx->chcoeffs[4] *= (nf * slev * LEVEL_MINUS_3DB);
|
||||
break;
|
||||
case AC3_OUTPUT_STEREO:
|
||||
ctx->chcoeffs[1] *= clev;
|
||||
ctx->chcoeffs[3] *= slev;
|
||||
ctx->chcoeffs[4] *= slev;
|
||||
nf = 1.0 / (1.0 + clev + slev);
|
||||
ctx->chcoeffs[0] *= nf;
|
||||
ctx->chcoeffs[2] *= nf;
|
||||
ctx->chcoeffs[1] *= (nf * clev);
|
||||
ctx->chcoeffs[3] *= (nf * slev);
|
||||
ctx->chcoeffs[4] *= (nf * slev);
|
||||
break;
|
||||
case AC3_OUTPUT_DOLBY:
|
||||
ctx->chcoeffs[1] *= LEVEL_MINUS_3DB;
|
||||
ctx->chcoeffs[3] *= LEVEL_MINUS_3DB;
|
||||
ctx->chcoeffs[4] *= LEVEL_MINUS_3DB;
|
||||
nf = 1.0 / (1.0 + (3.0 * LEVEL_MINUS_3DB));
|
||||
ctx->chcoeffs[0] *= nf;
|
||||
ctx->chcoeffs[1] *= nf;
|
||||
ctx->chcoeffs[1] *= (nf * LEVEL_MINUS_3DB);
|
||||
ctx->chcoeffs[3] *= (nf * LEVEL_MINUS_3DB);
|
||||
ctx->chcoeffs[4] *= (nf * LEVEL_MINUS_3DB);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -1529,102 +1566,39 @@ static void dump_floats(const char *name, int prec, const float *tab, int n)
|
|||
(pim) = _are * _bim + _aim * _bre;\
|
||||
}
|
||||
|
||||
static void do_imdct_256(FFTContext *fft_ctx, float *coeffs, float *output,
|
||||
float *delay, float *tmp_imdct, float *tmp_output)
|
||||
static void do_imdct_256(AC3DecodeContext *ctx, int chindex)
|
||||
{
|
||||
int k, n2, n4, n8;
|
||||
int k;
|
||||
float x1[128], x2[128];
|
||||
FFTComplex *z1 = (FFTComplex *)tmp_imdct;
|
||||
FFTComplex *z2 = (FFTComplex *)(tmp_imdct + 128);
|
||||
|
||||
n2 = N / 2;
|
||||
n4 = N / 4;
|
||||
n8 = N / 8;
|
||||
|
||||
for (k = 0; k < n4; k++) {
|
||||
x1[k] = coeffs[2 * k];
|
||||
x2[k] = coeffs[2 * k + 1];
|
||||
for (k = 0; k < N / 4; k++) {
|
||||
x1[k] = ctx->transform_coeffs[chindex][2 * k];
|
||||
x2[k] = ctx->transform_coeffs[chindex][2 * k + 1];
|
||||
}
|
||||
|
||||
/* Pre IFFT Complex Multiply Step. */
|
||||
for (k = 0; k < n8; k++) {
|
||||
CMUL(z1[k].re, z1[k].im, x1[n4 - 2 * k - 1], x1[2 * k], x_cos2[k], x_sin2[k]);
|
||||
CMUL(z2[k].re, z2[k].im, x2[n4 - 2 * k - 1], x2[2 * k], x_cos2[k], x_sin2[k]);
|
||||
}
|
||||
ff_imdct_calc(&ctx->imdct_256, ctx->tmp_output, x1, ctx->tmp_imdct);
|
||||
ff_imdct_calc(&ctx->imdct_256, ctx->tmp_output + 256, x2, ctx->tmp_imdct);
|
||||
|
||||
/* N/8 pointe complex IFFT. */
|
||||
ff_fft_permute(fft_ctx, z1);
|
||||
ff_fft_calc(fft_ctx, z1);
|
||||
ff_fft_permute(fft_ctx, z2);
|
||||
ff_fft_calc(fft_ctx, z2);
|
||||
|
||||
|
||||
/* Post IFFT Complex Multiply Step. */
|
||||
for (k = 0; k < n8; k++) {
|
||||
CMUL(z1[k].re, z1[k].im, z1[k].re, z1[k].im, x_cos2[k], x_sin2[k]);
|
||||
CMUL(z2[k].re, z2[k].im, z2[k].re, z2[k].im, x_cos2[k], x_sin2[k]);
|
||||
}
|
||||
|
||||
/* Windowing and de-interleaving step. */
|
||||
for (k = 0; k < n8; k++) {
|
||||
tmp_output[2 * k] = -z1[k].im * window[2 * k];
|
||||
tmp_output[2 * k + 1] = z1[n8 - k - 1].re * window[2 * k + 1];
|
||||
tmp_output[n4 + 2 * k] = -z1[k].re * window[n4 + 2 * k];
|
||||
tmp_output[n4 + 2 * k + 1] = z1[n8 - k - 1].im * window[n4 + 2 * k + 1];
|
||||
tmp_output[n2 + 2 * k] = -z2[k].re * window[n2 - 2 * k - 1];
|
||||
tmp_output[n2 + 2* k + 1] = z2[n8 - k - 1].im * window[n2 - 2 * k - 2];
|
||||
tmp_output[3 * n4 + 2 * k] = z2[k].im * window[n4 - 2 * k - 1] ;
|
||||
tmp_output[3 * n4 + 2 * k + 1] = -z2[n8 - k - 1].re * window[n4 - 2 * k - 2] ;
|
||||
}
|
||||
|
||||
/* Overlap and add step. */
|
||||
for (k = 0; k < n2; k++) {
|
||||
output[k] = 2 * (tmp_output[k] + delay[k]);
|
||||
delay[k] = tmp_output[n2 + k];
|
||||
for (k = 0; k < N / 2; k++) {
|
||||
ctx->output[chindex][k] = ctx->tmp_output[k] * window[k] + ctx->delay[chindex][k];
|
||||
//dump_floats("samples", 10, ctx->output[chindex], 256);
|
||||
ctx->delay[chindex][k] = ctx->tmp_output[N / 2 + k] * window[255 - k];
|
||||
}
|
||||
}
|
||||
|
||||
static void do_imdct_512(FFTContext *fft_ctx, float *coeffs, float *output,
|
||||
float *delay, float *tmp_imdct, float *tmp_output)
|
||||
static void do_imdct_512(AC3DecodeContext *ctx, int chindex)
|
||||
{
|
||||
int k, n2, n4, n8;
|
||||
FFTComplex *z = (FFTComplex *)tmp_imdct;
|
||||
int k;
|
||||
|
||||
n2 = N / 2;
|
||||
n4 = N / 4;
|
||||
n8 = N / 8;
|
||||
ff_imdct_calc(&ctx->imdct_512, ctx->tmp_output,
|
||||
ctx->transform_coeffs[chindex], ctx->tmp_imdct);
|
||||
//ff_imdct_calc_ac3_512(&ctx->imdct_512, ctx->tmp_output, ctx->transform_coeffs[chindex],
|
||||
// ctx->tmp_imdct, window);
|
||||
|
||||
|
||||
/* Pre IFFT Complex Multiply Step. */
|
||||
for (k = 0; k < n4; k++)
|
||||
CMUL(z[k].re, z[k].im, coeffs[n2 - 2 * k - 1], coeffs[2 * k], x_cos1[k], x_sin1[k]);
|
||||
|
||||
/* Permutation needed before calling ff_fft_calc. */
|
||||
ff_fft_permute(fft_ctx, z);
|
||||
|
||||
/* N/4 pointe complex IFFT. */
|
||||
ff_fft_calc(fft_ctx, z);
|
||||
|
||||
/* Post IFFT Complex Multiply Step. */
|
||||
for (k = 0; k < n4; k++)
|
||||
CMUL(z[k].re, z[k].im, z[k].re, z[k].im, x_cos1[k], x_sin1[k]);
|
||||
|
||||
/* Windowing and de-interleaving step. */
|
||||
for (k = 0; k < n8; k++) {
|
||||
tmp_output[2 * k] = -z[n8 + k].im * window[2 * k];
|
||||
tmp_output[2 * k + 1] = z[n8 - k - 1].re * window[2 * k + 1];
|
||||
tmp_output[n4 + 2 * k] = -z[k].re * window[n4 + 2 * k];
|
||||
tmp_output[n4 + 2 * k + 1] = z[n4 - k - 1].im * window[n4 + 2 * k + 1];
|
||||
tmp_output[n2 + 2 * k] = -z[n8 + k].re * window[n2 - 2 * k - 1];
|
||||
tmp_output[n2 + 2* k + 1] = z[n8 - k - 1].im * window[n2 - 2 * k - 2];
|
||||
tmp_output[3 * n4 + 2 * k] = z[k].im * window[n4 - 2 * k - 1] ;
|
||||
tmp_output[3 * n4 + 2 * k + 1] = -z[n4 - k - 1].re * window[n4 - 2 * k - 2] ;
|
||||
}
|
||||
|
||||
/* Overlap and add step. */
|
||||
for (k = 0; k < n2; k++) {
|
||||
output[k] = 2 * (tmp_output[k] + delay[k]);
|
||||
delay[k] = tmp_output[n2 + k];
|
||||
for (k = 0; k < N / 2; k++) {
|
||||
ctx->output[chindex][k] = ctx->tmp_output[k] * window[k] + ctx->delay[chindex][k];
|
||||
//dump_floats("samples", 10, ctx->output[chindex], 256);
|
||||
ctx->delay[chindex][k] = ctx->tmp_output[N / 2 + k] * window[255 - k];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1633,18 +1607,13 @@ static inline void do_imdct(AC3DecodeContext *ctx)
|
|||
int i;
|
||||
|
||||
if (ctx->blkoutput & AC3_OUTPUT_LFEON) {
|
||||
do_imdct_512(&ctx->fft_128, ctx->transform_coeffs[0], ctx->output[0],
|
||||
ctx->delay[0], ctx->tmp_imdct, ctx->tmp_output);
|
||||
do_imdct_512(ctx, 0);
|
||||
}
|
||||
for (i = 0; i < ctx->nfchans; i++) {
|
||||
if (!((ctx->blksw >> i) & 1)) {
|
||||
do_imdct_512(&ctx->fft_128, ctx->transform_coeffs[i + 1], ctx->output[i + 1],
|
||||
ctx->delay[i + 1], ctx->tmp_imdct, ctx->tmp_output);
|
||||
} else {
|
||||
av_log(NULL, AV_LOG_INFO, "block switching enabled.\n");
|
||||
do_imdct_256(&ctx->fft_64, ctx->transform_coeffs[i + 1], ctx->output[i + 1],
|
||||
ctx->delay[i + 1], ctx->tmp_imdct, ctx->tmp_output);
|
||||
}
|
||||
if ((ctx->blksw >> i) & 1)
|
||||
do_imdct_256(ctx, i + 1);
|
||||
else
|
||||
do_imdct_512(ctx, i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1661,7 +1630,7 @@ static int ac3_parse_audio_block(AC3DecodeContext * ctx)
|
|||
int dynrng, chbwcod, ngrps, cplabsexp, skipl;
|
||||
|
||||
for (i = 0; i < 5; i++)
|
||||
ctx->chcoeffs[i] = 1.0;
|
||||
ctx->chcoeffs[i] = 2.0;
|
||||
|
||||
for (i = 0; i < nfchans; i++) /*block switch flag */
|
||||
ctx->blksw |= get_bits1(gb) << i;
|
||||
|
@ -1670,14 +1639,14 @@ static int ac3_parse_audio_block(AC3DecodeContext * ctx)
|
|||
ctx->dithflag |= get_bits1(gb) << i;
|
||||
|
||||
if (get_bits1(gb)) { /* dynamic range */
|
||||
dynrng = get_bits(gb, 8);
|
||||
dynrng = get_sbits(gb, 8);
|
||||
drange = ((((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 */
|
||||
dynrng = get_bits(gb, 8);
|
||||
dynrng = get_sbits(gb, 8);
|
||||
drange = ((((dynrng & 0x1f) | 0x20) << 13) * scale_factors[3 - (dynrng >> 5)]);
|
||||
ctx->chcoeffs[1] *= drange;
|
||||
}
|
||||
|
@ -1931,9 +1900,12 @@ static int ac3_parse_audio_block(AC3DecodeContext * ctx)
|
|||
|
||||
static inline int16_t convert(float f)
|
||||
{
|
||||
int a;
|
||||
a = lrintf(f * 32767.0);
|
||||
return ((int16_t)a);
|
||||
if (f >= 1.0)
|
||||
return 32767;
|
||||
else if (f <= -1.0)
|
||||
return -32768;
|
||||
else
|
||||
return (lrintf(f * 32767.0));
|
||||
}
|
||||
|
||||
static int frame_count = 0;
|
||||
|
@ -1943,7 +1915,8 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size,
|
|||
AC3DecodeContext *ctx = (AC3DecodeContext *)avctx->priv_data;
|
||||
int frame_start;
|
||||
int16_t *out_samples = (int16_t *)data;
|
||||
int i, j, k, value;
|
||||
int i, j, k, value, fs_58;
|
||||
uint16_t crc1;
|
||||
|
||||
av_log(NULL, AV_LOG_INFO, "decoding frame %d buf_size = %d\n", frame_count++, buf_size);
|
||||
|
||||
|
@ -1966,38 +1939,34 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size,
|
|||
return buf_size;
|
||||
}
|
||||
|
||||
//Check for the errors.
|
||||
/* if (ac3_error_check(ctx)) {
|
||||
*data_size = 0;
|
||||
return -1;
|
||||
} */
|
||||
|
||||
//Parse the BSI.
|
||||
//If 'bsid' is not valid decoder shall not decode the audio as per the standard.
|
||||
ac3_parse_bsi(ctx);
|
||||
|
||||
avctx->sample_rate = ctx->sampling_rate;
|
||||
avctx->bit_rate = ctx->bit_rate;
|
||||
avctx->channels = 0;
|
||||
|
||||
if (avctx->channels == 0) {
|
||||
ctx->blkoutput |= AC3_OUTPUT_UNMODIFIED;
|
||||
avctx->channels = ctx->nfchans;
|
||||
} else if (ctx->nfchans + ctx->lfeon < avctx->channels) {
|
||||
av_log(avctx, AV_LOG_INFO, "ac3_decoder: AC3 Source Channels Are Less Then Specified %d: Output to %d Channels\n",
|
||||
avctx->channels, ctx->nfchans + ctx->lfeon);
|
||||
avctx->channels = ctx->nfchans;
|
||||
ctx->blkoutput |= AC3_OUTPUT_UNMODIFIED;
|
||||
} else if (avctx->channels == 1) {
|
||||
if (ctx->lfeon)
|
||||
ctx->blkoutput |= AC3_OUTPUT_LFEON;
|
||||
avctx->channels = ctx->nfchans + ctx->lfeon;
|
||||
}
|
||||
else if (avctx->channels == 1)
|
||||
ctx->blkoutput |= AC3_OUTPUT_MONO;
|
||||
} else if (avctx->channels == 2) {
|
||||
else if (avctx->channels == 2) {
|
||||
if (ctx->dsurmod == 0x02)
|
||||
ctx->blkoutput |= AC3_OUTPUT_DOLBY;
|
||||
else
|
||||
ctx->blkoutput |= AC3_OUTPUT_STEREO;
|
||||
}
|
||||
if (ctx->lfeon) {
|
||||
avctx->channels++;
|
||||
else {
|
||||
if (avctx->channels < (ctx->nfchans + ctx->lfeon))
|
||||
av_log(avctx, AV_LOG_INFO, "ac3_decoder: AC3 Source Channels Are Less Then Specified %d: Output to %d Channels\n",avctx->channels, ctx->nfchans + ctx->lfeon);
|
||||
ctx->blkoutput |= AC3_OUTPUT_UNMODIFIED;
|
||||
if (ctx->lfeon)
|
||||
ctx->blkoutput |= AC3_OUTPUT_LFEON;
|
||||
avctx->channels = ctx->nfchans + ctx->lfeon;
|
||||
}
|
||||
|
||||
av_log(avctx, AV_LOG_INFO, "channels = %d \t bit rate = %d \t sampling rate = %d \n", avctx->channels, avctx->bit_rate * 1000, avctx->sample_rate);
|
||||
|
@ -2009,10 +1978,9 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size,
|
|||
*data_size = 0;
|
||||
return ctx->frame_size;
|
||||
}
|
||||
j = ((ctx->blkoutput & AC3_OUTPUT_LFEON) ? 0 : 1);
|
||||
for (k = 0; k < BLOCK_SIZE; k++) {
|
||||
j = ((ctx->blkoutput & AC3_OUTPUT_LFEON) ? 0 : 1);
|
||||
for (;j < avctx->channels + 1; j++) {
|
||||
j = (ctx->blkoutput & AC3_OUTPUT_LFEON) ? 0 : 1;
|
||||
for (; j <= avctx->channels; j++) {
|
||||
value = convert(ctx->output[j][k]);
|
||||
*(out_samples++) = value;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue