/*****************************************************************************
 * Copyright (c) 2018, Broadcom Inc.                                         *
 *                                                                           *
 * All Rights Reserved.                                                      *
 *                                                                           *
 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Inc.;             *
 * the contents of this file may not be disclosed to third parties, copied   *
 * or duplicated in any form, in whole or in part, without the prior         *
 * written permission of Broadcom Inc.                                       *
 *****************************************************************************/
/**
 * @file overlay.h
 * @brief Header file for overlay
 * @Note
 */
#ifndef __OVERLAY_H__
#define __OVERLAY_H__

#include <string.h>

#ifndef ENABLE_SDK
#include "dsp_sdk_types.h"
#endif

#include "vend_au.h"
#include "vend_sp.h"

#define ENABLE_DITHERING    /* Enable dithering in each gain stage, not changeable in SDK */


#ifdef HACK_VEND_SP_TOBE_MSBC
typedef INT32 (HACK_FN_PTRS_t)();
extern HACK_FN_PTRS_t *g_hack_ptrs[4];

extern void *gp_sp_dec_inst;
extern void *gp_sp_enc_inst;

extern INT32 g_vend_sp_enc_cnt;
extern INT32 g_vend_sp_dec_cnt;

#endif



#ifdef HACK_VEND_AU_TOBE_SBC
typedef void (HACK_FN_PTRS_AU_t)();
extern INT32 g_vend_au_cnt;
//extern void *gp_au_dec_inst;

extern HACK_FN_PTRS_AU_t *g_hack_ptrs_au;

#endif




/**
 * Definitions.
 */
#define MAGIC_PATTERN_AU 0x00005541   /* ASCII of AU and 0x0000 */
#define MAGIC_PATTERN_SP 0x00005053   /* ASCII of SP and 0x0000 */

#define VEND_SUCCESS 0
#define VEND_FAIL -1


#define VEND_BUF_OVERFLOW   -100
#define VEND_BUF_UNDERFLOW  -101




#define VEND_GOOD_FRAME 0
#define VEND_LOST_FRAME 1
#define VEND_WAIT_NEXT_FRAME 2

#define VEND_FRAME_UNDERFLOW -200
#define VEND_FRAME_OVERFLOW -201


#define VEND_PRIVATE_PARAM_SIZE_BYTE 1024

/* DyVE and Inear related parameters */
//#define ENABLE_DYVE_ALGO_AND_BUFF
#define INEAR_BUFFER_START_CNT     2

#define CALL_ENTRY(ret, p_overlay_parameter, target_algo_idx) \
{                                                           \
    p_overlay_parameter->algo_idx = target_algo_idx;          \
    ret = (overlay_entry)(p_overlay_parameter);               \
}

/* long buffers index */
enum
{
    IDX_DYVE_IN_SPEECH = 0,
    IDX_DYVE_IN_NOISE,
    IDX_DYVE_OUT,
    IDX_INEAR_IN_MAIN_MIC,
    IDX_INEAR_IN_SUB_MIC,
    IDX_INEAR_IN_THIRD_MIC,
    IDX_INEAR_IN_FOURTH_MIC,
    IDX_INEAR_IN_FAREND,
    IDX_INEAR_OUT,
#ifndef ENABLE_DYVE_ALGO_AND_BUFF
    IDX_INEAR_IN_FAREND_BACKUP,
#endif

    NUM_OF_SPEECH_LONG_BUF
};

/* Audio packet type we obtain for dumping out */
enum
{
    SRC_AUDIO_PKT_DUMP_INEAR_INPUT = 1,
    SRC_AUDIO_PKT_DUMP_INEAR_OUTPUT,
    NUM_OF_AUDIO_PKT_DUMP_SRC
};

#ifdef ENABLE_LESS_DELAY_INEAR
#define VEND_INEAR_PROCESS_TIME 100 /* unit in us */
#else
#define VEND_INEAR_PROCESS_TIME 14000 /* unit in us */
#endif

#define VEND_AMB_PROCESS_TIME 1000 /* unit in us */

//enum
//{
//    NUM_OF_AUDIO_LONG_BUF = 0
//};


/** Index of each vendor function pointers
 *  Both audio overlay and speech overlay are listed in the enum
 */
typedef enum
{
    /* audio algorithms */
    ALGO_IDX_SS_AUDIO_INIT,       /* Scalable codec audio init       */
    ALGO_IDX_SS_AUDIO_EXEC,       /* Scalable codec audio decode     */
    ALGO_IDX_AMBIENT_INIT,        /* Ambient noise init              */
    ALGO_IDX_AMBIENT_EXEC,        /* Ambient noise execute           */


    /* speech algorithms */
    ALGO_IDX_SS_SPEECH_ENC_INIT, /* Scalable codec encoder init      */
    ALGO_IDX_SS_SPEECH_ENC_EXEC, /* Scalable codec encoder execution */
    ALGO_IDX_SS_SPEECH_DEC_INIT, /* Scalable codec decoder init      */
    ALGO_IDX_SS_SPEECH_DEC_EXEC, /* Scalable codec decoder execution */
    ALGO_IDX_DYVE_INIT,          /* DyVE init                        */
    ALGO_IDX_DYVE_EXEC,          /* DyVE execute                     */
    ALGO_IDX_INEAR_INIT,         /* Inear init                       */
    ALGO_IDX_INEAR_EXEC          /* Inear execute                    */

} ALGO_IDX_t;

