mirror of
https://github.com/FWGS/xash3d-fwgs
synced 2024-12-03 07:31:11 +01:00
5e0a0765ce
The `.editorconfig` file in this repo is configured to trim all trailing whitespace regardless of whether the line is modified. Trims all trailing whitespace in the repository to make the codebase easier to work with in editors that respect `.editorconfig`. `git blame` becomes less useful on these lines but it already isn't very useful. Commands: ``` find . -type f -name '*.h' -exec sed --in-place 's/[[:space:]]\+$//' {} \+ find . -type f -name '*.c' -exec sed --in-place 's/[[:space:]]\+$//' {} \+ ```
1595 lines
36 KiB
C
1595 lines
36 KiB
C
/*
|
|
layer3.c - compact version of famous library mpg123
|
|
Copyright (C) 2017 Uncle Mike
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program 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 General Public License for more details.
|
|
*/
|
|
|
|
#include "mpg123.h"
|
|
#include "huffman.h"
|
|
#include "getbits.h"
|
|
#include <math.h>
|
|
|
|
// static one-time calculated tables... or so
|
|
float COS6_1; // dct12 wants to use that
|
|
float COS6_2; // dct12 wants to use that
|
|
float cos9[3]; // dct36 wants to use that
|
|
float cos18[3]; // dct36 wants to use that
|
|
float tfcos12[3]; // dct12 wants to use that
|
|
float tfcos36[9]; // dct36 wants to use that
|
|
static float ispow[8207];
|
|
static float COS9[9];
|
|
static float aa_ca[8];
|
|
static float aa_cs[8];
|
|
static float win[4][36];
|
|
static float win1[4][36];
|
|
static float tan1_1[16];
|
|
static float tan2_1[16];
|
|
static float tan1_2[16];
|
|
static float tan2_2[16];
|
|
static float pow1_1[2][16];
|
|
static float pow2_1[2][16];
|
|
static float pow1_2[2][16];
|
|
static float pow2_2[2][16];
|
|
static int mapbuf0[9][152];
|
|
static int mapbuf1[9][156];
|
|
static int mapbuf2[9][44];
|
|
static int *map[9][3];
|
|
static int *mapend[9][3];
|
|
static uint n_slen2[512]; // MPEG 2.0 slen for 'normal' mode
|
|
static uint i_slen2[256]; // MPEG 2.0 slen for intensity stereo
|
|
|
|
// Decoder state data, living on the stack of do_layer3.
|
|
typedef struct gr_info_s
|
|
{
|
|
int scfsi;
|
|
uint part2_3_length;
|
|
uint big_values;
|
|
uint scalefac_compress;
|
|
uint block_type;
|
|
uint mixed_block_flag;
|
|
uint table_select[3];
|
|
|
|
// making those two signed int as workaround for open64/pathscale/sun compilers,
|
|
// and also for consistency, since they're worked on together with other signed variables.
|
|
int maxband[3];
|
|
int maxbandl;
|
|
uint maxb;
|
|
uint region1start;
|
|
uint region2start;
|
|
uint preflag;
|
|
uint scalefac_scale;
|
|
uint count1table_select;
|
|
float *full_gain[3];
|
|
float *pow2gain;
|
|
} gr_info_t;
|
|
|
|
typedef struct
|
|
{
|
|
uint main_data_begin;
|
|
uint private_bits;
|
|
|
|
// hm, funny... struct inside struct...
|
|
struct
|
|
{
|
|
gr_info_t gr[2];
|
|
} ch[2];
|
|
} III_sideinfo;
|
|
|
|
typedef struct
|
|
{
|
|
word longIdx[23];
|
|
byte longDiff[22];
|
|
word shortIdx[14];
|
|
byte shortDiff[13];
|
|
} bandInfoStruct;
|
|
|
|
// techy details about our friendly MPEG data. Fairly constant over the years ;-)
|
|
static const bandInfoStruct bandInfo[9] =
|
|
{
|
|
{ // MPEG 1.0
|
|
{0,4,8,12,16,20,24,30,36,44,52,62,74, 90,110,134,162,196,238,288,342,418,576},
|
|
{4,4,4,4,4,4,6,6,8, 8,10,12,16,20,24,28,34,42,50,54, 76,158},
|
|
{0,4*3,8*3,12*3,16*3,22*3,30*3,40*3,52*3,66*3, 84*3,106*3,136*3,192*3},
|
|
{4,4,4,4,6,8,10,12,14,18,22,30,56}
|
|
},
|
|
{
|
|
{0,4,8,12,16,20,24,30,36,42,50,60,72, 88,106,128,156,190,230,276,330,384,576},
|
|
{4,4,4,4,4,4,6,6,6, 8,10,12,16,18,22,28,34,40,46,54, 54,192},
|
|
{0,4*3,8*3,12*3,16*3,22*3,28*3,38*3,50*3,64*3, 80*3,100*3,126*3,192*3},
|
|
{4,4,4,4,6,6,10,12,14,16,20,26,66}
|
|
},
|
|
{
|
|
{0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576},
|
|
{4,4,4,4,4,4,6,6,8,10,12,16,20,24,30,38,46,56,68,84,102, 26},
|
|
{0,4*3,8*3,12*3,16*3,22*3,30*3,42*3,58*3,78*3,104*3,138*3,180*3,192*3},
|
|
{4,4,4,4,6,8,12,16,20,26,34,42,12}
|
|
},
|
|
{ // MPEG 2.0
|
|
{0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
|
|
{6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 } ,
|
|
{0,4*3,8*3,12*3,18*3,24*3,32*3,42*3,56*3,74*3,100*3,132*3,174*3,192*3} ,
|
|
{4,4,4,6,6,8,10,14,18,26,32,42,18 }
|
|
},
|
|
{ // twiddling 3 values here (not just 330->332!) fixed bug 1895025.
|
|
{0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,332,394,464,540,576},
|
|
{6,6,6,6,6,6,8,10,12,14,16,18,22,26,32,38,46,54,62,70,76,36 },
|
|
{0,4*3,8*3,12*3,18*3,26*3,36*3,48*3,62*3,80*3,104*3,136*3,180*3,192*3},
|
|
{4,4,4,6,8,10,12,14,18,24,32,44,12 }
|
|
},
|
|
{
|
|
{0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
|
|
{6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 },
|
|
{0,4*3,8*3,12*3,18*3,26*3,36*3,48*3,62*3,80*3,104*3,134*3,174*3,192*3},
|
|
{4,4,4,6,8,10,12,14,18,24,30,40,18 }
|
|
},
|
|
{ // MPEG 2.5
|
|
{0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
|
|
{6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54},
|
|
{0,12,24,36,54,78,108,144,186,240,312,402,522,576},
|
|
{4,4,4,6,8,10,12,14,18,24,30,40,18}
|
|
},
|
|
{
|
|
{0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576},
|
|
{6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54},
|
|
{0,12,24,36,54,78,108,144,186,240,312,402,522,576},
|
|
{4,4,4,6,8,10,12,14,18,24,30,40,18}
|
|
},
|
|
{
|
|
{0,12,24,36,48,60,72,88,108,132,160,192,232,280,336,400,476,566,568,570,572,574,576},
|
|
{12,12,12,12,12,12,16,20,24,28,32,40,48,56,64,76,90,2,2,2,2,2},
|
|
{0, 24, 48, 72,108,156,216,288,372,480,486,492,498,576},
|
|
{8,8,8,12,16,20,24,28,36,2,2,2,26}
|
|
}
|
|
};
|
|
|
|
static byte pretab_choice[2][22] =
|
|
{
|
|
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
|
|
{0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,3,3,3,2,0}
|
|
};
|
|
|
|
// init tables for layer-3 ... specific with the downsampling...
|
|
void init_layer3( void )
|
|
{
|
|
int i, j, k, l;
|
|
|
|
for( i = 0; i < 8207; i++ )
|
|
ispow[i] = DOUBLE_TO_REAL_POW43( pow( (double)i, (double)4.0 / 3.0 ));
|
|
|
|
for( i = 0; i < 8; i++ )
|
|
{
|
|
const double Ci[8] = { -0.6, -0.535, -0.33, -0.185, -0.095, -0.041, -0.0142, -0.0037 };
|
|
double sq = sqrt( 1.0 + Ci[i] * Ci[i] );
|
|
aa_cs[i] = DOUBLE_TO_REAL( 1.0 / sq );
|
|
aa_ca[i] = DOUBLE_TO_REAL( Ci[i] / sq );
|
|
}
|
|
|
|
for( i = 0; i < 18; i++ )
|
|
{
|
|
win[0][i] = win[1][i] = DOUBLE_TO_REAL( 0.5 * sin( M_PI / 72.0 * (double)(2 * (i + 0) + 1)) / cos( M_PI * (double)(2 * (i + 0) + 19) / 72.0) );
|
|
win[0][i+18] = win[3][i+18] = DOUBLE_TO_REAL( 0.5 * sin( M_PI/72.0 * (double)(2 * (i + 18) + 1)) / cos( M_PI * (double)(2 * (i + 18) + 19) / 72.0) );
|
|
}
|
|
|
|
for( i = 0; i < 6; i++ )
|
|
{
|
|
win[1][i+18] = DOUBLE_TO_REAL( 0.5 / cos ( M_PI * (double)(2 * (i + 18) + 19) / 72.0 ));
|
|
win[3][i+12] = DOUBLE_TO_REAL( 0.5 / cos ( M_PI * (double)(2 * (i + 12) + 19) / 72.0 ));
|
|
win[1][i+24] = DOUBLE_TO_REAL( 0.5 * sin( M_PI / 24.0 * (double)(2 * i + 13)) / cos( M_PI * (double)(2 * (i + 24) + 19) / 72.0 ));
|
|
win[1][i+30] = win[3][i] = DOUBLE_TO_REAL( 0.0 );
|
|
win[3][i+6 ] = DOUBLE_TO_REAL( 0.5 * sin( M_PI / 24.0 * (double)(2 * i + 1)) / cos( M_PI * (double)(2 * (i + 6 ) + 19) / 72.0 ));
|
|
}
|
|
|
|
for( i = 0; i < 9; i++ )
|
|
COS9[i] = DOUBLE_TO_REAL( cos( M_PI / 18.0 * (double)i ));
|
|
|
|
for( i = 0; i < 9; i++ )
|
|
tfcos36[i] = DOUBLE_TO_REAL( 0.5 / cos( M_PI * (double)(i * 2 + 1) / 36.0 ));
|
|
|
|
for( i = 0; i < 3; i++ )
|
|
tfcos12[i] = DOUBLE_TO_REAL( 0.5 / cos( M_PI * (double)(i * 2 + 1) / 12.0 ));
|
|
|
|
COS6_1 = DOUBLE_TO_REAL( cos( M_PI / 6.0 * (double)1 ));
|
|
COS6_2 = DOUBLE_TO_REAL( cos( M_PI / 6.0 * (double)2 ));
|
|
|
|
cos9[0] = DOUBLE_TO_REAL( cos( 1.0 * M_PI / 9.0));
|
|
cos9[1] = DOUBLE_TO_REAL( cos( 5.0 * M_PI / 9.0));
|
|
cos9[2] = DOUBLE_TO_REAL( cos( 7.0 * M_PI / 9.0));
|
|
cos18[0] = DOUBLE_TO_REAL( cos( 1.0 * M_PI / 18.0));
|
|
cos18[1] = DOUBLE_TO_REAL( cos( 11.0 * M_PI / 18.0));
|
|
cos18[2] = DOUBLE_TO_REAL( cos( 13.0 * M_PI / 18.0));
|
|
|
|
for( i = 0; i < 12; i++ )
|
|
win[2][i] = DOUBLE_TO_REAL( 0.5 * sin( M_PI / 24.0 * (double)(2 * i + 1) ) / cos( M_PI * (double)(2 * i + 7) / 24.0 ));
|
|
|
|
for( i = 0; i < 16; i++ )
|
|
{
|
|
double t = tan((double)i * M_PI / 12.0 );
|
|
tan1_1[i] = DOUBLE_TO_REAL_15( t / (1.0 + t));
|
|
tan2_1[i] = DOUBLE_TO_REAL_15( 1.0 / (1.0 + t));
|
|
tan1_2[i] = DOUBLE_TO_REAL_15( M_SQRT2 * t / (1.0 + t));
|
|
tan2_2[i] = DOUBLE_TO_REAL_15( M_SQRT2 / (1.0 + t));
|
|
|
|
for( j = 0; j < 2; j++ )
|
|
{
|
|
double base = pow( 2.0, -0.25 * (j + 1.0));
|
|
double p1 = 1.0, p2 = 1.0;
|
|
|
|
if( i > 0 )
|
|
{
|
|
if( i & 1 ) p1 = pow( base,(i + 1.0) * 0.5);
|
|
else p2 = pow( base, i * 0.5 );
|
|
}
|
|
|
|
pow1_1[j][i] = DOUBLE_TO_REAL_15( p1 );
|
|
pow2_1[j][i] = DOUBLE_TO_REAL_15( p2 );
|
|
pow1_2[j][i] = DOUBLE_TO_REAL_15( M_SQRT2 * p1 );
|
|
pow2_2[j][i] = DOUBLE_TO_REAL_15( M_SQRT2 * p2 );
|
|
}
|
|
}
|
|
|
|
for( j = 0; j < 4; j++ )
|
|
{
|
|
const int len[4] = { 36, 36, 12, 36 };
|
|
|
|
for( i = 0; i < len[j]; i += 2 )
|
|
win1[j][i] = +win[j][i];
|
|
|
|
for( i = 1; i < len[j]; i += 2 )
|
|
win1[j][i] = -win[j][i];
|
|
}
|
|
|
|
for( j = 0; j < 9; j++ )
|
|
{
|
|
const bandInfoStruct *bi = &bandInfo[j];
|
|
int cb, lwin;
|
|
const byte *bdf;
|
|
int *mp;
|
|
|
|
mp = map[j][0] = mapbuf0[j];
|
|
bdf = bi->longDiff;
|
|
|
|
for( i = 0, cb = 0; cb < 8 ; cb++, i += *bdf++ )
|
|
{
|
|
*mp++ = (*bdf) >> 1;
|
|
*mp++ = i;
|
|
*mp++ = 3;
|
|
*mp++ = cb;
|
|
}
|
|
|
|
bdf = bi->shortDiff + 3;
|
|
for( cb = 3;cb < 13; cb++ )
|
|
{
|
|
int l = (*bdf++) >> 1;
|
|
for( lwin = 0; lwin < 3; lwin++ )
|
|
{
|
|
*mp++ = l;
|
|
*mp++ = i + lwin;
|
|
*mp++ = lwin;
|
|
*mp++ = cb;
|
|
}
|
|
i += 6 * l;
|
|
}
|
|
|
|
mapend[j][0] = mp;
|
|
mp = map[j][1] = mapbuf1[j];
|
|
bdf = bi->shortDiff + 0;
|
|
|
|
for( i = 0, cb = 0; cb < 13; cb++ )
|
|
{
|
|
int l = (*bdf++) >> 1;
|
|
for( lwin = 0; lwin < 3; lwin++ )
|
|
{
|
|
*mp++ = l;
|
|
*mp++ = i + lwin;
|
|
*mp++ = lwin;
|
|
*mp++ = cb;
|
|
}
|
|
i += 6 * l;
|
|
}
|
|
|
|
mapend[j][1] = mp;
|
|
mp = map[j][2] = mapbuf2[j];
|
|
bdf = bi->longDiff;
|
|
|
|
for( cb = 0; cb < 22; cb++ )
|
|
{
|
|
*mp++ = (*bdf++) >> 1;
|
|
*mp++ = cb;
|
|
}
|
|
mapend[j][2] = mp;
|
|
}
|
|
|
|
// now for some serious loopings!
|
|
for( i = 0; i < 5; i++ )
|
|
{
|
|
for( j = 0; j < 6; j++ )
|
|
{
|
|
for( k = 0; k < 6; k++ )
|
|
{
|
|
int n = k + j * 6 + i * 36;
|
|
i_slen2[n] = i|(j<<3)|(k<<6)|(3<<12);
|
|
}
|
|
}
|
|
}
|
|
|
|
for( i = 0; i < 4; i++ )
|
|
{
|
|
for( j = 0; j < 4; j++ )
|
|
{
|
|
for( k = 0; k < 4; k++ )
|
|
{
|
|
int n = k + j * 4 + i * 16;
|
|
i_slen2[n+180] = i|(j<<3)|(k<<6)|(4<<12);
|
|
}
|
|
}
|
|
}
|
|
|
|
for( i = 0; i < 4; i++ )
|
|
{
|
|
for( j = 0; j < 3; j++ )
|
|
{
|
|
int n = j + i * 3;
|
|
i_slen2[n+244] = i|(j<<3) | (5<<12);
|
|
n_slen2[n+500] = i|(j<<3) | (2<<12) | (1<<15);
|
|
}
|
|
}
|
|
|
|
for( i = 0; i < 5; i++ )
|
|
{
|
|
for( j = 0; j < 5; j++ )
|
|
{
|
|
for( k = 0; k < 4; k++ )
|
|
{
|
|
for( l = 0; l < 4; l++ )
|
|
{
|
|
int n = l + k * 4 + j * 16 + i * 80;
|
|
n_slen2[n] = i|(j<<3)|(k<<6)|(l<<9)|(0<<12);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
for( i = 0; i < 5; i++ )
|
|
{
|
|
for( j = 0; j < 5; j++ )
|
|
{
|
|
for( k = 0; k < 4; k++ )
|
|
{
|
|
int n = k + j * 4 + i * 20;
|
|
n_slen2[n+400] = i|(j<<3)|(k<<6)|(1<<12);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void init_layer3_stuff( mpg123_handle_t *fr )
|
|
{
|
|
int i,j;
|
|
|
|
for( i = -256; i < 118 + 4; i++ )
|
|
fr->gainpow2[i+256] = DOUBLE_TO_REAL_SCALE_LAYER3( pow((double)2.0, -0.25 * (double)(i + 210)), i + 256 );
|
|
|
|
for( j = 0; j < 9; j++ )
|
|
{
|
|
for( i = 0; i < 23; i++ )
|
|
{
|
|
fr->longLimit[j][i] = (bandInfo[j].longIdx[i] - 1 + 8) / 18 + 1;
|
|
|
|
if( fr->longLimit[j][i] > fr->down_sample_sblimit )
|
|
fr->longLimit[j][i] = fr->down_sample_sblimit;
|
|
}
|
|
|
|
for( i = 0; i < 14; i++ )
|
|
{
|
|
fr->shortLimit[j][i] = (bandInfo[j].shortIdx[i] - 1) / 18 + 1;
|
|
|
|
if( fr->shortLimit[j][i] > fr->down_sample_sblimit )
|
|
fr->shortLimit[j][i] = fr->down_sample_sblimit;
|
|
}
|
|
}
|
|
}
|
|
|
|
// read additional side information (for MPEG 1 and MPEG 2)
|
|
static int III_get_side_info( mpg123_handle_t *fr, III_sideinfo *si, int stereo, int ms_stereo, long sfreq, int single )
|
|
{
|
|
int powdiff = (single == SINGLE_MIX) ? 4 : 0;
|
|
const int tabs[2][5] = { { 2,9,5,3,4 } , { 1,8,1,2,9 } };
|
|
const int *tab = tabs[fr->lsf];
|
|
int ch, gr;
|
|
|
|
si->main_data_begin = getbits( fr, tab[1] );
|
|
|
|
if( si->main_data_begin > fr->bitreservoir )
|
|
{
|
|
// overwrite main_data_begin for the floatly available bit reservoir
|
|
backbits( fr, tab[1] );
|
|
|
|
if( fr->lsf == 0 )
|
|
{
|
|
fr->wordpointer[0] = (byte)(fr->bitreservoir >> 1);
|
|
fr->wordpointer[1] = (byte)((fr->bitreservoir & 1) << 7);
|
|
}
|
|
else fr->wordpointer[0] = (byte)fr->bitreservoir;
|
|
|
|
// zero "side-info" data for a silence-frame
|
|
// without touching audio data used as bit reservoir for following frame
|
|
memset( fr->wordpointer + 2, 0, fr->ssize - 2 );
|
|
|
|
// reread the new bit reservoir offset
|
|
si->main_data_begin = getbits( fr, tab[1] );
|
|
}
|
|
|
|
// keep track of the available data bytes for the bit reservoir.
|
|
// think: Substract the 2 crc bytes in parser already?
|
|
fr->bitreservoir = fr->bitreservoir + fr->framesize - fr->ssize - (fr->error_protection ? 2 : 0);
|
|
// limit the reservoir to the max for MPEG 1.0 or 2.x.
|
|
if( fr->bitreservoir > (uint)(fr->lsf == 0 ? 511 : 255 ))
|
|
fr->bitreservoir = (fr->lsf == 0 ? 511 : 255);
|
|
|
|
// now back into less commented territory. It's code. It works.
|
|
|
|
if( stereo == 1 ) si->private_bits = getbits_fast( fr, tab[2] );
|
|
else si->private_bits = getbits_fast( fr, tab[3] );
|
|
|
|
if( !fr->lsf )
|
|
{
|
|
for( ch = 0; ch < stereo; ch++ )
|
|
{
|
|
si->ch[ch].gr[0].scfsi = -1;
|
|
si->ch[ch].gr[1].scfsi = getbits_fast( fr, 4 );
|
|
}
|
|
}
|
|
|
|
for( gr = 0; gr < tab[0]; gr++ )
|
|
{
|
|
for( ch = 0; ch < stereo; ch++ )
|
|
{
|
|
register gr_info_t *gr_info = &( si->ch[ch].gr[gr] );
|
|
|
|
gr_info->part2_3_length = getbits( fr, 12 );
|
|
gr_info->big_values = getbits( fr, 9 );
|
|
|
|
if( gr_info->big_values > 288 )
|
|
gr_info->big_values = 288;
|
|
|
|
gr_info->pow2gain = fr->gainpow2 + 256 - getbits_fast( fr, 8 ) + powdiff;
|
|
if( ms_stereo ) gr_info->pow2gain += 2;
|
|
|
|
gr_info->scalefac_compress = getbits( fr, tab[4] );
|
|
|
|
if( get1bit( fr ))
|
|
{
|
|
int i;
|
|
|
|
// window switch flag
|
|
gr_info->block_type = getbits_fast( fr, 2 );
|
|
gr_info->mixed_block_flag = get1bit( fr );
|
|
gr_info->table_select[0] = getbits_fast( fr, 5 );
|
|
gr_info->table_select[1] = getbits_fast( fr, 5 );
|
|
|
|
// table_select[2] not needed, because there is no region2,
|
|
// but to satisfy some verification tools we set it either.
|
|
gr_info->table_select[2] = 0;
|
|
|
|
for( i = 0; i < 3; i++ )
|
|
gr_info->full_gain[i] = gr_info->pow2gain + (getbits_fast( fr, 3 ) << 3);
|
|
|
|
if( gr_info->block_type == 0 )
|
|
return 1;
|
|
|
|
// region_count/start parameters are implicit in this case.
|
|
if(( !fr->lsf || ( gr_info->block_type == 2 )) && !fr->mpeg25 )
|
|
{
|
|
gr_info->region1start = 36 >> 1;
|
|
gr_info->region2start = 576 >> 1;
|
|
}
|
|
else
|
|
{
|
|
if( fr->mpeg25 )
|
|
{
|
|
int r0c, r1c;
|
|
|
|
if(( gr_info->block_type == 2 ) && ( !gr_info->mixed_block_flag ))
|
|
r0c = 5;
|
|
else r0c = 7;
|
|
|
|
// r0c + 1 + r1c + 1 == 22, always.
|
|
r1c = 20 - r0c;
|
|
gr_info->region1start = bandInfo[sfreq].longIdx[r0c+1] >> 1 ;
|
|
gr_info->region2start = bandInfo[sfreq].longIdx[r0c+1+r1c+1] >> 1;
|
|
}
|
|
else
|
|
{
|
|
gr_info->region1start = 54 >> 1;
|
|
gr_info->region2start = 576 >> 1;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int i, r0c, r1c;
|
|
|
|
for( i = 0; i < 3; i++ )
|
|
gr_info->table_select[i] = getbits_fast( fr, 5 );
|
|
|
|
r0c = getbits_fast( fr, 4 ); // 0 .. 15
|
|
r1c = getbits_fast( fr, 3 ); // 0 .. 7
|
|
gr_info->region1start = bandInfo[sfreq].longIdx[r0c+1] >> 1 ;
|
|
|
|
// max( r0c + r1c + 2 ) = 15 + 7 + 2 = 24
|
|
if( r0c + 1 + r1c + 1 > 22 )
|
|
gr_info->region2start = 576 >> 1;
|
|
else gr_info->region2start = bandInfo[sfreq].longIdx[r0c+1+r1c+1] >> 1;
|
|
|
|
gr_info->block_type = 0;
|
|
gr_info->mixed_block_flag = 0;
|
|
}
|
|
|
|
if( !fr->lsf )
|
|
gr_info->preflag = get1bit( fr );
|
|
|
|
gr_info->scalefac_scale = get1bit( fr );
|
|
gr_info->count1table_select = get1bit( fr );
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// read scalefactors
|
|
static int III_get_scale_factors_1( mpg123_handle_t *fr, int *scf, gr_info_t *gr_info )
|
|
{
|
|
const byte slen[2][16] =
|
|
{
|
|
{ 0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 },
|
|
{ 0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3 }
|
|
};
|
|
int num0 = slen[0][gr_info->scalefac_compress];
|
|
int num1 = slen[1][gr_info->scalefac_compress];
|
|
int numbits;
|
|
|
|
if( gr_info->block_type == 2 )
|
|
{
|
|
int i = 18;
|
|
numbits = (num0 + num1) * 18;
|
|
|
|
if( gr_info->mixed_block_flag )
|
|
{
|
|
for( i = 8; i; i-- )
|
|
*scf++ = getbits_fast( fr, num0 );
|
|
|
|
i = 9;
|
|
numbits -= num0; // num0 * 17 + num1 * 18
|
|
}
|
|
|
|
for( ; i; i-- )
|
|
*scf++ = getbits_fast( fr, num0 );
|
|
|
|
for( i = 18; i; i-- )
|
|
*scf++ = getbits_fast( fr, num1 );
|
|
|
|
// short[13][0..2] = 0
|
|
*scf++ = 0;
|
|
*scf++ = 0;
|
|
*scf++ = 0;
|
|
}
|
|
else
|
|
{
|
|
int i, scfsi = gr_info->scfsi;
|
|
|
|
if( scfsi < 0 )
|
|
{
|
|
// scfsi < 0 => granule == 0
|
|
for( i = 11; i; i-- )
|
|
*scf++ = getbits_fast( fr, num0 );
|
|
|
|
for( i = 10; i; i-- )
|
|
*scf++ = getbits_fast( fr, num1 );
|
|
|
|
numbits = (num0 + num1) * 10 + num0;
|
|
*scf++ = 0;
|
|
}
|
|
else
|
|
{
|
|
numbits = 0;
|
|
|
|
if(!( scfsi & 0x8 ))
|
|
{
|
|
for( i = 0; i < 6; i++ )
|
|
*scf++ = getbits_fast( fr, num0 );
|
|
|
|
numbits += num0 * 6;
|
|
}
|
|
else scf += 6;
|
|
|
|
if(!( scfsi & 0x4 ))
|
|
{
|
|
for( i = 0; i < 5; i++ )
|
|
*scf++ = getbits_fast( fr, num0 );
|
|
|
|
numbits += num0 * 5;
|
|
}
|
|
else scf += 5;
|
|
|
|
if(!( scfsi & 0x2 ))
|
|
{
|
|
for( i = 0; i < 5; i++ )
|
|
*scf++ = getbits_fast( fr, num1 );
|
|
|
|
numbits += num1 * 5;
|
|
}
|
|
else scf += 5;
|
|
|
|
if(!( scfsi & 0x1 ))
|
|
{
|
|
for( i = 0; i < 5; i++ )
|
|
*scf++ = getbits_fast( fr, num1 );
|
|
|
|
numbits += num1 * 5;
|
|
}
|
|
else scf += 5;
|
|
|
|
// no l[21] in original sources
|
|
*scf++ = 0;
|
|
}
|
|
}
|
|
|
|
return numbits;
|
|
}
|
|
|
|
static int III_get_scale_factors_2( mpg123_handle_t *fr, int *scf, gr_info_t *gr_info, int i_stereo )
|
|
{
|
|
const byte *pnt;
|
|
int i, j, n = 0;
|
|
int numbits = 0;
|
|
uint slen;
|
|
|
|
const byte stab[3][6][4] =
|
|
{
|
|
{
|
|
{ 6, 5, 5,5 } , { 6, 5, 7,3 } , { 11,10,0,0},
|
|
{ 7, 7, 7,0 } , { 6, 6, 6,3 } , { 8, 8,5,0}
|
|
},
|
|
{
|
|
{ 9, 9, 9,9 } , { 9, 9,12,6 } , { 18,18,0,0},
|
|
{12,12,12,0 } , {12, 9, 9,6 } , { 15,12,9,0}
|
|
},
|
|
{
|
|
{ 6, 9, 9,9 } , { 6, 9,12,6 } , { 15,18,0,0},
|
|
{ 6,15,12,0 } , { 6,12, 9,6 } , { 6,18,9,0}
|
|
}
|
|
};
|
|
|
|
// i_stereo AND second channel -> do_layer3() checks this
|
|
if( i_stereo ) slen = i_slen2[gr_info->scalefac_compress>>1];
|
|
else slen = n_slen2[gr_info->scalefac_compress];
|
|
|
|
gr_info->preflag = (slen >> 15) & 0x1;
|
|
n = 0;
|
|
|
|
if( gr_info->block_type == 2 )
|
|
{
|
|
if( gr_info->mixed_block_flag )
|
|
n++;
|
|
n++;
|
|
}
|
|
|
|
pnt = stab[n][(slen>>12)&0x7];
|
|
|
|
for( i = 0; i < 4; i++ )
|
|
{
|
|
int num = slen & 0x7;
|
|
|
|
slen >>= 3;
|
|
if( num )
|
|
{
|
|
for( j = 0; j < (int)(pnt[i]); j++ )
|
|
*scf++ = getbits_fast( fr, num );
|
|
numbits += pnt[i] * num;
|
|
}
|
|
else
|
|
{
|
|
for( j = 0; j < (int)(pnt[i]); j++ )
|
|
*scf++ = 0;
|
|
}
|
|
}
|
|
|
|
n = (n << 1) + 1;
|
|
|
|
for( i = 0; i < n; i++ )
|
|
*scf++ = 0;
|
|
|
|
return numbits;
|
|
}
|
|
|
|
/* 24 is enough because tab13 has max. a 19 bit huffvector */
|
|
/* The old code played games with shifting signed integers around in not quite */
|
|
/* legal ways. Also, it used long where just 32 bits are required. This could */
|
|
/* be good or bad on 64 bit architectures ... anyway, making clear that */
|
|
/* 32 bits suffice is a benefit. */
|
|
#if 0
|
|
/* To reconstruct old code, use this: */
|
|
#define MASK_STYPE long
|
|
#define MASK_UTYPE unsigned long
|
|
#define MASK_TYPE MASK_STYPE
|
|
#define MSB_MASK (mask < 0)
|
|
#else
|
|
/* This should be more proper: */
|
|
#define MASK_STYPE int32_t
|
|
#define MASK_UTYPE uint32_t
|
|
#define MASK_TYPE MASK_UTYPE
|
|
#define MSB_MASK ((MASK_UTYPE)mask & (MASK_UTYPE)1<<(sizeof(MASK_TYPE)*8-1))
|
|
#endif
|
|
|
|
// 24 is enough because tab13 has max. a 19 bit huffvector
|
|
#define BITSHIFT ((sizeof(MASK_TYPE) - 1) * 8)
|
|
|
|
#define REFRESH_MASK \
|
|
while( num < BITSHIFT ) { \
|
|
mask |= ((MASK_UTYPE)getbyte( fr )) << (BITSHIFT - num); \
|
|
num += 8; \
|
|
part2remain -= 8; }
|
|
|
|
static int III_dequantize_sample( mpg123_handle_t *fr, float xr[SBLIMIT][SSLIMIT], int *scf, gr_info_t *gr_info, int sfreq, int part2bits )
|
|
{
|
|
int shift = 1 + gr_info->scalefac_scale;
|
|
int part2remain = gr_info->part2_3_length - part2bits;
|
|
int region1 = gr_info->region1start;
|
|
int region2 = gr_info->region2start;
|
|
int bv = gr_info->big_values;
|
|
int num = getbitoffset( fr );
|
|
float *xrpnt = (float *)xr;
|
|
int l[3], l3;
|
|
MASK_TYPE mask;
|
|
int *me;
|
|
|
|
// we must split this, because for num == 0 the shift is undefined if you do it in one step.
|
|
mask = ((MASK_UTYPE)getbits( fr, num )) << BITSHIFT;
|
|
mask <<= 8 - num;
|
|
part2remain -= num;
|
|
|
|
l3 = ((576>>1)-bv)>>1;
|
|
|
|
// we may lose the 'odd' bit here !! check this later again
|
|
if( bv <= region1 )
|
|
{
|
|
l[0] = bv;
|
|
l[1] = 0;
|
|
l[2] = 0;
|
|
}
|
|
else
|
|
{
|
|
l[0] = region1;
|
|
|
|
if( bv <= region2 )
|
|
{
|
|
l[1] = bv - l[0];
|
|
l[2] = 0;
|
|
}
|
|
else
|
|
{
|
|
l[1] = region2 - l[0];
|
|
l[2] = bv - region2;
|
|
}
|
|
}
|
|
|
|
if( gr_info->block_type == 2 )
|
|
{
|
|
int i, max[4];
|
|
int step = 0;
|
|
int lwin = 3;
|
|
register float v = 0.0f;
|
|
int cb = 0;
|
|
register int *m, mc;
|
|
int rmax;
|
|
|
|
// decoding with short or mixed mode BandIndex table
|
|
if( gr_info->mixed_block_flag )
|
|
{
|
|
max[3] = -1;
|
|
max[0] = max[1] = max[2] = 2;
|
|
m = map[sfreq][0];
|
|
me = mapend[sfreq][0];
|
|
}
|
|
else
|
|
{
|
|
max[0] = max[1] = max[2] = max[3] = -1;
|
|
// max[3] not floatly needed in this case
|
|
m = map[sfreq][1];
|
|
me = mapend[sfreq][1];
|
|
}
|
|
|
|
mc = 0;
|
|
|
|
for( i = 0; i < 2; i++ )
|
|
{
|
|
const struct newhuff *h = ht + gr_info->table_select[i];
|
|
int lp = l[i];
|
|
|
|
for( ; lp; lp--, mc-- )
|
|
{
|
|
register MASK_STYPE x, y;
|
|
|
|
if( (!mc) )
|
|
{
|
|
mc = *m++;
|
|
xrpnt = ((float *)xr) + (*m++);
|
|
lwin = *m++;
|
|
cb = *m++;
|
|
|
|
if( lwin == 3 )
|
|
{
|
|
v = gr_info->pow2gain[(*scf++) << shift];
|
|
step = 1;
|
|
}
|
|
else
|
|
{
|
|
v = gr_info->full_gain[lwin][(*scf++) << shift];
|
|
step = 3;
|
|
}
|
|
}
|
|
{
|
|
const short *val = h->table;
|
|
REFRESH_MASK;
|
|
|
|
while(( y = *val++ ) < 0 )
|
|
{
|
|
if( MSB_MASK )
|
|
val -= y;
|
|
|
|
num--;
|
|
mask <<= 1;
|
|
}
|
|
x = y >> 4;
|
|
y &= 0xf;
|
|
}
|
|
|
|
if( x == 15 && h->linbits )
|
|
{
|
|
max[lwin] = cb;
|
|
REFRESH_MASK;
|
|
|
|
x += ((MASK_UTYPE)mask) >> (BITSHIFT + 8 - h->linbits);
|
|
num -= h->linbits + 1;
|
|
mask <<= h->linbits;
|
|
|
|
if( MSB_MASK ) *xrpnt = REAL_MUL_SCALE_LAYER3( -ispow[x], v );
|
|
else *xrpnt = REAL_MUL_SCALE_LAYER3( ispow[x], v );
|
|
|
|
mask <<= 1;
|
|
}
|
|
else if( x )
|
|
{
|
|
max[lwin] = cb;
|
|
|
|
if( MSB_MASK ) *xrpnt = REAL_MUL_SCALE_LAYER3( -ispow[x], v );
|
|
else *xrpnt = REAL_MUL_SCALE_LAYER3( ispow[x], v );
|
|
|
|
num--;
|
|
mask <<= 1;
|
|
}
|
|
else *xrpnt = DOUBLE_TO_REAL(0.0);
|
|
|
|
xrpnt += step;
|
|
|
|
if( y == 15 && h->linbits )
|
|
{
|
|
max[lwin] = cb;
|
|
REFRESH_MASK;
|
|
|
|
y += ((MASK_UTYPE) mask) >> (BITSHIFT + 8 - h->linbits);
|
|
num -= h->linbits + 1;
|
|
mask <<= h->linbits;
|
|
|
|
if( MSB_MASK ) *xrpnt = REAL_MUL_SCALE_LAYER3( -ispow[y], v );
|
|
else *xrpnt = REAL_MUL_SCALE_LAYER3( ispow[y], v );
|
|
|
|
mask <<= 1;
|
|
}
|
|
else if( y )
|
|
{
|
|
max[lwin] = cb;
|
|
|
|
if( MSB_MASK ) *xrpnt = REAL_MUL_SCALE_LAYER3( -ispow[y], v );
|
|
else *xrpnt = REAL_MUL_SCALE_LAYER3( ispow[y], v );
|
|
|
|
num--;
|
|
mask <<= 1;
|
|
}
|
|
else *xrpnt = DOUBLE_TO_REAL(0.0);
|
|
|
|
xrpnt += step;
|
|
}
|
|
}
|
|
|
|
for( ; l3 && (part2remain + num > 0); l3-- )
|
|
{
|
|
const struct newhuff *h;
|
|
const short *val;
|
|
register short a;
|
|
|
|
// this is only a humble hack to prevent a special segfault.
|
|
// more insight into the float workings is still needed.
|
|
// especially why there are (valid?) files that make xrpnt exceed the array with 4 bytes without segfaulting
|
|
// more seems to be floatly bad, though.
|
|
|
|
if(!( xrpnt < &xr[SBLIMIT][0] + 5 ))
|
|
return 2;
|
|
|
|
h = htc + gr_info->count1table_select;
|
|
val = h->table;
|
|
|
|
REFRESH_MASK;
|
|
|
|
while(( a = *val++ ) < 0 )
|
|
{
|
|
if( MSB_MASK )
|
|
val -= a;
|
|
|
|
num--;
|
|
mask <<= 1;
|
|
}
|
|
|
|
if( part2remain + num <= 0 )
|
|
{
|
|
num -= part2remain + num;
|
|
break;
|
|
}
|
|
|
|
for( i = 0; i < 4; i++ )
|
|
{
|
|
if(!( i & 1 ))
|
|
{
|
|
if( !mc )
|
|
{
|
|
mc = *m++;
|
|
xrpnt = ((float *)xr) + (*m++);
|
|
lwin = *m++;
|
|
cb = *m++;
|
|
|
|
if( lwin == 3 )
|
|
{
|
|
v = gr_info->pow2gain[(*scf++) << shift];
|
|
step = 1;
|
|
}
|
|
else
|
|
{
|
|
v = gr_info->full_gain[lwin][(*scf++) << shift];
|
|
step = 3;
|
|
}
|
|
}
|
|
mc--;
|
|
}
|
|
|
|
if(( a & ( 0x8 >> i )))
|
|
{
|
|
max[lwin] = cb;
|
|
|
|
if( part2remain + num <= 0 )
|
|
break;
|
|
|
|
if( MSB_MASK ) *xrpnt = -REAL_SCALE_LAYER3( v );
|
|
else *xrpnt = REAL_SCALE_LAYER3( v );
|
|
|
|
num--;
|
|
mask <<= 1;
|
|
}
|
|
else *xrpnt = DOUBLE_TO_REAL( 0.0 );
|
|
|
|
xrpnt += step;
|
|
}
|
|
}
|
|
|
|
if( lwin < 3 )
|
|
{
|
|
// short band?
|
|
while( 1 )
|
|
{
|
|
for( ; mc > 0; mc-- )
|
|
{
|
|
*xrpnt = DOUBLE_TO_REAL( 0.0 );
|
|
xrpnt += 3; // short band -> step = 3
|
|
*xrpnt = DOUBLE_TO_REAL( 0.0 );
|
|
xrpnt += 3;
|
|
}
|
|
|
|
if( m >= me ) break;
|
|
|
|
mc = *m++;
|
|
xrpnt = ((float *)xr) + *m++;
|
|
if( *m++ == 0 ) break; // optimize: field will be set to zero at the end of the function
|
|
|
|
m++; // cb
|
|
}
|
|
}
|
|
|
|
gr_info->maxband[0] = max[0]+1;
|
|
gr_info->maxband[1] = max[1]+1;
|
|
gr_info->maxband[2] = max[2]+1;
|
|
gr_info->maxbandl = max[3]+1;
|
|
|
|
rmax = max[0] > max[1] ? max[0] : max[1];
|
|
rmax = (rmax > max[2] ? rmax : max[2]) + 1;
|
|
gr_info->maxb = rmax ? fr->shortLimit[sfreq][rmax] : fr->longLimit[sfreq][max[3]+1];
|
|
}
|
|
else
|
|
{
|
|
// decoding with 'long' BandIndex table (block_type != 2)
|
|
const byte *pretab = pretab_choice[gr_info->preflag];
|
|
int *m = map[sfreq][2];
|
|
int i,max = -1;
|
|
int cb = 0;
|
|
register float v = 0.0;
|
|
int mc = 0;
|
|
|
|
// long hash table values
|
|
for( i = 0; i < 3; i++ )
|
|
{
|
|
const struct newhuff *h = ht + gr_info->table_select[i];
|
|
int lp = l[i];
|
|
|
|
for( ; lp; lp--, mc-- )
|
|
{
|
|
MASK_STYPE x, y;
|
|
|
|
if( !mc )
|
|
{
|
|
mc = *m++;
|
|
cb = *m++;
|
|
v = gr_info->pow2gain[(*(scf++) + (*pretab++)) << shift];
|
|
}
|
|
{
|
|
const short *val = h->table;
|
|
REFRESH_MASK;
|
|
|
|
while(( y = *val++ ) < 0 )
|
|
{
|
|
if( MSB_MASK )
|
|
val -= y;
|
|
|
|
num--;
|
|
mask <<= 1;
|
|
}
|
|
|
|
x = y >> 4;
|
|
y &= 0xf;
|
|
}
|
|
|
|
if( x == 15 && h->linbits )
|
|
{
|
|
max = cb;
|
|
REFRESH_MASK;
|
|
|
|
x += ((MASK_UTYPE)mask) >> (BITSHIFT + 8 - h->linbits);
|
|
num -= h->linbits+1;
|
|
mask <<= h->linbits;
|
|
|
|
if( MSB_MASK ) *xrpnt++ = REAL_MUL_SCALE_LAYER3(-ispow[x], v );
|
|
else *xrpnt++ = REAL_MUL_SCALE_LAYER3( ispow[x], v );
|
|
|
|
mask <<= 1;
|
|
}
|
|
else if( x )
|
|
{
|
|
max = cb;
|
|
|
|
if( MSB_MASK ) *xrpnt++ = REAL_MUL_SCALE_LAYER3( -ispow[x], v );
|
|
else *xrpnt++ = REAL_MUL_SCALE_LAYER3( ispow[x], v );
|
|
num--;
|
|
|
|
mask <<= 1;
|
|
}
|
|
else *xrpnt++ = DOUBLE_TO_REAL( 0.0 );
|
|
|
|
if( y == 15 && h->linbits )
|
|
{
|
|
max = cb;
|
|
REFRESH_MASK;
|
|
y += ((MASK_UTYPE)mask) >> (BITSHIFT + 8 - h->linbits);
|
|
num -= h->linbits+1;
|
|
mask <<= h->linbits;
|
|
|
|
if( MSB_MASK ) *xrpnt++ = REAL_MUL_SCALE_LAYER3( -ispow[y], v );
|
|
else *xrpnt++ = REAL_MUL_SCALE_LAYER3( ispow[y], v );
|
|
|
|
mask <<= 1;
|
|
}
|
|
else if( y )
|
|
{
|
|
max = cb;
|
|
if( MSB_MASK ) *xrpnt++ = REAL_MUL_SCALE_LAYER3( -ispow[y], v );
|
|
else *xrpnt++ = REAL_MUL_SCALE_LAYER3( ispow[y], v );
|
|
|
|
num--;
|
|
mask <<= 1;
|
|
}
|
|
else *xrpnt++ = DOUBLE_TO_REAL( 0.0 );
|
|
}
|
|
}
|
|
|
|
// short (count1table) values
|
|
for( ; l3 && (part2remain + num > 0); l3-- )
|
|
{
|
|
const struct newhuff *h = htc+gr_info->count1table_select;
|
|
const short *val = h->table;
|
|
register short a;
|
|
|
|
REFRESH_MASK;
|
|
while(( a = *val++ ) < 0 )
|
|
{
|
|
if( MSB_MASK )
|
|
val -= a;
|
|
|
|
num--;
|
|
mask <<= 1;
|
|
}
|
|
|
|
if( part2remain + num <= 0 )
|
|
{
|
|
num -= part2remain + num;
|
|
break;
|
|
}
|
|
|
|
for( i = 0; i < 4; i++ )
|
|
{
|
|
if(!( i & 1 ))
|
|
{
|
|
if( !mc )
|
|
{
|
|
mc = *m++;
|
|
cb = *m++;
|
|
|
|
v = gr_info->pow2gain[((*scf++) + (*pretab++)) << shift];
|
|
}
|
|
mc--;
|
|
}
|
|
|
|
if(( a & (0x8 >> i)))
|
|
{
|
|
max = cb;
|
|
if( part2remain + num <= 0 )
|
|
break;
|
|
|
|
if( MSB_MASK ) *xrpnt++ = -REAL_SCALE_LAYER3( v );
|
|
else *xrpnt++ = REAL_SCALE_LAYER3( v );
|
|
|
|
num--;
|
|
mask <<= 1;
|
|
}
|
|
else *xrpnt++ = DOUBLE_TO_REAL( 0.0 );
|
|
}
|
|
}
|
|
|
|
gr_info->maxbandl = max+1;
|
|
gr_info->maxb = fr->longLimit[sfreq][gr_info->maxbandl];
|
|
}
|
|
|
|
part2remain += num;
|
|
backbits( fr, num );
|
|
num = 0;
|
|
|
|
while( xrpnt < &xr[SBLIMIT][0] )
|
|
*xrpnt++ = DOUBLE_TO_REAL( 0.0 );
|
|
|
|
while( part2remain > 16 )
|
|
{
|
|
skipbits( fr, 16 ); // dismiss stuffing Bits
|
|
part2remain -= 16;
|
|
}
|
|
|
|
if( part2remain > 0 )
|
|
{
|
|
skipbits( fr, part2remain );
|
|
}
|
|
else if( part2remain < 0 )
|
|
{
|
|
// error
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// calculate float channel values for Joint-I-Stereo-mode
|
|
static void III_i_stereo( float xr_buf[2][SBLIMIT][SSLIMIT], int *scalefac, gr_info_t *gr_info, int sfreq, int ms_stereo, int lsf )
|
|
{
|
|
float (*xr)[SBLIMIT*SSLIMIT] = (float(*)[SBLIMIT*SSLIMIT])xr_buf;
|
|
const bandInfoStruct *bi = &bandInfo[sfreq];
|
|
const float *tab1, *tab2;
|
|
int tab;
|
|
|
|
// TODO: optimize as static
|
|
const float *tabs[3][2][2] =
|
|
{
|
|
{ { tan1_1,tan2_1 } , { tan1_2,tan2_2 } },
|
|
{ { pow1_1[0],pow2_1[0] } , { pow1_2[0],pow2_2[0] } },
|
|
{ { pow1_1[1],pow2_1[1] } , { pow1_2[1],pow2_2[1] } }
|
|
};
|
|
|
|
tab = lsf + (gr_info->scalefac_compress & lsf);
|
|
tab1 = tabs[tab][ms_stereo][0];
|
|
tab2 = tabs[tab][ms_stereo][1];
|
|
|
|
if( gr_info->block_type == 2 )
|
|
{
|
|
int lwin, do_l = 0;
|
|
|
|
if( gr_info->mixed_block_flag )
|
|
do_l = 1;
|
|
|
|
for( lwin = 0; lwin < 3; lwin++ )
|
|
{
|
|
int is_p, sb, idx;
|
|
int sfb = gr_info->maxband[lwin]; // sfb is minimal 3 for mixed mode
|
|
|
|
if( sfb > 3 ) do_l = 0;
|
|
|
|
// process each window
|
|
// get first band with zero values
|
|
for( ; sfb < 12; sfb++ )
|
|
{
|
|
is_p = scalefac[sfb * 3 + lwin - gr_info->mixed_block_flag]; // scale: 0-15
|
|
|
|
if( is_p != 7 )
|
|
{
|
|
float t1, t2;
|
|
|
|
sb = bi->shortDiff[sfb];
|
|
idx = bi->shortIdx[sfb] + lwin;
|
|
t1 = tab1[is_p];
|
|
t2 = tab2[is_p];
|
|
|
|
for( ; sb > 0; sb--, idx += 3 )
|
|
{
|
|
float v = xr[0][idx];
|
|
xr[0][idx] = REAL_MUL_15( v, t1 );
|
|
xr[1][idx] = REAL_MUL_15( v, t2 );
|
|
}
|
|
}
|
|
}
|
|
|
|
// in the original: copy 10 to 11 , here: copy 11 to 12
|
|
// maybe still wrong??? (copy 12 to 13?)
|
|
is_p = scalefac[11 * 3 + lwin - gr_info->mixed_block_flag]; // scale: 0-15
|
|
sb = bi->shortDiff[12];
|
|
idx = bi->shortIdx[12] + lwin;
|
|
|
|
if( is_p != 7 )
|
|
{
|
|
float t1, t2;
|
|
|
|
t1 = tab1[is_p];
|
|
t2 = tab2[is_p];
|
|
|
|
for( ; sb > 0; sb--, idx += 3 )
|
|
{
|
|
float v = xr[0][idx];
|
|
xr[0][idx] = REAL_MUL_15( v, t1 );
|
|
xr[1][idx] = REAL_MUL_15( v, t2 );
|
|
}
|
|
}
|
|
}
|
|
|
|
// also check l-part, if ALL bands in the three windows are 'empty' and mode = mixed_mode
|
|
if( do_l )
|
|
{
|
|
int idx, sfb = gr_info->maxbandl;
|
|
|
|
if( sfb > 21 ) return; // similarity fix related to CVE-2006-1655
|
|
|
|
idx = bi->longIdx[sfb];
|
|
|
|
for( ; sfb < 8; sfb++ )
|
|
{
|
|
int sb = bi->longDiff[sfb];
|
|
int is_p = scalefac[sfb]; // scale: 0-15
|
|
|
|
if( is_p != 7 )
|
|
{
|
|
float t1, t2;
|
|
|
|
t1 = tab1[is_p];
|
|
t2 = tab2[is_p];
|
|
|
|
for( ; sb > 0; sb--, idx++ )
|
|
{
|
|
float v = xr[0][idx];
|
|
xr[0][idx] = REAL_MUL_15( v, t1 );
|
|
xr[1][idx] = REAL_MUL_15( v, t2 );
|
|
}
|
|
}
|
|
else idx += sb;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
int sfb = gr_info->maxbandl;
|
|
int is_p, idx;
|
|
|
|
if( sfb > 21 ) return; // tightened fix for CVE-2006-1655
|
|
|
|
idx = bi->longIdx[sfb];
|
|
|
|
for( ; sfb < 21; sfb++ )
|
|
{
|
|
int sb = bi->longDiff[sfb];
|
|
|
|
is_p = scalefac[sfb]; // scale: 0-15
|
|
|
|
if( is_p != 7 )
|
|
{
|
|
float t1, t2;
|
|
|
|
t1 = tab1[is_p];
|
|
t2 = tab2[is_p];
|
|
|
|
for( ; sb > 0; sb--, idx++ )
|
|
{
|
|
float v = xr[0][idx];
|
|
xr[0][idx] = REAL_MUL_15( v, t1 );
|
|
xr[1][idx] = REAL_MUL_15( v, t2 );
|
|
}
|
|
}
|
|
else idx += sb;
|
|
}
|
|
|
|
is_p = scalefac[20];
|
|
|
|
if( is_p != 7 )
|
|
{
|
|
float t1, t2;
|
|
int sb;
|
|
|
|
t1 = tab1[is_p],
|
|
t2 = tab2[is_p];
|
|
|
|
// copy l-band 20 to l-band 21
|
|
for( sb = bi->longDiff[21]; sb > 0; sb--, idx++ )
|
|
{
|
|
float v = xr[0][idx];
|
|
xr[0][idx] = REAL_MUL_15( v, t1 );
|
|
xr[1][idx] = REAL_MUL_15( v, t2 );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void III_antialias( float xr[SBLIMIT][SSLIMIT], gr_info_t *gr_info )
|
|
{
|
|
int sblim, sb;
|
|
float *xr1;
|
|
|
|
if( gr_info->block_type == 2 )
|
|
{
|
|
if( !gr_info->mixed_block_flag )
|
|
return;
|
|
sblim = 1;
|
|
}
|
|
else
|
|
{
|
|
sblim = gr_info->maxb-1;
|
|
}
|
|
|
|
// 31 alias-reduction operations between each pair of sub-bands
|
|
// with 8 butterflies between each pair
|
|
xr1 = (float *)xr[1];
|
|
|
|
for( sb = sblim; sb; sb--, xr1 += 10 )
|
|
{
|
|
float *cs = aa_cs;
|
|
float *ca = aa_ca;
|
|
float *xr2 = xr1;
|
|
int ss;
|
|
|
|
for( ss = 7; ss >= 0; ss-- )
|
|
{
|
|
// upper and lower butterfly inputs
|
|
register float bu = *--xr2;
|
|
register float bd = *xr1;
|
|
|
|
*xr2 = REAL_MUL( bu, *cs ) - REAL_MUL( bd, *ca );
|
|
*xr1++ = REAL_MUL( bd, *cs++ ) + REAL_MUL( bu, *ca++ );
|
|
}
|
|
}
|
|
}
|
|
|
|
static void III_hybrid( float fsIn[SBLIMIT][SSLIMIT], float tsOut[SSLIMIT][SBLIMIT], int ch, gr_info_t *gr_info, mpg123_handle_t *fr )
|
|
{
|
|
float (*block)[2][SBLIMIT*SSLIMIT] = fr->hybrid_block;
|
|
int *blc = fr->hybrid_blc;
|
|
float *tspnt = (float *)tsOut;
|
|
float *rawout1, *rawout2;
|
|
int bt = 0, b, i;
|
|
size_t sb = 0;
|
|
|
|
b = blc[ch];
|
|
rawout1 = block[b][ch];
|
|
b=-b + 1;
|
|
rawout2 = block[b][ch];
|
|
blc[ch] = b;
|
|
|
|
if( gr_info->mixed_block_flag )
|
|
{
|
|
sb = 2;
|
|
dct36( fsIn[0], rawout1, rawout2, win[0], tspnt );
|
|
dct36( fsIn[1], rawout1+18, rawout2+18, win1[0], tspnt + 1 );
|
|
rawout1 += 36; rawout2 += 36; tspnt += 2;
|
|
}
|
|
|
|
bt = gr_info->block_type;
|
|
|
|
if( bt == 2 )
|
|
{
|
|
for( ; sb < gr_info->maxb; sb += 2, tspnt += 2, rawout1 += 36, rawout2 += 36 )
|
|
{
|
|
dct12( fsIn[sb], rawout1, rawout2, win[2], tspnt );
|
|
dct12( fsIn[sb+1], rawout1 + 18, rawout2 + 18, win1[2], tspnt + 1 );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for( ; sb < gr_info->maxb; sb += 2, tspnt += 2, rawout1 += 36, rawout2 += 36 )
|
|
{
|
|
dct36( fsIn[sb], rawout1, rawout2, win[bt], tspnt );
|
|
dct36( fsIn[sb+1], rawout1 + 18, rawout2 + 18, win1[bt], tspnt + 1 );
|
|
}
|
|
}
|
|
|
|
for( ; sb < SBLIMIT; sb++, tspnt++ )
|
|
{
|
|
for( i = 0; i < SSLIMIT; i++ )
|
|
{
|
|
tspnt[i*SBLIMIT] = *rawout1++;
|
|
*rawout2++ = DOUBLE_TO_REAL( 0.0 );
|
|
}
|
|
}
|
|
}
|
|
|
|
// and at the end... the main layer3 handler
|
|
int do_layer3( mpg123_handle_t *fr )
|
|
{
|
|
int gr, ch, ss, clip = 0;
|
|
int stereo = fr->stereo;
|
|
int single = fr->single;
|
|
int ms_stereo, i_stereo;
|
|
int sfreq = fr->sampling_frequency;
|
|
int scalefacs[2][39]; // max 39 for short[13][3] mode, mixed: 38, long: 22
|
|
int stereo1, granules;
|
|
III_sideinfo sideinfo;
|
|
|
|
if( stereo == 1 )
|
|
{
|
|
// stream is mono
|
|
stereo1 = 1;
|
|
single = SINGLE_LEFT;
|
|
}
|
|
else if( single != SINGLE_STEREO )
|
|
{
|
|
// stream is stereo, but force to mono
|
|
stereo1 = 1;
|
|
}
|
|
else
|
|
{
|
|
stereo1 = 2;
|
|
}
|
|
|
|
if( fr->mode == MPG_MD_JOINT_STEREO )
|
|
{
|
|
ms_stereo = (fr->mode_ext & 0x2) >> 1;
|
|
i_stereo = fr->mode_ext & 0x1;
|
|
}
|
|
else
|
|
{
|
|
ms_stereo = i_stereo = 0;
|
|
}
|
|
|
|
granules = fr->lsf ? 1 : 2;
|
|
|
|
// quick hack to keep the music playing
|
|
// after having seen this nasty test file...
|
|
if( III_get_side_info( fr, &sideinfo, stereo, ms_stereo, sfreq, single ))
|
|
return clip;
|
|
|
|
set_pointer( fr, sideinfo.main_data_begin );
|
|
|
|
for( gr = 0; gr < granules; gr++ )
|
|
{
|
|
float (*hybridIn)[SBLIMIT][SSLIMIT] = fr->layer3.hybrid_in; // hybridIn[2][SBLIMIT][SSLIMIT]
|
|
float (*hybridOut)[SSLIMIT][SBLIMIT] = fr->layer3.hybrid_out; // hybridOut[2][SSLIMIT][SBLIMIT]
|
|
gr_info_t *gr_info = &(sideinfo.ch[0].gr[gr]);
|
|
long part2bits;
|
|
|
|
if( fr->lsf ) part2bits = III_get_scale_factors_2( fr, scalefacs[0], gr_info, 0 );
|
|
else part2bits = III_get_scale_factors_1( fr, scalefacs[0], gr_info );
|
|
|
|
if( III_dequantize_sample( fr, hybridIn[0], scalefacs[0], gr_info, sfreq, part2bits ))
|
|
return clip;
|
|
|
|
if( stereo == 2 )
|
|
{
|
|
register float *in0, *in1;
|
|
register int i;
|
|
|
|
gr_info = &(sideinfo.ch[1].gr[gr]);
|
|
|
|
if( fr->lsf ) part2bits = III_get_scale_factors_2( fr, scalefacs[1], gr_info, i_stereo );
|
|
else part2bits = III_get_scale_factors_1( fr, scalefacs[1], gr_info );
|
|
|
|
if( III_dequantize_sample( fr, hybridIn[1], scalefacs[1], gr_info, sfreq, part2bits ))
|
|
return clip;
|
|
|
|
if( ms_stereo )
|
|
{
|
|
uint maxb = sideinfo.ch[0].gr[gr].maxb;
|
|
int i;
|
|
|
|
if( sideinfo.ch[1].gr[gr].maxb > maxb )
|
|
maxb = sideinfo.ch[1].gr[gr].maxb;
|
|
|
|
for( i = 0; i < SSLIMIT * (int)maxb; i++ )
|
|
{
|
|
float tmp0 = ((float *)hybridIn[0])[i];
|
|
float tmp1 = ((float *)hybridIn[1])[i];
|
|
((float *)hybridIn[0])[i] = tmp0 + tmp1;
|
|
((float *)hybridIn[1])[i] = tmp0 - tmp1;
|
|
}
|
|
}
|
|
|
|
if( i_stereo )
|
|
III_i_stereo( hybridIn, scalefacs[1], gr_info, sfreq, ms_stereo, fr->lsf );
|
|
|
|
if( ms_stereo || i_stereo || ( single == SINGLE_MIX ))
|
|
{
|
|
if( gr_info->maxb > sideinfo.ch[0].gr[gr].maxb )
|
|
sideinfo.ch[0].gr[gr].maxb = gr_info->maxb;
|
|
else gr_info->maxb = sideinfo.ch[0].gr[gr].maxb;
|
|
}
|
|
|
|
switch( single )
|
|
{
|
|
case SINGLE_MIX:
|
|
in0 = (float *)hybridIn[0];
|
|
in1 = (float *)hybridIn[1];
|
|
|
|
for( i = 0; i < SSLIMIT * (int)gr_info->maxb; i++, in0++ )
|
|
*in0 = (*in0 + *in1++); // *0.5 done by pow-scale
|
|
break;
|
|
case SINGLE_RIGHT:
|
|
in0 = (float *)hybridIn[0];
|
|
in1 = (float *)hybridIn[1];
|
|
|
|
for( i = 0; i < SSLIMIT * (int)gr_info->maxb; i++ )
|
|
*in0++ = *in1++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
for( ch = 0; ch < stereo1; ch++ )
|
|
{
|
|
gr_info = &(sideinfo.ch[ch].gr[gr]);
|
|
III_antialias( hybridIn[ch], gr_info );
|
|
III_hybrid( hybridIn[ch], hybridOut[ch], ch,gr_info, fr );
|
|
}
|
|
|
|
for( ss = 0; ss < SSLIMIT; ss++ )
|
|
{
|
|
if( single != SINGLE_STEREO )
|
|
clip += (fr->synth_mono)(hybridOut[0][ss], fr );
|
|
else clip += (fr->synth_stereo)(hybridOut[0][ss], hybridOut[1][ss], fr );
|
|
|
|
}
|
|
}
|
|
|
|
return clip;
|
|
}
|