Newer
Older
* 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., 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)
Michael Niedermayer
committed
# define MULL(ra, rb) \
({ int rt, dummy; asm (\
"imull %3 \n\t"\
"shrdl %4, %%edx, %%eax \n\t"\
: "=a"(rt), "=d"(dummy)\
: "a" (ra), "rm" (rb), "i"(FRAC_BITS));\
rt; })
# define MUL64(ra, rb) \
({ int64_t rt; asm ("imull %2\n\t" : "=A"(rt) : "a" (ra), "g" (rb)); rt; })
# define MULH(ra, rb) \
({ int rt, dummy; asm ("imull %3\n\t" : "=d"(rt), "=a"(dummy): "a" (ra), "rm" (rb)); rt; })
#elif defined(ARCH_ARMV4L)
# define MULL(a, b) \
({ int lo, hi;\
asm("smull %0, %1, %2, %3 \n\t"\
"mov %0, %0, lsr %4\n\t"\
"add %1, %0, %1, lsl %5\n\t"\
: "=&r"(lo), "=&r"(hi)\
: "r"(b), "r"(a), "i"(FRAC_BITS), "i"(32-FRAC_BITS));\
hi; })
# define MUL64(a,b) ((int64_t)(a) * (int64_t)(b))
# define MULH(a, b) ({ int lo, hi; asm ("smull %0, %1, %2, %3" : "=&r"(lo), "=&r"(hi) : "r"(b), "r"(a)); hi; })
#else
# define MULL(a,b) (((int64_t)(a) * (int64_t)(b)) >> FRAC_BITS)
# define MUL64(a,b) ((int64_t)(a) * (int64_t)(b))
//#define MULH(a,b) (((int64_t)(a) * (int64_t)(b))>>32) //gcc 3.4 creates an incredibly bloated mess out of this
static always_inline int MULH(int a, int b){
return ((int64_t)(a) * (int64_t)(b))>>32;
}
#endif
Fabrice Bellard
committed
#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
struct GranuleDef;
uint8_t inbuf1[2][MPA_MAX_CODED_FRAME_SIZE + BACKSTEP_SIZE]; /* input buffer */
Fabrice Bellard
committed
int free_format_frame_size; /* frame size in case of free format
(zero if currently unknown) */
/* 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 */
int bit_rate;
int old_frame_size;
GetBitContext gb;
Fabrice Bellard
committed
int nb_channels;
int mode;
int mode_ext;
int lsf;
Michael Niedermayer
committed
MPA_INT synth_buf[MPA_MAX_CHANNELS][512 * 2] __attribute__((aligned(16)));
Fabrice Bellard
committed
int synth_buf_offset[MPA_MAX_CHANNELS];
Michael Niedermayer
committed
int32_t sb_samples[MPA_MAX_CHANNELS][36][SBLIMIT] __attribute__((aligned(16)));
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
/**
* 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;
#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;
static uint32_t *table_4_3_value;
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
};
void ff_mpa_synth_init(MPA_INT *window);
Michael Niedermayer
committed
static MPA_INT window[512] __attribute__((aligned(16)));
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
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
/* 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->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_t_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
dprintf("%d: norm=%x s=%x %x %x\n",
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];
uint8_t tmp_bits [256];
uint16_t tmp_codes[256];
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++) {
for(y=0;y<xsize;y++){
tmp_bits [(x << 4) | y]= h->bits [j ];
tmp_codes[(x << 4) | y]= h->codes[j++];
}
Fabrice Bellard
committed
}
init_vlc(&huff_vlc[i], 7, 256,
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 */
table_4_3_exp= av_mallocz_static(TABLE_4_3_SIZE * sizeof(table_4_3_exp[0]));
if(!table_4_3_exp)
return -1;
table_4_3_value= av_mallocz_static(TABLE_4_3_SIZE * sizeof(table_4_3_value[0]));
if(!table_4_3_value)
Fabrice Bellard
committed
return -1;
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]= lrintf(f);
exp_table[exponent]= lrintf(f);
Fabrice Bellard
committed
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
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);
dprintf("is_table_lsf %d %d: %x %x\n",
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
init = 1;
}
s->inbuf_index = 0;
s->inbuf = &s->inbuf1[s->inbuf_index][BACKSTEP_SIZE];
s->inbuf_ptr = s->inbuf;
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
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
#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
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
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
}
# if defined(ARCH_POWERPC_405)
/* signed 16x16 -> 32 multiply add accumulate */
# define MACS(rt, ra, rb) \
asm ("maclhw %0, %2, %3" : "=r" (rt) : "0" (rt), "r" (ra), "r" (rb));
/* signed 16x16 -> 32 multiply */
# define MULS(ra, rb) \
({ int __rt; asm ("mullhw %0, %1, %2" : "=r" (__rt) : "r" (ra), "r" (rb)); __rt; })
# else
/* signed 16x16 -> 32 multiply add accumulate */
# define MACS(rt, ra, rb) rt += (ra) * (rb)
/* signed 16x16 -> 32 multiply */
# define MULS(ra, rb) ((ra) * (rb))
# endif
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
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
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];