/**********************************************************************
MPEG-4 Audio VM

This software module was originally developed by
  Y.B. Thomas Kim and S.H. Park (Samsung AIT)
and edited by
  Y.B. Thomas Kim (Samsung AIT) on 1997-11-06

in the course of development of the MPEG-2 NBC/MPEG-4 Audio standard
ISO/IEC 13818-7, 14496-1,2 and 3. This software module is an
implementation of a part of one or more MPEG-2 NBC/MPEG-4 Audio tools
as specified by the MPEG-2 NBC/MPEG-4 Audio standard. ISO/IEC gives
users of the MPEG-2 NBC/MPEG-4 Audio standards free license to this
software module or modifications thereof for use in hardware or
software products claiming conformance to the MPEG-2 NBC/ MPEG-4 Audio
standards. Those intending to use this software module in hardware or
software products are advised that this use may infringe existing
patents. The original developer of this software module and his/her
company, the subsequent editors and their companies, and ISO/IEC have
no liability for use of this software module or modifications thereof
in an implementation. Copyright is not released for non MPEG-2
NBC/MPEG-4 Audio conforming products. The original developer retains
full right to use the code for his/her own purpose, assign or donate
the code to a third party and to inhibit third party from using the
code for non MPEG-2 NBC/MPEG-4 Audio conforming products. This
copyright notice must be included in all copies or derivative works.

Copyright (c) 1997.

**********************************************************************/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include "sam_scale.h"
#include "sam_model.h"
#include "sam_scf_coding.h"
#include "sam_dec.h"

#define	TOP_LAYER	48

static int *select_scf_model(int scalefactor_model);
static int *select_Ar_model(int ArModel_model);
static int *select_model(int model_no, int cur_snf, int m0cnt, int pre_state);

