/*
 * Copyright 2010 Trident Microsystems (Far East) Ltd. All rights reserved.
 * All prior copyright rights in this work and the accompanying software
 * products transferred to Trident Microsystems (Far East) Ltd. by written
 * agreement.
 */
/*****************************************************************************/
/* Copyright (c) 2010 NXP B.V.  All rights are reserved.                     */
/*                                                                           */
/* Redistribution and use in source and binary forms, with or without        */
/* modification, are permitted provided that the following conditions        */
/* are met:                                                                  */
/*                                                                           */
/* Redistributions of source code must retain the above copyright            */
/* notice, this list of conditions and the following disclaimer.             */
/*                                                                           */
/* Redistributions in binary form must reproduce the above copyright         */
/* notice, this list of conditions and the following disclaimer in the       */
/* documentation and/or other materials provided with the distribution.      */
/*                                                                           */
/* Neither the name of NXP nor the names of its                              */
/* contributors may be used to endorse or promote products derived from      */
/* this software without specific prior written permission.                  */
/*                                                                           */
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       */
/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT         */
/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR     */
/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT      */
/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,     */
/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT          */
/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     */
/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY     */
/* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT       */
/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE         */
/* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH          */
/* DAMAGE.                                                                   */
/*                                                                           */
/*****************************************************************************/
/**
 * REFERENCE DOCUMENTS : SCS, SCD of tmdlAudio
 *
 * This file contains all the APIs of CPI component which is responsible for the
 * control of the audio decoder
 *
 * \section info Change Information
 *
 * \verbatim
 * Date          Modified by CRPRNr  TASKNr  Maintenance description
 * -------------|-----------|-------|-------|-----------------------------------
 * 12-Sept-2007 | robbe     | 12127 | 21374 | Common Caen/Soton agreed version
 * 06-June-2007 | legendre  |       |       | Initial version
 * 25-Octo-2007 | batelaan  | Overwrote with PNX8335 version (26). Sorry, needs merging!
 * 09-Jan--2008 | burningh  | Adding Audio events for 8335 only. As above.
 * 15-Jan-2008  | laird     | Changing API for 64bit maths issue.
 * 28-Jan-2008  | barnish   | Include IO & AVDecs events
 * 11-Feb-2008  | iwillis   | Added buffer threshold and fullness functions
 * 14-Mar-2008  | barnish   | Added enum guards
 * 18-Mar-2008  | barnish   | Added tmdlAudio_SwitchFormat
 * 03-Apr-2008  | awest     | add Lpcm
 * 04-Apr-2008  | awest     | rework
 * 10-Apr-2008  | barnish   | Use integer for sample rates
 * 22-May-2008  | barnish   | Added prototype for _SetAmplify()
 * 07-Jul-2008  | AShetty   | Modify WMAPRO Header
 * 10-Jul-2008  | laird     | Add tmdlAudio_EventIOFrameRendered
 * 15-Jul-2008  | laird     | Merged from 'tmdlAudio.h-SOUsb225#13:incl:CFR_BSS#1' and 'tmdlAudio.h-ds14#12.1.2:incl:CFR_BSS#1' by laird.
 * 24-Jul-2008  | iwillis   | Added tmdlAudio_Flush. Removed unnecessary interface diversity.
 * 08-Aug-2008  | Awest     | Update Burst specific data
 * 27-Aug-2008  | awest     | increase linear buffer number.
 * 03-Sep-2008  | awest     | add tmdlAudio_SelectOutput
 * 04-Sep-2008  | steel     | add audio pts event
 * 08-Sep-2008  | burningh  | add EOS event
 * 30-Sep-2008  | iwillis   | Added discardEarlyAudio
 * 03-Nov-2008  | ashetty   | Add multichannel support for LPCM
 * 03-Nov-2008  | laird     | Adding time over and under events.
 * 26-Nov-2008  | ashetty   | Add support for 8bit and 16bit LPCM streams
 * 20-Jan-2009  | batelaan  | Update file copyright/license text
 * 23-Jan-2009  | laird     | Merged from 'tmdlAudio.h-SOUsb225#23:incl:CFR_BSS#1' and 'tmdlAudio.h-ds14#23:incl:CFR_BSS#1' by laird.
 * 26-Jan-2009  | laird     | Remove Parallels.
 * 26-Feb-2009  | laird     | Tidying enums.....
 * 25-Feb-2009  | steel     | add dss support
 * 26-Feb-2009  | laird     | Merged from 'tmdlAudio.h-SOUsb225#25.1.1:incl:CFR_BSS#1' and 'tmdlAudio.h-SOUsb225#25.2.1:incl:CFR_BSS#1' by laird.
 * 12-Mar-2009  | burningh  | Add accessor functions for volume, balance, routing
 * 18-Feb-2009  | myers     | Tidy up enums and macros for buffer types
 * 17-Mar-2009  | myers     | Merge
 * 25-Mar-2009  | burningh  | PR 2111: Use AudioES for both PES & ES buffers
 * 08-Apr-2009  | burningh  | Merged from 'tmdlAudio.h-BJ_STB2#27:incl:CFR_BSS#1' and 'tmdlAudio.h-ds14#29:incl:CFR_BSS#1' by burningh.
 * 30-Oct-2009  | mpage     | Add mixer sync support
 * 30-Nov-2009  | amccurdy  | Include prjconfig.h (tmdlAudio_Open definition is conditional on CONFIG_DUAL_AUDIO_CHANNELS...)
 * 15-Jan-2010  | ashetty   | Add option for channel swap under audio decoder routing.
 * 11-Feb-2010  | mpage     | Add SetPcrSigmaDeltaMode and ForcePcrRecovery.
 * \endverbatim
 *
 */

#ifndef TMDLAUDIO_H
#define TMDLAUDIO_H

/*============================================================================*/
/*                      STANDARD INCLUDE FILES                                */
/*============================================================================*/
#include "tmCompId.h"
#include "tmNxTypes.h"
#include "phStbCommon.h"

#include <prjconfig.h>

/*============================================================================*/
/*                      PROJECT INCLUDE FILES                                 */
/*============================================================================*/


