/*------------------------------------------------------------------------------

    File    :	mpega_decode_asm.h

    Author  :	Stéphane TAVENARD

    $VER:   mpega_decode_asm.h	1.1  (24/07/1995)

    (C) Copyright 1995 Stéphane TAVENARD
	All Rights Reserved

    #Rev|   Date   |			  Comment
    ----|----------|--------------------------------------------------------
    0	|04/05/1995| Initial revision					  ST
    1	|23/06/1995| Aminet release					  ST
    2	|24/07/1995| Added Mixing frequency				  ST

    ------------------------------------------------------------------------

    Definition of MPEG audio routines (optimized)

------------------------------------------------------------------------------*/

#ifndef MPEGA_DECODE_ASM_H
#define MPEGA_DECODE_ASM_H

#include "Bitstream.h"
#include "AudioPort.h"

#define SBLIMIT      32
#define SCALE_BLOCK  12
#define INT	     short

#define MPEGA_SYNC_WORD 	(long)0xFFF
#define MPEGA_SYNC_WORD_LNGTH	12

#define MPEGA_FILETYPE_RAW    0
#define MPEGA_FILETYPE_AIFF   1

/* Structure for Reading Layer II Allocation Tables from File */

typedef struct {
    unsigned int steps:16;
    unsigned int shift:4;
    unsigned int bits:5;
    unsigned int group:2;
    unsigned int quant:5;
} sb_alloc, *alloc_ptr;

typedef sb_alloc	al_table[SBLIMIT][16];


/* Header Information Structure */

typedef struct {
    int version;
    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;
} layer, *the_layer;

/* Parent Structure Interpreting some Frame Parameters in Header */

typedef struct {
    layer	*header;	 /* raw header information */
    int 	actual_mode;	 /* when writing IS, may forget if 0 chs */
    al_table	*alloc; 	 /* current bit allocation table */
    int 	tab_num;	 /* number of allocation table */
    int 	stereo; 	 /* 1 for mono, 2 for stereo */
    int 	jsbound;	 /* first band of joint stereo coding */
    int 	sblimit;	 /* total number of sub bands */
    int 	channels;	 /* # of channels to read (= stereo if not mono forced) */
    int 	*bit_alloc;
    int 	*scfsi;
    int 	*scale_index;
    int 	*sample;
    INT 	*fraction;
    char	*bitstream_name;
    BITSTREAM	*bs;		       /* Bistream */
    BYTE	*out_buffer[ 2 ];
    long	out_buffer_size;
    int 	freq_div;
    int 	output_8bits;
    int 	quality;
    int 	mono_forced;
    int 	play;
    int 	audio_filter;
    char	*out_file_name;
    int 	out_file_type;	       /* 0=raw PCM 1=AIFF */
    FILE	*out_file;
    int 	sub_band_size;
    int 	got_bits;
    int 	frame_count;
    int 	out_write_level;
    int 	out_write_length;
    int 	out_sample_length;
    int 	out_sample_freq;
    int 	bitstream_rate;        /* kbit/sec */
    int 	bitstream_freq;        /* Hz */
    int 	bitstream_buffer_size;
    AU_PORT	*audio_port;
    int 	no_audio_wait;	       /* if set, don't wait audio writes */
    int 	mixing_frequency;      /* Use mixing if > 0  #3 */

} frame_params;

#ifndef ASM
#ifdef __SASC
#define REG_A0 register __a0
#define REG_A1 register __a1
#define REG_A2 register __a2
#define REG_A3 register __a3
#define REG_A4 register __a4
#define REG_A5 register __a5
#define REG_A6 register __a6
#define REG_D0 register __d0
#define REG_D1 register __d1
#define REG_D2 register __d2
#define REG_D3 register __d3
#define REG_D4 register __d4
#define REG_D5 register __d5
#define REG_D6 register __d6
#define REG_D7 register __d7
#define ASM __asm __saved
#else
#define ASM_A0 __A0
#define ASM_A1 __A1
#define ASM_A2 __A2
#define ASM_A3 __A3
#define ASM_A4 __A4
#define ASM_A5 __A5
#define ASM_A6 __A6
#define ASM_D0 __D0
#define ASM_D1 __D1
#define ASM_D2 __D2
#define ASM_D3 __D3
#define ASM_D4 __D4
#define ASM_D5 __D5
#define ASM_D6 __D6
#define ASM_D7 __D7
#define ASM
#endif
#endif


void ASM ASM_init_decode( ASM_D0 int sub_band_size,
			  ASM_D1 int output_8bits,
			  ASM_D2 int quality );

int ASM ASM_read_header( ASM_A0 frame_params *fr_ps );
void ASM ASM_decode_header( ASM_A0 frame_params *fr_ps );


void ASM ASM_I_decode_bitalloc( ASM_A0 frame_params *fr_ps );
void ASM ASM_I_decode_scale( ASM_A0 frame_params *fr_ps );
void ASM ASM_I_buffer_sample( ASM_A0 frame_params *fr_ps );
void ASM ASM_I_deqnorm( ASM_A0 frame_params *fr_ps );

void ASM ASM_II_decode_bitalloc( ASM_A0 frame_params *fr_ps );
void ASM ASM_II_decode_scale( ASM_A0 frame_params *fr_ps );
void ASM ASM_II_buffer_sample( ASM_A0 frame_params *fr_ps );
void ASM ASM_II_deqnorm( ASM_A0 frame_params *fr_ps, ASM_D0 int x );

LONG ASM ASM_sub_band_synthesis( ASM_A0 frame_params *fr_ps,
				 ASM_D0 int band_count );

void ASM ASM_I_decode_frame( ASM_A0 frame_params *fr_ps );
void ASM ASM_II_decode_frame( ASM_A0 frame_params *fr_ps );


#endif /* MPEGA_DECODE_ASM_H */