void
sam_decode_bsac_stream(int	windowSequence[],
	int encodedLayer,
	int target,
	int sample[][1024],
	int maxScalefactor[],
	int scalefactors[][112],
	int maxSfb[],
	int	groupInfo[][7],
	int	ms_mask[],
	int	stereo_mode,
	int	is_info[],
	int	swb_offset[][114],
	int frameLength,
	int	nch)
{
	int		i, k, m, w, ch;
	int		m1, m0, m1cnt, m0cnt;
	int		sfb, qband, cband;
	int		band_bal;
	int		read_bits;
	int		layer;
	int		num_window_group[2], s[2][8], e[2][8];
	int		scaleqbw[2][114];
	int		layer_sfb[2][64];
	int		layer_index[2][64];
	int		snf;
	int		tmpsnf;
	int		maxsnf;
	int		last_index;
	int		is_pos;
	int		prev_scf[2];
	int		scf_coding[2];
	int		cur_snf[2][256];
	int		ar_error;
	int		exit_flag;
	int		scalefactor_model[2], ArModel_model[2];
	int		decode_cband[2][200];
    int     min_ArModel[2];
	int		band_snf[2][200];
	int     dscale_bits[64];
	char	prestate[2][1024];
	int		which_model[2][200];
	int		*p_freq0, *p_freq1;
    double	estimated_bits;


	if(encodedLayer < 0 || encodedLayer > TOP_LAYER) {
		fprintf(stderr, "Strange Bitstream! %d\n", encodedLayer);
		return;
	}
	if(target < 0 || target > TOP_LAYER) {
		fprintf(stderr, "Strange Target Bitrate! %d\n", target);
		return;
	}

	if(maxSfb[0] == 0) {
		if(nch == 1) return;
		if(nch == 2 && maxSfb[1] == 0) return;
	}

	/* ***************************************************** */
	/* #                  Initialization					 */
	/* ***************************************************** */
	for(ch = 0; ch < nch; ch++) {
		num_window_group[ch] = 1;
		if(windowSequence[ch] == 2) {
			num_window_group[ch] = sam_get_region_info(groupInfo[ch], s[ch], e[ch]);
			for(i = 0; i <= target; i++)
				scaleqbw[ch][i] = scale_qbws[i];

		} else {
			for(i = 0; i <= target; i++)
				scaleqbw[ch][i] = scale_qbw[i];
		}
	}

	for(ch = 0; ch < nch; ch++) {
	   	layer_sfb[ch][0] = 0;
		layer_index[ch][0] = 0;
	}

	for (layer = 0; layer <= target && layer <= encodedLayer; layer++) {
		for(ch = 0; ch < nch; ch++) {
	    	if (scaleqbw[ch][layer] < maxSfb[ch])
				layer_sfb[ch][layer+1] = scaleqbw[ch][layer];
	    	else
				layer_sfb[ch][layer+1] = maxSfb[ch];

			qband = layer_sfb[ch][layer+1] * num_window_group[ch];

			if(windowSequence[ch] == 2) {
				layer_index[ch][layer+1] = scale_findex_s[layer] * 8;
			} else {
				layer_index[ch][layer+1] = scale_findex_l[layer];
			}
        	if (swb_offset[ch][qband] < layer_index[ch][layer+1])
               	layer_index[ch][layer+1] = swb_offset[ch][qband];
		}
	}

    for (i=0; i<encodedLayer; i++) {
		if (frameLength < scale_bits[i] * nch) 
			dscale_bits[i] = frameLength; 
		else
			dscale_bits[i] = scale_bits[i] * nch;
	}
	dscale_bits[encodedLayer] = frameLength;

	/*** Clear variables ***/
	for(ch = 0; ch < nch; ch++) {
		for (i=0; i<1024; i++)
    		sample[ch][i] = 0;

		for (i=0; i<200; i++) 
			band_snf[ch][i] = 0;

		for(i = 0; i < 200; i++)
			decode_cband[ch][i] = 0;

		for (i=0; i<200; i++) 
			which_model[ch][i] = 0;

		for (i=0; i<1024; i++)
			prestate[ch][i] = 0;
	}

	read_bits = sam_getUsedBits();

	/* ***************************************************** */
	/* 	  		the common side info for all bitrates  	     */
	/* ***************************************************** */

	for(ch = 0; ch < nch; ch++) {
    	/* scalefactor model */
		scalefactor_model[ch] = sam_getbits(2);
		read_bits += 2;
	
    	/* minimum Arithmetic Model */
		min_ArModel[ch] = sam_getbits(5);
		read_bits += 5;

    	/* Arithmetic Model */
		ArModel_model[ch] = sam_getbits(2);
		read_bits += 2;

    	/* scf model selection */
		scf_coding[ch] = sam_getbits(1);
		read_bits += 1;
	}

	/* *********** ARITHMETIC DECODING **** */
	estimated_bits = read_bits;

	sam_start_decoding(read_bits, dscale_bits[target]);
		
	ar_error = 0;

	/* ***************************************************** */
	/* 	  			the BSAC_STREAM                          */
	/* ***************************************************** */
	for(ch = 0; ch < nch; ch++)
		prev_scf[ch] = maxScalefactor[ch];

	is_pos = 0;
	for (layer=0; layer<=target && layer<=encodedLayer; layer++) {

	   	if (ar_error) break;

		/* ##################################################### */
		/* #              start of bsac_side_info                */
		/* ##################################################### */

		/* ***************************************************** */
		/* #                  Stereo Information                 */
		/* ***************************************************** */
		if(stereo_mode > 1) {
			for(w = 0; w < num_window_group[1]; w++) {
				for(sfb = layer_sfb[1][layer]; sfb < layer_sfb[1][layer+1]; sfb++) {
					if(stereo_mode == 2)
	    				ar_error = sam_decode_symbol(AModelMsUsed, &m, &estimated_bits);
					else
	    				ar_error = sam_decode_symbol(AModelStereoInfo, &m, &estimated_bits);

	    			if (ar_error) break;

					qband = (w * maxSfb[1]) + sfb;
					switch(m) {
					case 1:
						ms_mask[qband+1] = 1;
						break;
					case 2:
						is_info[qband] = 1;
						break;
					case 3:
						is_info[qband] = 2;
						break;
					}
				}
			}
		}

		/* ***************************************************** */
		/* #             Scalefactor Information                 */
		/* ***************************************************** */
		for(ch = 0; ch < nch; ch++) for(w = 0; w < num_window_group[ch]; w++) {
			for(sfb = layer_sfb[ch][layer]; sfb < layer_sfb[ch][layer+1]; sfb++) {

				qband = (w * maxSfb[ch]) + sfb;
				if(scf_coding[ch] == 1) {
					int	*pModel;

					pModel = select_scf_model(scalefactor_model[ch]);

					ar_error = sam_decode_symbol(pModel, &m, &estimated_bits);
					if (ar_error) break;
					scalefactors[ch][qband] = maxScalefactor[ch] - m;

				} else {
					ar_error = sam_decode_symbol(AModelDifScf0, &m1, &estimated_bits);
					if (ar_error) break;

					if(m1 == 54) {
						ar_error = sam_decode_symbol(AModelDifScf1, &m1, &estimated_bits);
						if (ar_error) break;
						m1 += 54;
					}
					m = index2scf[m1];
					if(ch == 1 && is_info[qband]) {
						is_pos += m - 60;
						scalefactors[ch][qband] = is_pos;
					} else {
						scalefactors[ch][qband] = prev_scf[ch] - m + 60;
						prev_scf[ch] = scalefactors[ch][qband];
					}
				}
			}
		}

		/* ***************************************************** */
		/* #                  Model  Information                 */
		/* ***************************************************** */
		for(ch = 0; ch < nch; ch++) {
			int	*pModel;
			for(sfb = layer_sfb[ch][layer]; sfb < layer_sfb[ch][layer+1]; sfb++) {
				for(w = 0; w < num_window_group[ch]; w++) {
					qband = (sfb * num_window_group[ch]) + w;
					for (i = swb_offset[ch][qband]; i < swb_offset[ch][qband+1]; i+=4) {
						if(windowSequence[ch] == 2) {
							cband = sam_i2cb(ch, i);
							if(cband == -1) continue;
						} else {
							cband = i / 32;
						}
						if(decode_cband[ch][cband]) continue;

						pModel = select_Ar_model(ArModel_model[ch]);

		    			ar_error = sam_decode_symbol(pModel, &m, &estimated_bits);
		    			if (ar_error) break;

		    			m += min_ArModel[ch];
		    			band_snf[ch][cband] = m / 2;
						which_model[ch][cband] = m;

						decode_cband[ch][cband] = 1;
		  			}
				}
			}
		}

		if (ar_error) break;

		/* ##################################################### */
		/* #              end of bsac_side_info                  */
		/* ##################################################### */


		/* ##################################################### */
		/* #            start of bsac_spectral_data              */
		/* ##################################################### */

		/* ***************************************************** */
		/* #               Layer  Initialization                 */
		/* ***************************************************** */

		/*
		  set current snf
		*/
		for(ch = 0; ch < nch; ch++) {
			for(sfb = layer_sfb[ch][layer]; sfb < layer_sfb[ch][layer+1]; sfb++) {
				for(w = 0; w < num_window_group[ch]; w++) {
					qband = (sfb * num_window_group[ch]) + w;
					for (i = swb_offset[ch][qband]; i < swb_offset[ch][qband+1]; i+=4) {
						if(windowSequence[ch] == 2) {
							cband = sam_i2cb(ch, i);
						} else {
							cband = i / 32;
						}
						if(cband < 0)
							cur_snf[ch][i/4] = 0;
						else
		   					cur_snf[ch][i/4] = band_snf[ch][cband];
					}
				}
			}
		}

		/*
		  find maximum snf
		*/
		maxsnf = 0;
		for(ch = 0; ch < nch; ch++) {
			qband = layer_sfb[ch][layer+1] * num_window_group[ch];
			for(i = 0; i< swb_offset[ch][qband]/4; i++) 
				if (maxsnf < cur_snf[ch][i]) maxsnf = cur_snf[ch][i];
		}

		/*
		  find last index
		*/
		last_index = 0;
		for(ch = 0; ch < nch; ch++) {
			qband = layer_sfb[ch][layer+1] * num_window_group[ch];
			if(last_index < swb_offset[ch][qband])
				last_index = swb_offset[ch][qband];
		}

		exit_flag = 0;
		for (snf=maxsnf; snf > 0 && !ar_error && !exit_flag; snf--) {

			for(i = 0; i < last_index && !exit_flag; i+=4) {

				for(ch = 0; ch < nch; ch++) {

					if (i >= layer_index[ch][layer+1]) break;

					if (cur_snf[ch][i/4]<snf || cur_snf[ch][i/4]<=0)
						continue;

					/* The number of the sample is counted 
						whose sign bit was not encoded previously. 
						It is the size of the vector to be decoded. */
					m0cnt = 0; m1cnt = 0;
					for(k = 0; k < 4; k++) 
						if (prestate[ch][i+k]==0) m0cnt++;
						else				  m1cnt++;

					/* select the model for arithmetic coding as 
						the function of band snf & current vector snf */

					if(windowSequence[ch] == 2) {
						cband = sam_i2cb(ch, i);
						if(cband == -1) band_bal = 0;
						else band_bal = band_snf[ch][cband];
					} else {
						cband = i / 32;
						band_bal = band_snf[ch][cband];
					}

		     		tmpsnf = band_bal - cur_snf[ch][i/4];
					p_freq0 = select_model(which_model[ch][cband], tmpsnf, m0cnt, 0);
					p_freq1 = select_model(which_model[ch][cband], tmpsnf, m1cnt, 1);

					/* decode the vector */
					if (m1cnt>0) {
						ar_error = sam_decode_symbol(p_freq1, &m1, &estimated_bits);
						if (ar_error) break;
					}

					if (m0cnt>0) {
						ar_error = sam_decode_symbol(p_freq0, &m0, &estimated_bits);
						if (ar_error) break;
					}

					/* disassemble the decoded vector and
						reconstruct the decoded sample */
					for(k = 0; k < 4; k++) {
						if (prestate[ch][i+k]==0) { 
							m = m0 & 0x01;
							m0 >>= 1;	
						} else { 
							m = m1 & 0x01;
							m1 >>= 1;	
						}

						if (m) {
							int tval;

							if (sample[ch][i+k]>=0) 
								tval = sample[ch][i+k];
							else 
								tval = -sample[ch][i+k];  

							tval |= 0x1<<(cur_snf[ch][i/4]-1);  
							if (sample[ch][i+k]>=0) 
								sample[ch][i+k] = tval;
							else 
								sample[ch][i+k] = -tval;  

						}
					}

					/* decode the sign bit */
					for(k = 0; k < 4; k++) {
						if (sample[ch][i+k] && prestate[ch][i+k] == 0) {
							ar_error = sam_decode_symbol(AModelSign, &m, &estimated_bits);
							if (ar_error) break;

							if (m) sample[ch][i+k] *= -1;

							prestate[ch][i+k] = 1;
						}
					}
					if (ar_error) break;

					cur_snf[ch][i/4]--;

					if(estimated_bits >= dscale_bits[layer]) {
						exit_flag = 1;
						break;
					}
				}	/* for(ch = 0; ch < nch; ch++) */

			}	/* for(i = 0; i < last_index && !exit_flag; i+=4) */

			if (estimated_bits >= dscale_bits[layer]) break;
			else if (ar_error)                   break;

		} /* for (snf=maxsnf; snf>0 && !ar_error && !exit_flag; snf--) */

		/* ##################################################### */
		/* #              end of bsac_spectral_data              */
		/* ##################################################### */

	} /* for (layer=0; layer<=target && layer<=encodedLayer; layer++) */ 
}

