/* layer3.h

   Declarations for the Layer III decoder object */

#ifndef LAYERIII_H
#define LAYERIII_H

#include "all.h"

#ifndef L3TYPE_H
#define L3TYPE_H

#include "all.h"

typedef	struct {
  uint32 part2_3_length;
  uint32 big_values;
  uint32 global_gain;
  uint32 scalefac_compress;
  uint32 window_switching_flag;
  uint32 block_type;
  uint32 mixed_block_flag;
  uint32 table_select[3];
  uint32 subblock_gain[3];
  uint32 region0_count;
  uint32 region1_count;
  uint32 preflag;
  uint32 scalefac_scale;
  uint32 count1table_select;
} gr_info_s;


typedef struct {
  uint32 main_data_begin;
  uint32 private_bits;
  struct {
    uint32 scfsi[4];
    gr_info_s gr[2];
  } ch[2];
} III_side_info_t;


typedef struct {
  int32 l[23];            /* [cb] */
  int32 s[3][13];         /* [window][cb] */
} III_scalefac_t[2];


#endif





//#include "l3type.h"
#include "ibitstream.h"
#include "obuffer.h"
#include "bit_res.h"
#include "header.h"
#include "synthesis_filter.h"

#define SSLIMIT 18
#define SBLIMIT 32

/* Size of the table of whole numbers raised to 4/3 power.
   This may be adjusted for performance without any problems. */
#define POW_TABLE_LIMIT 512

class LayerIII_Decoder {

public:

	LayerIII_Decoder(Ibitstream *stream0, Header *header0,
   	           	  SynthesisFilter *filtera, SynthesisFilter *filterb,
                    Obuffer *buffer0, enum e_channels which_ch0);

   ~LayerIII_Decoder();

   // Notify decoder that a seek is being made
   void seek_notify();

   // Decode one frame, filling the buffer with the output samples
	void decode();

private:

	// private data

	int32 is[SBLIMIT][SSLIMIT];
   real  ro[2][SBLIMIT][SSLIMIT];
   real  lr[2][SBLIMIT][SSLIMIT];
	real  hybridIn[SBLIMIT][SSLIMIT];
   real  re_hybridOut[SBLIMIT][SSLIMIT];
   real  prevblck[2][SBLIMIT][SSLIMIT];

	Ibitstream *stream;
   Header *header;
   SynthesisFilter *filter1, *filter2;
   Obuffer *buffer;
   enum e_channels which_channels;
   Bit_Reserve *br;
   III_side_info_t *si;
   III_scalefac_t scalefac;

   uint32 max_gr;
   int32  frame_start;
   int32  part2_start;
   uint32 channels;
   uint32 first_channel;
   uint32 last_channel;

   // private member functions

	BOOL get_side_info();
	void get_scale_factors(uint32 ch, uint32 gr);
   void huffman_decode(uint32 ch, uint32 gr);
	void dequantize_sample(real xr[SBLIMIT][SSLIMIT], uint32 ch, uint32 gr);
	void reorder(real xr[SBLIMIT][SSLIMIT], uint32 ch, uint32 gr);
	void stereo(uint32 gr);
	void antialias(uint32 ch, uint32 gr);
	void hybrid(uint32 ch, uint32 gr);
   void do_downmix();

};

#endif
