/******************************************************************************
Copyright (c) 2007 Analog Devices, Inc.  All Rights Reserved.  This software is
proprietary and confidential to Analog Devices, Inc. and its licensors.
*******************************************************************************


Project:    AAC decoder
Title:      AAC decoder library header
Author:     CFJ

Description:
            AAC decoder library header

References:
            None

******************************************************************************/
#ifndef __ADI_AAC_DECODER_H__
#define __ADI_AAC_DECODER_H__

// Make Create API Function include version, so link will fail if versions do not match between dlb and header file!!

  
    
#define adi_aacd_create adi_heaacv2_create_3_0
#ifndef ADI_AACD_HEAACv2_BUILD
#define ADI_AACD_HEAACv2_BUILD
#endif
    
  


/******************************************************************************
**          #defines
******************************************************************************/


#define ADI_AACD_MAX_NUM_OUTPUT_CHANS				(2)



#define ADI_AACD_MAX_OUTPUT_PCM_SAMPLES_PER_CHAN	(2048)


// Minimum number of bytes required by the decoder to decode a frame
//	Worst-case is 6144 bits (768 bytes) per channel - SECTION 4.5.3 ISO/IEC 14496:2005
#define ADI_AACD_MIN_INPUT_NUMBYTES_PER_CHAN	    (768)
#define ADI_AACD_MIN_BITSTREAM_BUFFER_NUMBYTES		(ADI_AACD_MAX_NUM_OUTPUT_CHANS*ADI_AACD_MIN_INPUT_NUMBYTES_PER_CHAN)

// Size of an ADTS header
#define ADI_AACD_ADTS_HEADER_NUMBYTES   7 // SECTION 1.A.3.2 ISO/IEC 14496:2005

// Size of an ADIF header
#define ADI_AACD_ADIF_HEADER_NUMBYTES   20 // SECTION 1.A.3.1 ISO/IEC 14496:2005

// Instance memory object sizes required

  
    
    #define ADI_AACD_FASTB0_PRIO0_SCRATCH_MEM_NUMBYTES (16384)
#define ADI_AACD_FASTB1_PRIO1_SCRATCH_MEM_NUMBYTES (0)
#define ADI_AACD_FAST_PRIO2_SCRATCH_MEM_NUMBYTES   (4576)
#define ADI_AACD_FAST_PRIO3_SCRATCH_MEM_NUMBYTES   (24576)
#define ADI_AACD_FASTB0_PRIO4_STATE_MEM_NUMBYTES   (7712)
#define ADI_AACD_FASTB1_PRIO6_STATE_MEM_NUMBYTES   (11784)
#define ADI_AACD_FAST_PRIO7_STATE_MEM_NUMBYTES     (13044)
    
  


// Channel element identification in PCE
#define ADI_AACD_ELEMENT_IS_FRONT      0x10
#define ADI_AACD_ELEMENT_IS_SIDE       0x20
#define ADI_AACD_ELEMENT_IS_BACK       0x30
#define ADI_AACD_ELEMENT_IS_LFE        0x40
#define ADI_AACD_ELEMENT_IS_CPE        0x80
#define ADI_AACD_ELEMENT_TYPE_MASK     0x70
#define ADI_AACD_ELEMENT_TAG_MASK      0x0F


#define ADI_AACD_MAX_NUM_AUDIO_ELEMENTS 16 // Maximum number of MPEG-4 AAC front channel audio elements


// API function Return codes
typedef enum {
ADI_AACD_SUCCESS                        =    0,
/* terminal failure return codes (decoder needs to be re-initialised) */
ADI_AACD_TERMINAL_FAILURE               =   -2,
ADI_AACD_INVALID_BITSTREAM              = -100,
ADI_AACD_INVALID_HEADER                 = -101,
/* non-critical failure return codes (decoder can still continue on) */
ADI_AACD_TIMEOUT_REACHED				=    1,
ADI_AACD_OPERATION_FAILED               =   10,
ADI_AACD_INVALID_CONFIG_PARAMS			=   11,
ADI_AACD_NEED_MORE_INPUT                =  100,
ADI_AACD_INVALID_POINTER                = 0x10ff
} adi_aacd_return_code_t;

/* warning flags bit mask definitions */
#define ADI_AACD_WARNING_BAD_FILL_ELEMENT       0x00000001

/******************************************************************************
**          Typedefs/Enumerations
******************************************************************************/