/**
 *  Defines the parameters of EQ.
 *  PEQ_PARAM_t should sync with EQ_PARAM_t
 */
typedef struct
{
    /* Each biquad filter contains 5 coefficients and one gain */
    INT32 filter_coef[50];           /* filter coefficients for 10 biquad filters */
    INT16 filter_gain[10];           /* filter gain for 10 biquad filters         */
    INT16 last_gain;                 /* last gain of the EQ                       */
} PEQ_PARAM_t;



/**
 *  Buffer struct for algorithms
 */
typedef struct
{
    INT16 *buf;             /* base address of this buffer      */
    INT32 len;              /* buffer length in samples         */
    INT32 offset;           /* buffer offset in samples         */
}VEND_BUF_t;


/**
 *  External parameters for audio overlay
 */
typedef struct
{
    SS_AUDIO_EXT_ST_t   ss_audio_external_parameter;
    AMBIENT_EXT_ST_t    ambient_external_parameter;
    //VEND_BUF_t          long_buf[NUM_OF_AUDIO_LONG_BUF];

}OVL_AU_ST_t;


/**
 *  External parameters for speech overlay
 */
typedef struct
{
    SS_SPEECH_DEC_EXT_ST_t   ss_speech_dec_external_parameter;
    SS_SPEECH_ENC_EXT_ST_t   ss_speech_enc_external_parameter;
    DYVE_EXT_ST_t            dyve_external_parameter;
    INEAR_EXT_ST_t           inear_external_parameter;
    VEND_BUF_t               long_buf[NUM_OF_SPEECH_LONG_BUF];
}OVL_SP_ST_t;


/**
 *  union type for the parameters in each overlay
 */
typedef union
{
    OVL_SP_ST_t ovl_sp;
    OVL_AU_ST_t ovl_au;
}OVL_ST_t;


/**
 *  Top level structure of overlay parameters
 */
typedef struct
{
   ALGO_IDX_t algo_idx;        /* Index of each vendor function pointers  */
   OVL_ST_t ovl_paramter;      /* parameters for the functions in overlay */
   INT32 vend_dyve_enable;     /* enable/disable of DyVE                  */
   INT32 vend_inear_enable;    /* enable/disable of Inear                 */
   INT32 vend_ambient_enable;  /* enable/disable of Ambient noise         */
   INT32 vend_the3rdmic_enable;  /* enable/disable of the 3rd mic         */
   INT32 vend_sbm_enable;      /* enable/disable SBM feature    */
}OVERLAY_ST_t;


/**
 *  Overlay information in the beginning of overlay dRAM
 */
typedef struct
{
    INT32 magic_pattern;    /* Each overlay has different magic pattern      */
    void *entry_fp;         /* Pointer of entry function for linking purpose */
}OVERLAY_INFO_t;


/* Overlay function pointer */
typedef INT32 (FN_t)(OVERLAY_ST_t *);

/* Jitter buffer change event type */
typedef enum
{
    EVENTTYPE_JITTER_BUFFER_LEVEL_CHANGE_STARTED = 0,    /* Notification to MCU : Buf Level Change Started  */
    EVENTTYPE_JITTER_BUFFER_LEVEL_CHANGE_COMPLETED,      /* Notification to MCU : Buf Level Change Completed */
    EVENTTYPE_JITTER_BUFFER_LEVEL_INIT_DEPTH             /* Notification to MCU : Initial buffer depth when streaming started, buf depth would be stored in additional_info */
                                                         /* Note, this notification would be sent by framework, do not send this event from overlay (vendor interface) layer */
} EVENTTYPE_JITTER_BUFFER_LEVEL_CHANGE_t;

/**
 * Extern Variables
 */
extern UINT32 _iram0_overlay_entry_text_start;
extern OVERLAY_ST_t g_overlay_parameter;
extern FN_t *overlay_entry;


/* Private parameters for SS algorithms */
extern UINT8 g_vend_private_param[VEND_PRIVATE_PARAM_SIZE_BYTE];

/* extern for paramtric EQ*/
extern PEQ_PARAM_t g_peq_coef_tx_8k;
extern PEQ_PARAM_t g_peq_coef_rx_8k;
extern PEQ_PARAM_t g_peq_coef_tx_16k;
extern PEQ_PARAM_t g_peq_coef_rx_16k;


