//#include <windows.h>

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

#ifndef WIN32
#include        <signal.h>
#include        <unistd.h>
#endif

#include        <math.h>

#ifdef _WIN32
# undef WIN32
# define WIN32

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

# define random rand
# define srandom srand

#endif

#ifdef REAL_IS_FLOAT
#  define real float
#elif defined(REAL_IS_LONG_DOUBLE)
#  define real long double
#else
#  define real 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 /* Layer 2 */

#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

#define MP3_ERR -1
#define MP3_OK  0
#define MP3_NEED_MORE 1


/* 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 */
    int II_sblimit; /* Layer 2 */
    struct al_table *alloc; /* Layer 2 */
    int (*do_layer)(struct frame *fr,unsigned char *, int *);/* Layer 2 */
};

/* 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 do_layer3(struct frame *fr,unsigned char *,int *);
extern int do_layer2(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 int synth_1to1 (real *,int,unsigned char *,int *);
extern int tsynth_1to1 (real *,int,unsigned char *,int *);
extern int synth_1to1_mono (real *,unsigned char *,int *);

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

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


/* Preserves exiting */

#define BE_QUIET

/* Windows debugging message */
void MessageI(int i);

//-- content of mpglib.h ------

struct buf {
	unsigned char *pnt;
	long size;
	long pos;
	struct buf *next;
	struct buf *prev;
};

struct framebuf {
	struct buf *buf;
	long pos;
	struct frame *next;
	struct frame *prev;
};

struct mpstr {
	struct buf *head,*tail;
	int bsize;
	int framesize;
	int fsizeold;
	struct frame fr;
	unsigned char bsspace[2][MAXFRAMESIZE+512]; /* MAXFRAMESIZE */
	real hybrid_block[2][2][SBLIMIT*SSLIMIT];
	int hybrid_blc[2];
	unsigned long header;
	int bsnum;
	real synth_buffs[2][2][0x110];
	int  synth_bo;
};

//--------wfz_added--------
/*
extern	BOOL InitMP3(struct mpstr *mp);
extern	void ExitMP3(struct mpstr *mp);
extern	int  decodeMP3(struct mpstr *mp, char *in, int isize, char *out, int osize, int *done);
*/

