#import <Foundation/Foundation.h>


#define LEVEL_PLUS6DB 2.0
#define LEVEL_PLUS3DB 1.4142135623730951
#define LEVEL_3DB 0.7071067811865476
#define LEVEL_45DB 0.5946035575013605
#define LEVEL_6DB 0.5

#define DELTA_BIT_REUSE (0)
#define DELTA_BIT_NEW (1)
#define DELTA_BIT_NONE (2)
#define DELTA_BIT_RESERVED (3)

#define EXP_REUSE (0)
#define EXP_D15   (1)
#define EXP_D25   (2)
#define EXP_D45   (3)

typedef struct
{
    uint8_t bai;		// fine SNR offset, fast gain
    uint8_t deltbae;	// delta bit allocation exists
    int8_t deltba[50];	// per-band delta bit allocation
} ba_t;

typedef struct
{
    uint8_t exp[256];		// decoded channel exponents
    int8_t bap[256];		// derived channel bit allocation
} expbap_t;

typedef struct
{
    uint8_t fscod;	// sample rate
    uint8_t halfrate;	// halfrate factor
    uint8_t acmod;	// coded channels
    uint8_t lfeon;	// coded lfe channel
	
    int output;		// type of output
    float level;	// output level
	
    int dynrnge;	// apply dynamic range
    float dynrng;	// dynamic range
	
    uint8_t chincpl;		// channel coupled
    uint8_t phsflginu;	// phase flags in use (stereo only)
    uint8_t cplstrtmant;	// coupling channel start mantissa
    uint8_t cplendmant;	// coupling channel end mantissa
    uint32_t cplbndstrc;		// coupling band structure
    float cplco[5][18];			// coupling coordinates
	
    uint8_t cplstrtbnd;	// coupling start band (for bit allocation)
    uint8_t ncplbnd;		// number of coupling bands
    uint8_t rematflg;		// stereo rematrixing
    uint8_t endmant[5];	// channel end mantissa
    uint16_t bai;			// bit allocation information
	
    uint32_t * buffer_start;
    uint16_t lfsr_state;	// dither state
    uint32_t bits_left;
    uint32_t current_word;
	
    uint8_t csnroffst;	// coarse SNR offset
    ba_t cplba;					// coupling bit allocation parameters
    ba_t ba[5];					// channel bit allocation parameters
    ba_t lfeba;					// lfe bit allocation parameters
	
    uint8_t cplfleak;		// coupling fast leak init
    uint8_t cplsleak;		// coupling slow leak init
	
    expbap_t cpl_expbap;
    expbap_t fbw_expbap[5];
    expbap_t lfe_expbap;
	
    float *samples;
} AC3DecoderState;

@interface AC3Decoder : NSObject
{
	AC3DecoderState *state;
	
	NSInteger format;
	NSInteger sampleRate;
	NSUInteger bitrate;
	
	BOOL useCompression;
}

- (NSInteger)frameSize:(unsigned char *)buffer;
- (NSInteger)decodeFrame:(unsigned char *)buffer;
- (NSInteger)decodeBlock;

- (NSInteger)format;
- (NSInteger)sampleRate;
- (NSUInteger)bitrate;
- (NSUInteger)numberOfChannels;

- (void)copyChannel:(float *)channel toBuffer:(float *)buffer;
- (float *)leftChannel;
- (float *)rightChannel;
- (float *)centerChannel;
- (float *)leftSurroundChannel;
- (float *)rightSurroundChannel;
- (float *)lfeChannel;

- (BOOL)useCompression;
- (void)setUseCompression:(BOOL)s;

@end