// This is the main data structure for an instance of the AAC decoder
// The application is only allowed to use pointers to this struct -
// all internal fields are private to the decoder.
typedef struct adi_aacd_t adi_aacd_t;

// This structure contains pointers to memory pools that need to be passed to
// the decoder via the function adi_aac_dec_create()
typedef struct
{
    struct
    {
        void *prio2;
        void *prio3;
    } fast;

    struct
    {
        void *prio0;
    } fastb0;

    struct
    {
        void *prio1;
    } fastb1;

} adi_aacd_scratch_mem_t;

typedef struct
{
    struct
    {
        void *prio7;
    } fast;

    struct
    {
        void *prio4;
    } fastb0;

    struct
    {
        void *prio6;
    } fastb1;
} adi_aacd_state_mem_t;

typedef struct {
    adi_aacd_state_mem_t state;
    adi_aacd_scratch_mem_t scratch;
} adi_aacd_mem_t;

// This type is to be used to represent the input bitstream to the decoder
typedef char adi_aacd_bitstream_data_t;

// A pointer to this structure is passed by the application as part of the
// configuration parameter. The decoder fills the properties in this structure
// once it has enough input data to determine these properties.
typedef struct
{
	int sample_rate; /* sampling rate of the output audio */
	int num_channels; /* total number of channels coded in the bitstream */
} adi_aacd_frame_properties_t;

// A pointer to this structure is passed by the application as part of the
// configuration parameter. The decoder fills the properties in this structure
// once it has enough input data to determine these properties.
typedef struct
{
	unsigned int is_sbr_present;
} adi_aacd_stream_properties_t;

// This structure is embedded in the adi_aacd_config_t struct and is used to allow
// the application to control how the output audio is rendered at run-time
typedef struct
{
    unsigned int    enable_dyn_range_control;
}  adi_aacd_audio_config_t;

// This list specifies the container format
typedef enum
{
	ADI_AACD_ADTS=1,
	ADI_AACD_ADIF,
	ADI_AACD_RAW
} adi_aacd_stream_format_t;

// This structure is embedded in the adi_aacd_config_t struct
// and is used to allow the application to pass stream configuration
// information that has been extracted from an external parser
// for all container formats other than ADIF/ADTS
typedef struct
{
	int num_channels; /* total number of channels represented in the bitstream (valid values = 0..8) */
	unsigned int sampling_frequency_index; /* A four bit field indicating the sampling rate used. */
	int sampling_frequency; /* actual sampling rate if samplingFrequencyIndex equals 15 */
	int sbr_sampling_frequency; /* sampling rate of audio signal after applying SBR */
	unsigned int frame_length_flag; /* flag determining core AAC block length: 0 means 1024, 1 means 960 */

    /* channel configuration specified outside the AAC payload */
	unsigned int channel_configuration;
	unsigned int num_front_channel_elements; /* the number of front channel elements (SCE's or CPE's) in the bitstream */

    /* number of side/back/lfe/coupled channel elements for a multi-channel bitstream */
	unsigned int num_side_channel_elements;
	unsigned int num_back_channel_elements;
	unsigned int num_coupled_channel_elements;
	unsigned int num_lfe_channel_elements;
	

	unsigned char channel_element_id[ADI_AACD_MAX_NUM_AUDIO_ELEMENTS]; // 4-bit channel element type + 4-bit channel element tag

} adi_aacd_stream_config_t;

// This list specifies the channel configuration (output speaker mapping)
typedef enum {
	ADI_AACD_1_0_CHAN_CONFIG	=	0x1,
	ADI_AACD_2_0_CHAN_CONFIG	=	0x2,
	ADI_AACD_3_0_CHAN_CONFIG	=	0x3,
	ADI_AACD_3_1_CHAN_CONFIG 	=	0x5,
	ADI_AACD_3_2_CHAN_CONFIG 	=	0x7,
	ADI_AACD_3_2_1_CHAN_CONFIG 	=	0x10007
} adi_aacd_chan_config_t ;

// This list specifies the desired decoding mode of the library
typedef enum {
    ADI_AACD_DECODING_MODE_AACLC,
    ADI_AACD_DECODING_MODE_HEAACv1,
    ADI_AACD_DECODING_MODE_HEAACv2
} adi_aacd_decoder_mode_t;