#ifdef __cplusplus
extern "C"
{
#endif

/*============================================================================*/
/*                      PUBLIC MACRO DEFINITION                               */
/*============================================================================*/
/* Can be accessed by external components                                     */

/*******************************************************************************
 * NOTE: The following value must be the same as the tmgdrAudio_NumSBMBuffers
 * definition in ma_dec.h
 */
/** number of sbm buffers required per decoder instance */
#define tmdlAudio_NumSBMBuffers 2

/** enum for each SBM buffer required.
    This must match the enum used in ma_dec*/
typedef enum
{
    tmdlAudio_SBMBufESInput,
    tmdlAudio_SBMBufAuPPInput,
    tmdlAudio_SBMBufGuard
}tmdlAudio_SBMBuf_t;

/** number of linear buffers required per decoder instance */
#define tmdlAudio_NumLinBuffers 5

/** enum for each linear buffer required.
    This must match the enum used in ma_dec*/
typedef enum
{
    tmdlAudio_LinBufDecIn,
    tmdlAudio_LinBufDecOut,
    tmdlAudio_LinBufDecOut2,
    tmdlAudio_LinBufAuppIn,
    tmdlAudio_LinBufAuppOut,
    tmdlAudio_LinBufGuard
}tmdlAudio_LinBuf_t;

/** number of parser buffers required per decoder instance */
#define tmdlAudio_NumParserBuffers 3

/** enum for each parser buffer required.
    This must match the enum used in ma_dec*/
typedef enum
{
    tmdlAudio_ParserBufES,
    tmdlAudio_ParserBufHeader,
    tmdlAudio_ParserBufPTS,
    tmdlAudio_ParserBufGuard
}tmdlAudio_ParserBuf_t;


/* Error codes */
#define TMDL_ERR_AUDIO_BASE               (CID_COMP_AUDIO | CID_LAYER_DEVLIB)


/* Standard error */
#define TMDL_ERR_AUDIO_INST_NOT_AVAIL (TMDL_ERR_AUDIO_BASE+TM_ERR_NO_INSTANCES)
#define TMDL_ERR_AUDIO_INITIALIZATION (TMDL_ERR_AUDIO_BASE+TM_ERR_INIT_FAILED)
#define TMDL_ERR_AUDIO_NOT_SUPPORTED  (TMDL_ERR_AUDIO_BASE+TM_ERR_NOT_SUPPORTED)
#define TMDL_ERR_AUDIO_NULL_FUNCTION  (TMDL_ERR_AUDIO_BASE+TM_ERR_NULL_ERRORFUNC)
#define TMDL_ERR_AUDIO_BAD_PARAMS     (TMDL_ERR_AUDIO_BASE+TM_ERR_BAD_PARAMETER)
#define TMDL_ERR_AUDIO_COMPATIBILITY  (TMDL_ERR_AUDIO_BASE+TM_ERR_COMPATIBILITY)
#define TMDL_ERR_AUDIO_MAJOR_VERSION  (TMDL_ERR_AUDIO_BASE+TM_ERR_MAJOR_VERSION)

/* Component specific error */
#define TMDL_ERR_AUDIO_BAD_CONFIG_CMD \
    (TMDL_ERR_AUDIO_BASE+TM_ERR_COMP_UNIQUE_START+0x0000)
#define TMDL_ERR_AUDIO_HW_CONSTRAINTS_NOT_MET \
    (TMDL_ERR_AUDIO_BASE+TM_ERR_COMP_UNIQUE_START+0x0001)
#define TMDL_ERR_AUDIO_FATAL \
    (TMDL_ERR_AUDIO_BASE+TM_ERR_COMP_UNIQUE_START+0x0002)
#define TMDL_ERR_AUDIO_POWER_STATE \
    (TMDL_ERR_AUDIO_BASE+TM_ERR_COMP_UNIQUE_START+0x0003)
#define TMDL_ERR_AUDIO_ALREADY_OPEN \
    (TMDL_ERR_AUDIO_BASE+TM_ERR_COMP_UNIQUE_START+0x0004)


/**
 * Setting for the bufferMask parameter of tmdlAudio_SetBufferThresholds().
 * Sets no thresholds (not vary useful, but included for completeness).
 * @see tmdlAudio_SetBufferThresholds.
 */
#define TMDL_AUDIO_THRESHOLD_MASK_NONE                0x00000000ul

/**
 * Setting for the bufferMask parameter of tmdlAudio_SetBufferThresholds().
 * Sets data low threshold.
 * @see tmdlAudio_SetBufferThresholds.
 */
#define TMDL_AUDIO_THRESHOLD_MASK_DATA_LOW            0x00000001ul

/**
 * Setting for the bufferMask parameter of tmdlAudio_SetBufferThresholds().
 * Sets data high threshold.
 * @see tmdlAudio_SetBufferThresholds.
 */
#define TMDL_AUDIO_THRESHOLD_MASK_DATA_HIGH           0x00000002ul

/**
 * Setting for the bufferMask parameter of tmdlAudio_SetBufferThresholds().
 * Sets buffer time low threshold.
 * @see tmdlAudio_SetBufferThresholds.
 */
#define TMDL_AUDIO_THRESHOLD_MASK_BUFFER_TIME_LOW     0x00000004ul

/**
 * Setting for the bufferMask parameter of tmdlAudio_SetBufferThresholds().
 * Sets buffer time high threshold.
 * @see tmdlAudio_SetBufferThresholds.
 */
#define TMDL_AUDIO_THRESHOLD_MASK_BUFFER_TIME_HIGH    0x00000008ul

/**
 * Setting for the bufferMask parameter of tmdlAudio_SetBufferThresholds().
 * Sets all thresholds.
 * @see tmdlAudio_SetBufferThresholds.
 */
#define TMDL_AUDIO_THRESHOLD_MASK_ALL                 0x0000000ful

/** Method to relate tmdlAudio SBM buffer types to KBufMgr types.
    The number of buffers allocated in kBufMgr must line up with this macro*/
#define tmdlAudio_SBMBufType2KBufMgrBufType(SBMBufType) \
            (((SBMBufType)==tmdlAudio_SBMBufESInput)      ? phStbKBufMgr_Buffer_AUDIO_ES  : \
                                                            phStbKBufMgr_Buffer_AUDIO)

/** Method to relate tmdlAudio linear buffer types to KBufMgr types.
    The number of buffers allocated in kBufMgr must line up with this macro*/
#define tmdlAudio_LinBufType2KBufMgrBufType(linBufType) \
            (((linBufType)==tmdlAudio_LinBufAuppOut)      ? phStbKBufMgr_Buffer_AUDIO_OUT : \
             ((linBufType)==tmdlAudio_LinBufDecOut2)      ? phStbKBufMgr_Buffer_AUDIO_OUT : \
                                                            phStbKBufMgr_Buffer_AUDIO)

/** Method to relate tmdlAudio parser buffer types to KBufMgr types.
    The number of buffers allocated in kBufMgr must line up with this macro*/
#define tmdlAudio_ParserBufType2KBufMgrBufType(parserBufType) \
            (((parserBufType)==tmdlAudio_ParserBufES)     ? phStbKBufMgr_Buffer_AUDIO_ES  : \
             ((parserBufType)==tmdlAudio_ParserBufHeader) ? phStbKBufMgr_Buffer_AHeader   : \
                                                            phStbKBufMgr_Buffer_APTS)

/*==========================================================================*/
/*               PUBLIC TYPE DEFINITION                                     */
/*==========================================================================*/

typedef enum
{
    tmdlAudio_Output_I2S_0,
    tmdlAudio_Output_I2S_1,
    tmdlAudio_Output_I2S_2,
    tmdlAudio_Output_I2S_3,
    tmdlAudio_Output_I2S_4,
    tmdlAudio_Output_SPDIF,
    tmdlAudio_Output_Guard
} tmdlAudio_Output_t;


/** Sampling frequency of decoded PCM */
typedef enum
{
    tmdlAudioLpcmSampleSize8Bit,
    tmdlAudioLpcmSampleSize16Bit,
    tmdlAudioLpcmSampleSize24Bit,
    tmdlAudioLpcmSampleSize32Bit,
    tmdlAudioLpcmSampleSizeGuard
} tmdlAudioLpcmSampleSize_t;

typedef enum
{
    tmdlAudioLpcmBufferTypeSeperate,
    tmdlAudioLpcmBufferTypeInterleaved,
    tmdlAudioLpcmBufferTypeGuard
}tmdlAudioLpcmBufferType_t;

typedef enum
{
    tmdlAudioLpcmChannelMono,
    tmdlAudioLpcmChannelStereo,
    tmdlAudioLpcmChannelMulti,
    tmdlAudioLpcmChannelGuard
}tmdlAudioLpcmChannel_t;

typedef enum
{
    tmdlAudioLpcmEndianBig,
    tmdlAudioLpcmEndianLittle,
    tmdlAudioLpcmEndianGuard
}tmdlAudioLpcmEndian_t;

typedef struct
{
    tmdlAudioLpcmSampleSize_t   sampleSize;
    tmdlAudioLpcmBufferType_t   bufferType;
    uint32_t                    sampleFreq;
    tmdlAudioLpcmChannel_t      channelType;
    unsigned long               samplePairs;
    uint32_t                    nChannels;
}tmdlAudioLpcmAudioHeader_t;



/** Contents of the MPEG audio header.
*/
// TODO: Work out how/if we can replicate this for the current system
/*    int id;
    int layer;
    int protection_bit;
    int bitrate_index;
    int sampling_frequency;
    int padding_bit;
    int private_bit;
    int mode;
    int mode_extension;
    int copyright;
    int orig_copy;
    int emphasis;
*/

typedef struct
{
    uint32_t                 sample_rate;
    unsigned long            samplesPerFrame;
    unsigned int             number_channels;
    unsigned long            compr_frame_length;
}tmdlAudioMPEGAudioHeader_t;

/** Contents of the burst audio header.
*/
typedef unsigned long tmdlAudioBurstAudioHeader_t;

/** Contents of the AC3 audio header.*/

typedef enum
{
    tmdlAudioAC3InputChConfigDualMono    = 0,
    tmdlAudioAC3InputChConfigCenter      = 1,   // 1/0 (C)
    tmdlAudioAC3InputChConfigLR          = 2,   // 2/0 (L, R)
    tmdlAudioAC3InputChConfigLCR         = 3,   // 3/0 (L, C, R)
    tmdlAudioAC3InputChConfigLRS         = 4,   // 2/1 (L, R, l)
    tmdlAudioAC3InputChConfigLCRS        = 5,   // 3/1 (L, C, R, l)
    tmdlAudioAC3InputChConfigLR_SL_SR    = 6,   // 2/2 (L, R, l, r)
    tmdlAudioAC3InputChConfigLCR_SL_SR   = 7    // 3/2 (L, C, R, l, r)
} tmdlAudioAC3InputChConfig_t;

/* Information from AC3 frame that may be useful to application */
typedef struct
{
    uint32_t                    sampling_freq;
    int16_t                     frame_size;
    int16_t                     bsinfo;
    int16_t                     dialnorm;
    int16_t                     langcod;
    int16_t                     audprod;
    int16_t                     ex_bitstream_info;
    tmdlAudioAC3InputChConfig_t input_ch_config;
} tmdlAudioAC3AudioHeader_t;

/** Contents of the MP3 audio header. */
typedef struct
{
    uint32_t        sample_rate;
    unsigned int    samplesperchannel;
    unsigned int    numchans;
    unsigned int    free_format;
}tmdlAudioMP3AudioHeader_t;

/** AAC channel mode */
typedef enum
{
  tmdlAudioAACChannelModeUnknown,
  tmdlAudioAACChannelModeMono,
  tmdlAudioAACChannelModeStereo,
  tmdlAudioAACChannelModeDualMono
} tmdlAudioAACChannelMode_t;

/** Contents of the AAC audio header.*/
typedef struct
{
  uint32_t                  SampleRate;
  unsigned int              NumberChannels;
  tmdlAudioAACChannelMode_t ChannelMode;
  unsigned int              BitRate;
  int                       FrameSize;
  int                       sbrFlag;
  int                       psFlag;
}tmdlAudioAACAudioHeader_t;

/** Contents of the WMA audio header.
*/
typedef struct
{
    unsigned int      wFormatTag;        /* format type */
    unsigned int      nChannels;         /* number of channels (i.e. mono, stereo...) */
    unsigned long int nSamplesPerSec;    /* sample rate */
    unsigned long int nAvgBytesPerSec;   /* for buffer estimation */
    unsigned int      nBlockAlign;       /* block size of data */
    unsigned int      wBitsPerSample;    /* Number of bits per sample of mono data */
    unsigned int      cbsize;            /* Count in bytes of the size of extra data */

} tmdlAudioWMAAudioHeaderFormat_t;

typedef struct
{
    tmdlAudioWMAAudioHeaderFormat_t  wfx;
    unsigned long int dwSamplesPerBlock;
    unsigned int      wEncodeOptions;
    unsigned long int dwSuperBlockalign;
    unsigned long int NumberofPairs;
} tmdlAudioWMAAudioHeader_t;

/** Contents of the WMAPRO audio header.
*/
typedef struct
{
    unsigned int      wFormatTag;        /* format type */
    unsigned int      nChannels;         /* number of channels (i.e. mono, stereo...) */
    unsigned long int nSamplesPerSec;    /* sample rate */
    unsigned long int nAvgBytesPerSec;   /* for buffer estimation */
    unsigned int      nBlockAlign;       /* block size of data */
    unsigned int      wBitsPerSample;    /* Number of bits per sample of mono data */
    unsigned int      cbsize;            /* Count in bytes of the size of extra data */

} tmdlAudioWMAProAudioHeaderFormat_t;

typedef struct
{
    tmdlAudioWMAProAudioHeaderFormat_t  wfx;
    unsigned long int dwSamplesPerBlock;
    unsigned int      wEncodeOptions;
    unsigned long int dwSuperBlockalign;
    unsigned long int NumberofPairs;
} tmdlAudioWMAProAudioHeader_t;

/** Contents of the Real audio header.*/
typedef struct
{
  int           SampleRate;
  unsigned int  NumOfChannels;
  unsigned int  BitRate;
  unsigned int  NumSamplePairs;
  int           BitsPerSample;
} tmdlAudioRealAudioHeader_t;

/** contents of decoded or processed audio headers.
*/
typedef union
{
    tmdlAudioMPEGAudioHeader_t    MPEG;
    tmdlAudioAC3AudioHeader_t     AC3;
    tmdlAudioBurstAudioHeader_t   Burst;
    tmdlAudioMP3AudioHeader_t     MP3;
    tmdlAudioAACAudioHeader_t     AAC;
    tmdlAudioWMAAudioHeader_t     WMA;
    tmdlAudioWMAProAudioHeader_t  WMAPRO;
    tmdlAudioLpcmAudioHeader_t    LPCM;
    tmdlAudioRealAudioHeader_t    REALAUDIO;

}tmdlAudioHeader_t;


/******************************************************************************/
/** Selection of decoder specific parameters to update

    Used with the SetDecParams function this identifies the data struct being
    passed.
*/
typedef enum
{
    tmdlAudioParamUpdateMPEG = 0,
    tmdlAudioParamUpdateAC3,
    tmdlAudioParamUpdateLPCM,
    tmdlAudioParamUpdateG729,
    tmdlAudioParamUpdateBurst,
    tmdlAudioParamUpdateMP3,
    tmdlAudioParamUpdateAAC,
    tmdlAudioParamUpdateWMA,
    tmdlAudioParamUpdateWMAPRO,
    tmdlAudioParamUpdateREALAUDIO,
    tmdlAudioParamUpdateNone,
    tmdlAudioParamUpdateGuard           /* Guard value - must be last in enum */

} tmdlAudioParamUpdate_t;


/** MPEG decoder output channel selection
    On pnx8330/1 this controls which mixer the decoder output goes to.
    On pnx8335 this is done with the streaming system and this setting is ignored
*/
typedef enum
{
    tmdlAudioChannelOne = 0,
    tmdlAudioChannelTwo,
    tmdlAudioBothChannels
} tmdlAudioChannel_t;

/** MPEG decode specific data */
typedef struct
{
   tmdlAudioChannel_t channel_select;
}tmdlAudioMPEGSpecific_t;

/** AC3 decoder specific data */

/** AC3 Compression mode */
typedef enum
{
    tmdlAudioAC3CompCust0 = 0,
    tmdlAudioAC3CompCust1,
    tmdlAudioAC3CompLineOut,
    tmdlAudioAC3CompRFMode
} tmdlAudioAC3Compression_t;

/** AC3 input data streams downmix */
typedef enum
{
    tmdlAudioDownmixSurround = 0,
    tmdlAudioDownmixMono,
    tmdlAudioDownmixStereo
} tmdlAudioAC3Downmix_t;

/** AC3 input stereo output mode */
typedef enum
{
    tmdlAudioAC3StereoOutModeAuto = 0,
    tmdlAudioAC3StereoOutModeDBStereo,
    tmdlAudioAC3StereoOutModeStereo
} tmdlAudioAC3StereoOutMode_t;

/** AC3 Dual mono reproduction mode */
typedef enum
{
    tmdlAudioAC3MRepStereo = 0,
    tmdlAudioAC3MRepCh1,
    tmdlAudioAC3MRepCh2,
    tmdlAudioAC3MRepMix
} tmdlAudioAC3MRep_t;

/** AC3 Karaoke mode */
typedef enum
{
    tmdlAudioAC3KaraokeNo = 0,
    tmdlAudioAC3KaraokeLeft,
    tmdlAudioAC3KaraokeRight,
    tmdlAudioAC3KaraokeBoth
} tmdlAudioAC3Karaoke_t;

typedef enum
{
    tmdlAudioAC3OutLfeNone = 0,
    tmdlAudioAC3OutLfePresent
} tmdlAudioAC3OutLfe_t;

typedef enum
{
    tmdlAudioAC3OutputChannelConfig_1_0 = 1,
    tmdlAudioAC3OutputChannelConfig_2_0 = 2,
    tmdlAudioAC3OutputChannelConfig_3_0 = 3,
    tmdlAudioAC3OutputChannelConfig_2_1 = 4,
    tmdlAudioAC3OutputChannelConfig_3_1 = 5,
    tmdlAudioAC3OutputChannelConfig_2_2 = 6,
    tmdlAudioAC3OutputChannelConfig_3_2 = 7
} tmdlAudioAC3OutputChannelConfig_t;

/** AC3 specific scalefactors */
typedef unsigned long tmdlAudioAC3Scale_t;

typedef enum
{
    tmdlAudioAC3BufferNOLimit = 0,
    tmdlAudioAC3Buffer8Bit,
    tmdlAudioAC3Buffer9Bit
} tmdlAudioAC3BufferConfig_t;

/** AC3 PCM rounding  */
typedef enum
{
    tmdlAudioAC3RndDSP = 0,
    tmdlAudioAC3Rnd16,
    tmdlAudioAC3Rnd18,
    tmdlAudioAC3Rnd20
} tmdlAudioAC3Rnd_t;

/** Bass redirection mode */
typedef enum
{
    tmdlAudioAC3BassNo = 0,
    tmdlAudioAC3BassSur,
    tmdlAudioAC3BassCenter,
    tmdlAudioAC3BassSurCenter
} tmdlAudioAC3BassRed_t;

/** AC3 decoder specific parameters */
typedef struct tmdlAudioAC3DecParamStruct
{
    tmdlAudioAC3Compression_t   		compression_mode;
    tmdlAudioAC3Downmix_t       		ac3_downmix;
    tmdlAudioAC3StereoOutMode_t 		stereo_out_mode;
    tmdlAudioAC3MRep_t          		mono_reproduction;
    tmdlAudioAC3Karaoke_t       		karaoke_mode;
    tmdlAudioAC3OutLfe_t        		out_lfe_mode;
    tmdlAudioAC3Scale_t         		dynscl_high;
    tmdlAudioAC3Scale_t         		dynscl_low;
    tmdlAudioAC3Scale_t         		pcm_scale;
    uint16_t                    		enableBurstOutput;
    tmdlAudioAC3OutputChannelConfig_t 	outputChannelConfig;

    /* Leave as is for 220 */
    tmdlAudioAC3BufferConfig_t  buf_config;
    tmdlAudioAC3Rnd_t           rounding_ctrl;
    tmdlAudioAC3BassRed_t       bass_redirection;
} tmdlAudioAC3Specific_t;

/** LPCM number of channels */
typedef uint8_t tmdlAudioLPCMCh_t;

/** LPCM downmix factor */
typedef uint32_t tmdlAudioLPCMDownmixFactor_t;

/** LPCM downmix factors per channel */
typedef struct tmdlAudioLPCMChDownmixStruct
{
    tmdlAudioLPCMDownmixFactor_t left;
    tmdlAudioLPCMDownmixFactor_t right;
}tmdlAudioLPCMChDownmix_t;

/** LPCM downmix factors */
typedef struct tmdlAudioLPCMDownmixStruct
{
    tmdlAudioLPCMCh_t nr_of_channels;
    tmdlAudioLPCMChDownmix_t channel[8];
}tmdlAudioLPCMDownmix_t;

/** G729 decoder specific data */
typedef uint32_t tmdlAudioG729Specific_t;   // TODO:

/** Burst decoder specific data */
typedef enum
{
    tmdlAudioBurstType_AC3,
    tmdlAudioBurstType_MPEG1_L1,
    tmdlAudioBurstType_MPEG1_L23,
    tmdlAudioBurstType_MPEG2,
    tmdlAudioBurstType_MPEG2_AAC,
    tmdlAudioBurstType_MPEG2_L1,
    tmdlAudioBurstType_MPEG2_L23,
    tmdlAudioBurstType_DTS,
    tmdlAudioBurstType_ATRAC,
    tmdlAudioBurstType_ATRAC_2_3,
    tmdlAudioBurstType_ExtDataType,
    tmdlAudioBurstType_Guard,
} tmdlAudioBurstType_t;


typedef struct
{
    tmdlAudioBurstType_t   BurstFormat;
    uint16_t            dataTypeDependanyInfo;
    uint16_t            AudioChannels;
    uint16_t            streamNumber;
    uint16_t            ExtentedPe;
    uint16_t            ExtentedPf;
} tmdlAudioBurstSpecific_t;

/** MP3 decoder specific data */
typedef struct
{
    Bool     dualOut;
    Bool     interleave;
    uint32_t MaxSyncAttempts;
}tmdlAudioMP3Specific_t;

/** AAC bit stream format */
typedef enum
{
    tmdlAudioAACBitStreamRaw,
    tmdlAudioAACBitStreamADTS,
    tmdlAudioAACBitStreamADIF,
    tmdlAudioAACBitStreamLATM
}tmdlAudioAACBitStream_t;

/** AAC decoder specific data */
typedef struct
{
   tmdlAudioAACBitStream_t bitstream;
   Bool downmixedOutput;
}tmdlAudioAACSpecific_t;

/** WMA decoder specific data */
typedef uint32_t tmdlAudioWMASpecific_t;        // TODO:

/** WMAPRO decoder specific data */
typedef uint32_t tmdlAudioWMAPROSpecific_t;     // TODO:

/** Real audio decoder specific data: to be completed */
typedef uint32_t tmdlAudioREALAUDIOSpecific_t;  // TODO:

typedef struct
{
    tmdlAudioLpcmAudioHeader_t header;
    tmdlAudioLpcmEndian_t    endian;

}tmdlAudioLPCMSpecific_t;

/** the decoder parameter pointer is a pointer to void which is
    cast to the appropriate type for the decoder in use
*/
typedef union
{
    tmdlAudioMPEGSpecific_t       MPEG;
    tmdlAudioAC3Specific_t        AC3;
    tmdlAudioLPCMSpecific_t       LPCM;
    tmdlAudioG729Specific_t       G729;
    tmdlAudioBurstSpecific_t      Burst;
    tmdlAudioMP3Specific_t        MP3;
    tmdlAudioAACSpecific_t        AAC;
    tmdlAudioWMASpecific_t        WMA;
    tmdlAudioWMAPROSpecific_t     WMAPRO;
    tmdlAudioREALAUDIOSpecific_t  REALAUDIO;

}tmdlAudioDecoderParameter_t;

/******************************************************************************/
/** Audio data stream input format.

    @note When the audio data type is MA_INP_TYPE_LPCM or MA_INP_TYPE_BURST, the
          format of the input data stream has to be MA_INP_FORMAT_OTHER.
          In these cases the format of data in the audio input buffer will be
          determined by MA_INP_EXT_FORMAT in the extension pointer.

*/

typedef enum
{
    tmdlAudioFormatPES = 0,   /* MPEG2 packetized ES          */
    tmdlAudioFormatES,        /* elementary stream            */
    tmdlAudioFormatSWES,      /* Software demuxed elementary stream            */
    tmdlAudioFormatDSS,       /* dss packetised ES            */
    tmdlAudioFormatOther,     /* stream format defined in ext */
    tmdlAudioFormatGuard      /* Guard value - must be last in enum */
} tmdlAudioFormat_t;

/******************************************************************************/
/** Audio data stream type.
*/
typedef enum
{
    tmdlAudioTypeNone = 0,
    tmdlAudioTypeMPEG,
    tmdlAudioTypeAC3,
    tmdlAudioTypeLPCM,
    tmdlAudioTypeG729,      /* not implemented on stb225 */
    tmdlAudioTypeBURST,
    tmdlAudioTypeMP3,
    tmdlAudioTypeAAC,
    tmdlAudioTypeWMA,
    tmdlAudioTypeWMAPRO,
    tmdlAudioTypeRMAUDIO,
    tmdlAudioTypeGuard      /* Guard value - must be last in enum */
} tmdlAudioType_t;


/******************************************************************************/
/** Audio data stream input formats for LPCM & Burst audio data types
*/
typedef enum
{
    tmdlAudioExtFormatLPCMAligned = 0,
    tmdlAudioExtFormatLPCMCompact,
    tmdlAudioExtFormatLPCMPES,
    tmdlAudioExtFormatBURSTMPEGES,
    tmdlAudioExtFormatBURSTMPEGPES,
    tmdlAudioExtFormatBURSTMPEGDVDEXTES,
    tmdlAudioExtFormatBURSTMPEGDVDEXTPES,
    tmdlAudioExtFormatBURSTMPEGDVBEXTES,
    tmdlAudioExtFormatBURSTAC3ES,
    tmdlAudioExtFormatBURSTAC3PES,
    tmdlAudioExtFormatBURSTDTSES8,
    tmdlAudioExtFormatBURSTDTSES16,
    tmdlAudioExtFormatBURSTDTSPES
} tmdlAudioExtFormat_t;
/******************************************************************************/
/** Audio extension data LPCM & Burst audio data types
*/
typedef struct
{
    tmdlAudioExtFormat_t    extension_format;
    uint16_t                nr_of_channels;
    uint16_t                quantization;
    uint16_t                deemphasis;
    uint16_t                lpcm_drc;
    uint16_t                burst_length;
    uint16_t                burst_pc;
    uint16_t                frequency;
    uint16_t                opt_pes_bytes;
} tmdlAudioExtension_t;

/*******************************************************************************
 * NOTE: The following typedef must be the same as the tmgdrAudio_buffer_t
 * typedef in ma_dec.h
 */

/** buffer requirements in instance setup */
typedef struct tmdlAudio_buffer_struct
{
    uint32_t size;
    uint32_t address;
} tmdlAudio_buffer_t;

/*******************************************************************************
 * NOTE: The following typedef must be the same as the tmgdrAudio_DecSetup_t
 * typedef in ma_dec.h
 */
/** The instance setup data */
typedef struct tmdlAudio_InstanceSetup_struct
{
    tmdlAudio_buffer_t  SBMBuffer[tmdlAudio_NumSBMBuffers];
    tmdlAudio_buffer_t  LinBuffer[tmdlAudio_NumLinBuffers];
    tmdlAudio_buffer_t  ParserBuffer[tmdlAudio_NumParserBuffers];

    bool                discardEarlyAudio;
    bool                audioMixerSyncEnable;
} tmdlAudio_InstanceSetup_t;

/** audio source */
typedef enum
{
    tmdlAudioSourceFrontend,        /* Decoder source is coming from a frontend */
    tmdlAudioSourceMemory,          /* Decoder source is coming from the memory (HDD, memory space) */
    tmdlAudioSourceUndefined,       /* Default value before opening device (internal use)*/
    tmdlAudioSourceGuard            /* Guard value - must be last in enum */
} tmdlAudio_StreamSource_t;

/** L/R channel routing */
typedef enum
{
    tmdlAudioRoutingNormal = 0, /* Stereo output */
    tmdlAudioRoutingChannelSwap,
    tmdlAudioRoutingMono,
    tmdlAudioRoutingLeft,
    tmdlAudioRoutingRight,
    tmdlAudioRoutingGuard           /* Guard value - must be last in enum */
} tmdlAudio_Routing_t;

/** Enumeration of possible audio events. */
typedef enum tmdlAudio_Event_enum
{
    tmdlAudio_EventNone                         = 0x00000000, /**< No event occurred. */
/** Note that these MUST correspond to their equivalents in ma_dec.h */
    tmdlAudio_EventDecStarted                   = 0x00000001, /**< The decoder started. */
    tmdlAudio_EventDecStopped                   = 0x00000002, /**< The decoder stopped. */
    tmdlAudio_EventDecAncilData                 = 0x00000004, /**< Ancilliary data arrived. */
    tmdlAudio_EventDecFatalError                = 0x00000008, /**< A fatal error occurred. */
    tmdlAudio_EventDecNonFatalError             = 0x00000010, /**< A non-fatal error occurred. */
    tmdlAudio_EventDecFrameHeaderChanged        = 0x00000020, /**< The frame header changed. */
    tmdlAudio_EventDecInSync                    = 0x00000040, /**< The decoder is in sync. */
    tmdlAudio_EventDecOutOfSync                 = 0x00000080, /**< The decoder is out of sync. */
    tmdlAudio_EventDecPause                     = 0x00000100, /**< The decoder's pause state has changed. */
    tmdlAudio_EventDecMute                      = 0x00000200, /**< The decoder's output has been muted. */
    tmdlAudio_EventDecUnMute                    = 0x00000400, /**< The decoder's output has been unmuted. */
    tmdlAudio_EventDecConfigError               = 0x00000800, /**< A configuration error has occurred. */
    tmdlAudio_EventDecNewPts                    = 0x00001000, /**< A new PTS has arrived. */
    tmdlAudio_EventDecPesExtension              = 0x00002000, /**< PES extension data is available. */
    tmdlAudio_EventDecPtsDisc                   = 0x00004000, /**< A PTS discontinuity has been detected. */
    tmdlAudio_EventDecStcDisc                   = 0x00008000, /**< An STC discontinuity has been detected. */
    tmdlAudio_EventDecEOS                       = 0x00100000, /**< End of Stream has been detected. (OUT OF SEQUENCE.) */
    tmdlAudio_EventDecFadingOut                 = 0x00200000,
/** following events must correspond to their equivalents in tmdlAudioIO_inpl.h */
    tmdlAudio_EventIODataExhausted              = 0x00010000, /**< Data exhausted at the output. */
    tmdlAudio_EventIOStarted                    = 0x00020000, /**< Audio output started */
    tmdlAudio_EventIOFrameRendered              = 0x00040000, /**< Audio Frame has been rendered.*/
/*                                                0x00100000,      Already used above (_EventDecEOS) */
/** following events are from tmdlAVDecs.h */
    tmdlAudio_EventAVFrameHeaderChanged         = 0x01000000, /**< AVDecs reported Frame Header Changed */
    tmdlAudio_EventAVStarted                    = 0x02000000, /**< AVDecs audio started */
    tmdlAudio_EventAVStopped                    = 0x04000000, /** AVDecs audio stopped */
    tmdlAudio_EventAVPaused                     = 0x08000000, /** AVDecs audio paused */
    tmdlAudio_EventAVFatalError                 = 0x10000000, /** AVDecs audio fatal error encountered */
    tmdlAudio_EventAVDataHi                     = 0x20000000, /** AVDecs audio input buffer data high */
    tmdlAudio_EventAVDataLo                     = 0x40000000, /** AVDecs audio input buffer data low */
    tmdlAudio_EventAVFadingOut                  = 0x00400000,
    tmdlAudio_EventAVDecoderEos                 = 0x00080000,

    tmdlAudio_EventAVBufferTimeOver             = 0x00800000, /** Difference between newest and oldest PTS > high time threshold. */
    tmdlAudio_EventAVBufferTimeUnder            = 0x80000000, /** Difference between newest and oldest PTS < low time threshold. */

    /** mask for all events */
    tmdlAudio_EventAll                          = 0xffffffff  /**< Mask for all events. */

} tmdlAudio_Event_t;

typedef union _tmdlAudioEventData_t
{
    phStbClock_t pts;
} tmdlAudioEventData_t;

/** Function pointer type to register for event callbacks. */
typedef void (*tmdlAudio_EventCallback_t)(tmInstance_t instance, tmdlAudio_Event_t event, tmdlAudioEventData_t *pData, void *pUserData);


/**
 * @brief The Flush behaviour to be used as people mean different things
 * when it comes to flushing.
 *
 * You can flush (discard data currently in buffers) or flush (playout data
 * currently in buffers).
 */
typedef enum {
    /** Flush by dicarding all data in buffers. */
    tmdlAudio_FlushMode_Discard,
    /** Flush by playing all data in all buffers. */
    tmdlAudio_FlushMode_Play,
    /** Guard value. */
    tmdlAudio_FlushMode_Guard
} tmdlAudio_FlushMode_t;



/*============================================================================*/
/*                      PUBLIC FUNCTION DECLARATION                           */
/*============================================================================*/
/* Can be accessed by external components                                     */



/******************************************************************************/
/**  open a decoder instance with a unit no.

    @param pinstance    Out: instance number opened
*/
extern tmErrorCode_t tmdlAudio_OpenM(
    tmInstance_t    *pinstance,
    tmUnitSelect_t   in_UnitSelect,
    Bool 			 events_from_spdif
    );


/******************************************************************************/
/**  open a decoder instance

    @param pinstance    Out: instance number opened

    This is done as a macro so we avoid the need for another kernel interface
*/
#if defined (CONFIG_DUAL_AUDIO_CHANNELS)
#define tmdlAudio_Open(x, tmUnit0)   tmdlAudio_OpenM((x), tmUnit0, False);
#else
#define tmdlAudio_Open(x)   tmdlAudio_OpenM((x), tmUnit0, False);
#endif

/******************************************************************************/
/**  close a decoder instance

    @param instance     In: instance
*/
extern tmErrorCode_t tmdlAudio_Close(
    tmInstance_t instance
    );

/******************************************************************************/
/**  Get instance setup data

    @param  instance    IN      instance
    @param  ppSetup     OUT     pointer to current setup

*/
extern tmErrorCode_t tmdlAudio_GetInstanceSetup(
    tmInstance_t instance,
    tmdlAudio_InstanceSetup_t *pSetup
    );


/******************************************************************************/
/**  Select the output I2S0-4 or SPDIF

    @param  instance    IN      instance
    @param  output      IN      output for this audio instance

*/
extern tmErrorCode_t tmdlAudio_SelectOutput(
    tmInstance_t instance,
    tmdlAudio_Output_t     output
    );

/******************************************************************************/
/**  Setup instance

    @param  instance    IN      instance
    @param  pSetup      IN      pointer to new setup

*/
extern tmErrorCode_t tmdlAudio_InstanceSetup(
    tmInstance_t instance,
    tmdlAudio_InstanceSetup_t * pSetup
    );

/******************************************************************************/
/**  Set Format

    @param  instance        IN      instance
    @param  format          IN      the audio input format
    @param  audioType       IN      the type of audio data
    @param  pExtensionPtr   IN      the format and type extension

*/
extern tmErrorCode_t tmdlAudio_SetFormat(
    tmInstance_t            instance,
    tmdlAudioFormat_t       format,
    tmdlAudioType_t         audioType,
    tmdlAudioExtension_t    *pExtensionPtr
    );

/******************************************************************************/
/**  Switch Format

    @param  instance        IN      instance
    @param  format          IN      the audio input format
    @param  audioType       IN      the type of audio data
    @param  pExtensionPtr   IN      the format and type extension

*/
extern tmErrorCode_t tmdlAudio_SwitchFormat(
    tmInstance_t            instance,
    tmdlAudioFormat_t       format,
    tmdlAudioType_t         audioType,
    tmdlAudioExtension_t    *pExtensionPtr
    );


extern tmErrorCode_t tmdlAudio_Play(
    tmInstance_t instance                   /* In: decoder instance                      */
    );                                      /* See MA_DEC_play; shall also take care of A/V Sync
                                            (see reference implementation in audio part in tmdlAVDecs.c in STB220) */
extern tmErrorCode_t tmdlAudio_Continue(
    tmInstance_t instance                   /* In: decoder instance                      */
    );                                      /* New; shall also take care of A/V Sync
                                            (see reference implementation in audio part in tmdlAVDecs.c in STB220) */
extern tmErrorCode_t tmdlAudio_Stop(
    tmInstance_t instance                   /* In: decoder instance                      */
    );                                      /* See MA_DEC_stop; shall also take care of A/V Sync
                                            (see reference implementation in audio part in tmdlAVDecs.c in STB220) */
extern tmErrorCode_t tmdlAudio_Pause(
    tmInstance_t instance,                  /* In: decoder instance                   */
    uint32_t pauseLength                    /* In: pause length in ms                 */
    );                                      /* See MA_DEC_pause; shall also take care of A/V Sync
                                            (see reference implementation in audio part in tmdlAVDecs.c in STB220) */

extern tmErrorCode_t tmdlAudio_SetMute(
    tmInstance_t instance,                  /* In: decoder instance                      */
    bool mute                               /* In: desired mute state                    */
    );                                      // See MA_DEC_set_mute

/** Set the mask for events that are to be enabled on the specified decoder instance. */
extern tmErrorCode_t tmdlAudio_SetEventMask(
    tmInstance_t instance,                  /* In: decoder instance */
    tmdlAudio_Event_t eventMask             /* In: event mask       */
                                            );
/** Set the function to be called when events occur on the specified decoder instance. */
extern tmErrorCode_t tmdlAudio_SetEventCallback(
    tmInstance_t instance,                  /* In: decoder instance        */
    tmdlAudio_EventCallback_t eventCallback,/* In: event callback function, or NULL to disable callbacks. */
    void *pUserData                         /* In: user data to send out on each callback */
                                                );
/******************************************************************************/
/** \brief  This function allows the caller to set the PTS offset used by the
 *          specified instance.
 *
 *  \param  kAudioInstance  : (In) the audio decoder instance
 *  \param  ptsOffset       : (In) PTS offset in 90kHz cycles
 *
 *  \return The error code.
 *          - TM_OK                         : success
 *          - TMDL_ERR_AUDIO_BAD_INSTANCE   : the specified instance is not valid
 *          - TMDL_ERR_AUDIO_BAD_PARAMS     : null pointer
 *          - TMDL_ERR_AUDIO_FATAL          : error at OS level
 *
 *  \note   tmdlAudioOpen must have been called before.
 */
/******************************************************************************/
extern tmErrorCode_t tmdlAudio_SetPtsOffset(
    tmInstance_t kAudioInstance,
    int32_t      ptsOffset
    );                                      // See MA_DEC_set_pts_offset


#if 0 // not implemented yet

extern tmErrorCode_t tmdlAudio_SetPts(
    tmInstance_t instance,                  /* In: decoder instance                      */
    tmTimeStamp_t ptsValue                  /* In: PTS value in 90 kHz cycles            */
    );                                      // See MA_DEC_set_pts

extern tmErrorCode_t tmdlAudio_GetPts(
    tmInstance_t instance,                  /* In: decoder instance                      */
    tmTimeStamp_t *ptsValue                 /* Out: PTS value in 90 kHz cycles           */
    );                                      // See MA_DEC_get_pts

#endif  // not implemented yet
/******************************************************************************/
/** Get audio header

    @param  instance        In: decoder instance
    @param  pAudioHeader    Out: header structure

    @retval

*/
extern tmErrorCode_t tmdlAudio_GetAudioHeader(
    tmInstance_t instance,
    tmdlAudioHeader_t *pAudioHeader
    );


#if 0
extern tmErrorCode_t tmdlAudio_GetPesInfo(
    tmInstance_t instance,                  /* In: decoder instance                      */
    tmdlAudioPesInfo_t *ppesInfo            /* Out: optional PES field flags             */
    );                                      // See MA_DEC_get_pes_info

extern tmErrorCode_t tmdlAudio_GetExtInfo(
    tmInstance_t instance,                  /* In: decoder instance                    */
    tmdlAudioExtInfo_t *pextInfo            /* Out: extension information              */
    );                                      // See MA_DEC_get_ext_info

extern tmErrorCode_t tmdlAudio_GetDecDelay(
    tmInstance_t instance,                  /* In: decoder instance                      */
    uint32_t *pdelay                        /* Out: decoding delay                      */
    );                                      // See MA_DEC_get_dec_delay

extern tmErrorCode_t tmdlAudio_GetDecWindow(
    tmInstance_t instance,                  /* In: decoder instance                      */
    uint32_t *pdecWin                       /* Out: decoding window length                      */
    );                                      // See MA_DEC_get_dec_window

extern tmErrorCode_t tmdlAudio_RequestAncillaryData(
    tmInstance_t instance,                  /* In: decoder instance                      */
    bool enable                             /* In: ancillary data enable                 */
    );                                      // See MA_DEC_request_ancillary_data

extern tmErrorCode_t tmdlAudio_GetAncillaryData(
    tmInstance_t instance,                  /* In: decoder instance                      */
    tmdlAudioAncillaryData_t *pdata         /* Out: Ancillary data                       */
    );                                      // See MA_DEC_get_ancillary_data

#endif

/******************************************************************************/
/**  Set decoder parameters

    @param instance,        In: decoder instance
    @param updateCmd,       In: decoder update command
    @param pParameter       In: special decoder parameters

    @retval                 TM_OK - success
*/
extern tmErrorCode_t tmdlAudio_SetDecParam(
    tmInstance_t instance,
    tmdlAudioParamUpdate_t updateCmd,
    tmdlAudioDecoderParameter_t *pParameter
    );

#if 0 // not implemented yet

extern tmErrorCode_t tmdlAudio_SelectInput(
    tmInstance_t instance,                  /* In: decoder instance                  */
    tmdlAudioSelectInp_t decInputSelect     /* In: input buffer selection            */
    );                                      // See MA_DEC_select_input

extern tmErrorCode_t tmdlAudio_Reset(
    tmInstance_t instance                   // Instance
    );                                      // See MA_DEC_reset

extern tmErrorCode_t tmdlAudio_SetPtsShift(
    tmInstance_t instance,                  /* In: decoder instance                 */
    tmTimeStamp_t ptsShiftValue             /* In: pts shift value                  */
    );                                      // See MA_DEC_set_pts_shift

extern tmErrorCode_t tmdlAudio_GetStuffZeros(
    tmInstance_t instance,                  /* In : decoder instance                 */
    uint32_t* pstuffZerosValue              /* Out: stuff zeros value                */
);                                          // TODO: !! What is the use of this ? !!
                                            // See MA_DEC_get_stuff_zeros
extern tmErrorCode_t tmdlAudio_Beep(
    tmInstance_t instance,                  /* In: analog output instance         */
    uint16_t frequency,                     /* In: beep frequency                 */
    uint16_t length,                        /* In: beep length                    */
    uint32_t volume,                        /* In: beep volume                    */
    bool wait                               /* In: wait for completion            */
    );                                      // TODO: !!! Shouldn't beep be a seperate decoder ? !!!

#endif                                            // See MA_OUT_beep

/** Set the decoder output volume

    @param instance @b IN the decoder instance
    @param volume   @b IN the percentage volume 0-1500% (or thereabouts)

    @retval TM_OK - success, otherwise failed.
*/
extern tmErrorCode_t tmdlAudio_SetVolume(
    tmInstance_t instance,
    uint32_t volume);

/** Get the decoder output volume

    @param instance @b IN the decoder instance
    @param volume   @b OUT the percentage volume 0-1500% (or thereabouts)

    @retval TM_OK - success, otherwise failed.
*/
extern tmErrorCode_t tmdlAudio_GetVolume(
    tmInstance_t instance,
    uint32_t *pVolume);

/** Set the decoder output balance

    @param instance @b IN the decoder instance
    @param balance  @b IN the percentage balance. -100 = fully left, +100 = fully right 0 = centre

    @retval TM_OK - success, otherwise failed.
*/
extern tmErrorCode_t tmdlAudio_SetBalance(
    tmInstance_t instance,
    int32_t balance);

/** Get the decoder output balance

    @param instance @b IN the decoder instance
    @param balance  @b OUT the percentage balance. -100 = fully left, +100 = fully right 0 = centre

    @retval TM_OK - success, otherwise failed.
*/
extern tmErrorCode_t tmdlAudio_GetBalance(
    tmInstance_t instance,
    int32_t *pBalance);


extern tmErrorCode_t tmdlAudio_SetPorches(
    tmInstance_t instance,
    int32_t 	 front_porch,
    int32_t 	 back_porch);

extern tmErrorCode_t tmdlAudio_GetPorches(
    tmInstance_t instance,
    int32_t *	 front_porch,
    int32_t *	 back_porch);

extern tmErrorCode_t tmdlAudio_SetSegue(
    tmInstance_t instance,
    int32_t 	 segue_location);

extern tmErrorCode_t tmdlAudio_GetSegue(
    tmInstance_t instance,
    int32_t *	 segue_location);

extern tmErrorCode_t tmdlAudio_SetTrackVolume(
    tmInstance_t instance,
    int32_t 	 track_volume);

extern tmErrorCode_t tmdlAudio_GetTrackVolume(
    tmInstance_t instance,
    int32_t *	 track_volume);

/** Set the decoder fade

    @param instance @b IN the decoder instance
    @param fade_in @b IN whether this is a fade in or a fade out
    @param location @b IN the location in ms of the fade start. -1 means immediate.
    @param length @b IN the length of the fade in ms.

    @retval TM_OK - success, otherwise failed.
*/
extern tmErrorCode_t tmdlAudio_SetFade(
    tmInstance_t instance,
    bool 		 fade_in,
    int32_t 	 location,
    int32_t 	 length,
    int32_t 	 level);

/** Get the decoder fade

    @param instance @b IN the decoder instance
    @param fade_in @b IN whether this is a fade in or a fade out
    @param location @b OUT the location in ms of the fade start. -1 means immediate.
    @param length @b OUT the length of the fade in ms.

    @retval TM_OK - success, otherwise failed.
*/
extern tmErrorCode_t tmdlAudio_GetFade(
    tmInstance_t instance,
    bool 		 fade_in,
    int32_t *	 location,
    int32_t *	 length,
    int32_t *	 level);

/** Set the decoder output routing

    @param instance @b IN the decoder instance
    @param routing  @b IN the new output routing to use

    @retval TM_OK - success, otherwise failed.
*/
extern tmErrorCode_t tmdlAudio_SetRouting(
    tmInstance_t instance,
    tmdlAudio_Routing_t routing);

/** Get the decoder output routing

    @param instance @b IN the decoder instance
    @param pRouting @b OUT the current output routing

    @retval TM_OK - success, otherwise failed.
*/
extern tmErrorCode_t tmdlAudio_GetRouting(
    tmInstance_t instance,
    tmdlAudio_Routing_t *pRouting);

/** Set the audio input source

    @param instance @b IN the decoder instance
    @param source   @b IN the source

    @retval TM_OK - success, otherwise failed.
*/
extern tmErrorCode_t tmdlAudio_SetSource(
    tmInstance_t instance,
    tmdlAudio_StreamSource_t  source
);


/******************************************************************************/
/**
 * Sets the thresholds for the buffer events. When the thresholds are
 * exceeded (above a high level or below a low level), an event will be
 * generated.
 *
 * The dataLow and dataHigh thresholds are specified in terms of a number of
 * bytes of data in the video ES buffer.
 *
 * The bufferTimeLow and bufferTimeHigh thresholds are specified in terms of
 * number of milliseconds of data in the video ES buffer, measured by taking
 * the difference between the oldest and newest timestamp in the buffer.
 *
 * The bufferMask field can be used to specify which thresholds are set
 * by a call to this function.
 *
 * @param instance          @b IN   The tmdlAudio instance number
 * @param bufferMask        @b IN   Mask which specifies the thresholds that will
 *                                  be modified by this call.
 * @param dataLow           @b IN   Data low threshold (bytes)
 * @param dataHigh          @b IN   Data high threshold (bytes)
 * @param bufferTimeLow     @b IN   Buffer time low threshold (milliseconds)
 * @param bufferTimeHigh    @b IN   Buffer time high threshold (milliseconds)
 *
 * @retval TM_OK                            Success
 * @retval TMDL_ERR_AUDIO_INST_NOT_AVAIL    Invalid instance
 * @retval TMDL_ERR_AUDIO_BAD_PARAMS        Invalid parameter
 * @retval TMDL_ERR_AUDIO_FATAL             Lower level driver error
 *
 * @see   tmdlAudio_GetBufferThresholds
 */
extern tmErrorCode_t tmdlAudio_SetBufferThresholds( tmInstance_t instance,
                                                    UInt32       bufferMask,
                                                    UInt32       dataLow,
                                                    UInt32       dataHigh,
                                                    UInt32       bufferTimeLow,
                                                    UInt32       bufferTimeHigh );

/******************************************************************************/
/**
 * Gets the thresholds for the buffer events. See tmdlAudio_SetBufferThresholds()
 * for further details.
 *
 * @param instance          @b IN   The tmdlAudio instance number
 * @param pDataLow          @b OUT  Data low threshold (bytes)
 * @param pDataHigh         @b OUT  Data high threshold (bytes)
 * @param pBufferTimeLow    @b OUT  Buffer time low threshold (milliseconds)
 * @param pBufferTimeHigh   @b OUT  Buffer time high threshold (milliseconds)
 *
 * @retval TM_OK                            Success
 * @retval TMDL_ERR_AUDIO_INST_NOT_AVAIL    Invalid instance
 * @retval TMDL_ERR_AUDIO_BAD_PARAMS        Invalid parameter
 * @retval TMDL_ERR_AUDIO_FATAL             Lower level driver error
 *
 * @see   tmdlAudio_SetBufferThresholds
 */
extern tmErrorCode_t tmdlAudio_GetBufferThresholds( tmInstance_t instance,
                                                    UInt32       *pDataLow,
                                                    UInt32       *pDataHigh,
                                                    UInt32       *pBufferTimeLow,
                                                    UInt32       *pBufferTimeHigh );

/******************************************************************************/
/**
 * Gets the number of bytes currently in the video ES buffer.
 *
 * @param instance          @b IN   The tmdlAudio instance number
 * @param pFullness         @b OUT  Number of bytes in the video ES buffer
 * @param pSize             @b OUT  Size of the video ES buffer
 *
 * @retval TM_OK                            Success
 * @retval TMDL_ERR_AUDIO_INST_NOT_AVAIL    Invalid instance
 * @retval TMDL_ERR_AUDIO_BAD_PARAMS        Invalid parameter
 * @retval TMDL_ERR_AUDIO_FATAL             Lower level driver error
 *
 * @note  tmdlAudioInstanceSetup() must be performed prior to calling this function.
 *
 * @see   tmdlAudio_SetBufferThresholds(), TMDL_AUDIO_EVENT_ES_BUFFER_TIME_OVER
 */
extern tmErrorCode_t tmdlAudio_GetBufferFullness( tmInstance_t instance,
                                                  UInt32       *pFullness,
                                                  UInt32       *pSize );

/******************************************************************************/
/**
 * Flush the audio buffers.
 * Either discard the data without playing or play out all data in the buffers.
 *
 * @param instance      @b IN   The tmdlAudio instance number
 * @param flushMode     @b IN   Flush mode (discard or playout)
 *
 * @retval TM_OK                            Success
 * @retval TMDL_ERR_AUDIO_INST_NOT_AVAIL    Invalid instance
 * @retval TMDL_ERR_AUDIO_BAD_PARAMS        Invalid parameter
 * @retval TMDL_ERR_AUDIO_FATAL             Lower level driver error
 *
 * @note  tmdlAudioInstanceSetup() must be performed prior to calling this function.
 */
extern tmErrorCode_t tmdlAudio_Flush( tmInstance_t instance,
                                      tmdlAudio_FlushMode_t flushMode );

/******************************************************************************/
/** Enable/disable PCR sigma-delta pulling of the clock.
 *
 *  @param instance IN - the decoder instance
 *  @param enable       IN - True/False.
 *
 *  @retval TM_OK - success, otherwise failed.
 */
extern tmErrorCode_t tmdlAudio_SetPcrSigmaDeltaMode(
    tmInstance_t                instance,
    Bool                        enable);

/******************************************************************************/
/** Enable/disable forcing of PCR recovery (for non-frontend sources).
 *
 *  @param instance IN - the decoder instance
 *  @param enable       IN - True/False.
 *
 *  @retval TM_OK - success, otherwise failed.
 */
extern tmErrorCode_t tmdlAudio_ForcePcrRecovery(
    tmInstance_t                instance,
    Bool                        enable);



extern tmErrorCode_t tmdlAudio_SetOutputVolume(uint32_t output, uint32_t volume);

#ifdef __cplusplus
}
#endif

#endif /* TMDLAUDIO_H */

/*=============================================================================*/
/*                            END OF FILE                                      */
/*=============================================================================*/
