/*
 * mpg123 defines 
 * used source: musicout.h from mpegaudio package
 */

#include <sys/types.h>

#include        <stdio.h>
#include        <string.h>
#include        <signal.h>
#include        <sys/signal.h>
#include        <unistd.h>

#include        <math.h>

#include "libfiles.h"

#include "dxhead.h"

typedef unsigned char byte;
extern void screw_up(void);

#ifdef SUNOS
#define memmove(dst,src,size) bcopy(src,dst,size)
#endif

#ifdef REAL_IS_FLOAT
#  define real float
#elif defined(REAL_IS_LONG_DOUBLE)
#  define real int32_t 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         MAX_NAME_SIZE           81
#define         SBLIMIT                 32
#define         SCALE_BLOCK             12
#define         SSLIMIT                 18

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


struct audio_info_struct;
/*
 {
	int rate;
	int channels;
	int format;
};
*/

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


struct al_table 
{
  short bits;
  short d;
};

struct frame {
    struct al_table *alloc;
    int (*synth)(real *,int,unsigned char *,int *);
    int (*synth_mono)(real *,unsigned char *,int *);
    int stereo;
    int jsbound;
    int single;
    int II_sblimit;
    int down_sample_sblimit;
    int lsf;
    int mpeg25;
    int down_sample;
    int header_change;
    int lay;
    int (*do_layer)(struct frame *fr,struct audio_info_struct *);
    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 */
};

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



/* ------ Declarations from "common.c" ------ */

extern void audio_flush(void);

extern void print_header(struct frame *);
extern void print_header_compact(struct frame *);
extern void print_id3_tag(unsigned char *buf);

extern int split_dir_file(const char *path, char **dname, char **fname);

extern unsigned int   get1bit(void);
extern unsigned int   getbits(int);
extern unsigned int   getbits_fast(int);
extern void           backbits(int);
extern int            getbitoffset(void);
extern int            getbyte(void);

extern void set_pointer(int32_t);

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 open_stream(Files f,Eweid c);
extern void read_frame_init (void);
extern int read_frame(CFH ,struct frame *fr);
extern void play_frame(int init,struct frame *fr);
extern int do_layer3(struct frame *fr,struct audio_info_struct *);
extern int do_layer2(struct frame *fr,struct audio_info_struct *);
extern int do_layer1(struct frame *fr,struct audio_info_struct *);

#ifdef PENTIUM_OPT
extern int synth_1to1_pent (real *,int,unsigned char *);
#endif
#ifdef USE_3DNOW
extern int synth_1to1_3dnow (real *,int,unsigned char *);
#endif
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 void set_pointer(int32_t);
extern void huffman_decoder(int ,int *);
extern void huffman_count1(int,int *);
extern void print_stat(CFH c,struct frame *fr,int no,int32_t buffsize);
extern int get_songlen(CFH c,struct frame *fr,int no);

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

extern void synth_ntom_set_step(int32_t,int32_t);

extern void control_generic(struct frame *fr);
extern void control_sajber(struct frame *fr);
extern void control_tk3play(struct frame *fr);

extern int cdr_open(struct audio_info_struct *ai, char *ame);
extern int au_open(struct audio_info_struct *ai, char *name);
extern int wav_open(struct audio_info_struct *ai, char *wavfilename);
extern int wav_write(unsigned char *buf,int len);
extern int cdr_close(void);
extern int au_close(void);
extern int wav_close(void);

extern int au_open(struct audio_info_struct *ai, char *aufilename);
extern int au_close(void);

extern int cdr_open(struct audio_info_struct *ai, char *cdrfilename);
extern int cdr_close(void);



/* 486 optimizations */
#define FIR_BUFFER_SIZE  128
extern void dct64_486(int *a,int *b,real *c);
extern int synth_1to1_486(real *bandPtr,int channel,unsigned char *out,int nb_blocks);

/* Static variables */

/* These are tables - so ok*/
extern unsigned char *conv16to8;
extern const int32_t freqs[9];
extern real muls[27][64];
#ifdef USE_3DNOW
extern real decwin[2*(512+32)];
#else
extern real decwin[512+32];
#endif
extern real *pnts[5];

/* Rest of the rubbish */


extern unsigned char *pcm_sample;
extern int pcm_point;
extern int audiobufsize;

extern struct parameter param;

extern u_int32_t firsthead;
extern const int tabsel_123[2][3][16];

extern struct bitstream_info bsi;


double compute_tpf(struct frame *fr);
double compute_bpf(struct frame *fr);

int head_read(CFH c,u_int32_t *newhead);
int skip_bytes(CFH c,int len);
int head_shift(CFH c,u_int32_t *head);
int read_frame_body(CFH c,unsigned char *buf, int size);
int back_bytes(CFH c,int bytes);

int check_for_xing_header(CFH c,struct frame *fr, XHEADDATA * xhead);



extern int outfd;
void jump_to_frame(CFH c,struct frame *fr, int frame);
void jump_to_byte(CFH c,struct frame *fr, int byte);

