

#ifndef VALIB_DTS_PARSER_H
#define VALIB_DTS_PARSER_H

#include "../../parser.h"
#include "../../bitstream.h"
#include "dts_defs.h"

class DTSInfo
{
public:
  
  int frame_type;         
  int samples_deficit;    
  int crc_present;        
  int sample_blocks;      
  int amode;              
  int sample_rate;        
  int bit_rate;           

  int downmix;            
  int dynrange;           
  int timestamp;          
  int aux_data;           
  int hdcd;               
  int ext_descr;          
  int ext_coding;         
  int aspf;               
  int lfe;                
  int predictor_history;  
  int header_crc;         
  int multirate_inter;    
  int version;            
  int copy_history;       
  int source_pcm_res;     
  int front_sum;          
  int surround_sum;       
  int dialog_norm;        

  
  int subframes;          
  int prim_channels;      
  
  int subband_activity[DTS_PRIM_CHANNELS_MAX];    
  int vq_start_subband[DTS_PRIM_CHANNELS_MAX];    
  int joint_intensity[DTS_PRIM_CHANNELS_MAX];     
  int transient_huffman[DTS_PRIM_CHANNELS_MAX];   
  int scalefactor_huffman[DTS_PRIM_CHANNELS_MAX]; 
  int bitalloc_huffman[DTS_PRIM_CHANNELS_MAX];    
  int quant_index_huffman[DTS_PRIM_CHANNELS_MAX][DTS_ABITS_MAX]; 
  float scalefactor_adj[DTS_PRIM_CHANNELS_MAX][DTS_ABITS_MAX];   

  
  int subsubframes;       
  int partial_samples;    
  int prediction_mode[DTS_PRIM_CHANNELS_MAX][DTS_SUBBANDS];   
  int prediction_vq[DTS_PRIM_CHANNELS_MAX][DTS_SUBBANDS];     
  int bitalloc[DTS_PRIM_CHANNELS_MAX][DTS_SUBBANDS];          
  int transition_mode[DTS_PRIM_CHANNELS_MAX][DTS_SUBBANDS];   
  int scale_factor[DTS_PRIM_CHANNELS_MAX][DTS_SUBBANDS][2];   
  int joint_huff[DTS_PRIM_CHANNELS_MAX];                      
  int joint_scale_factor[DTS_PRIM_CHANNELS_MAX][DTS_SUBBANDS];
  int downmix_coef[DTS_PRIM_CHANNELS_MAX][2];                 
  int dynrange_coef;      

  
  int high_freq_vq[DTS_PRIM_CHANNELS_MAX][DTS_SUBBANDS];

  
  double lfe_data[2*DTS_SUBSUBFAMES_MAX*DTS_LFE_MAX * 2];
  int lfe_scale_factor;

  
  double subband_samples_hist[DTS_PRIM_CHANNELS_MAX][DTS_SUBBANDS][4];
  double subband_fir_hist[DTS_PRIM_CHANNELS_MAX][512];
  double subband_fir_noidea[DTS_PRIM_CHANNELS_MAX][64];
};

class DTSParser : public FrameParser, public DTSInfo
{
public:
  DTSParser();

  
  

  virtual const HeaderParser *header_parser() const;

  virtual void reset();
  virtual bool parse_frame(uint8_t *frame, size_t size);

  virtual Speakers  get_spk()      const { return spk;      }
  virtual samples_t get_samples()  const { return samples;  }
  virtual size_t    get_nsamples() const { return nsamples; }
  virtual uint8_t  *get_rawdata()  const { return 0;        }
  virtual size_t    get_rawsize()  const { return 0;        }

  virtual size_t stream_info(char *buf, size_t size) const;
  virtual size_t frame_info(char *buf, size_t size) const;

protected:
  
  

  Speakers  spk;
  size_t    frame_size;
  int       nsamples;
  int       bs_type;

  ReadBS    bs;
  SampleBuf samples;

  int current_subframe;
  int current_subsubframe;

  
  double cos_mod[544];
  void init_cosmod();

  
  bool parse_frame_header();
  bool parse_subframe_header();
  bool parse_subsubframe();
  bool parse_subframe_footer();

  
  int  InverseQ(const huff_entry_t *huff);
  void qmf_32_subbands(int ch, 
         double samples_in[32][8], 
         sample_t *samples_out,
         double scale);
  void lfe_interpolation_fir(int nDecimationSelect, 
         int nNumDeciSample,
         double *samples_in, 
         sample_t *samples_out,
         double scale);
};

#endif
