Newer
Older
Diego Biurrun
committed
* This file is part of FFmpeg.
*
* FFmpeg 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
Diego Biurrun
committed
* version 2.1 of the License, or (at your option) any later version.
Diego Biurrun
committed
* FFmpeg 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
Diego Biurrun
committed
* License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
/**
* @file mpegaudiodec.c
* MPEG Audio decoder.
Fabrice Bellard
committed
//#define DEBUG
Michael Niedermayer
committed
#include "bitstream.h"
#include "dsputil.h"
Fabrice Bellard
committed
* TODO:
* - in low precision mode, use more 16 bit multiplies in synth filter
* - test lsf / mpeg25 extensively.
Fabrice Bellard
committed
/* define USE_HIGHPRECISION to have a bit exact (but slower) mpeg
audio decoder */
Fabrice Bellard
committed
#ifdef CONFIG_MPEGAUDIO_HP
Fabrice Bellard
committed
#endif
Fabrice Bellard
committed
Fabrice Bellard
committed
#define FRAC_ONE (1 << FRAC_BITS)
#define FIX(a) ((int)((a) * FRAC_ONE))
/* WARNING: only correct for posititive numbers */
#define FIXR(a) ((int)((a) * FRAC_ONE + 0.5))
#define FRAC_RND(a) (((a) + (FRAC_ONE/2)) >> FRAC_BITS)
#define FIXHR(a) ((int)((a) * (1LL<<32) + 0.5))
Fabrice Bellard
committed
/****************/
Michael Niedermayer
committed
#define EXTRABYTES 24
Michael Niedermayer
committed
struct GranuleDef;
DECLARE_ALIGNED_8(uint8_t, last_buf[2*BACKSTEP_SIZE + EXTRABYTES]);
Michael Niedermayer
committed
int last_buf_size;
Fabrice Bellard
committed
/* next header (used in free format parsing) */
uint32_t free_format_next_header;
int error_protection;
int layer;
int sample_rate;
Fabrice Bellard
committed
int sample_rate_index; /* between 0 and 8 */
Michael Niedermayer
committed
GetBitContext in_gb;
Fabrice Bellard
committed
int nb_channels;
int mode;
int mode_ext;
int lsf;
DECLARE_ALIGNED_16(MPA_INT, synth_buf[MPA_MAX_CHANNELS][512 * 2]);
Fabrice Bellard
committed
int synth_buf_offset[MPA_MAX_CHANNELS];
DECLARE_ALIGNED_16(int32_t, sb_samples[MPA_MAX_CHANNELS][36][SBLIMIT]);
int32_t mdct_buf[MPA_MAX_CHANNELS][SBLIMIT * 18]; /* previous samples, for layer 3 MDCT */
Fabrice Bellard
committed
#ifdef DEBUG
int frame_count;
#endif
Michael Niedermayer
committed
void (*compute_antialias)(struct MPADecodeContext *s, struct GranuleDef *g);
int adu_mode; ///< 0 for standard mp3, 1 for adu formatted mp3
int error_resilience;
/**
* Context for MP3On4 decoder
*/
typedef struct MP3On4DecodeContext {
int frames; ///< number of mp3 frames per block (number of mp3 decoder instances)
int chan_cfg; ///< channel config number
MPADecodeContext *mp3decctx[5]; ///< MPADecodeContext for every decoder instance
} MP3On4DecodeContext;
Fabrice Bellard
committed
/* layer 3 "granule" */
typedef struct GranuleDef {
Fabrice Bellard
committed
int part2_3_length;
int big_values;
int global_gain;
int scalefac_compress;
uint8_t block_type;
uint8_t switch_point;
Fabrice Bellard
committed
int table_select[3];
int subblock_gain[3];
uint8_t scalefac_scale;
uint8_t count1table_select;
Fabrice Bellard
committed
int region_size[3]; /* number of huffman codes in each region */
int preflag;
int short_start, long_end; /* long/short band indexes */
uint8_t scale_factors[40];
int32_t sb_hybrid[SBLIMIT * 18]; /* 576 samples */
Fabrice Bellard
committed
} GranuleDef;
Fabrice Bellard
committed
#define MODE_EXT_MS_STEREO 2
#define MODE_EXT_I_STEREO 1
/* layer 3 huffman tables */
typedef struct HuffTable {
int xsize;
const uint8_t *bits;
const uint16_t *codes;
Fabrice Bellard
committed
} HuffTable;
Aurelien Jacobs
committed
#include "mpegaudiodata.h"
Fabrice Bellard
committed
#include "mpegaudiodectab.h"
Michael Niedermayer
committed
static void compute_antialias_integer(MPADecodeContext *s, GranuleDef *g);
static void compute_antialias_float(MPADecodeContext *s, GranuleDef *g);
Fabrice Bellard
committed
/* vlc structure for decoding layer 3 huffman tables */
Fabrice Bellard
committed
static VLC huff_quad_vlc[2];
/* computed from band_size_long */
static uint16_t band_index_long[9][23];
Fabrice Bellard
committed
/* XXX: free when all decoders are closed */
#define TABLE_4_3_SIZE (8191 + 16)*4
static int8_t table_4_3_exp[TABLE_4_3_SIZE];
static uint32_t table_4_3_value[TABLE_4_3_SIZE];
static uint32_t exp_table[512];
static uint32_t expval_table[512][16];
Fabrice Bellard
committed
/* intensity stereo coef table */
static int32_t is_table[2][16];
static int32_t is_table_lsf[2][2][16];
Michael Niedermayer
committed
static int32_t csa_table[8][4];
static float csa_table_float[8][4];
Fabrice Bellard
committed
/* lower 2 bits: modulo 3, higher bits: shift */
static uint16_t scale_factor_modshift[64];
Fabrice Bellard
committed
/* [i][j]: 2^(-j/3) * FRAC_ONE * 2^(i+2) / (2^(i+2) - 1) */
static int32_t scale_factor_mult[15][3];
Fabrice Bellard
committed
/* mult table for layer 2 group quantization */
#define SCALE_GEN(v) \
{ FIXR(1.0 * (v)), FIXR(0.7937005259 * (v)), FIXR(0.6299605249 * (v)) }
static const int32_t scale_factor_mult2[3][3] = {
Fabrice Bellard
committed
SCALE_GEN(4.0 / 3.0), /* 3 steps */
SCALE_GEN(4.0 / 5.0), /* 5 steps */
SCALE_GEN(4.0 / 9.0), /* 9 steps */
Fabrice Bellard
committed
};
static DECLARE_ALIGNED_16(MPA_INT, window[512]);
Fabrice Bellard
committed
/* layer 1 unscaling */
/* n = number of bits of the mantissa minus 1 */
static inline int l1_unscale(int n, int mant, int scale_factor)
{
int shift, mod;
Fabrice Bellard
committed
shift = scale_factor_modshift[scale_factor];
mod = shift & 3;
shift >>= 2;
val = MUL64(mant + (-1 << n) + 1, scale_factor_mult[n-1][mod]);
shift += n;
Fabrice Bellard
committed
/* NOTE: at this point, 1 <= shift >= 21 + 15 */
return (int)((val + (1LL << (shift - 1))) >> shift);
Fabrice Bellard
committed
}
static inline int l2_unscale_group(int steps, int mant, int scale_factor)
{
int shift, mod, val;
shift = scale_factor_modshift[scale_factor];
mod = shift & 3;
shift >>= 2;
Fabrice Bellard
committed
val = (mant - (steps >> 1)) * scale_factor_mult2[steps >> 2][mod];
/* NOTE: at this point, 0 <= shift <= 21 */
if (shift > 0)
val = (val + (1 << (shift - 1))) >> shift;
return val;
Fabrice Bellard
committed
}
/* compute value^(4/3) * 2^(exponent/4). It normalized to FRAC_BITS */
static inline int l3_unscale(int value, int exponent)
{
unsigned int m;
int e;
e = table_4_3_exp [4*value + (exponent&3)];
m = table_4_3_value[4*value + (exponent&3)];
e -= (exponent >> 2);
assert(e>=1);
Fabrice Bellard
committed
if (e > 31)
Fabrice Bellard
committed
m = (m + (1 << (e-1))) >> e;
Fabrice Bellard
committed
return m;
}
Fabrice Bellard
committed
/* all integer n^(4/3) computation code */
#define DEV_ORDER 13
#define POW_FRAC_BITS 24
#define POW_FRAC_ONE (1 << POW_FRAC_BITS)
#define POW_FIX(a) ((int)((a) * POW_FRAC_ONE))
#define POW_MULL(a,b) (((int64_t)(a) * (int64_t)(b)) >> POW_FRAC_BITS)
Fabrice Bellard
committed
static int dev_4_3_coefs[DEV_ORDER];
#if 0 /* unused */
Fabrice Bellard
committed
static int pow_mult3[3] = {
POW_FIX(1.0),
POW_FIX(1.25992104989487316476),
POW_FIX(1.58740105196819947474),
};
Fabrice Bellard
committed
static void int_pow_init(void)
{
int i, a;
a = POW_FIX(1.0);
for(i=0;i<DEV_ORDER;i++) {
a = POW_MULL(a, POW_FIX(4.0 / 3.0) - i * POW_FIX(1.0)) / (i + 1);
dev_4_3_coefs[i] = a;
}
}
#if 0 /* unused, remove? */
Fabrice Bellard
committed
/* return the mantissa and the binary exponent */
static int int_pow(int i, int *exp_ptr)
{
int e, er, eq, j;
int a, a1;
Fabrice Bellard
committed
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
/* renormalize */
a = i;
e = POW_FRAC_BITS;
while (a < (1 << (POW_FRAC_BITS - 1))) {
a = a << 1;
e--;
}
a -= (1 << POW_FRAC_BITS);
a1 = 0;
for(j = DEV_ORDER - 1; j >= 0; j--)
a1 = POW_MULL(a, dev_4_3_coefs[j] + a1);
a = (1 << POW_FRAC_BITS) + a1;
/* exponent compute (exact) */
e = e * 4;
er = e % 3;
eq = e / 3;
a = POW_MULL(a, pow_mult3[er]);
while (a >= 2 * POW_FRAC_ONE) {
a = a >> 1;
eq++;
}
/* convert to float */
while (a < POW_FRAC_ONE) {
a = a << 1;
eq--;
}
Fabrice Bellard
committed
/* now POW_FRAC_ONE <= a < 2 * POW_FRAC_ONE */
Fabrice Bellard
committed
#if POW_FRAC_BITS > FRAC_BITS
Fabrice Bellard
committed
a = (a + (1 << (POW_FRAC_BITS - FRAC_BITS - 1))) >> (POW_FRAC_BITS - FRAC_BITS);
/* correct overflow */
if (a >= 2 * (1 << FRAC_BITS)) {
a = a >> 1;
eq++;
}
#endif
Fabrice Bellard
committed
*exp_ptr = eq;
return a;
}
static int decode_init(AVCodecContext * avctx)
{
MPADecodeContext *s = avctx->priv_data;
static int init=0;
Fabrice Bellard
committed
int i, j, k;
#if defined(USE_HIGHPRECISION) && defined(CONFIG_AUDIO_NONSHORT)
avctx->sample_fmt= SAMPLE_FMT_S32;
#else
avctx->sample_fmt= SAMPLE_FMT_S16;
s->error_resilience= avctx->error_resilience;
s->compute_antialias= compute_antialias_integer;
else
s->compute_antialias= compute_antialias_float;
Fabrice Bellard
committed
if (!init && !avctx->parse_only) {
Fabrice Bellard
committed
/* scale factors table for layer 1/2 */
for(i=0;i<64;i++) {
int shift, mod;
/* 1.0 (i = 3) is normalized to 2 ^ FRAC_BITS */
Fabrice Bellard
committed
shift = (i / 3);
Fabrice Bellard
committed
mod = i % 3;
scale_factor_modshift[i] = mod | (shift << 2);
}
/* scale factor multiply for layer 1 */
for(i=0;i<15;i++) {
int n, norm;
n = i + 2;
norm = ((INT64_C(1) << n) * FRAC_ONE) / ((1 << n) - 1);
Fabrice Bellard
committed
scale_factor_mult[i][0] = MULL(FIXR(1.0 * 2.0), norm);
scale_factor_mult[i][1] = MULL(FIXR(0.7937005259 * 2.0), norm);
scale_factor_mult[i][2] = MULL(FIXR(0.6299605249 * 2.0), norm);
Fabrice Bellard
committed
scale_factor_mult[i][0],
scale_factor_mult[i][1],
scale_factor_mult[i][2]);
}
ff_mpa_synth_init(window);
Fabrice Bellard
committed
/* huffman decode tables */
for(i=1;i<16;i++) {
const HuffTable *h = &mpa_huff_tables[i];
memset(tmp_bits , 0, sizeof(tmp_bits ));
memset(tmp_codes, 0, sizeof(tmp_codes));
Fabrice Bellard
committed
xsize = h->xsize;
n = xsize * xsize;
Fabrice Bellard
committed
j = 0;
for(x=0;x<xsize;x++) {
tmp_bits [(x << 5) | y | ((x&&y)<<4)]= h->bits [j ];
tmp_codes[(x << 5) | y | ((x&&y)<<4)]= h->codes[j++];
Fabrice Bellard
committed
}
Fabrice Bellard
committed
}
for(i=0;i<2;i++) {
init_vlc(&huff_quad_vlc[i], i == 0 ? 7 : 4, 16,
Burkhard Plaum
committed
mpa_quad_bits[i], 1, 1, mpa_quad_codes[i], 1, 1, 1);
Fabrice Bellard
committed
}
for(i=0;i<9;i++) {
k = 0;
for(j=0;j<22;j++) {
band_index_long[i][j] = k;
k += band_size_long[i][j];
}
band_index_long[i][22] = k;
}
/* compute n ^ (4/3) and store it in mantissa/exp format */
Fabrice Bellard
committed
int_pow_init();
Fabrice Bellard
committed
for(i=1;i<TABLE_4_3_SIZE;i++) {
Fabrice Bellard
committed
int e, m;
f = pow((double)(i/4), 4.0 / 3.0) * pow(2, (i&3)*0.25);
fm = frexp(f, &e);
Michael Niedermayer
committed
m = (uint32_t)(fm*(1LL<<31) + 0.5);
e+= FRAC_BITS - 31 + 5 - 100;
Fabrice Bellard
committed
/* normalized to FRAC_BITS */
table_4_3_value[i] = m;
// av_log(NULL, AV_LOG_DEBUG, "%d %d %f\n", i, m, pow((double)i, 4.0 / 3.0));
table_4_3_exp[i] = -e;
Fabrice Bellard
committed
}
for(i=0; i<512*16; i++){
int exponent= (i>>4);
double f= pow(i&15, 4.0 / 3.0) * pow(2, (exponent-400)*0.25 + FRAC_BITS + 5);
expval_table[exponent][i&15]= llrint(f);
Fabrice Bellard
committed
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
for(i=0;i<7;i++) {
float f;
int v;
if (i != 6) {
f = tan((double)i * M_PI / 12.0);
v = FIXR(f / (1.0 + f));
} else {
v = FIXR(1.0);
}
is_table[0][i] = v;
is_table[1][6 - i] = v;
}
/* invalid values */
for(i=7;i<16;i++)
is_table[0][i] = is_table[1][i] = 0.0;
for(i=0;i<16;i++) {
double f;
int e, k;
for(j=0;j<2;j++) {
e = -(j + 1) * ((i + 1) >> 1);
f = pow(2.0, e / 4.0);
k = i & 1;
is_table_lsf[j][k ^ 1][i] = FIXR(f);
is_table_lsf[j][k][i] = FIXR(1.0);
Fabrice Bellard
committed
i, j, is_table_lsf[j][0][i], is_table_lsf[j][1][i]);
}
}
for(i=0;i<8;i++) {
float ci, cs, ca;
ci = ci_table[i];
cs = 1.0 / sqrt(1.0 + ci * ci);
ca = cs * ci;
csa_table[i][0] = FIXHR(cs/4);
csa_table[i][1] = FIXHR(ca/4);
csa_table[i][2] = FIXHR(ca/4) + FIXHR(cs/4);
csa_table[i][3] = FIXHR(ca/4) - FIXHR(cs/4);
Michael Niedermayer
committed
csa_table_float[i][0] = cs;
csa_table_float[i][1] = ca;
csa_table_float[i][2] = ca + cs;
csa_table_float[i][3] = ca - cs;
Michael Niedermayer
committed
// printf("%d %d %d %d\n", FIX(cs), FIX(cs-1), FIX(ca), FIX(cs)-FIX(ca));
// av_log(NULL, AV_LOG_DEBUG,"%f %f %f %f\n", cs, ca, ca+cs, ca-cs);
Fabrice Bellard
committed
}
/* compute mdct windows */
for(i=0;i<36;i++) {
d= sin(M_PI * (i + 0.5) / 36.0);
if(j==1){
if (i>=30) d= 0;
else if(i>=24) d= sin(M_PI * (i - 18 + 0.5) / 12.0);
else if(i>=18) d= 1;
}else if(j==3){
if (i< 6) d= 0;
else if(i< 12) d= sin(M_PI * (i - 6 + 0.5) / 12.0);
else if(i< 18) d= 1;
}
//merge last stage of imdct into the window coefficients
d*= 0.5 / cos(M_PI*(2*i + 19)/72);
if(j==2)
mdct_win[j][i/3] = FIXHR((d / (1<<5)));
else
mdct_win[j][i ] = FIXHR((d / (1<<5)));
// av_log(NULL, AV_LOG_DEBUG, "%2d %d %f\n", i,j,d / (1<<5));
}
Fabrice Bellard
committed
}
/* NOTE: we do frequency inversion adter the MDCT by changing
the sign of the right window coefs */
for(j=0;j<4;j++) {
for(i=0;i<36;i+=2) {
mdct_win[j + 4][i] = mdct_win[j][i];
mdct_win[j + 4][i + 1] = -mdct_win[j][i + 1];
}
}
#if defined(DEBUG)
for(j=0;j<8;j++) {
av_log(avctx, AV_LOG_DEBUG, "win%d=\n", j);
Fabrice Bellard
committed
for(i=0;i<36;i++)
av_log(avctx, AV_LOG_DEBUG, "%f, ", (double)mdct_win[j][i] / FRAC_ONE);
av_log(avctx, AV_LOG_DEBUG, "\n");
Fabrice Bellard
committed
}
#endif
Fabrice Bellard
committed
#ifdef DEBUG
s->frame_count = 0;
#endif
if (avctx->codec_id == CODEC_ID_MP3ADU)
s->adu_mode = 1;
Måns Rullgård
committed
/* tab[i][j] = 1.0 / (2.0 * cos(pi*(2*k+1) / 2^(6 - j))) */
Fabrice Bellard
committed
/* cos(i*pi/64) */
Michael Niedermayer
committed
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
#define COS0_0 FIXHR(0.50060299823519630134/2)
#define COS0_1 FIXHR(0.50547095989754365998/2)
#define COS0_2 FIXHR(0.51544730992262454697/2)
#define COS0_3 FIXHR(0.53104259108978417447/2)
#define COS0_4 FIXHR(0.55310389603444452782/2)
#define COS0_5 FIXHR(0.58293496820613387367/2)
#define COS0_6 FIXHR(0.62250412303566481615/2)
#define COS0_7 FIXHR(0.67480834145500574602/2)
#define COS0_8 FIXHR(0.74453627100229844977/2)
#define COS0_9 FIXHR(0.83934964541552703873/2)
#define COS0_10 FIXHR(0.97256823786196069369/2)
#define COS0_11 FIXHR(1.16943993343288495515/4)
#define COS0_12 FIXHR(1.48416461631416627724/4)
#define COS0_13 FIXHR(2.05778100995341155085/8)
#define COS0_14 FIXHR(3.40760841846871878570/8)
#define COS0_15 FIXHR(10.19000812354805681150/32)
#define COS1_0 FIXHR(0.50241928618815570551/2)
#define COS1_1 FIXHR(0.52249861493968888062/2)
#define COS1_2 FIXHR(0.56694403481635770368/2)
#define COS1_3 FIXHR(0.64682178335999012954/2)
#define COS1_4 FIXHR(0.78815462345125022473/2)
#define COS1_5 FIXHR(1.06067768599034747134/4)
#define COS1_6 FIXHR(1.72244709823833392782/4)
#define COS1_7 FIXHR(5.10114861868916385802/16)
#define COS2_0 FIXHR(0.50979557910415916894/2)
#define COS2_1 FIXHR(0.60134488693504528054/2)
#define COS2_2 FIXHR(0.89997622313641570463/2)
#define COS2_3 FIXHR(2.56291544774150617881/8)
#define COS3_0 FIXHR(0.54119610014619698439/2)
#define COS3_1 FIXHR(1.30656296487637652785/4)
#define COS4_0 FIXHR(0.70710678118654752439/2)
Fabrice Bellard
committed
/* butterfly operator */
Michael Niedermayer
committed
#define BF(a, b, c, s)\
Fabrice Bellard
committed
{\
tmp0 = tab[a] + tab[b];\
tmp1 = tab[a] - tab[b];\
tab[a] = tmp0;\
Michael Niedermayer
committed
tab[b] = MULH(tmp1<<(s), c);\
Fabrice Bellard
committed
}
#define BF1(a, b, c, d)\
{\
Michael Niedermayer
committed
BF(a, b, COS4_0, 1);\
BF(c, d,-COS4_0, 1);\
Fabrice Bellard
committed
tab[c] += tab[d];\
}
#define BF2(a, b, c, d)\
{\
Michael Niedermayer
committed
BF(a, b, COS4_0, 1);\
BF(c, d,-COS4_0, 1);\
Fabrice Bellard
committed
tab[c] += tab[d];\
tab[a] += tab[c];\
tab[c] += tab[b];\
tab[b] += tab[d];\
}
#define ADD(a, b) tab[a] += tab[b]
/* DCT32 without 1/sqrt(2) coef zero scaling. */
static void dct32(int32_t *out, int32_t *tab)
Fabrice Bellard
committed
{
int tmp0, tmp1;
/* pass 1 */
Michael Niedermayer
committed
BF( 0, 31, COS0_0 , 1);
BF(15, 16, COS0_15, 5);
Michael Niedermayer
committed
BF( 0, 15, COS1_0 , 1);
BF(16, 31,-COS1_0 , 1);
Michael Niedermayer
committed
BF( 7, 24, COS0_7 , 1);
BF( 8, 23, COS0_8 , 1);
Michael Niedermayer
committed
BF( 7, 8, COS1_7 , 4);
BF(23, 24,-COS1_7 , 4);
Michael Niedermayer
committed
BF( 0, 7, COS2_0 , 1);
BF( 8, 15,-COS2_0 , 1);
BF(16, 23, COS2_0 , 1);
BF(24, 31,-COS2_0 , 1);
Michael Niedermayer
committed
BF( 3, 28, COS0_3 , 1);
BF(12, 19, COS0_12, 2);
Fabrice Bellard
committed
/* pass 2 */
Michael Niedermayer
committed
BF( 3, 12, COS1_3 , 1);
BF(19, 28,-COS1_3 , 1);
Michael Niedermayer
committed
BF( 4, 27, COS0_4 , 1);
BF(11, 20, COS0_11, 2);
Michael Niedermayer
committed
BF( 4, 11, COS1_4 , 1);
BF(20, 27,-COS1_4 , 1);
Michael Niedermayer
committed
BF( 3, 4, COS2_3 , 3);
BF(11, 12,-COS2_3 , 3);
BF(19, 20, COS2_3 , 3);
BF(27, 28,-COS2_3 , 3);
Michael Niedermayer
committed
BF( 0, 3, COS3_0 , 1);
BF( 4, 7,-COS3_0 , 1);
BF( 8, 11, COS3_0 , 1);
BF(12, 15,-COS3_0 , 1);
BF(16, 19, COS3_0 , 1);
BF(20, 23,-COS3_0 , 1);
BF(24, 27, COS3_0 , 1);
BF(28, 31,-COS3_0 , 1);
/* pass 1 */
Michael Niedermayer
committed
BF( 1, 30, COS0_1 , 1);
BF(14, 17, COS0_14, 3);
Michael Niedermayer
committed
BF( 1, 14, COS1_1 , 1);
BF(17, 30,-COS1_1 , 1);
Michael Niedermayer
committed
BF( 6, 25, COS0_6 , 1);
BF( 9, 22, COS0_9 , 1);
Michael Niedermayer
committed
BF( 6, 9, COS1_6 , 2);
BF(22, 25,-COS1_6 , 2);
Fabrice Bellard
committed
/* pass 3 */
Michael Niedermayer
committed
BF( 1, 6, COS2_1 , 1);
BF( 9, 14,-COS2_1 , 1);
BF(17, 22, COS2_1 , 1);
BF(25, 30,-COS2_1 , 1);
Fabrice Bellard
committed
Michael Niedermayer
committed
BF( 2, 29, COS0_2 , 1);
BF(13, 18, COS0_13, 3);
Michael Niedermayer
committed
BF( 2, 13, COS1_2 , 1);
BF(18, 29,-COS1_2 , 1);
Michael Niedermayer
committed
BF( 5, 26, COS0_5 , 1);
BF(10, 21, COS0_10, 1);
Michael Niedermayer
committed
BF( 5, 10, COS1_5 , 2);
BF(21, 26,-COS1_5 , 2);
Michael Niedermayer
committed
BF( 2, 5, COS2_2 , 1);
BF(10, 13,-COS2_2 , 1);
BF(18, 21, COS2_2 , 1);
BF(26, 29,-COS2_2 , 1);
Fabrice Bellard
committed
/* pass 4 */
Michael Niedermayer
committed
BF( 1, 2, COS3_1 , 2);
BF( 5, 6,-COS3_1 , 2);
BF( 9, 10, COS3_1 , 2);
BF(13, 14,-COS3_1 , 2);
BF(17, 18, COS3_1 , 2);
BF(21, 22,-COS3_1 , 2);
BF(25, 26, COS3_1 , 2);
BF(29, 30,-COS3_1 , 2);
Fabrice Bellard
committed
/* pass 5 */
Michael Niedermayer
committed
BF1( 0, 1, 2, 3);
BF2( 4, 5, 6, 7);
BF1( 8, 9, 10, 11);
Fabrice Bellard
committed
BF2(12, 13, 14, 15);
BF1(16, 17, 18, 19);
BF2(20, 21, 22, 23);
BF1(24, 25, 26, 27);
BF2(28, 29, 30, 31);
Fabrice Bellard
committed
/* pass 6 */
Fabrice Bellard
committed
ADD( 8, 12);
ADD(12, 10);
ADD(10, 14);
ADD(14, 9);
ADD( 9, 13);
ADD(13, 11);
ADD(11, 15);
out[ 0] = tab[0];
out[16] = tab[1];
out[ 8] = tab[2];
out[24] = tab[3];
out[ 4] = tab[4];
out[20] = tab[5];
out[12] = tab[6];
out[28] = tab[7];
out[ 2] = tab[8];
out[18] = tab[9];
out[10] = tab[10];
out[26] = tab[11];
out[ 6] = tab[12];
out[22] = tab[13];
out[14] = tab[14];
out[30] = tab[15];
Fabrice Bellard
committed
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
ADD(24, 28);
ADD(28, 26);
ADD(26, 30);
ADD(30, 25);
ADD(25, 29);
ADD(29, 27);
ADD(27, 31);
out[ 1] = tab[16] + tab[24];
out[17] = tab[17] + tab[25];
out[ 9] = tab[18] + tab[26];
out[25] = tab[19] + tab[27];
out[ 5] = tab[20] + tab[28];
out[21] = tab[21] + tab[29];
out[13] = tab[22] + tab[30];
out[29] = tab[23] + tab[31];
out[ 3] = tab[24] + tab[20];
out[19] = tab[25] + tab[21];
out[11] = tab[26] + tab[22];
out[27] = tab[27] + tab[23];
out[ 7] = tab[28] + tab[18];
out[23] = tab[29] + tab[19];
out[15] = tab[30] + tab[17];
out[31] = tab[31];
}
#if FRAC_BITS <= 15
static inline int round_sample(int *sum)
Fabrice Bellard
committed
{
int sum1;
sum1 = (*sum) >> OUT_SHIFT;
*sum &= (1<<OUT_SHIFT)-1;
if (sum1 < OUT_MIN)
sum1 = OUT_MIN;
else if (sum1 > OUT_MAX)
sum1 = OUT_MAX;
Fabrice Bellard
committed
return sum1;
Fabrice Bellard
committed
}
/* signed 16x16 -> 32 multiply add accumulate */
#define MACS(rt, ra, rb) MAC16(rt, ra, rb)
/* signed 16x16 -> 32 multiply */
#define MULS(ra, rb) MUL16(ra, rb)
Fabrice Bellard
committed
#else
static inline int round_sample(int64_t *sum)
Fabrice Bellard
committed
{
int sum1;
sum1 = (int)((*sum) >> OUT_SHIFT);
*sum &= (1<<OUT_SHIFT)-1;
if (sum1 < OUT_MIN)
sum1 = OUT_MIN;
else if (sum1 > OUT_MAX)
sum1 = OUT_MAX;
Fabrice Bellard
committed
return sum1;
Fabrice Bellard
committed
}
Fabrice Bellard
committed
#endif
#define SUM8(sum, op, w, p) \
Fabrice Bellard
committed
{ \
Fabrice Bellard
committed
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
sum op MULS((w)[0 * 64], p[0 * 64]);\
sum op MULS((w)[1 * 64], p[1 * 64]);\
sum op MULS((w)[2 * 64], p[2 * 64]);\
sum op MULS((w)[3 * 64], p[3 * 64]);\
sum op MULS((w)[4 * 64], p[4 * 64]);\
sum op MULS((w)[5 * 64], p[5 * 64]);\
sum op MULS((w)[6 * 64], p[6 * 64]);\
sum op MULS((w)[7 * 64], p[7 * 64]);\
}
#define SUM8P2(sum1, op1, sum2, op2, w1, w2, p) \
{ \
int tmp;\
tmp = p[0 * 64];\
sum1 op1 MULS((w1)[0 * 64], tmp);\
sum2 op2 MULS((w2)[0 * 64], tmp);\
tmp = p[1 * 64];\
sum1 op1 MULS((w1)[1 * 64], tmp);\
sum2 op2 MULS((w2)[1 * 64], tmp);\
tmp = p[2 * 64];\
sum1 op1 MULS((w1)[2 * 64], tmp);\
sum2 op2 MULS((w2)[2 * 64], tmp);\
tmp = p[3 * 64];\
sum1 op1 MULS((w1)[3 * 64], tmp);\
sum2 op2 MULS((w2)[3 * 64], tmp);\
tmp = p[4 * 64];\
sum1 op1 MULS((w1)[4 * 64], tmp);\
sum2 op2 MULS((w2)[4 * 64], tmp);\
tmp = p[5 * 64];\
sum1 op1 MULS((w1)[5 * 64], tmp);\
sum2 op2 MULS((w2)[5 * 64], tmp);\
tmp = p[6 * 64];\
sum1 op1 MULS((w1)[6 * 64], tmp);\
sum2 op2 MULS((w2)[6 * 64], tmp);\
tmp = p[7 * 64];\
sum1 op1 MULS((w1)[7 * 64], tmp);\
sum2 op2 MULS((w2)[7 * 64], tmp);\
Fabrice Bellard
committed
}
void ff_mpa_synth_init(MPA_INT *window)
{
int i;
/* max = 18760, max sum over all 16 coefs : 44736 */
for(i=0;i<257;i++) {
int v;
v = mpa_enwindow[i];
#if WFRAC_BITS < 16
v = (v + (1 << (16 - WFRAC_BITS - 1))) >> (16 - WFRAC_BITS);
#endif
window[i] = v;
if ((i & 63) != 0)
v = -v;
if (i != 0)
window[512 - i] = v;
Fabrice Bellard
committed
/* 32 sub band synthesis filter. Input: 32 sub band samples, Output:
32 samples. */
/* XXX: optimize by avoiding ring buffer usage */
void ff_mpa_synth_filter(MPA_INT *synth_buf_ptr, int *synth_buf_offset,
MPA_INT *window, int *dither_state,
Fabrice Bellard
committed
{
Fabrice Bellard
committed
register MPA_INT *synth_buf;
Fabrice Bellard
committed
int j, offset, v;
OUT_INT *samples2;
Fabrice Bellard
committed
#if FRAC_BITS <= 15
Fabrice Bellard
committed
int sum, sum2;
Fabrice Bellard
committed
#else
Fabrice Bellard
committed
int64_t sum, sum2;
Fabrice Bellard
committed
#endif
Fabrice Bellard
committed
dct32(tmp, sb_samples);
offset = *synth_buf_offset;
synth_buf = synth_buf_ptr + offset;
Fabrice Bellard
committed
for(j=0;j<32;j++) {
v = tmp[j];
#if FRAC_BITS <= 15
Fabrice Bellard
committed
/* NOTE: can cause a loss in precision if very high amplitude
sound */
Fabrice Bellard
committed
if (v > 32767)
v = 32767;
else if (v < -32768)
v = -32768;
#endif
synth_buf[j] = v;
}
/* copy to avoid wrap */
memcpy(synth_buf + 512, synth_buf, 32 * sizeof(MPA_INT));
Fabrice Bellard
committed
samples2 = samples + 31 * incr;
Fabrice Bellard
committed
w = window;
Fabrice Bellard
committed
w2 = window + 31;
Fabrice Bellard
committed
p = synth_buf + 16;
SUM8(sum, +=, w, p);
p = synth_buf + 48;
SUM8(sum, -=, w + 32, p);
*samples = round_sample(&sum);
Fabrice Bellard
committed
samples += incr;
Fabrice Bellard
committed
w++;
Fabrice Bellard
committed
/* we calculate two samples at the same time to avoid one memory
access per two sample */
for(j=1;j<16;j++) {
sum2 = 0;
p = synth_buf + 16 + j;
SUM8P2(sum, +=, sum2, -=, w, w2, p);
p = synth_buf + 48 - j;
SUM8P2(sum, -=, sum2, -=, w + 32, w2 + 32, p);
*samples = round_sample(&sum);
Fabrice Bellard
committed
samples += incr;
sum += sum2;
*samples2 = round_sample(&sum);
Fabrice Bellard
committed
samples2 -= incr;
Fabrice Bellard
committed
w++;
Fabrice Bellard
committed
w2--;
Fabrice Bellard
committed
}
Fabrice Bellard
committed
p = synth_buf + 32;
SUM8(sum, -=, w + 32, p);
*samples = round_sample(&sum);
Fabrice Bellard
committed
Fabrice Bellard
committed
offset = (offset - 32) & 511;
*synth_buf_offset = offset;
Fabrice Bellard
committed
}
#define C3 FIXHR(0.86602540378443864676/2)
/* 0.5 / cos(pi*(2*i+1)/36) */
static const int icos36[9] = {
FIXR(0.50190991877167369479),
FIXR(0.51763809020504152469), //0
FIXR(0.55168895948124587824),
FIXR(0.61038729438072803416),
FIXR(0.70710678118654752439), //1
FIXR(0.87172339781054900991),
FIXR(1.18310079157624925896),
FIXR(1.93185165257813657349), //2
FIXR(5.73685662283492756461),
};
Fabrice Bellard
committed
/* 0.5 / cos(pi*(2*i+1)/36) */
static const int icos36h[9] = {
FIXHR(0.50190991877167369479/2),
FIXHR(0.51763809020504152469/2), //0
FIXHR(0.55168895948124587824/2),
FIXHR(0.61038729438072803416/2),
FIXHR(0.70710678118654752439/2), //1
FIXHR(0.87172339781054900991/2),
FIXHR(1.18310079157624925896/4),
FIXHR(1.93185165257813657349/4), //2
// FIXHR(5.73685662283492756461),
};
Fabrice Bellard
committed
/* 12 points IMDCT. We compute it "by hand" by factorizing obvious
cases. */
static void imdct12(int *out, int *in)
{
Michael Niedermayer
committed
in0= in[0*3];
in1= in[1*3] + in[0*3];
in2= in[2*3] + in[1*3];
in3= in[3*3] + in[2*3];
in4= in[4*3] + in[3*3];
in5= in[5*3] + in[4*3];
in5 += in3;
in3 += in1;
in2= MULH(2*in2, C3);
out[10]= t1 + t2;
out[ 1]=
out[ 4]= t1 - t2;
in0 += in4>>1;
in4 = in0 + in2;
in5 += 2*in1;
in1 = MULH(in5 + in3, icos36h[1]);
Fabrice Bellard
committed
}
/* cos(pi*i/18) */
#define C1 FIXHR(0.98480775301220805936/2)
#define C2 FIXHR(0.93969262078590838405/2)
#define C3 FIXHR(0.86602540378443864676/2)
#define C4 FIXHR(0.76604444311897803520/2)
#define C5 FIXHR(0.64278760968653932632/2)
#define C6 FIXHR(0.5/2)
#define C7 FIXHR(0.34202014332566873304/2)
#define C8 FIXHR(0.17364817766693034885/2)