int *select_scf_model(int scalefactor_model)
{
	int	*pModel;

	pModel = NULL;
	switch(scalefactor_model) {
		case 0:
			pModel = (int *)AModelDifScf2;
			break;
		case 1:
			pModel = (int *)AModelDifScf3;
			break;
		case 2:
			pModel = (int *)AModelDifScf4;
			break;
		case 3:
			pModel = (int *)AModelDifScf5;
			break;
	}

	return pModel;
}

int *select_Ar_model(int ArModel_model)
{
	int	*pModel;

	pModel = NULL;
	switch(ArModel_model) {
		case 0:
			pModel = (int *)AModelDiffAModel0;
			break;
		case 1:
			pModel = (int *)AModelDiffAModel1;
			break;
		case 2:
			pModel = (int *)AModelDiffAModel2;
			break;
		case 3:
			pModel = (int *)AModelDiffAModel3;
			break;
	}

	return pModel;
}

int *select_model(int model_no,
		int cur_snf,
		int m0cnt,
		int pre_state)
{
	int	*ptr;
	int	model;
	int	snf;
	int	i, offset;
	static int	position4[]={
		0,  0,  0,  1,  2,  5,
		8, 13, 18, 25, 32, 41
	};
	static int	positions[]={
		0, 0,  0,  0,  0,  2,
		4, 8, 12, 18, 24, 32
	};
	static int	alloc_bit[]={
		 0,  0,  1,  1,  2,  2,  3, 3,
		 4,  4,  5,  5,  6,  6,  7, 7,
		 8,  8,  9,  9, 10, 10, 11, 11,
		12, 12, 13, 13, 14, 14, 15, 15,
		16, 16
	};


	snf = cur_snf;
	model = model_no;
	if(model_no > 11) {
		if(model_no % 2)
			model = 11;
		else
			model = 10;
	}
	if(snf < 0) snf = 0;
	if(snf > 4) snf = 4;


	offset = 0;
	if(snf != 0) {
		if(m0cnt == 4)
			offset = 1;
		for(i = 1; i < alloc_bit[model]; i++) {
			if(snf == i) break;
			offset += 2;
		}
		if(pre_state == 1)
			offset += 1;
	}

	ptr = NULL;
	switch(m0cnt) {
	case 4:
		ptr = (int *)AModelDim4[position4[model]+offset];
		break;
	case 3:
		ptr = (int *)AModelDim3[positions[model]+offset];
		break;
	case 2:
		ptr = (int *)AModelDim2[positions[model]+offset];
		break;
	case 1:
		ptr = (int *)AModelDim1[positions[model]+offset];
		break;
	default:
		break;
	}

	return ptr;
}
