#include <stdio.h>
#include <string.h>
#include <math.h>

# define M_PI       3.14159265358979323846
# define M_SQRT2	1.41421356237309504880
# define REAL_IS_FLOAT
# define REAL_LONG_IS_FLOAT
# define NEW_DCT9

# define random rand
# define srandom srand

#ifdef REAL_IS_FLOAT
#  define real float
#elif defined(REAL_IS_LONG_DOUBLE)
#  define real long double
#else
#  define real double
#endif

#ifdef REAL_LONG_IS_FLOAT
#  define reallong float
#elif defined(REAL_LONG_IS_LONG_DOUBLE)
#  define reallong long double
#else
#  define reallong double
#endif

#ifdef __GNUC__
#define INLINE inline
#else
#define INLINE
#endif

/* AUDIOBUFSIZE = n*64 with n=1,2,3 ...  */
#define         AUDIOBUFSIZE            16384

#define         FALSE                   0
#define         TRUE                    1

#define         SBLIMIT                 32
#define         SSLIMIT                 18

#define         SCALE_BLOCK             12


#define         MPG_MD_STEREO           0
#define         MPG_MD_JOINT_STEREO     1
#define         MPG_MD_DUAL_CHANNEL     2
#define         MPG_MD_MONO             3

#define MAXFRAMESIZE 1792


/* Pre Shift fo 16 to 8 bit converter table */
#define AUSHIFT (3)

struct frame {
  int stereo;
  int jsbound;
  int single;
  int lsf;
  int mpeg25;
  int header_change;
  int lay;
  int error_protection;
  int bitrate_index;
  int sampling_frequency;
  int padding;
  int extension;
  int mode;
  int mode_ext;
  int copyright;
  int original;
  int emphasis;
  int framesize; /* computed framesize */

  /* layer2 stuff */
  int II_sblimit;
  void *alloc;
};

struct parameter {
  int quiet;      /* shut up! */
  int tryresync;  /* resync stream after error */
  int verbose;    /* verbose level */
  int checkrange;
};

extern unsigned int get1bit(void);
extern unsigned int getbits(int);
extern unsigned int getbits_fast(int);
extern int set_pointer(long);

extern unsigned char *wordpointer;
extern int bitindex;
extern int down_sample;

extern int (*func_synth)(real *,int,unsigned char *,int *);
extern int (*func_synth_mono)(real *,unsigned char *,int *);

extern void make_decode_tables(long scaleval);
extern int do_layer3(struct frame *fr,unsigned char *,int *);
extern int do_layer2(struct frame *fr,unsigned char *,int *);
extern int do_layer1(struct frame *fr,unsigned char *,int *);
extern int decode_header(struct frame *fr,unsigned long newhead);

struct gr_info_s {
  int scfsi;
  unsigned part2_3_length;
  unsigned big_values;
  unsigned scalefac_compress;
  unsigned block_type;
  unsigned mixed_block_flag;
  unsigned table_select[3];
  unsigned subblock_gain[3];
  unsigned maxband[3];
  unsigned maxbandl;
  unsigned maxb;
  unsigned region1start;
  unsigned region2start;
  unsigned preflag;
  unsigned scalefac_scale;
  unsigned count1table_select;
  real *full_gain[3];
  real *pow2gain;
};

struct III_sideinfo
{
  unsigned main_data_begin;
  unsigned private_bits;
  struct {
    struct gr_info_s gr[2];
  } ch[2];
};

extern void set_synth_functions(void);
extern int synth_1to1 (real *,int,unsigned char *,int *);
extern int synth_1to1_8bit (real *,int,unsigned char *,int *);
extern int synth_1to1_mono (real *,unsigned char *,int *);
extern int synth_1to1_mono2stereo (real *,unsigned char *,int *);
extern int synth_1to1_8bit_mono (real *,unsigned char *,int *);
extern int synth_1to1_8bit_mono2stereo (real *,unsigned char *,int *);

extern int synth_2to1 (real *,int,unsigned char *,int *);
extern int synth_2to1_8bit (real *,int,unsigned char *,int *);
extern int synth_2to1_mono (real *,unsigned char *,int *);
extern int synth_2to1_mono2stereo (real *,unsigned char *,int *);
extern int synth_2to1_8bit_mono (real *,unsigned char *,int *);
extern int synth_2to1_8bit_mono2stereo (real *,unsigned char *,int *);

extern int synth_4to1 (real *,int,unsigned char *,int *);
extern int synth_4to1_8bit (real *,int,unsigned char *,int *);
extern int synth_4to1_mono (real *,unsigned char *,int *);
extern int synth_4to1_mono2stereo (real *,unsigned char *,int *);
extern int synth_4to1_8bit_mono (real *,unsigned char *,int *);
extern int synth_4to1_8bit_mono2stereo (real *,unsigned char *,int *);

extern int synth_ntom (real *,int,unsigned char *,int *);
extern int synth_ntom_8bit (real *,int,unsigned char *,int *);
extern int synth_ntom_mono (real *,unsigned char *,int *);
extern int synth_ntom_mono2stereo (real *,unsigned char *,int *);
extern int synth_ntom_8bit_mono (real *,unsigned char *,int *);
extern int synth_ntom_8bit_mono2stereo (real *,unsigned char *,int *);

extern void rewindNbits(int bits);
extern int  hsstell(void);
extern int get_songlen(struct frame *fr,int no);

extern void init_layer3(int);
extern void init_layer2(void);
extern void make_decode_tables(long scale);
extern void make_conv16to8_table(int);
extern void dct64(real *,real *,real *);
extern void dct64_2(real *,real *,real *);
extern void dct64_4(real *,real *,real *);

extern void synth_ntom_set_step(long,long);

extern unsigned char *conv16to8;
extern long freqs[9];
extern real muls[27][64];
extern real decwin[512+32];
extern real *pnts[5];

extern struct parameter param;
