Newer
Older
* Copyright (c) 2001, 2002 Fabrice Bellard
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
#include "dsputil.h"
Fabrice Bellard
committed
* TODO:
* - in low precision mode, use more 16 bit multiplies in synth filter
* - test lsf / mpeg25 extensively.
#if CONFIG_FLOAT
# define SHR(a,b) ((a)*(1.0/(1<<(b))))
# define compute_antialias compute_antialias_float
# define FIXR_OLD(a) ((int)((a) * FRAC_ONE + 0.5))
# define FIXR(x) (x)
# define FIXHR(x) (x)
# define MULH3(x, y, s) ((s)*(y)*(x))
# define MULLx(x, y, s) ((y)*(x))
# define RENAME(a) a ## _float
#else
# define SHR(a,b) ((a)>>(b))
# define compute_antialias compute_antialias_integer
Fabrice Bellard
committed
/* WARNING: only correct for posititive numbers */
# define FIXR_OLD(a) ((int)((a) * FRAC_ONE + 0.5))
# define FIXR(a) ((int)((a) * FRAC_ONE + 0.5))
# define FIXHR(a) ((int)((a) * (1LL<<32) + 0.5))
# define MULH3(x, y, s) MULH((s)*(x), y)
# define MULLx(x, y, s) MULL(x,y,s)
# define RENAME(a) a
#endif
Fabrice Bellard
committed
/****************/
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 */
static VLC_TYPE huff_vlc_tables[
0+128+128+128+130+128+154+166+
142+204+190+170+542+460+662+414
][2];
static const int huff_vlc_tables_sizes[16] = {
0, 128, 128, 128, 130, 128, 154, 166,
142, 204, 190, 170, 542, 460, 662, 414
};
Fabrice Bellard
committed
static VLC huff_quad_vlc[2];
static VLC_TYPE huff_quad_vlc_tables[128+16][2];
static const int huff_quad_vlc_tables_sizes[2] = {
128, 16
};
Fabrice Bellard
committed
/* computed from band_size_long */
static uint16_t band_index_long[9][23];
#include "mpegaudio_tablegen.h"
Fabrice Bellard
committed
/* intensity stereo coef table */
static INTFLOAT is_table[2][16];
static INTFLOAT 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_OLD(1.0 * (v)), FIXR_OLD(0.7937005259 * (v)), FIXR_OLD(0.6299605249 * (v)) }
Fabrice Bellard
committed
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
};
DECLARE_ALIGNED(16, MPA_INT, RENAME(ff_mpa_synth_window))[512];
/**
* Convert region offsets to region sizes and truncate
* size to big_values.
*/
static void ff_region_offset2size(GranuleDef *g){
int i, k, j=0;
g->region_size[2] = (576 / 2);
for(i=0;i<3;i++) {
k = FFMIN(g->region_size[i], g->big_values);
g->region_size[i] = k - j;
j = k;
}
}
static void ff_init_short_region(MPADecodeContext *s, GranuleDef *g){
if (g->block_type == 2)
g->region_size[0] = (36 / 2);
else {
if (s->sample_rate_index <= 2)
g->region_size[0] = (36 / 2);
else if (s->sample_rate_index != 8)
g->region_size[0] = (54 / 2);
else
g->region_size[0] = (108 / 2);
}
g->region_size[1] = (576 / 2);
}
static void ff_init_long_region(MPADecodeContext *s, GranuleDef *g, int ra1, int ra2){
int l;
g->region_size[0] =
band_index_long[s->sample_rate_index][ra1 + 1] >> 1;
/* should not overflow */
l = FFMIN(ra1 + ra2 + 2, 22);
g->region_size[1] =
band_index_long[s->sample_rate_index][l] >> 1;
}
static void ff_compute_band_indexes(MPADecodeContext *s, GranuleDef *g){
if (g->block_type == 2) {
if (g->switch_point) {
/* if switched mode, we handle the 36 first samples as
long blocks. For 8000Hz, we handle the 48 first
exponents as long blocks (XXX: check this!) */
if (s->sample_rate_index <= 2)
g->long_end = 8;
else if (s->sample_rate_index != 8)
g->long_end = 6;
else
g->long_end = 4; /* 8000 Hz */
g->short_start = 2 + (s->sample_rate_index != 8);
} else {
g->long_end = 0;
g->short_start = 0;
}
} else {
g->short_start = 13;
g->long_end = 22;
}
}
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 av_cold void int_pow_init(void)
Fabrice Bellard
committed
{
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
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
286
/* 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 av_cold int decode_init(AVCodecContext * avctx)
static int init=0;
Fabrice Bellard
committed
int i, j, k;
avctx->sample_fmt= OUT_FMT;
s->error_recognition= avctx->error_recognition;
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);
scale_factor_mult[i][0] = MULLx(norm, FIXR(1.0 * 2.0), FRAC_BITS);
scale_factor_mult[i][1] = MULLx(norm, FIXR(0.7937005259 * 2.0), FRAC_BITS);
scale_factor_mult[i][2] = MULLx(norm, FIXR(0.6299605249 * 2.0), FRAC_BITS);
Fabrice Bellard
committed
scale_factor_mult[i][0],
scale_factor_mult[i][1],
scale_factor_mult[i][2]);
}
RENAME(ff_mpa_synth_init)(RENAME(ff_mpa_synth_window));
Fabrice Bellard
committed
/* huffman decode tables */
Fabrice Bellard
committed
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;
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
}
huff_vlc[i].table = huff_vlc_tables+offset;
huff_vlc[i].table_allocated = huff_vlc_tables_sizes[i];
tmp_bits, 1, 1, tmp_codes, 2, 2,
INIT_VLC_USE_NEW_STATIC);
offset += huff_vlc_tables_sizes[i];
Fabrice Bellard
committed
}
assert(offset == FF_ARRAY_ELEMS(huff_vlc_tables));
Fabrice Bellard
committed
for(i=0;i<2;i++) {
huff_quad_vlc[i].table = huff_quad_vlc_tables+offset;
huff_quad_vlc[i].table_allocated = huff_quad_vlc_tables_sizes[i];
init_vlc(&huff_quad_vlc[i], i == 0 ? 7 : 4, 16,
mpa_quad_bits[i], 1, 1, mpa_quad_codes[i], 1, 1,
INIT_VLC_USE_NEW_STATIC);
offset += huff_quad_vlc_tables_sizes[i];
Fabrice Bellard
committed
}
assert(offset == FF_ARRAY_ELEMS(huff_quad_vlc_tables));
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();
mpegaudio_tableinit();
Fabrice Bellard
committed
for(i=0;i<7;i++) {
float f;
Fabrice Bellard
committed
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;
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)));
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 (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
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
#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;\
tab[b] = MULH3(tmp1, c, 1<<(s));\
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(INTFLOAT *out, INTFLOAT *tab)
Fabrice Bellard
committed
{
Fabrice Bellard
committed
/* 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
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
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 CONFIG_FLOAT
static inline float round_sample(float *sum)
{
float sum1=*sum;
*sum = 0;
return sum1;
}
/* signed 16x16 -> 32 multiply add accumulate */
#define MACS(rt, ra, rb) rt+=(ra)*(rb)
/* signed 16x16 -> 32 multiply */
#define MULS(ra, rb) ((ra)*(rb))
#define MLSS(rt, ra, rb) rt-=(ra)*(rb)
#elif FRAC_BITS <= 15
Fabrice Bellard
committed
static inline int round_sample(int *sum)
Fabrice Bellard
committed
{
int sum1;
sum1 = (*sum) >> OUT_SHIFT;
*sum &= (1<<OUT_SHIFT)-1;
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)
#define MLSS(rt, ra, rb) MLS16(rt, 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;
Fabrice Bellard
committed
}
# define MACS(rt, ra, rb) MAC64(rt, ra, rb)
# define MLSS(rt, ra, rb) MLS64(rt, ra, rb)
Fabrice Bellard
committed
#endif
#define SUM8(op, sum, w, p) \
{ \
op(sum, (w)[0 * 64], (p)[0 * 64]); \
op(sum, (w)[1 * 64], (p)[1 * 64]); \
op(sum, (w)[2 * 64], (p)[2 * 64]); \
op(sum, (w)[3 * 64], (p)[3 * 64]); \
op(sum, (w)[4 * 64], (p)[4 * 64]); \
op(sum, (w)[5 * 64], (p)[5 * 64]); \
op(sum, (w)[6 * 64], (p)[6 * 64]); \
op(sum, (w)[7 * 64], (p)[7 * 64]); \
Fabrice Bellard
committed
}
#define SUM8P2(sum1, op1, sum2, op2, w1, w2, p) \
{ \
Fabrice Bellard
committed
tmp = p[0 * 64];\
op1(sum1, (w1)[0 * 64], tmp);\
op2(sum2, (w2)[0 * 64], tmp);\
Fabrice Bellard
committed
tmp = p[1 * 64];\
op1(sum1, (w1)[1 * 64], tmp);\
op2(sum2, (w2)[1 * 64], tmp);\
Fabrice Bellard
committed
tmp = p[2 * 64];\
op1(sum1, (w1)[2 * 64], tmp);\
op2(sum2, (w2)[2 * 64], tmp);\
Fabrice Bellard
committed
tmp = p[3 * 64];\
op1(sum1, (w1)[3 * 64], tmp);\
op2(sum2, (w2)[3 * 64], tmp);\
Fabrice Bellard
committed
tmp = p[4 * 64];\
op1(sum1, (w1)[4 * 64], tmp);\
op2(sum2, (w2)[4 * 64], tmp);\
Fabrice Bellard
committed
tmp = p[5 * 64];\
op1(sum1, (w1)[5 * 64], tmp);\
op2(sum2, (w2)[5 * 64], tmp);\
Fabrice Bellard
committed
tmp = p[6 * 64];\
op1(sum1, (w1)[6 * 64], tmp);\
op2(sum2, (w2)[6 * 64], tmp);\
Fabrice Bellard
committed
tmp = p[7 * 64];\
op1(sum1, (w1)[7 * 64], tmp);\
op2(sum2, (w2)[7 * 64], tmp);\
Fabrice Bellard
committed
}
void av_cold RENAME(ff_mpa_synth_init)(MPA_INT *window)
{
int i;
/* max = 18760, max sum over all 16 coefs : 44736 */
for(i=0;i<257;i++) {
v = ff_mpa_enwindow[i];
#if CONFIG_FLOAT
v *= 1.0 / (1LL<<(16 + FRAC_BITS));
#elif 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 RENAME(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;
OUT_INT *samples2;
#if CONFIG_FLOAT
float sum, sum2;
#elif FRAC_BITS <= 15
int32_t tmp[32];
Fabrice Bellard
committed
int sum, sum2;
Fabrice Bellard
committed
#else
Fabrice Bellard
committed
int64_t sum, sum2;
Fabrice Bellard
committed
#endif
offset = *synth_buf_offset;
synth_buf = synth_buf_ptr + offset;
Fabrice Bellard
committed
#if FRAC_BITS <= 15
dct32(tmp, sb_samples);
for(j=0;j<32;j++) {
Fabrice Bellard
committed
/* NOTE: can cause a loss in precision if very high amplitude
sound */
synth_buf[j] = av_clip_int16(tmp[j]);
Fabrice Bellard
committed
}
#else
dct32(synth_buf, sb_samples);
#endif
Fabrice Bellard
committed
/* copy to avoid wrap */
memcpy(synth_buf + 512, synth_buf, 32 * sizeof(*synth_buf));
Fabrice Bellard
committed
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(MACS, sum, w, p);
Fabrice Bellard
committed
p = synth_buf + 48;
SUM8(MLSS, 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, MACS, sum2, MLSS, w, w2, p);
Fabrice Bellard
committed
p = synth_buf + 48 - j;
SUM8P2(sum, MLSS, sum2, MLSS, w + 32, w2 + 32, p);
Fabrice Bellard
committed
*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(MLSS, 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 INTFLOAT 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
static const INTFLOAT 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(INTFLOAT *out, INTFLOAT *in)
Fabrice Bellard
committed
{
INTFLOAT in0, in1, in2, in3, in4, in5, t1, t2;
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];
in2= MULH3(in2, C3, 2);
in3= MULH3(in3, C3, 4);
t2 = MULH3(in1 - in5, icos36h[4], 2);
out[10]= t1 + t2;
out[ 1]=
out[ 4]= t1 - t2;
in1 = MULH3(in5 + in3, icos36h[1], 1);
in5 = MULH3(in5 - in3, icos36h[7], 2);
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)
Fabrice Bellard
committed
/* using Lee like decomposition followed by hand coded 9 points DCT */
static void imdct36(INTFLOAT *out, INTFLOAT *buf, INTFLOAT *in, INTFLOAT *win)
Fabrice Bellard
committed
{
int i, j;
INTFLOAT t0, t1, t2, t3, s0, s1, s2, s3;
INTFLOAT tmp[18], *tmp1, *in1;
Fabrice Bellard
committed
for(i=17;i>=1;i--)
in[i] += in[i-1];
for(i=17;i>=3;i-=2)
in[i] += in[i-2];
for(j=0;j<2;j++) {
tmp1 = tmp + j;