mp3/layer3.c
Joshua C. Colp 292540b472 build: Fix warning under modern GCC.
The mpglib library had some fun code to clear
out the remainder of an array. This tripped
up the array bounds check.

This change makes the code just go through the
array until it reaches the end, instead.

ASTERISK-29687
ASTERISK-29712

Change-Id: Ib4f636409fe58d31ead3bd3f958cd74c087b892d
2022-03-29 12:22:17 -03:00

2029 lines
52 KiB
C

/*
* Mpeg Layer-3 audio decoder
* --------------------------
* copyright (c) 1995,1996,1997 by Michael Hipp.
* All rights reserved. See also 'README'
*/
#include "asterisk.h"
#include "asterisk/logger.h"
#include <stdlib.h>
#include "mpg123.h"
#include "mpglib.h"
#include "huffman.h"
#define MPEG1
/* These should all be constants setup once using init_layer3_const */
static real ispow[8207];
static real aa_ca[8],aa_cs[8];
static real COS1[12][6];
static real win[4][36];
static real win1[4][36];
static real gainpow2[256+118+4];
static real COS9[9];
static real COS6_1,COS6_2;
static real tfcos36[9];
static real tfcos12[3];
struct bandInfoStruct {
short longIdx[23];
short longDiff[22];
short shortIdx[14];
short shortDiff[13];
};
struct 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 } } ,
{ {0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,330,394,464,540,576},
{6,6,6,6,6,6,8,10,12,14,16,18,22,26,32,38,46,52,64,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 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 unsigned int n_slen2[512]; /* MPEG 2.0 slen for 'normal' mode */
static unsigned int i_slen2[256]; /* MPEG 2.0 slen for intensity stereo */
static real tan1_1[16],tan2_1[16],tan1_2[16],tan2_2[16];
static real pow1_1[2][16],pow2_1[2][16],pow1_2[2][16],pow2_2[2][16];
/*
* init constant tables for layer-3
*/
void init_layer3_const(void)
{
int i,j,k,l;
for(i=-256;i<118+4;i++)
gainpow2[i+256] = pow((double)2.0,-0.25 * (double) (i+210) );
for(i=0;i<8207;i++)
ispow[i] = pow((double)i,(double)4.0/3.0);
for (i=0;i<8;i++)
{
static 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] = 1.0/sq;
aa_ca[i] = Ci[i]/sq;
}
for(i=0;i<18;i++)
{
win[0][i] = win[1][i] = 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] = 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] = 0.5 / cos ( M_PI * (double) (2*(i+18)+19) / 72.0 );
win[3][i+12] = 0.5 / cos ( M_PI * (double) (2*(i+12)+19) / 72.0 );
win[1][i+24] = 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] = 0.0;
win[3][i+6 ] = 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] = cos( M_PI / 18.0 * (double) i);
for(i=0;i<9;i++)
tfcos36[i] = 0.5 / cos ( M_PI * (double) (i*2+1) / 36.0 );
for(i=0;i<3;i++)
tfcos12[i] = 0.5 / cos ( M_PI * (double) (i*2+1) / 12.0 );
COS6_1 = cos( M_PI / 6.0 * (double) 1);
COS6_2 = cos( M_PI / 6.0 * (double) 2);
for(i=0;i<12;i++)
{
win[2][i] = 0.5 * sin( M_PI / 24.0 * (double) (2*i+1) ) / cos ( M_PI * (double) (2*i+7) / 24.0 );
for(j=0;j<6;j++)
COS1[i][j] = cos( M_PI / 24.0 * (double) ((2*i+7)*(2*j+1)) );
}
for(j=0;j<4;j++) {
static 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(i=0;i<16;i++)
{
double t = tan( (double) i * M_PI / 12.0 );
tan1_1[i] = t / (1.0+t);
tan2_1[i] = 1.0 / (1.0 + t);
tan1_2[i] = M_SQRT2 * t / (1.0+t);
tan2_2[i] = 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] = p1;
pow2_1[j][i] = p2;
pow1_2[j][i] = M_SQRT2 * p1;
pow2_2[j][i] = M_SQRT2 * p2;
}
}
for(j=0;j<9;j++)
{
struct bandInfoStruct *bi = &bandInfo[j];
int *mp;
int cb,lwin;
short *bdf;
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;
}
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);
}
}
}
}
/* MP3 file specific rates */
void init_layer3_sample_limits(struct mpstr *mp, int down_sample_sblimit)
{
int i,j;
for(j=0;j<9;j++) {
for(i=0;i<23;i++) {
(mp->longLimit)[j][i] = (bandInfo[j].longIdx[i] - 1 + 8) / 18 + 1;
if((mp->longLimit)[j][i] > (down_sample_sblimit) )
(mp->longLimit)[j][i] = down_sample_sblimit;
}
for(i=0;i<14;i++) {
(mp->shortLimit)[j][i] = (bandInfo[j].shortIdx[i] - 1) / 18 + 1;
if((mp->shortLimit)[j][i] > (down_sample_sblimit) )
(mp->shortLimit)[j][i] = down_sample_sblimit;
}
}
}
/*
* read additional side information
*/
#ifdef MPEG1
static int III_get_side_info_1(struct mpstr *mp, struct III_sideinfo *si,int stereo,
int ms_stereo,long sfreq,int single)
{
int ch, gr;
int powdiff = (single == 3) ? 4 : 0;
si->main_data_begin = getbits(mp, 9);
if (stereo == 1)
si->private_bits = getbits_fast(mp, 5);
else
si->private_bits = getbits_fast(mp, 3);
for (ch=0; ch<stereo; ch++) {
si->ch[ch].gr[0].scfsi = -1;
si->ch[ch].gr[1].scfsi = getbits_fast(mp, 4);
}
for (gr=0; gr<2; gr++)
{
for (ch=0; ch<stereo; ch++)
{
register struct gr_info_s *gr_info = &(si->ch[ch].gr[gr]);
gr_info->part2_3_length = getbits(mp, 12);
gr_info->big_values = getbits_fast(mp, 9);
if(gr_info->big_values > 288) {
ast_log(LOG_WARNING,"big_values too large!\n");
gr_info->big_values = 288;
}
gr_info->pow2gain = gainpow2+256 - getbits_fast(mp, 8) + powdiff;
if(ms_stereo)
gr_info->pow2gain += 2;
gr_info->scalefac_compress = getbits_fast(mp, 4);
/* window-switching flag == 1 for block_Type != 0 .. and block-type == 0 -> win-sw-flag = 0 */
if(get1bit(mp))
{
int i;
gr_info->block_type = getbits_fast(mp, 2);
gr_info->mixed_block_flag = get1bit(mp);
gr_info->table_select[0] = getbits_fast(mp, 5);
gr_info->table_select[1] = getbits_fast(mp, 5);
/*
* table_select[2] not needed, because there is no region2,
* but to satisfy some verifications 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(mp, 3)<<3);
if(gr_info->block_type == 0) {
ast_log(LOG_WARNING,"Blocktype == 0 and window-switching == 1 not allowed.\n");
return (1);
}
/* region_count/start parameters are implicit in this case. */
gr_info->region1start = 36>>1;
gr_info->region2start = 576>>1;
}
else
{
int i,r0c,r1c;
for (i=0; i<3; i++)
gr_info->table_select[i] = getbits_fast(mp, 5);
r0c = getbits_fast(mp, 4);
r1c = getbits_fast(mp, 3);
gr_info->region1start = bandInfo[sfreq].longIdx[r0c+1] >> 1 ;
gr_info->region2start = bandInfo[sfreq].longIdx[r0c+1+r1c+1] >> 1;
gr_info->block_type = 0;
gr_info->mixed_block_flag = 0;
}
gr_info->preflag = get1bit(mp);
gr_info->scalefac_scale = get1bit(mp);
gr_info->count1table_select = get1bit(mp);
}
}
return (0);
}
#endif
/*
* Side Info for MPEG 2.0 / LSF
*/
static int III_get_side_info_2(struct mpstr *mp, struct III_sideinfo *si,int stereo,
int ms_stereo,long sfreq,int single)
{
int ch;
int powdiff = (single == 3) ? 4 : 0;
si->main_data_begin = getbits(mp, 8);
if (stereo == 1)
si->private_bits = get1bit(mp);
else
si->private_bits = getbits_fast(mp, 2);
for (ch=0; ch<stereo; ch++)
{
register struct gr_info_s *gr_info = &(si->ch[ch].gr[0]);
gr_info->part2_3_length = getbits(mp, 12);
gr_info->big_values = getbits_fast(mp, 9);
if(gr_info->big_values > 288) {
ast_log(LOG_WARNING,"big_values too large!\n");
gr_info->big_values = 288;
}
gr_info->pow2gain = gainpow2+256 - getbits_fast(mp, 8) + powdiff;
if(ms_stereo)
gr_info->pow2gain += 2;
gr_info->scalefac_compress = getbits(mp, 9);
/* window-switching flag == 1 for block_Type != 0 .. and block-type == 0 -> win-sw-flag = 0 */
if(get1bit(mp))
{
int i;
gr_info->block_type = getbits_fast(mp, 2);
gr_info->mixed_block_flag = get1bit(mp);
gr_info->table_select[0] = getbits_fast(mp, 5);
gr_info->table_select[1] = getbits_fast(mp, 5);
/*
* table_select[2] not needed, because there is no region2,
* but to satisfy some verifications 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(mp, 3)<<3);
if(gr_info->block_type == 0) {
ast_log(LOG_WARNING,"Blocktype == 0 and window-switching == 1 not allowed.\n");
return (1);
}
/* region_count/start parameters are implicit in this case. */
/* check this again! */
if(gr_info->block_type == 2)
gr_info->region1start = 36>>1;
else if(sfreq == 8)
/* check this for 2.5 and sfreq=8 */
gr_info->region1start = 108>>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(mp, 5);
r0c = getbits_fast(mp, 4);
r1c = getbits_fast(mp, 3);
gr_info->region1start = bandInfo[sfreq].longIdx[r0c+1] >> 1 ;
gr_info->region2start = bandInfo[sfreq].longIdx[r0c+1+r1c+1] >> 1;
gr_info->block_type = 0;
gr_info->mixed_block_flag = 0;
}
gr_info->scalefac_scale = get1bit(mp);
gr_info->count1table_select = get1bit(mp);
}
return (0);
}
/*
* read scalefactors
*/
#ifdef MPEG1
static int III_get_scale_factors_1(struct mpstr *mp, int *scf,struct gr_info_s *gr_info)
{
static unsigned char 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 numbits;
int num0 = slen[0][gr_info->scalefac_compress];
int num1 = slen[1][gr_info->scalefac_compress];
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(mp, num0);
i = 9;
numbits -= num0; /* num0 * 17 + num1 * 18 */
}
for (;i;i--)
*scf++ = getbits_fast(mp, num0);
for (i = 18; i; i--)
*scf++ = getbits_fast(mp, num1);
*scf++ = 0; *scf++ = 0; *scf++ = 0; /* short[13][0..2] = 0 */
}
else
{
int i;
int scfsi = gr_info->scfsi;
if(scfsi < 0) { /* scfsi < 0 => granule == 0 */
for(i=11;i;i--)
*scf++ = getbits_fast(mp, num0);
for(i=10;i;i--)
*scf++ = getbits_fast(mp, num1);
numbits = (num0 + num1) * 10 + num0;
}
else {
numbits = 0;
if(!(scfsi & 0x8)) {
for (i=6;i;i--)
*scf++ = getbits_fast(mp, num0);
numbits += num0 * 6;
}
else {
*scf++ = 0; *scf++ = 0; *scf++ = 0; /* set to ZERO necessary? */
*scf++ = 0; *scf++ = 0; *scf++ = 0;
}
if(!(scfsi & 0x4)) {
for (i=5;i;i--)
*scf++ = getbits_fast(mp, num0);
numbits += num0 * 5;
}
else {
*scf++ = 0; *scf++ = 0; *scf++ = 0; /* set to ZERO necessary? */
*scf++ = 0; *scf++ = 0;
}
if(!(scfsi & 0x2)) {
for(i=5;i;i--)
*scf++ = getbits_fast(mp, num1);
numbits += num1 * 5;
}
else {
*scf++ = 0; *scf++ = 0; *scf++ = 0; /* set to ZERO necessary? */
*scf++ = 0; *scf++ = 0;
}
if(!(scfsi & 0x1)) {
for (i=5;i;i--)
*scf++ = getbits_fast(mp, num1);
numbits += num1 * 5;
}
else {
*scf++ = 0; *scf++ = 0; *scf++ = 0; /* set to ZERO necessary? */
*scf++ = 0; *scf++ = 0;
}
}
*scf++ = 0; /* no l[21] in original sources */
}
return numbits;
}
#endif
static int III_get_scale_factors_2(struct mpstr *mp, int *scf,struct gr_info_s *gr_info,int i_stereo)
{
unsigned char *pnt;
int i,j;
unsigned int slen;
int n = 0;
int numbits = 0;
static unsigned char 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} } };
if(i_stereo) /* i_stereo AND second channel -> do_layer3() checks this */
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 ) {
n++;
if(gr_info->mixed_block_flag)
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(mp, 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;
}
static int pretab1[22] = {0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,3,3,3,2,0};
static int pretab2[22] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
/*
* don't forget to apply the same changes to III_dequantize_sample_ms() !!!
*/
static int III_dequantize_sample(struct mpstr *mp, real xr[SBLIMIT][SSLIMIT],int *scf,
struct gr_info_s *gr_info,int sfreq,int part2bits)
{
int shift = 1 + gr_info->scalefac_scale;
real *xrpnt = (real *) xr;
int l[3],l3;
int part2remain = gr_info->part2_3_length - part2bits;
int *me;
{
int bv = gr_info->big_values;
int region1 = gr_info->region1start;
int region2 = gr_info->region2start;
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) {
/*
* decoding with short or mixed mode BandIndex table
*/
int i,max[4];
int step=0,lwin=0,cb=0;
register real v = 0.0;
register int *m,mc;
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 really needed in this case */
m = map[sfreq][1];
me = mapend[sfreq][1];
}
mc = 0;
for(i=0;i<2;i++) {
int lp = l[i];
struct newhuff *h = ht+gr_info->table_select[i];
for(;lp;lp--,mc--) {
register int x,y;
if( (!mc) ) {
mc = *m++;
xrpnt = ((real *) 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;
}
}
{
register short *val = h->table;
while((y=*val++)<0) {
if (get1bit(mp))
val -= y;
part2remain--;
}
x = y >> 4;
y &= 0xf;
}
if(x == 15) {
max[lwin] = cb;
part2remain -= h->linbits+1;
x += getbits(mp, h->linbits);
if(get1bit(mp))
*xrpnt = -ispow[x] * v;
else
*xrpnt = ispow[x] * v;
}
else if(x) {
max[lwin] = cb;
if(get1bit(mp))
*xrpnt = -ispow[x] * v;
else
*xrpnt = ispow[x] * v;
part2remain--;
}
else
*xrpnt = 0.0;
xrpnt += step;
if(y == 15) {
max[lwin] = cb;
part2remain -= h->linbits+1;
y += getbits(mp, h->linbits);
if(get1bit(mp))
*xrpnt = -ispow[y] * v;
else
*xrpnt = ispow[y] * v;
}
else if(y) {
max[lwin] = cb;
if(get1bit(mp))
*xrpnt = -ispow[y] * v;
else
*xrpnt = ispow[y] * v;
part2remain--;
}
else
*xrpnt = 0.0;
xrpnt += step;
}
}
for(;l3 && (part2remain > 0);l3--) {
struct newhuff *h = htc+gr_info->count1table_select;
register short *val = h->table,a;
while((a=*val++)<0) {
part2remain--;
if(part2remain < 0) {
part2remain++;
a = 0;
break;
}
if (get1bit(mp))
val -= a;
}
for(i=0;i<4;i++) {
if(!(i & 1)) {
if(!mc) {
mc = *m++;
xrpnt = ((real *) 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;
part2remain--;
if(part2remain < 0) {
part2remain++;
break;
}
if(get1bit(mp))
*xrpnt = -v;
else
*xrpnt = v;
}
else
*xrpnt = 0.0;
xrpnt += step;
}
}
while( m < me ) {
if(!mc) {
mc = *m++;
xrpnt = ((real *) xr) + *m++;
if( (*m++) == 3)
step = 1;
else
step = 3;
m++; /* cb */
}
mc--;
*xrpnt = 0.0;
xrpnt += step;
*xrpnt = 0.0;
xrpnt += step;
/* we could add a little opt. here:
* if we finished a band for window 3 or a long band
* further bands could copied in a simple loop without a
* special 'map' decoding
*/
}
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;
{
int rmax = max[0] > max[1] ? max[0] : max[1];
rmax = (rmax > max[2] ? rmax : max[2]) + 1;
gr_info->maxb = rmax ? (mp->shortLimit)[sfreq][rmax] : (mp->longLimit)[sfreq][max[3]+1];
}
}
else {
/*
* decoding with 'long' BandIndex table (block_type != 2)
*/
int *pretab = gr_info->preflag ? pretab1 : pretab2;
int i,max = -1;
int cb = 0;
register int *m = map[sfreq][2];
register real v = 0.0;
register int mc = 0;
#if 0
me = mapend[sfreq][2];
#endif
/*
* long hash table values
*/
for(i=0;i<3;i++) {
int lp = l[i];
struct newhuff *h = ht+gr_info->table_select[i];
for(;lp;lp--,mc--) {
int x,y;
if(!mc) {
mc = *m++;
v = gr_info->pow2gain[((*scf++) + (*pretab++)) << shift];
cb = *m++;
}
{
register short *val = h->table;
while((y=*val++)<0) {
if (get1bit(mp))
val -= y;
part2remain--;
}
x = y >> 4;
y &= 0xf;
}
if (x == 15) {
max = cb;
part2remain -= h->linbits+1;
x += getbits(mp, h->linbits);
if(get1bit(mp))
*xrpnt++ = -ispow[x] * v;
else
*xrpnt++ = ispow[x] * v;
}
else if(x) {
max = cb;
if(get1bit(mp))
*xrpnt++ = -ispow[x] * v;
else
*xrpnt++ = ispow[x] * v;
part2remain--;
}
else
*xrpnt++ = 0.0;
if (y == 15) {
max = cb;
part2remain -= h->linbits+1;
y += getbits(mp, h->linbits);
if(get1bit(mp))
*xrpnt++ = -ispow[y] * v;
else
*xrpnt++ = ispow[y] * v;
}
else if(y) {
max = cb;
if(get1bit(mp))
*xrpnt++ = -ispow[y] * v;
else
*xrpnt++ = ispow[y] * v;
part2remain--;
}
else
*xrpnt++ = 0.0;
}
}
/*
* short (count1table) values
*/
for(;l3 && (part2remain > 0);l3--) {
struct newhuff *h = htc+gr_info->count1table_select;
register short *val = h->table,a;
while((a=*val++)<0) {
part2remain--;
if(part2remain < 0) {
part2remain++;
a = 0;
break;
}
if (get1bit(mp))
val -= a;
}
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;
part2remain--;
if(part2remain < 0) {
part2remain++;
break;
}
if(get1bit(mp))
*xrpnt++ = -v;
else
*xrpnt++ = v;
}
else
*xrpnt++ = 0.0;
}
}
/*
* zero part
*/
while (xrpnt <= &xr[SBLIMIT-1][SSLIMIT-1]) {
*xrpnt++ = 0.0;
}
gr_info->maxbandl = max+1;
gr_info->maxb = (mp->longLimit)[sfreq][gr_info->maxbandl];
}
while( part2remain > 16 ) {
getbits(mp, 16); /* Dismiss stuffing Bits */
part2remain -= 16;
}
if(part2remain > 0)
getbits(mp, part2remain);
else if(part2remain < 0) {
ast_log(LOG_WARNING,"mpg123: Can't rewind stream by %d bits!\n",-part2remain);
return 1; /* -> error */
}
return 0;
}
#if 0
static int III_dequantize_sample_ms(real xr[2][SBLIMIT][SSLIMIT],int *scf,
struct gr_info_s *gr_info,int sfreq,int part2bits)
{
int shift = 1 + gr_info->scalefac_scale;
real *xrpnt = (real *) xr[1];
real *xr0pnt = (real *) xr[0];
int l[3],l3;
int part2remain = gr_info->part2_3_length - part2bits;
int *me;
{
int bv = gr_info->big_values;
int region1 = gr_info->region1start;
int region2 = gr_info->region2start;
l3 = ((576>>1)-bv)>>1;
/*
* we may lose the 'odd' bit here !!
* check this later gain
*/
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,lwin=0,cb=0;
register real v = 0.0;
register int *m,mc = 0;
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 really needed in this case */
m = map[sfreq][1];
me = mapend[sfreq][1];
}
for(i=0;i<2;i++) {
int lp = l[i];
struct newhuff *h = ht+gr_info->table_select[i];
for(;lp;lp--,mc--) {
int x,y;
if(!mc) {
mc = *m++;
xrpnt = ((real *) xr[1]) + *m;
xr0pnt = ((real *) xr[0]) + *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;
}
}
{
register short *val = h->table;
while((y=*val++)<0) {
if (get1bit(mp))
val -= y;
part2remain--;
}
x = y >> 4;
y &= 0xf;
}
if(x == 15) {
max[lwin] = cb;
part2remain -= h->linbits+1;
x += getbits(mp, h->linbits);
if(get1bit(mp)) {
real a = ispow[x] * v;
*xrpnt = *xr0pnt + a;
*xr0pnt -= a;
}
else {
real a = ispow[x] * v;
*xrpnt = *xr0pnt - a;
*xr0pnt += a;
}
}
else if(x) {
max[lwin] = cb;
if(get1bit(mp)) {
real a = ispow[x] * v;
*xrpnt = *xr0pnt + a;
*xr0pnt -= a;
}
else {
real a = ispow[x] * v;
*xrpnt = *xr0pnt - a;
*xr0pnt += a;
}
part2remain--;
}
else
*xrpnt = *xr0pnt;
xrpnt += step;
xr0pnt += step;
if(y == 15) {
max[lwin] = cb;
part2remain -= h->linbits+1;
y += getbits(mp, h->linbits);
if(get1bit(mp)) {
real a = ispow[y] * v;
*xrpnt = *xr0pnt + a;
*xr0pnt -= a;
}
else {
real a = ispow[y] * v;
*xrpnt = *xr0pnt - a;
*xr0pnt += a;
}
}
else if(y) {
max[lwin] = cb;
if(get1bit(mp)) {
real a = ispow[y] * v;
*xrpnt = *xr0pnt + a;
*xr0pnt -= a;
}
else {
real a = ispow[y] * v;
*xrpnt = *xr0pnt - a;
*xr0pnt += a;
}
part2remain--;
}
else
*xrpnt = *xr0pnt;
xrpnt += step;
xr0pnt += step;
}
}
for(;l3 && (part2remain > 0);l3--) {
struct newhuff *h = htc+gr_info->count1table_select;
register short *val = h->table,a;
while((a=*val++)<0) {
part2remain--;
if(part2remain < 0) {
part2remain++;
a = 0;
break;
}
if (get1bit(mp))
val -= a;
}
for(i=0;i<4;i++) {
if(!(i & 1)) {
if(!mc) {
mc = *m++;
xrpnt = ((real *) xr[1]) + *m;
xr0pnt = ((real *) xr[0]) + *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;
part2remain--;
if(part2remain < 0) {
part2remain++;
break;
}
if(get1bit(mp)) {
*xrpnt = *xr0pnt + v;
*xr0pnt -= v;
}
else {
*xrpnt = *xr0pnt - v;
*xr0pnt += v;
}
}
else
*xrpnt = *xr0pnt;
xrpnt += step;
xr0pnt += step;
}
}
while( m < me ) {
if(!mc) {
mc = *m++;
xrpnt = ((real *) xr[1]) + *m;
xr0pnt = ((real *) xr[0]) + *m++;
if(*m++ == 3)
step = 1;
else
step = 3;
m++; /* cb */
}
mc--;
*xrpnt = *xr0pnt;
xrpnt += step;
xr0pnt += step;
*xrpnt = *xr0pnt;
xrpnt += step;
xr0pnt += step;
/* we could add a little opt. here:
* if we finished a band for window 3 or a long band
* further bands could copied in a simple loop without a
* special 'map' decoding
*/
}
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;
{
int rmax = max[0] > max[1] ? max[0] : max[1];
rmax = (rmax > max[2] ? rmax : max[2]) + 1;
gr_info->maxb = rmax ? (mp->shortLimit)[sfreq][rmax] : (mp->longLimit)[sfreq][max[3]+1];
}
}
else {
int *pretab = gr_info->preflag ? pretab1 : pretab2;
int i,max = -1;
int cb = 0;
register int mc=0,*m = map[sfreq][2];
register real v = 0.0;
#if 0
me = mapend[sfreq][2];
#endif
for(i=0;i<3;i++) {
int lp = l[i];
struct newhuff *h = ht+gr_info->table_select[i];
for(;lp;lp--,mc--) {
int x,y;
if(!mc) {
mc = *m++;
cb = *m++;
v = gr_info->pow2gain[((*scf++) + (*pretab++)) << shift];
}
{
register short *val = h->table;
while((y=*val++)<0) {
if (get1bit(mp))
val -= y;
part2remain--;
}
x = y >> 4;
y &= 0xf;
}
if (x == 15) {
max = cb;
part2remain -= h->linbits+1;
x += getbits(mp, h->linbits);
if(get1bit(mp)) {
real a = ispow[x] * v;
*xrpnt++ = *xr0pnt + a;
*xr0pnt++ -= a;
}
else {
real a = ispow[x] * v;
*xrpnt++ = *xr0pnt - a;
*xr0pnt++ += a;
}
}
else if(x) {
max = cb;
if(get1bit(mp)) {
real a = ispow[x] * v;
*xrpnt++ = *xr0pnt + a;
*xr0pnt++ -= a;
}
else {
real a = ispow[x] * v;
*xrpnt++ = *xr0pnt - a;
*xr0pnt++ += a;
}
part2remain--;
}
else
*xrpnt++ = *xr0pnt++;
if (y == 15) {
max = cb;
part2remain -= h->linbits+1;
y += getbits(mp, h->linbits);
if(get1bit(mp)) {
real a = ispow[y] * v;
*xrpnt++ = *xr0pnt + a;
*xr0pnt++ -= a;
}
else {
real a = ispow[y] * v;
*xrpnt++ = *xr0pnt - a;
*xr0pnt++ += a;
}
}
else if(y) {
max = cb;
if(get1bit(mp)) {
real a = ispow[y] * v;
*xrpnt++ = *xr0pnt + a;
*xr0pnt++ -= a;
}
else {
real a = ispow[y] * v;
*xrpnt++ = *xr0pnt - a;
*xr0pnt++ += a;
}
part2remain--;
}
else
*xrpnt++ = *xr0pnt++;
}
}
for(;l3 && (part2remain > 0);l3--) {
struct newhuff *h = htc+gr_info->count1table_select;
register short *val = h->table,a;
while((a=*val++)<0) {
part2remain--;
if(part2remain < 0) {
part2remain++;
a = 0;
break;
}
if (get1bit(mp))
val -= a;
}
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;
part2remain--;
if(part2remain <= 0) {
part2remain++;
break;
}
if(get1bit(mp)) {
*xrpnt++ = *xr0pnt + v;
*xr0pnt++ -= v;
}
else {
*xrpnt++ = *xr0pnt - v;
*xr0pnt++ += v;
}
}
else
*xrpnt++ = *xr0pnt++;
}
}
for(i=(&xr[1][SBLIMIT][0]-xrpnt)>>1;i;i--) {
*xrpnt++ = *xr0pnt++;
*xrpnt++ = *xr0pnt++;
}
gr_info->maxbandl = max+1;
gr_info->maxb = longLimit[sfreq][gr_info->maxbandl];
}
while ( part2remain > 16 ) {
getbits(mp, 16); /* Dismiss stuffing Bits */
part2remain -= 16;
}
if(part2remain > 0 )
getbits(mp, part2remain);
else if(part2remain < 0) {
ast_log(LOG_WARNING,"mpg123_ms: Can't rewind stream by %d bits!\n",-part2remain);
return 1; /* -> error */
}
return 0;
}
#endif
/*
* III_stereo: calculate real channel values for Joint-I-Stereo-mode
*/
static void III_i_stereo(real xr_buf[2][SBLIMIT][SSLIMIT],int *scalefac,
struct gr_info_s *gr_info,int sfreq,int ms_stereo,int lsf)
{
real (*xr)[SBLIMIT*SSLIMIT] = (real (*)[SBLIMIT*SSLIMIT] ) xr_buf;
struct bandInfoStruct *bi = &bandInfo[sfreq];
real *tab1,*tab2;
if(lsf) {
int p = gr_info->scalefac_compress & 0x1;
if(ms_stereo) {
tab1 = pow1_2[p]; tab2 = pow2_2[p];
}
else {
tab1 = pow1_1[p]; tab2 = pow2_1[p];
}
}
else {
if(ms_stereo) {
tab1 = tan1_2; tab2 = tan2_2;
}
else {
tab1 = tan1_1; tab2 = tan2_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++) /* process each window */
{
/* get first band with zero values */
int is_p,sb,idx,sfb = gr_info->maxband[lwin]; /* sfb is minimal 3 for mixed mode */
if(sfb > 3)
do_l = 0;
for(;sfb<12;sfb++)
{
is_p = scalefac[sfb*3+lwin-gr_info->mixed_block_flag]; /* scale: 0-15 */
if(is_p != 7) {
real 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)
{
real v = xr[0][idx];
xr[0][idx] = v * t1;
xr[1][idx] = v * t2;
}
}
}
#if 1
/* 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;
#else
is_p = scalefac[10*3+lwin-gr_info->mixed_block_flag]; /* scale: 0-15 */
sb = bi->shortDiff[11];
idx = bi->shortIdx[11] + lwin;
#endif
if(is_p != 7)
{
real t1,t2;
t1 = tab1[is_p]; t2 = tab2[is_p];
for ( ; sb > 0; sb--,idx+=3 )
{
real v = xr[0][idx];
xr[0][idx] = v * t1;
xr[1][idx] = v * t2;
}
}
} /* end for(lwin; .. ; . ) */
if (do_l)
{
/* also check l-part, if ALL bands in the three windows are 'empty'
* and mode = mixed_mode
*/
int sfb = gr_info->maxbandl;
int 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) {
real t1,t2;
t1 = tab1[is_p]; t2 = tab2[is_p];
for ( ; sb > 0; sb--,idx++)
{
real v = xr[0][idx];
xr[0][idx] = v * t1;
xr[1][idx] = v * t2;
}
}
else
idx += sb;
}
}
}
else /* ((gr_info->block_type != 2)) */
{
int sfb = gr_info->maxbandl;
int is_p,idx = bi->longIdx[sfb];
for ( ; sfb<21; sfb++)
{
int sb = bi->longDiff[sfb];
is_p = scalefac[sfb]; /* scale: 0-15 */
if(is_p != 7) {
real t1,t2;
t1 = tab1[is_p]; t2 = tab2[is_p];
for ( ; sb > 0; sb--,idx++)
{
real v = xr[0][idx];
xr[0][idx] = v * t1;
xr[1][idx] = v * t2;
}
}
else
idx += sb;
}
is_p = scalefac[20]; /* copy l-band 20 to l-band 21 */
if(is_p != 7)
{
int sb;
real t1 = tab1[is_p],t2 = tab2[is_p];
for ( sb = bi->longDiff[21]; sb > 0; sb--,idx++ )
{
real v = xr[0][idx];
xr[0][idx] = v * t1;
xr[1][idx] = v * t2;
}
}
} /* ... */
}
static void III_antialias(real xr[SBLIMIT][SSLIMIT],struct gr_info_s *gr_info)
{
int sblim;
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 */
{
int sb;
real *xr1=(real *) xr[1];
for(sb=sblim;sb;sb--,xr1+=10)
{
int ss;
real *cs=aa_cs,*ca=aa_ca;
real *xr2 = xr1;
for(ss=7;ss>=0;ss--)
{ /* upper and lower butterfly inputs */
register real bu = *--xr2,bd = *xr1;
*xr2 = (bu * (*cs) ) - (bd * (*ca) );
*xr1++ = (bd * (*cs++) ) + (bu * (*ca++) );
}
}
}
}
/*
DCT insipired by Jeff Tsay's DCT from the maplay package
this is an optimized version with manual unroll.
References:
[1] S. Winograd: "On Computing the Discrete Fourier Transform",
Mathematics of Computation, Volume 32, Number 141, January 1978,
Pages 175-199
*/
static void dct36(real *inbuf,real *o1,real *o2,real *wintab,real *tsbuf)
{
{
register real *in = inbuf;
in[17]+=in[16]; in[16]+=in[15]; in[15]+=in[14];
in[14]+=in[13]; in[13]+=in[12]; in[12]+=in[11];
in[11]+=in[10]; in[10]+=in[9]; in[9] +=in[8];
in[8] +=in[7]; in[7] +=in[6]; in[6] +=in[5];
in[5] +=in[4]; in[4] +=in[3]; in[3] +=in[2];
in[2] +=in[1]; in[1] +=in[0];
in[17]+=in[15]; in[15]+=in[13]; in[13]+=in[11]; in[11]+=in[9];
in[9] +=in[7]; in[7] +=in[5]; in[5] +=in[3]; in[3] +=in[1];
{
#define MACRO0(v) { \
real tmp; \
out2[9+(v)] = (tmp = sum0 + sum1) * w[27+(v)]; \
out2[8-(v)] = tmp * w[26-(v)]; } \
sum0 -= sum1; \
ts[SBLIMIT*(8-(v))] = out1[8-(v)] + sum0 * w[8-(v)]; \
ts[SBLIMIT*(9+(v))] = out1[9+(v)] + sum0 * w[9+(v)];
#define MACRO1(v) { \
real sum0,sum1; \
sum0 = tmp1a + tmp2a; \
sum1 = (tmp1b + tmp2b) * tfcos36[(v)]; \
MACRO0(v); }
#define MACRO2(v) { \
real sum0,sum1; \
sum0 = tmp2a - tmp1a; \
sum1 = (tmp2b - tmp1b) * tfcos36[(v)]; \
MACRO0(v); }
register const real *c = COS9;
register real *out2 = o2;
register real *w = wintab;
register real *out1 = o1;
register real *ts = tsbuf;
real ta33,ta66,tb33,tb66;
ta33 = in[2*3+0] * c[3];
ta66 = in[2*6+0] * c[6];
tb33 = in[2*3+1] * c[3];
tb66 = in[2*6+1] * c[6];
{
real tmp1a,tmp2a,tmp1b,tmp2b;
tmp1a = in[2*1+0] * c[1] + ta33 + in[2*5+0] * c[5] + in[2*7+0] * c[7];
tmp1b = in[2*1+1] * c[1] + tb33 + in[2*5+1] * c[5] + in[2*7+1] * c[7];
tmp2a = in[2*0+0] + in[2*2+0] * c[2] + in[2*4+0] * c[4] + ta66 + in[2*8+0] * c[8];
tmp2b = in[2*0+1] + in[2*2+1] * c[2] + in[2*4+1] * c[4] + tb66 + in[2*8+1] * c[8];
MACRO1(0);
MACRO2(8);
}
{
real tmp1a,tmp2a,tmp1b,tmp2b;
tmp1a = ( in[2*1+0] - in[2*5+0] - in[2*7+0] ) * c[3];
tmp1b = ( in[2*1+1] - in[2*5+1] - in[2*7+1] ) * c[3];
tmp2a = ( in[2*2+0] - in[2*4+0] - in[2*8+0] ) * c[6] - in[2*6+0] + in[2*0+0];
tmp2b = ( in[2*2+1] - in[2*4+1] - in[2*8+1] ) * c[6] - in[2*6+1] + in[2*0+1];
MACRO1(1);
MACRO2(7);
}
{
real tmp1a,tmp2a,tmp1b,tmp2b;
tmp1a = in[2*1+0] * c[5] - ta33 - in[2*5+0] * c[7] + in[2*7+0] * c[1];
tmp1b = in[2*1+1] * c[5] - tb33 - in[2*5+1] * c[7] + in[2*7+1] * c[1];
tmp2a = in[2*0+0] - in[2*2+0] * c[8] - in[2*4+0] * c[2] + ta66 + in[2*8+0] * c[4];
tmp2b = in[2*0+1] - in[2*2+1] * c[8] - in[2*4+1] * c[2] + tb66 + in[2*8+1] * c[4];
MACRO1(2);
MACRO2(6);
}
{
real tmp1a,tmp2a,tmp1b,tmp2b;
tmp1a = in[2*1+0] * c[7] - ta33 + in[2*5+0] * c[1] - in[2*7+0] * c[5];
tmp1b = in[2*1+1] * c[7] - tb33 + in[2*5+1] * c[1] - in[2*7+1] * c[5];
tmp2a = in[2*0+0] - in[2*2+0] * c[4] + in[2*4+0] * c[8] + ta66 - in[2*8+0] * c[2];
tmp2b = in[2*0+1] - in[2*2+1] * c[4] + in[2*4+1] * c[8] + tb66 - in[2*8+1] * c[2];
MACRO1(3);
MACRO2(5);
}
{
real sum0,sum1;
sum0 = in[2*0+0] - in[2*2+0] + in[2*4+0] - in[2*6+0] + in[2*8+0];
sum1 = (in[2*0+1] - in[2*2+1] + in[2*4+1] - in[2*6+1] + in[2*8+1] ) * tfcos36[4];
MACRO0(4);
}
}
}
}
/*
* new DCT12
*/
static void dct12(real *in,real *rawout1,real *rawout2,register real *wi,register real *ts)
{
#define DCT12_PART1 \
in5 = in[5*3]; \
in5 += (in4 = in[4*3]); \
in4 += (in3 = in[3*3]); \
in3 += (in2 = in[2*3]); \
in2 += (in1 = in[1*3]); \
in1 += (in0 = in[0*3]); \
\
in5 += in3; in3 += in1; \
\
in2 *= COS6_1; \
in3 *= COS6_1; \
#define DCT12_PART2 \
in0 += in4 * COS6_2; \
\
in4 = in0 + in2; \
in0 -= in2; \
\
in1 += in5 * COS6_2; \
\
in5 = (in1 + in3) * tfcos12[0]; \
in1 = (in1 - in3) * tfcos12[2]; \
\
in3 = in4 + in5; \
in4 -= in5; \
\
in2 = in0 + in1; \
in0 -= in1;
{
real in0,in1,in2,in3,in4,in5;
register real *out1 = rawout1;
ts[SBLIMIT*0] = out1[0]; ts[SBLIMIT*1] = out1[1]; ts[SBLIMIT*2] = out1[2];
ts[SBLIMIT*3] = out1[3]; ts[SBLIMIT*4] = out1[4]; ts[SBLIMIT*5] = out1[5];
DCT12_PART1
{
real tmp0,tmp1 = (in0 - in4);
{
real tmp2 = (in1 - in5) * tfcos12[1];
tmp0 = tmp1 + tmp2;
tmp1 -= tmp2;
}
ts[(17-1)*SBLIMIT] = out1[17-1] + tmp0 * wi[11-1];
ts[(12+1)*SBLIMIT] = out1[12+1] + tmp0 * wi[6+1];
ts[(6 +1)*SBLIMIT] = out1[6 +1] + tmp1 * wi[1];
ts[(11-1)*SBLIMIT] = out1[11-1] + tmp1 * wi[5-1];
}
DCT12_PART2
ts[(17-0)*SBLIMIT] = out1[17-0] + in2 * wi[11-0];
ts[(12+0)*SBLIMIT] = out1[12+0] + in2 * wi[6+0];
ts[(12+2)*SBLIMIT] = out1[12+2] + in3 * wi[6+2];
ts[(17-2)*SBLIMIT] = out1[17-2] + in3 * wi[11-2];
ts[(6+0)*SBLIMIT] = out1[6+0] + in0 * wi[0];
ts[(11-0)*SBLIMIT] = out1[11-0] + in0 * wi[5-0];
ts[(6+2)*SBLIMIT] = out1[6+2] + in4 * wi[2];
ts[(11-2)*SBLIMIT] = out1[11-2] + in4 * wi[5-2];
}
in++;
{
real in0,in1,in2,in3,in4,in5;
register real *out2 = rawout2;
DCT12_PART1
{
real tmp0,tmp1 = (in0 - in4);
{
real tmp2 = (in1 - in5) * tfcos12[1];
tmp0 = tmp1 + tmp2;
tmp1 -= tmp2;
}
out2[5-1] = tmp0 * wi[11-1];
out2[0+1] = tmp0 * wi[6+1];
ts[(12+1)*SBLIMIT] += tmp1 * wi[1];
ts[(17-1)*SBLIMIT] += tmp1 * wi[5-1];
}
DCT12_PART2
out2[5-0] = in2 * wi[11-0];
out2[0+0] = in2 * wi[6+0];
out2[0+2] = in3 * wi[6+2];
out2[5-2] = in3 * wi[11-2];
ts[(12+0)*SBLIMIT] += in0 * wi[0];
ts[(17-0)*SBLIMIT] += in0 * wi[5-0];
ts[(12+2)*SBLIMIT] += in4 * wi[2];
ts[(17-2)*SBLIMIT] += in4 * wi[5-2];
}
in++;
{
real in0,in1,in2,in3,in4,in5;
register real *out2 = rawout2;
out2[12]=out2[13]=out2[14]=out2[15]=out2[16]=out2[17]=0.0;
DCT12_PART1
{
real tmp0,tmp1 = (in0 - in4);
{
real tmp2 = (in1 - in5) * tfcos12[1];
tmp0 = tmp1 + tmp2;
tmp1 -= tmp2;
}
out2[11-1] = tmp0 * wi[11-1];
out2[6 +1] = tmp0 * wi[6+1];
out2[0+1] += tmp1 * wi[1];
out2[5-1] += tmp1 * wi[5-1];
}
DCT12_PART2
out2[11-0] = in2 * wi[11-0];
out2[6 +0] = in2 * wi[6+0];
out2[6 +2] = in3 * wi[6+2];
out2[11-2] = in3 * wi[11-2];
out2[0+0] += in0 * wi[0];
out2[5-0] += in0 * wi[5-0];
out2[0+2] += in4 * wi[2];
out2[5-2] += in4 * wi[5-2];
}
}
/*
* III_hybrid
*/
static void III_hybrid(struct mpstr *mp, real fsIn[SBLIMIT][SSLIMIT],real tsOut[SSLIMIT][SBLIMIT],
int ch,struct gr_info_s *gr_info)
{
real *tspnt = (real *) tsOut;
real (*block)[2][SBLIMIT*SSLIMIT] = mp->hybrid_block;
int *blc = mp->hybrid_blc;
real *rawout1,*rawout2;
int bt;
int sb = 0;
{
int 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++) {
int i;
for(i=0;i<SSLIMIT;i++) {
tspnt[i*SBLIMIT] = *rawout1++;
*rawout2++ = 0.0;
}
}
}
/*
* main layer3 handler
*/
int do_layer3(struct mpstr *mp,unsigned char *pcm_sample,int *pcm_point)
{
int gr, ch, ss,clip=0;
int scalefacs[39]; /* max 39 for short[13][3] mode, mixed: 38, long: 22 */
struct III_sideinfo sideinfo;
struct frame *fr;
int stereo, single, sfreq;
int ms_stereo,i_stereo;
int stereo1,granules;
fr = &(mp->fr);
stereo = fr->stereo;
single = fr->single;
sfreq = fr->sampling_frequency;
if(stereo == 1) { /* stream is mono */
stereo1 = 1;
single = 0;
}
else if(single >= 0) /* 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;
i_stereo = fr->mode_ext & 0x1;
}
else
ms_stereo = i_stereo = 0;
if(fr->lsf) {
granules = 1;
if (III_get_side_info_2(mp, &sideinfo,stereo,ms_stereo,sfreq,single))
return (MP3_ERR);
}
else {
granules = 2;
#ifdef MPEG1
if ( III_get_side_info_1(mp, &sideinfo,stereo,ms_stereo,sfreq,single))
return (MP3_ERR);
#else
ast_log(LOG_WARNING,"Not supported\n");
#endif
}
if(set_pointer(mp, sideinfo.main_data_begin) == MP3_ERR)
return 0;
for (gr=0;gr<granules;gr++)
{
static real hybridIn[2][SBLIMIT][SSLIMIT];
static real hybridOut[2][SSLIMIT][SBLIMIT];
{
struct gr_info_s *gr_info = &(sideinfo.ch[0].gr[gr]);
long part2bits;
if(fr->lsf)
part2bits = III_get_scale_factors_2(mp, scalefacs,gr_info,0);
else {
#ifdef MPEG1
part2bits = III_get_scale_factors_1(mp, scalefacs,gr_info);
#else
ast_log(LOG_WARNING,"Not supported\n");
#endif
}
if(III_dequantize_sample(mp, hybridIn[0], scalefacs,gr_info,sfreq,part2bits))
return (MP3_ERR);
}
if(stereo == 2) {
struct gr_info_s *gr_info = &(sideinfo.ch[1].gr[gr]);
long part2bits;
if(fr->lsf)
part2bits = III_get_scale_factors_2(mp, scalefacs,gr_info,i_stereo);
else {
#ifdef MPEG1
part2bits = III_get_scale_factors_1(mp, scalefacs,gr_info);
#else
ast_log(LOG_WARNING,"Not supported\n");
#endif
}
if(III_dequantize_sample(mp, hybridIn[1],scalefacs,gr_info,sfreq,part2bits))
return (MP3_ERR);
if(ms_stereo) {
int i;
for(i=0;i<SBLIMIT*SSLIMIT;i++) {
real tmp0,tmp1;
tmp0 = ((real *) hybridIn[0])[i];
tmp1 = ((real *) hybridIn[1])[i];
((real *) hybridIn[1])[i] = tmp0 - tmp1;
((real *) hybridIn[0])[i] = tmp0 + tmp1;
}
}
if(i_stereo)
III_i_stereo(hybridIn,scalefacs,gr_info,sfreq,ms_stereo,fr->lsf);
if(ms_stereo || i_stereo || (single == 3) ) {
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 3:
{
register int i;
register real *in0 = (real *) hybridIn[0],*in1 = (real *) hybridIn[1];
for(i=0;i<SSLIMIT*gr_info->maxb;i++,in0++)
*in0 = (*in0 + *in1++); /* *0.5 done by pow-scale */
}
break;
case 1:
{
register int i;
register real *in0 = (real *) hybridIn[0],*in1 = (real *) hybridIn[1];
for(i=0;i<SSLIMIT*gr_info->maxb;i++)
*in0++ = *in1++;
}
break;
}
}
for(ch=0;ch<stereo1;ch++) {
struct gr_info_s *gr_info = &(sideinfo.ch[ch].gr[gr]);
III_antialias(hybridIn[ch],gr_info);
III_hybrid(mp, hybridIn[ch], hybridOut[ch], ch,gr_info);
}
for(ss=0;ss<SSLIMIT;ss++) {
if(single >= 0) {
clip += synth_ntom_mono(mp,hybridOut[0][ss],pcm_sample,pcm_point);
}
else {
int p1 = *pcm_point;
clip += synth_ntom(mp,hybridOut[0][ss],0,pcm_sample,&p1);
clip += synth_ntom(mp,hybridOut[1][ss],1,pcm_sample,pcm_point);
}
}
}
return 0;
}