// This structure is to be used to store all configuration parameters whether
// they'd be reconfigurable or not.
typedef struct
{
	adi_aacd_audio_config_t	    audio_render_params;
	unsigned int                use_circular_bitstream_buffer;
	int                         circular_buffer_length;
	adi_aacd_bitstream_data_t * circular_buffer_base;
	adi_aacd_frame_properties_t *frame_properties_ptr;
	adi_aacd_stream_properties_t *stream_properties_ptr;
	adi_aacd_chan_config_t      output_chan_config;
	int                         output_chan_stride[ADI_AACD_MAX_NUM_OUTPUT_CHANS];
	adi_aacd_stream_format_t	container_format;
	adi_aacd_stream_config_t    container_info;
	adi_aacd_decoder_mode_t     decoding_mode;
	int                         selected_program_id; // PCE tag ID for the selected audio program (must be provided by user if the channel config in adi_aacd_stream_config_t is set by user)
} adi_aacd_config_t;

// this list contains all the configuration parameters that are allowed to be
// reconfigured at run time after the init API function is invoked
typedef enum {
	ADI_AACD_ALL_RECONFIG_PARAMS 	        = 0
}
adi_aacd_config_item_t;

// This structure is returned by the call to the main decoder function
// adi_aac_decoder(). It contains important information about the state of
// the decoder.
typedef struct
{
    unsigned int warning_info;
    int num_output_samples_per_chan;
    unsigned int active_output_chans;
    adi_aacd_bitstream_data_t *unconsumed_input_data_ptr;
    int num_input_bytes_consumed;
} adi_aacd_output_status_t;

// This type is to be used to represent PCM samples output from the decoder.
// Each PCM sample produced is a 16-bit integer
typedef short adi_aacd_audio_data_t;

// This structure contains module information such as the version number.
typedef struct  {
    unsigned int    version_num;
    char*           version_text;
} adi_aacd_module_info_t;


