📄 layer3.c
字号:
MAD_F_ML0(hi, lo, X[0], MAD_F(0x00b2aa3e));
MAD_F_MLA(hi, lo, X[2], MAD_F(0x03768962));
MAD_F_MLA(hi, lo, X[3], -MAD_F(0x04cfb0e2));
MAD_F_MLA(hi, lo, X[5], -MAD_F(0x07635284));
MAD_F_MLA(hi, lo, X[6], MAD_F(0x0898c779));
MAD_F_MLA(hi, lo, X[8], MAD_F(0x0acf37ad));
MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0bcbe352));
MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0d7e8807));
MAD_F_MLA(hi, lo, X[12], MAD_F(0x0e313245));
MAD_F_MLA(hi, lo, X[14], MAD_F(0x0f426cb5));
MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0f9ee890));
MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0ffc19fd));
x[8] = MAD_F_MLZ(hi, lo) + t3;
x[9] = -x[8];
MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0e313245));
MAD_F_MLA(hi, lo, X[2], MAD_F(0x0bcbe352));
MAD_F_MLA(hi, lo, X[3], MAD_F(0x0f9ee890));
MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0898c779));
MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0ffc19fd));
MAD_F_MLA(hi, lo, X[8], MAD_F(0x04cfb0e2));
MAD_F_MLA(hi, lo, X[9], MAD_F(0x0f426cb5));
MAD_F_MLA(hi, lo, X[11], -MAD_F(0x00b2aa3e));
MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0d7e8807));
MAD_F_MLA(hi, lo, X[14], -MAD_F(0x03768962));
MAD_F_MLA(hi, lo, X[15], MAD_F(0x0acf37ad));
MAD_F_MLA(hi, lo, X[17], MAD_F(0x07635284));
x[21] = x[32] = MAD_F_MLZ(hi, lo) + t3;
MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0d7e8807));
MAD_F_MLA(hi, lo, X[2], MAD_F(0x0f426cb5));
MAD_F_MLA(hi, lo, X[3], MAD_F(0x0acf37ad));
MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0ffc19fd));
MAD_F_MLA(hi, lo, X[6], -MAD_F(0x07635284));
MAD_F_MLA(hi, lo, X[8], MAD_F(0x0f9ee890));
MAD_F_MLA(hi, lo, X[9], MAD_F(0x03768962));
MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0e313245));
MAD_F_MLA(hi, lo, X[12], MAD_F(0x00b2aa3e));
MAD_F_MLA(hi, lo, X[14], MAD_F(0x0bcbe352));
MAD_F_MLA(hi, lo, X[15], -MAD_F(0x04cfb0e2));
MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0898c779));
x[20] = x[33] = MAD_F_MLZ(hi, lo) - t3;
MAD_F_ML0(hi, lo, t14, -MAD_F(0x0ec835e8));
MAD_F_MLA(hi, lo, t15, MAD_F(0x061f78aa));
t4 = MAD_F_MLZ(hi, lo) - t7;
MAD_F_ML0(hi, lo, t12, MAD_F(0x061f78aa));
MAD_F_MLA(hi, lo, t13, MAD_F(0x0ec835e8));
x[4] = MAD_F_MLZ(hi, lo) + t4;
x[13] = -x[4];
MAD_F_ML0(hi, lo, t8, MAD_F(0x09bd7ca0));
MAD_F_MLA(hi, lo, t9, -MAD_F(0x0216a2a2));
MAD_F_MLA(hi, lo, t10, MAD_F(0x0fdcf549));
MAD_F_MLA(hi, lo, t11, -MAD_F(0x0cb19346));
x[1] = MAD_F_MLZ(hi, lo) + t4;
x[16] = -x[1];
MAD_F_ML0(hi, lo, t8, -MAD_F(0x0fdcf549));
MAD_F_MLA(hi, lo, t9, -MAD_F(0x0cb19346));
MAD_F_MLA(hi, lo, t10, -MAD_F(0x09bd7ca0));
MAD_F_MLA(hi, lo, t11, -MAD_F(0x0216a2a2));
x[25] = x[28] = MAD_F_MLZ(hi, lo) + t4;
MAD_F_ML0(hi, lo, X[1], -MAD_F(0x0fdcf549));
MAD_F_MLA(hi, lo, X[7], -MAD_F(0x0cb19346));
MAD_F_MLA(hi, lo, X[10], -MAD_F(0x09bd7ca0));
MAD_F_MLA(hi, lo, X[16], -MAD_F(0x0216a2a2));
t5 = MAD_F_MLZ(hi, lo) - t6;
MAD_F_ML0(hi, lo, X[0], MAD_F(0x0898c779));
MAD_F_MLA(hi, lo, X[2], MAD_F(0x04cfb0e2));
MAD_F_MLA(hi, lo, X[3], MAD_F(0x0bcbe352));
MAD_F_MLA(hi, lo, X[5], MAD_F(0x00b2aa3e));
MAD_F_MLA(hi, lo, X[6], MAD_F(0x0e313245));
MAD_F_MLA(hi, lo, X[8], -MAD_F(0x03768962));
MAD_F_MLA(hi, lo, X[9], MAD_F(0x0f9ee890));
MAD_F_MLA(hi, lo, X[11], -MAD_F(0x07635284));
MAD_F_MLA(hi, lo, X[12], MAD_F(0x0ffc19fd));
MAD_F_MLA(hi, lo, X[14], -MAD_F(0x0acf37ad));
MAD_F_MLA(hi, lo, X[15], MAD_F(0x0f426cb5));
MAD_F_MLA(hi, lo, X[17], -MAD_F(0x0d7e8807));
x[2] = MAD_F_MLZ(hi, lo) + t5;
x[15] = -x[2];
MAD_F_ML0(hi, lo, X[0], MAD_F(0x07635284));
MAD_F_MLA(hi, lo, X[2], MAD_F(0x0acf37ad));
MAD_F_MLA(hi, lo, X[3], MAD_F(0x03768962));
MAD_F_MLA(hi, lo, X[5], MAD_F(0x0d7e8807));
MAD_F_MLA(hi, lo, X[6], -MAD_F(0x00b2aa3e));
MAD_F_MLA(hi, lo, X[8], MAD_F(0x0f426cb5));
MAD_F_MLA(hi, lo, X[9], -MAD_F(0x04cfb0e2));
MAD_F_MLA(hi, lo, X[11], MAD_F(0x0ffc19fd));
MAD_F_MLA(hi, lo, X[12], -MAD_F(0x0898c779));
MAD_F_MLA(hi, lo, X[14], MAD_F(0x0f9ee890));
MAD_F_MLA(hi, lo, X[15], -MAD_F(0x0bcbe352));
MAD_F_MLA(hi, lo, X[17], MAD_F(0x0e313245));
x[3] = MAD_F_MLZ(hi, lo) + t5;
x[14] = -x[3];
MAD_F_ML0(hi, lo, X[0], -MAD_F(0x0ffc19fd));
MAD_F_MLA(hi, lo, X[2], -MAD_F(0x0f9ee890));
MAD_F_MLA(hi, lo, X[3], -MAD_F(0x0f426cb5));
MAD_F_MLA(hi, lo, X[5], -MAD_F(0x0e313245));
MAD_F_MLA(hi, lo, X[6], -MAD_F(0x0d7e8807));
MAD_F_MLA(hi, lo, X[8], -MAD_F(0x0bcbe352));
MAD_F_MLA(hi, lo, X[9], -MAD_F(0x0acf37ad));
MAD_F_MLA(hi, lo, X[11], -MAD_F(0x0898c779));
MAD_F_MLA(hi, lo, X[12], -MAD_F(0x07635284));
MAD_F_MLA(hi, lo, X[14], -MAD_F(0x04cfb0e2));
MAD_F_MLA(hi, lo, X[15], -MAD_F(0x03768962));
MAD_F_MLA(hi, lo, X[17], -MAD_F(0x00b2aa3e));
x[26] = x[27] = MAD_F_MLZ(hi, lo) + t5;
}
# endif
/*
* NAME: III_imdct_l()
* DESCRIPTION: perform IMDCT and windowing for long blocks
*/
static
void III_imdct_l(mad_fixed_t const X[18], mad_fixed_t z[36],
unsigned int block_type)
{
unsigned int i;
/* IMDCT */
imdct36(X, z);
/* windowing */
switch (block_type) {
case 0: /* normal window */
# if defined(ASO_INTERLEAVE1)
{
register mad_fixed_t tmp1, tmp2;
tmp1 = window_l[0];
tmp2 = window_l[1];
for (i = 0; i < 34; i += 2) {
z[i + 0] = mad_f_mul(z[i + 0], tmp1);
tmp1 = window_l[i + 2];
z[i + 1] = mad_f_mul(z[i + 1], tmp2);
tmp2 = window_l[i + 3];
}
z[34] = mad_f_mul(z[34], tmp1);
z[35] = mad_f_mul(z[35], tmp2);
}
# elif defined(ASO_INTERLEAVE2)
{
register mad_fixed_t tmp1, tmp2;
tmp1 = z[0];
tmp2 = window_l[0];
for (i = 0; i < 35; ++i) {
z[i] = mad_f_mul(tmp1, tmp2);
tmp1 = z[i + 1];
tmp2 = window_l[i + 1];
}
z[35] = mad_f_mul(tmp1, tmp2);
}
# elif 1
for (i = 0; i < 36; i += 4) {
z[i + 0] = mad_f_mul(z[i + 0], window_l[i + 0]);
z[i + 1] = mad_f_mul(z[i + 1], window_l[i + 1]);
z[i + 2] = mad_f_mul(z[i + 2], window_l[i + 2]);
z[i + 3] = mad_f_mul(z[i + 3], window_l[i + 3]);
}
# else
for (i = 0; i < 36; ++i) z[i] = mad_f_mul(z[i], window_l[i]);
# endif
break;
case 1: /* start block */
for (i = 0; i < 18; i += 3) {
z[i + 0] = mad_f_mul(z[i + 0], window_l[i + 0]);
z[i + 1] = mad_f_mul(z[i + 1], window_l[i + 1]);
z[i + 2] = mad_f_mul(z[i + 2], window_l[i + 2]);
}
/* (i = 18; i < 24; ++i) z[i] unchanged */
for (i = 24; i < 30; ++i) z[i] = mad_f_mul(z[i], window_s[i - 18]);
for (i = 30; i < 36; ++i) z[i] = 0;
break;
case 3: /* stop block */
for (i = 0; i < 6; ++i) z[i] = 0;
for (i = 6; i < 12; ++i) z[i] = mad_f_mul(z[i], window_s[i - 6]);
/* (i = 12; i < 18; ++i) z[i] unchanged */
for (i = 18; i < 36; i += 3) {
z[i + 0] = mad_f_mul(z[i + 0], window_l[i + 0]);
z[i + 1] = mad_f_mul(z[i + 1], window_l[i + 1]);
z[i + 2] = mad_f_mul(z[i + 2], window_l[i + 2]);
}
break;
}
}
# endif /* ASO_IMDCT */
/*
* NAME: III_imdct_s()
* DESCRIPTION: perform IMDCT and windowing for short blocks
*/
static
void III_imdct_s(mad_fixed_t const X[18], mad_fixed_t z[36])
{
mad_fixed_t y[36], *yptr;
mad_fixed_t const *wptr;
int w, i;
register mad_fixed64hi_t hi;
register mad_fixed64lo_t lo;
/* IMDCT */
yptr = &y[0];
for (w = 0; w < 3; ++w) {
register mad_fixed_t const (*s)[6];
s = imdct_s;
for (i = 0; i < 3; ++i) {
MAD_F_ML0(hi, lo, X[0], (*s)[0]);
MAD_F_MLA(hi, lo, X[1], (*s)[1]);
MAD_F_MLA(hi, lo, X[2], (*s)[2]);
MAD_F_MLA(hi, lo, X[3], (*s)[3]);
MAD_F_MLA(hi, lo, X[4], (*s)[4]);
MAD_F_MLA(hi, lo, X[5], (*s)[5]);
yptr[i + 0] = MAD_F_MLZ(hi, lo);
yptr[5 - i] = -yptr[i + 0];
++s;
MAD_F_ML0(hi, lo, X[0], (*s)[0]);
MAD_F_MLA(hi, lo, X[1], (*s)[1]);
MAD_F_MLA(hi, lo, X[2], (*s)[2]);
MAD_F_MLA(hi, lo, X[3], (*s)[3]);
MAD_F_MLA(hi, lo, X[4], (*s)[4]);
MAD_F_MLA(hi, lo, X[5], (*s)[5]);
yptr[ i + 6] = MAD_F_MLZ(hi, lo);
yptr[11 - i] = yptr[i + 6];
++s;
}
yptr += 12;
X += 6;
}
/* windowing, overlapping and concatenation */
yptr = &y[0];
wptr = &window_s[0];
for (i = 0; i < 6; ++i) {
z[i + 0] = 0;
z[i + 6] = mad_f_mul(yptr[ 0 + 0], wptr[0]);
MAD_F_ML0(hi, lo, yptr[ 0 + 6], wptr[6]);
MAD_F_MLA(hi, lo, yptr[12 + 0], wptr[0]);
z[i + 12] = MAD_F_MLZ(hi, lo);
MAD_F_ML0(hi, lo, yptr[12 + 6], wptr[6]);
MAD_F_MLA(hi, lo, yptr[24 + 0], wptr[0]);
z[i + 18] = MAD_F_MLZ(hi, lo);
z[i + 24] = mad_f_mul(yptr[24 + 6], wptr[6]);
z[i + 30] = 0;
++yptr;
++wptr;
}
}
/*
* NAME: III_overlap()
* DESCRIPTION: perform overlap-add of windowed IMDCT outputs
*/
static
void III_overlap(mad_fixed_t const output[36], mad_fixed_t overlap[18],
mad_fixed_t sample[18][32], unsigned int sb)
{
unsigned int i;
# if defined(ASO_INTERLEAVE2)
{
register mad_fixed_t tmp1, tmp2;
tmp1 = overlap[0];
tmp2 = overlap[1];
for (i = 0; i < 16; i += 2) {
sample[i + 0][sb] = output[i + 0 + 0] + tmp1;
overlap[i + 0] = output[i + 0 + 18];
tmp1 = overlap[i + 2];
sample[i + 1][sb] = output[i + 1 + 0] + tmp2;
overlap[i + 1] = output[i + 1 + 18];
tmp2 = overlap[i + 3];
}
sample[16][sb] = output[16 + 0] + tmp1;
overlap[16] = output[16 + 18];
sample[17][sb] = output[17 + 0] + tmp2;
overlap[17] = output[17 + 18];
}
# elif 0
for (i = 0; i < 18; i += 2) {
sample[i + 0][sb] = output[i + 0 + 0] + overlap[i + 0];
overlap[i + 0] = output[i + 0 + 18];
sample[i + 1][sb] = output[i + 1 + 0] + overlap[i + 1];
overlap[i + 1] = output[i + 1 + 18];
}
# else
for (i = 0; i < 18; ++i) {
sample[i][sb] = output[i + 0] + overlap[i];
overlap[i] = output[i + 18];
}
# endif
}
/*
* NAME: III_overlap_z()
* DESCRIPTION: perform "overlap-add" of zero IMDCT outputs
*/
static inline
void III_overlap_z(mad_fixed_t overlap[18],
mad_fixed_t sample[18][32], unsigned int sb)
{
unsigned int i;
# if defined(ASO_INTERLEAVE2)
{
register mad_fixed_t tmp1, tmp2;
tmp1 = overlap[0];
tmp2 = overlap[1];
for (i = 0; i < 16; i += 2) {
sample[i + 0][sb] = tmp1;
overlap[i + 0] = 0;
tmp1 = overlap[i + 2];
sample[i + 1][sb] = tmp2;
overlap[i + 1] = 0;
tmp2 = overlap[i + 3];
}
sample[16][sb] = tmp1;
overlap[16] = 0;
sample[17][sb] = tmp2;
overlap[17] = 0;
}
# else
for (i = 0; i < 18; ++i) {
sample[i][sb] = overlap[i];
overlap[i] = 0;
}
# endif
}
/*
* NAME: III_freqinver()
* DESCRIPTION: perform subband frequency inversion for odd sample lines
*/
static
void III_freqinver(mad_fixed_t sample[18][32], unsigned int sb)
{
unsigned int i;
# if 1 || defined(ASO_INTERLEAVE1) || defined(ASO_INTERLEAVE2)
{
register mad_fixed_t tmp1, tmp2;
tmp1 = sample[1][sb];
tmp2 = sample[3][sb];
for (i = 1; i < 13; i += 4) {
sample[i + 0][sb] = -tmp1;
tmp1 = sample[i + 4][sb];
sample[i + 2][sb] = -tmp2;
tmp2 = sample[i + 6][sb];
}
sample[13][sb] = -tmp1;
tmp1 = sample[17][sb];
sample[15][sb] = -tmp2;
sample[17][sb] = -tmp1;
}
# else
for (i = 1; i < 18; i += 2)
sample[i][sb] = -sample[i][sb];
# endif
}
/*
* NAME: III_decode()
* DESCRIPTION: decode frame main_data
*/
static
enum mad_error III_decode(struct mad_bitptr *ptr, struct mad_frame *frame,
struct sideinfo *si, unsigned int nch)
{
struct mad_header *header = &frame->header;
unsigned int sfreqi, ngr, gr;
{
unsigned int sfreq;
sfreq = header->samplerate;
if (header->flags & MAD_FLAG_MPEG_2_5_EXT)
sfreq *= 2;
/* 48000 => 0, 44100 => 1, 32000 => 2,
24000 => 3, 22050 => 4, 16000 => 5 */
sfreqi = ((sfreq >> 7) & 0x000f) +
((sfreq >> 15) & 0x0001) - 8;
if (header->flags & MAD_FLAG_MPEG_2_5_EXT)
sfreqi += 3;
}
/* scalefactors, Huffman decoding, requantization */
ngr = (header->flags & MAD_FLAG_LSF_EXT) ? 1 : 2;
for (gr = 0; gr < ngr; ++gr) {
struct granule *granule = &si->gr[gr];
unsigned char const *sfbwidth[2];
mad_fixed_t xr[2][576];
unsigned int ch;
enum mad_error error;
for (ch = 0; ch < nch; ++ch) {
struct channel *channel = &granule->ch[ch];
unsigned int part2_length;
sfbwidth[ch] = sfbwidth_table[sfreqi].l;
if (channel->block_type == 2) {
sfbwidth[ch] = (channel->flags & mixed_block_flag) ?
sfbwidth_table[sfreqi].m : sfbwidth_table[sfreqi].s;
}
if (header->flags & MAD_FLAG_LSF_EXT) {
part2_length = III_scalefactors_lsf(ptr, channel,
ch == 0 ? 0 : &si->gr[1].ch[1],
header->mode_extension);
}
else {
part2_length = III_scalefactors(ptr, channel, &si->gr[0].ch[ch],
gr == 0 ? 0 : si->scfsi[ch]);
}
error = III_huffdecode(ptr, xr[ch], channel, sfbwidth[ch], part2_length);
if (error)
return error;
}
/* joint stereo processing */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -