/* this file is a part of amp software, (C) tomislav uzelac 1996,1997
*/

/* layer2.c   MPEG audio layer2 support
 *
 * Created by: Tomislav Uzelac  Mar 1996
 * merged with amp, May 19 1997
 */
#include "amp.h"
#include "audio.h"
#include "getbits.h"
#include "transform.h"

#define LAYER2
#include "layer2.h"

int layer2_frame(struct AUDIO_HEADER *header,int cnt)
{
int i,s,sb,ch,gr,bitrate,bound;
char (*nbal)[],(*bit_alloc_index)[][16];
unsigned char allocation[2][32];
unsigned char scfsi[2][32];
float scalefactor[2][32][3];
float subband_sample[2][32][36];
int sblimit,nlevels,grouping; 

float  c,d;
int no_of_bits,mpi;				
unsigned short sb_sample_buf[3];	

int hsize,fs,mean_frame_size;

	hsize=4;
	if (header->protection_bit==0) hsize+=2;

	bitrate=t_bitrate[header->ID][3-header->layer][header->bitrate_index];
        fs=t_sampling_frequency[header->ID][header->sampling_frequency];
        if (header->ID) mean_frame_size=144000*bitrate/fs;
        else mean_frame_size=72000*bitrate/fs;

	/* layers 1 and 2 do not have a 'bit reservoir'
	 */
	append=data=0;

	fillbfr(mean_frame_size + header->padding_bit - hsize);

	switch (header->mode)
		{
		case 0 : 
		case 2 : nch=2; bound=32; bitrate=bitrate/2;  
			break;
		case 3 : nch=1; bound=32; 
			break;
		case 1 : nch=2; bitrate=bitrate/2; bound=(header->mode_extension+1)*4; 
		}
		
	if (header->ID==1) switch (header->sampling_frequency) {
		case 0 : switch (bitrate)	/* 0 = 44.1 kHz */
				{
				case 56  :
				case 64  :
				case 80  : bit_alloc_index=&t_alloc0;
					   nbal=&t_nbal0;
					   sblimit=27;
					   break;
				case 96  :
				case 112 :
				case 128 :
				case 160 :
				case 192 : bit_alloc_index=&t_alloc1;
					   nbal=&t_nbal1;
					   sblimit=30;  
					   break;
				case 32  :
				case 48  : bit_alloc_index=&t_alloc2;
					   nbal=&t_nbal2;
					   sblimit=8;
					   break;
				default  : printf(" bit alloc info no gud ");
				}
				break;
		case 1 : switch (bitrate)	/* 1 = 48 kHz */
				{
				case 56  : 
				case 64  :
				case 80  :
				case 96  :
				case 112 :
				case 128 :
				case 160 :
				case 192 : bit_alloc_index=&t_alloc0;
					   nbal=&t_nbal0;
					   sblimit=27;
					   break;
				case 32  :
				case 48  : bit_alloc_index=&t_alloc2;
					   nbal=&t_nbal2;
					   sblimit=8;
					   break;
				default  : printf(" bit alloc info no gud ");
				}
				break;
		case 2 : switch (bitrate)	/* 2 = 32 kHz */
				{
			case 56  :
                        case 64  :
                        case 80  : bit_alloc_index=&t_alloc0;
                                   nbal=&t_nbal0;
                                   sblimit=27;
                                   break;
                        case 96  :
                        case 112 :
                        case 128 :
                        case 160 :
                        case 192 : bit_alloc_index=&t_alloc1;
                                   nbal=&t_nbal1;
                                   sblimit=30;
                                   break;
			case 32  :
			case 48  : bit_alloc_index=&t_alloc3;
                                   nbal=&t_nbal3;
                                   sblimit=12;
				   break;
			default  : printf("bit alloc info not ok\n");
			}
	                break;                                                    
		default  : printf("sampling freq. not ok/n");
	} else {
		bit_alloc_index=&t_allocMPG2;
		nbal=&t_nbalMPG2;
		sblimit=30;
	}

/*
 * bit allocation per subband per channel decoding *****************************
 */

	if (bound==32) bound=sblimit;	/* bound=32 means there is no intensity stereo */
	 
	for (sb=0;sb<bound;sb++)
		for (ch=0;ch<nch;ch++)
			allocation[ch][sb]=getbits((*nbal)[sb]);

	for (sb=bound;sb<sblimit;sb++)
		allocation[1][sb] = allocation[0][sb] = getbits((*nbal)[sb]);


/*
 * scfsi ***********************************************************************
 */

	for (sb=0;sb<sblimit;sb++)
		for (ch=0;ch<nch;ch++)
			if (allocation[ch][sb]!=0) scfsi[ch][sb]=getbits(2);
			else scfsi[ch][sb]=0;

/*
 * scalefactors ****************************************************************
 */

	for (sb=0;sb<sblimit;sb++)
	for (ch=0;ch<nch;ch++)
		if (allocation[ch][sb]!=0) {
			scalefactor[ch][sb][0]=t_scalefactor[getbits(6)];
			switch (scfsi[ch][sb])
			{
			case 0: scalefactor[ch][sb][1]=t_scalefactor[getbits(6)];
				scalefactor[ch][sb][2]=t_scalefactor[getbits(6)];
				break;
			case 1: scalefactor[ch][sb][2]=t_scalefactor[getbits(6)];
				scalefactor[ch][sb][1]=scalefactor[ch][sb][0];
				break;
			case 2: scalefactor[ch][sb][1]=scalefactor[ch][sb][0];
				scalefactor[ch][sb][2]=scalefactor[ch][sb][0];
				break;
			case 3: scalefactor[ch][sb][2]=t_scalefactor[getbits(6)];
				scalefactor[ch][sb][1]=scalefactor[ch][sb][2];
			}		 	
		} 
		else scalefactor[ch][sb][0]=scalefactor[ch][sb][1]=\
			scalefactor[ch][sb][2]=0.0;


/*
 * samples *********************************************************************
 */

	for (gr=0;gr<12;gr++) {
		/*
		 * normal ********************************
		 */
   	
		for (sb=0;sb<bound;sb++)
		for (ch=0;ch<nch;ch++)
		if (allocation[ch][sb]!=0) {
			mpi=(*bit_alloc_index)[sb][allocation[ch][sb]];	
			no_of_bits=t_bpc[mpi];
			c=t_c[mpi];
			d=t_d[mpi];
			grouping=t_grouping[mpi];
			nlevels=t_nlevels[mpi];

			if (grouping) {
				int samplecode=getbits(no_of_bits);
				convert_samplecode(samplecode,grouping,sb_sample_buf);

                        	for (s=0;s<3;s++)
                                	subband_sample[ch][sb][3*gr+s]=requantize_sample (sb_sample_buf[s],nlevels,c,d,scalefactor[ch][sb][gr/4]);
			} else {
				for (s=0;s<3;s++) sb_sample_buf[s]=getbits(no_of_bits);
				
				for (s=0;s<3;s++) { 
					/*subband_sample[ch][sb][3*gr+s]=requantize_sample (sb_sample_buf[s],nlevels,c,d,scalefactor[ch][sb][gr/4]);*/
					subband_sample[ch][sb][3*gr+s]=(t_dd[mpi]+sb_sample_buf[s]*t_nli[mpi])*c*scalefactor[ch][sb][gr>>2];
				}
			}
	    	} else 
			for (s=0;s<3;s++) subband_sample[ch][sb][3*gr+s]=0;


		/*
		 * joint stereo ********************************************
		 */
      
		for (sb=bound;sb<sblimit;sb++)
   		if (allocation[0][sb]!=0) {
			/*ispravka!
			*/
			mpi=(*bit_alloc_index)[sb][allocation[0][sb]];	
			no_of_bits=t_bpc[mpi];
			c=t_c[mpi];
			d=t_d[mpi];
			grouping=t_grouping[mpi];
			nlevels=t_nlevels[mpi];	
	    	   
			if (grouping) {
				int samplecode=getbits(no_of_bits);
				convert_samplecode(samplecode,grouping,sb_sample_buf);

				for (s=0;s<3;s++) {
					subband_sample[0][sb][3*gr+s]=requantize_sample (sb_sample_buf[s],nlevels,c,d,scalefactor[0][sb][gr/4]);
					subband_sample[1][sb][3*gr+s]=subband_sample[0][sb][3*gr+s];
				}
			} else {
				for (s=0;s<3;s++) sb_sample_buf[s]=getbits(no_of_bits);

				for (s=0;s<3;s++) { 
					subband_sample[0][sb][3*gr+s]=subband_sample[1][sb][3*gr+s]=\
						(t_dd[mpi]+sb_sample_buf[s]*t_nli[mpi])*c*scalefactor[0][sb][gr>>2];
				}
			}

		} else for (s=0;s<3;s++) {
			subband_sample[0][sb][3*gr+s]=0;
			subband_sample[1][sb][3*gr+s]=0;
		}

		/*
		 * the rest *******************************************
		 */
		for (sb=sblimit;sb<32;sb++)
			for (ch=0;ch<nch;ch++)

				for (s=0;s<3;s++) subband_sample[ch][sb][3*gr+s]=0;
	}	

	/*
	 * this is, in fact, horrible, but I had to adjust it to amp/mp3. The hack to make downmixing
	 * work is as ugly as possible.
	 */

	if (A_DOWNMIX && header->mode!=3) {
		for (ch=0;ch<nch;ch++) 
			for (sb=0;sb<32;sb++)
				for (i=0;i<36;i++)
					subband_sample[0][sb][i]=(subband_sample[0][sb][i]+subband_sample[1][sb][i])*0.5f;
		nch=1;
	}

	for (ch=0;ch<nch;ch++) {
		for (sb=0;sb<32;sb++) 
			for (i=0;i<18;i++) res[sb][i]=subband_sample[ch][sb][i]; 
	   	for (i=0;i<18;i++)
			poly(ch,i);
	}
	printout();
	for (ch=0;ch<nch;ch++) {
                for (sb=0;sb<32;sb++)
                        for (i=0;i<18;i++) res[sb][i]=subband_sample[ch][sb][i+18];
                for (i=0;i<18;i++)
                        poly(ch,i);
        }
        printout();

	if (A_DOWNMIX && header->mode!=3) nch=2;

	return 0;
}                        
/****************************************************************************/	
/****************************************************************************/

void convert_samplecode(unsigned int samplecode,unsigned int nlevels,unsigned short* sb_sample_buf)
{
int i;

	for (i=0;i<3;i++) {
		*sb_sample_buf=samplecode%nlevels;
		samplecode=samplecode/nlevels;
		sb_sample_buf++;
	}
}

float requantize_sample(unsigned short s4,unsigned short nlevels,float c,float d,float factor)
{
register float s,s2,s3;
s3=-1.0+s4*2.0/(nlevels+1);
s2=c*(s3+d);
s=factor*s2;
return s;
} 