/**
 * Extern functions
 */
/* au_task_vend.c */
extern INT32 au_task_vend_AmbInit(OVERLAY_ST_t *p_overlay_parameter);
extern INT32 au_task_vend_AmbExec(OVERLAY_ST_t *p_overlay_parameter);
extern INT32 au_task_vend_AudioInit(OVERLAY_ST_t *p_overlay_parameter);
extern INT32 au_task_vend_AudioDecode(OVERLAY_ST_t *p_overlay_parameter, UINT16  plc_frame);
extern INT32 au_task_vend_SpeechCodecAlgoInit(OVERLAY_ST_t *p_overlay_parameter);
extern INT32 au_task_vend_SpeechDecode(OVERLAY_ST_t *p_overlay_parameter);
extern INT32 au_task_vend_SpeechEncode(OVERLAY_ST_t *p_overlay_parameter);
extern INT32 au_task_vend_SpeechAlgoForEnc(OVERLAY_ST_t *p_overlay_parameter);
extern INT32 au_task_vend_SpeechAlgoInit(OVERLAY_ST_t *p_overlay_parameter);
extern INT32 au_task_vend_SpeechAlgoForDec(OVERLAY_ST_t *p_overlay_parameter);
extern INT32 au_task_vend_FillBuf(VEND_BUF_t *buf_st, INT16 *src, UINT16 samples);
extern INT32 au_task_vend_DrainBuf(VEND_BUF_t *buf_st, INT16 *dest, UINT16 samples);
extern INT32 au_task_vend_CopyBuf(VEND_BUF_t *dest_buf_st, VEND_BUF_t *src_buf_st);
extern INT32 au_task_vend_PassBuf(VEND_BUF_t *dest_buf_st, VEND_BUF_t *src_buf_st, UINT16 samples);
extern INT32 au_task_vend_FlushBuf(VEND_BUF_t *buf_st, UINT16 samples);
extern INT32 au_task_vend_TriggerSBM(OVERLAY_ST_t *overlay_parameter, UINT16 current_buffer_depth, UINT16 target_buffer_depth);
extern INT16 au_task_vend_GetNumOfOutputSamples(OVERLAY_ST_t *overlay_parameter);

/* au_task.c */
extern void au_task_TimerDelay(UINT32 delay_time_in_us);
extern INT32 au_task_AudioPktDumpObtainFrames(OVERLAY_ST_t *p_overlay_parameter, UINT8 frame_src);
extern INT32 au_task_GetAmbientInputFrame(OVERLAY_ST_t *p_overlay_parameter);
extern INT32 au_task_SendAmbientOutputFrame(OVERLAY_ST_t *p_overlay_parameter);
extern INT32 au_task_GetAudioVendInputFrame(OVERLAY_ST_t *p_overlay_parameter);
extern INT32 au_task_SendAudioVendOutputFrame(OVERLAY_ST_t *p_overlay_parameter);
extern INT32 au_task_GetSpeechDecVendInputFrame(OVERLAY_ST_t *p_overlay_parameter);
extern INT32 au_task_GetSpeechEncVendInputFrame(OVERLAY_ST_t *p_overlay_parameter);
extern INT32 au_task_SendSpeechEncVendOutputFrame(OVERLAY_ST_t *p_overlay_parameter);
extern INT32 au_task_SendSpeechDecVendOutputFrame(OVERLAY_ST_t *p_overlay_parameter);
extern INT32 au_task_SendVendInearOutputFrame(OVERLAY_ST_t *p_overlay_parameter);

/**
* brief API for sending vendor data to MCU
*
* param[in]   vendor_data : 4bytes value to send it to MCU application.
*
* return 0 if successful
*/
extern INT32 au_task_SendVendorData(UINT32 vendor_data);

/**
* brief Send notification to MCU application when jitter buffer level changed initiated or completed
*
* param[in]   event_type : indication for jitter buffer level change started/completed (refer to EVENTTYPE_JITTER_BUFFER_LEVEL_CHANGE_t)
* param[in]   additional_info : extra infomation, MCU application will receive event with this value.
*
* return 0 if successful
*/
extern INT32 au_task_NotifyJitterBufLevelChange(UINT16 event_type, UINT16 additional_info);

/**
* brief Get jitter buffer depth MCU configurated and current jitter buffer level
*
* param[in/out]   buff_depth : pointer for jitter buffer depth MCU configured (ignored if null)
* param[in/out]   que_count : pointer for current jitter buffer level (ignored if null)
*                                          Typically, this jitter level will be lower than average of jitter buffer count if invoked from decoder function,
*                                          because jitter level would be decreased prior to decoder function call.
*
* return 0 if successful
*/
extern INT32 au_task_GetAuBufLevel(UINT8 *buff_depth, UINT32 *que_count);

#endif //__OVERLAY_H__