/******************************************************************************
**          Function Definitions
******************************************************************************/
#if defined(__cplusplus)
extern "C" { /* this is added to support integration into C++ systems */
#endif

//  Global const data struct containing module information
extern const adi_aacd_module_info_t adi_aacd_module_info;


/*
**
** Function:            adi_aacd_create
**
** Description:         Instantiation of codec
**
** Arguments:
**
**  	*per_instance_mem_blocks	Memory pool for storing decoder internal
                        state and scratch information.
**
** Outputs:             None
**
** Return value:        Pointer to decoder instance
**
**
**
*/
adi_aacd_t* adi_aacd_create(
adi_aacd_mem_t *per_instance_mem_blocks
);

/*
**
** Function:            adi_aacd_init
**
** Description:         Stream initialisation for codec instance
**
** Arguments:
**
**		*decoder_instance
**		*requested_dec_config 		Pointer to configuration parameters
**		*actual_dec_config_used		Pointer to actual configuration parameters used in the initialization
**
**
** Outputs:             None
**
** Return value:        ADI_AACD_SUCCESS if initialisation OK
**						Error code otherwise
**
**
**
*/
adi_aacd_return_code_t adi_aacd_init(
    adi_aacd_t *instance_handle,
    adi_aacd_config_t *config_params
);

/*
**
** Function:            adi_aacd_decoder
**
** Description:         Main decoding function
**
** Arguments:
**
**		*decoder_instance
**		num_input_bytes				The number of bytes in "input_bitstream" in this call to the decoder
**		input_bitstream				The AAC coded input bitstream to the decoder
**		*dec_output_status			Output status information returned from the decoder
**		*output_pcm_channels[]		Each element must contain the pointer to where the decoder shall write the 1152 output PCM samples of one channel
**
**
** Outputs:             Decoded samples to the output PCM channels
**
** Return value:        ADI_AACD_SUCCESS if OK
**						Error code otherwise
**
**
**
*/
adi_aacd_return_code_t adi_aacd_decoder(
    adi_aacd_t *instance_handle,
    int num_input_bytes,
    adi_aacd_bitstream_data_t *input_bitstream,
    adi_aacd_output_status_t *decoder_status,
    adi_aacd_audio_data_t *output_pcm_data[ADI_AACD_MAX_NUM_OUTPUT_CHANS]
);




/*
**
** Function:            adi_aacd_resynch
**
** Description:         Stream reinitialisation for codec instance
**
** Arguments:
**
**		*decoder_instance
**
**
** Outputs:             None
**
** Return value:        None
**
**
**
*/
void adi_aacd_resynch(
    adi_aacd_t *instance_handle
);

/*
** Function: adi_aacd_reconfigure()
**
** Description:
**  Run time configuration for the decoder. This function allows either all
**  configuration parameters to be reconfigured or just one. When wanting to
**  reconfigure all parameters, the enumerated type "config_item" must be set
**  to "ADI_AACD_ALL_RECONFIG_PARAMS" and config_value must contain the
**  pointer to the configuration structure, typecasted to an int. When
**  wanting to reconfigure a single parameter, "config_item" must contain the
**  enumerated name of the chosen parameter and its value specified in
**  "config_value".
**
**  Note not all configuration parameters that can be modified on the
**  fly. The set of those that can be is indicated by their enum value. The
**  function returns an error code in the event a configuration parameter
**  cannot be modified on the fly, is invalid and cannot be overridden by
**  default or clipped.
**
** Arguments:
**  void *dec_instance (INPUT)
**      Decoder instance pointer.
**
**  adi_aacd_config_item_t config_item (INPUT)
**      Configuration parameter. If this is equal to "ADI_AACD_ALL_RECONFIG_PARAMS", the
**      function reconfigures all reconfigurable parameters. In this case the
**      third parameter "config_value" contains the configuration parameter.
**
**  int config_value (INPUT)
**      If the parameter "config_item" is equal to "ADI_AACD_ALL_RECONFIG_PARAMS", this
**      must be the pointer to the configuration parameter, typecasted to a
**      integer value, otherwise it will be the integer value for the
**      specified configuration parameter.
**
** Outputs
**  adi_aacd_config_t *actual_dec_config_used
**      The configuration parameters actually used in the initialization.
**
** Return value:
**  ADI_AACD_SUCCESS
**  ADI_AACD_INVALID_CONFIG_PARAMS
**
**  See the developers guide on the definition of each code.
*/
adi_aacd_return_code_t adi_aacd_reconfigure (
    adi_aacd_t *instance_handle,
    adi_aacd_config_item_t config_item,
    adi_aacd_config_t *config_params
);

/*
** Function: adi_aacd_input_is_adts()
**
** Description:
**  Checks whether the input bitstream is contained in an ADTS transport stream.
**
**  Note that it only checks for a valid ADTS header at the start of the
**  bitstream buffer.  No searching is carried out.
**
** Arguments:
**  adi_aacd_bitstream_data_t* input_buf (INPUT)
**      Input bitstream buffer.
**
**  int num_input_bytes (INPUT)
**      Number of valid bytes contained in the input buffer.
**
** Return value:
**  ADI_AACD_SUCCESS
**  ADI_AACD_NEED_MORE_INPUT
**  ADI_AACD_INVALID_HEADER
**
**  See the developers guide on the definition of each code.
*/
adi_aacd_return_code_t adi_aacd_input_is_adts (
	adi_aacd_bitstream_data_t *input_buf,
	int num_input_bytes
);


/*
** Function: adi_aacd_input_is_adif()
**
** Description:
**  Checks whether the input bitstream is contained in an ADIFF interchange format.
**
**  Note that it only checks for a valid ADIFF header at the start of the
**  bitstream buffer.  No searching is carried out.
**
** Arguments:
**  adi_aacd_bitstream_data_t* input_buf (INPUT)
**      Input bitstream buffer.
**
**  int num_input_bytes (INPUT)
**      Number of valid bytes contained in the input buffer.
**
** Return value:
**  ADI_AACD_SUCCESS
**  ADI_AACD_NEED_MORE_INPUT
**  ADI_AACD_INVALID_HEADER
**
**  See the developers guide on the definition of each code.
*/
adi_aacd_return_code_t adi_aacd_input_is_adif (
	adi_aacd_bitstream_data_t *input_buf,
	int num_input_bytes
);

/*
**
** Function:            adi_aacd_get_default_config
**
** Description:         Populates a supplied configuration structure with default values
**
** Arguments:
**
**		config		    pointer to the configuration object to populate
**
** Outputs:             None
**
** Return value:        None
**
**
*/
void adi_aacd_get_default_config(
    adi_aacd_config_t *config
);

int AAC_Decode(char *filename);

#if defined(__cplusplus)
} /* extern "C" { */
#endif

#endif // __ADI_AAC_DECODER_H__


/*
**
**
*/
