/**********************************************************************
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

#define	PNS_SF_OFFSET 90

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);

static int sam_scale_bits[64];
static int *scale_index_long;
static int *scale_index_short;
static int *scale_qbw_long;
static int *scale_qbw_short;

void sam_scale_bits_init(int sampling_rate_decoded, int block_size_samples)
{
  int i, layer, layer_bit_rate;
  int average_layer_bits;

  /* calculate the avaerage amount of bits available
     for the scalability layer of one block per channel */
  for (layer=0; layer<=48; layer++) {
    layer_bit_rate = (layer+16) * 1000;
    average_layer_bits = (int)((double)layer_bit_rate*(double)block_size_samples/(double)sampling_rate_decoded);
    sam_scale_bits[layer] = average_layer_bits;
  }

  for(i = 0; i < 10; i++) {
    if(sampling_rate_decoded == sam_scale_info_bsac[i].sampling_frequency) {
      scale_index_short = (int *)sam_scale_info_bsac[i].scale_index_short;
      scale_qbw_short   = (int *)sam_scale_info_bsac[i].scale_qbw_short;
      scale_index_long = (int *)sam_scale_info_bsac[i].scale_index_long;
      scale_qbw_long   = (int *)sam_scale_info_bsac[i].scale_qbw_long;
      break;
    }
  }
}

void
sam_decode_bsac_stream ( WINDOW_TYPE windowSequence[],
                         int         target,
                         int         frameLength,
                         int         encodedLayer,
                         int         core_used_bits,
                         int         sample[][1024],
                         int         scalefactors[][136],
                         int         maxSfb[],
                         int         groupInfo[][7],
                         int         ms_mask[],
                         int         stereo_mode,
                         int         is_info[],
                         int         *pns_sfb_start,
                         int         pns_sfb_flag[][136],
                         int         pns_sfb_mode[],
                         int         swb_offset[][136],
                         int         block_size_samples,
                         int         nch )
{
  int           i, k, m, w, ch;
  int           m1, m0, m1cnt, m0cnt;
  int           sfb, qband, cband;
  int           band_bal;
  int           read_bits;
  int           max_target_bits;
  int           maxScalefactor[2];
  int           pns_nrg[2];
  int           layer;
  int           num_window_group[2], s[2][8], e[2][8];
  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           pns_data_present;
  int           noise_pcm_flag[2];
  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;
  static int	AModelNoiseNrg[512];
  static int	is_start=1;


  if(is_start) {
    int prob=16384-32;
    for(i = 0; i < 512; i++) {
      AModelNoiseNrg[i] = prob;
      prob -= 32;
    }
    is_start = 0;
  }


  if(encodedLayer < 0 || encodedLayer > TOP_LAYER) {
    fprintf(stderr, "Strange Bitstream! %d\n", encodedLayer);
    return;
  }
  if(target < 0 || target > encodedLayer) {
    fprintf(stdout, "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]);

    layer_sfb[ch][0] = 0;
    layer_index[ch][0] = 0;
	noise_pcm_flag[ch] = 1;
    for (layer = 0; layer <= target && layer <= encodedLayer; layer++) {
	  int scaleqbw;

      if(windowSequence[ch] == 2) {
        layer_index[ch][layer+1] = scale_index_short[layer] * 8;
		scaleqbw = scale_qbw_short[layer];
      } else {
        layer_index[ch][layer+1] = scale_index_long[layer];
		scaleqbw = scale_qbw_long[layer];
      }
      if (scaleqbw < maxSfb[ch])
        layer_sfb[ch][layer+1] = scaleqbw;
      else
        layer_sfb[ch][layer+1] = maxSfb[ch];

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

      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++) {
    dscale_bits[i] = sam_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;

	pns_nrg[ch] = 0;
  }

  read_bits = sam_getUsedBits() + core_used_bits;

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


  for(ch = 0; ch < nch; ch++) {
	/* maximum scalefactors */
    maxScalefactor[ch] = sam_GetBits(8);
    read_bits += 8;

    /* 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;
  }

  pns_data_present = sam_GetBits(1);
  read_bits += 1;
  if(pns_data_present) {
    *pns_sfb_start = sam_GetBits(6);
    read_bits += 6;
  } else {
    *pns_sfb_start = -1;
  }

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

  max_target_bits = dscale_bits[target];
  if(max_target_bits > dscale_bits[encodedLayer])
    max_target_bits = dscale_bits[encodedLayer];

  sam_start_decoding(read_bits, max_target_bits);
                
  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/PNS Information                 */
    /* ***************************************************** */
	if(nch == 1) {
	if(pns_data_present) {
    	for(w = 0; w < num_window_group[0]; w++)
      		for(sfb = layer_sfb[0][layer]; sfb < layer_sfb[0][layer+1]; sfb++) {
				if(sfb >= *pns_sfb_start) {
          			qband = (w * maxSfb[0]) + sfb;
            		ar_error = sam_decode_symbol(AModelNoiseFlag, &m, &estimated_bits);
					pns_sfb_flag[0][qband] = m;
				}
			}
	}
	} else if(stereo_mode != 2) {
      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 == 1)
            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;
          }
		  if(pns_data_present && sfb > *pns_sfb_start) {
            ar_error = sam_decode_symbol(AModelNoiseFlag, &m, &estimated_bits);
			pns_sfb_flag[0][qband] = m;
            ar_error = sam_decode_symbol(AModelNoiseFlag, &m, &estimated_bits);
			pns_sfb_flag[1][qband] = m;
			if(stereo_mode == 3 && is_info[qband] == 2) {
				is_info[qband] = 0;
				if(pns_sfb_flag[0][qband] && pns_sfb_flag[1][qband]) {
            		ar_error = sam_decode_symbol(AModelNoiseMode, &m, &estimated_bits);
					pns_sfb_mode[qband] = m;
				}
			}
		  }
        }
      }
    }

    /* ***************************************************** */
    /* #                  PNS    Information                 */
    /* ***************************************************** */

    /* ***************************************************** */
    /* #             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 {
		  if(pns_data_present && noise_pcm_flag[ch] && sfb >= *pns_sfb_start) {
          ar_error = sam_decode_symbol(AModelNoiseNrg, &m, &estimated_bits);
          scalefactors[ch][qband] = m - PNS_SF_OFFSET;
          prev_scf[ch] = scalefactors[ch][qband];
		  noise_pcm_flag[ch] = 0;
		  } 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;
}
