/*******************************************************
*           SoundBooster_DRC_classic_impl.h            *
********************************************************/

#include "SoundBooster_DRC_classic.h"

typedef long long INT64;

//#define FRAME 54 // 256
#define FRAME 108 // 256

#define MAX(a,b) ((a>b) ? a:b)
#define MIN(a,b) ((a<b) ? a:b)
#define QGAIN 14
#define QGAIN_L 22
#define QTAU (24-2)

#define QLEV 15




//#define HEADROOMBITS 4

#define MAXVAL ((1<<(QLEV))-1)
#define MINVAL (-MAXVAL-1)

#define MAX_FAKE_GAIN (1 << (7 + QGAIN_L))

typedef struct{
	int limit_gain;   // Qformat 16bit
    int tau_attack;
    int tau_release;
    int gain_var;
    int gain_start;
    int st;
} DRC_T;



typedef enum{
	DRC_OFF=0,
	DRC_PEAK,
	DRC_RMS
} MODE_T;


#ifndef VC_PROJ

static __inline short DVTXOP_saturate(int L_var1) {return AE_SAT16X4_scalar(L_var1);}
static __inline short DVTXOP_add(short var1, short var2){return AE_ADD16S_scalar(var1, var2);}
static __inline short DVTXOP_sub(short var1, short var2){return AE_SUB16S_scalar(var1, var2);}
static __inline short DVTXOP_abs_s(short var1){return AE_ABS16S_scalar(var1);}
static __inline short DVTXOP_shl(short var1, short var2) {return AE_SLAA16S_scalar(var1, var2);}
static __inline short DVTXOP_shr(short var1, short var2) {return AE_SRAA16S_scalar(var1, var2);}
static __inline short DVTXOP_mult(short var1, short var2) {return AE_MULFP16X4S_scalar(var1, var2);}
static __inline int DVTXOP_L_mult(short var1, short var2) {return AE_MULF16X4SS_scalar(var1, var2);}
static __inline short DVTXOP_negate(short var1) {return AE_NEG16S_scalar(var1);}
static __inline short DVTXOP_extract_h(int L_var1) {return AE_TRUNC16X4F32_scalar(L_var1);}
static __inline short DVTXOP_extract_l(int L_var1) {return AE_CVT16X4_scalar(L_var1);}
static __inline short DVTXOP_round(int L_var1) {return AE_ROUND16X4F32SASYM_scalar(L_var1);}
static __inline int DVTXOP_L_mac(int L_var3, short var1, short var2) {return AE_MULAF16X4SS_scalar(L_var3, var1, var2);}
static __inline int DVTXOP_L_msu(int L_var3, short var1, short var2) {return AE_MULSF16X4SS_scalar(L_var3, var1, var2);}
static __inline int DVTXOP_L_add(int L_var1, int L_var2) {return AE_ADD32S_scalar(L_var1, L_var2);}
static __inline int DVTXOP_L_sub(int L_var1, int L_var2) {return AE_SUB32S_scalar(L_var1, L_var2);}
static __inline int DVTXOP_L_negate(int L_var1) {return AE_NEG32S_scalar(L_var1);}
static __inline short DVTXOP_mult_r(short var1, short var2) {return AE_MULFP16X4RAS_scalar(var1, var2);}
static __inline int DVTXOP_L_shl(int L_var1, short var2) {return AE_SLAA32S_scalar(L_var1, var2);}
static __inline int DVTXOP_L_shr(int L_var1, short var2) {return AE_SRAA32S_scalar(L_var1, var2);}
static __inline short DVTXOP_shr_r(short var1, short var2) {return AE_SRAA16RS_scalar (var1, var2);}
static __inline short DVTXOP_mac_r(int L_var3, short var1, short var2) {return AE_ROUND16X4F32SASYM_scalar(AE_MULAF16X4SS_scalar(L_var3, var1, var2));}
static __inline short DVTXOP_msu_r(int L_var3, short var1, short var2) {return AE_ROUND16X4F32SASYM_scalar(AE_MULSF16X4SS_scalar(L_var3, var1, var2));}
static __inline int DVTXOP_L_deposit_h(short var1) {return AE_CVT32X2F16_10_scalar(var1);}
static __inline int DVTXOP_L_deposit_l(short var1) {return AE_SEXT32X2D16_10_scalar(var1);}
static __inline int DVTXOP_L_shr_r(int L_var1, short var2) {return AE_SRAA32RS_scalar(L_var1, var2);}
static __inline int DVTXOP_L_abs(int L_var1) {return AE_ABS32S_scalar(L_var1);}
static __inline short DVTXOP_norm_s(short var1) {return AE_NSAZ16_0_scalar(var1);}
static __inline short DVTXOP_norm_l(int L_var1) { return AE_NSAZ32_L(L_var1); }
static __inline int DVTXOP_Ls_mult_r(int L_var1, short var2) { return AE_MOVAD32_L(AE_MULFP32X16X2RAS_L(AE_MOVDA32(L_var1), AE_MOVDA16(var2))); }
static __inline int DVTXOP_L_mult_r(int L_var1, int L_var2) { return AE_MOVAD32_L(AE_MULFP32X2RAS(AE_MOVDA32(L_var1), AE_MOVDA32(L_var2))); }


static __inline int DVTXOP_L_mpy_ls(int L_var2, short var1)
{

#ifndef OPT_DVTXOP_L_mpy_ls
	int L_varOut;
	short hi, lo;
	hi = AE_TRUNC16X4F32_scalar(L_var2);
	lo = (ae_int16)(ae_int32)AE_SRLI_32(AE_SLLI_32(L_var2, 16), 17);

	L_varOut = AE_MULF16X4SS_scalar(var1, lo);//DVTXOP_L_mult(var1, lo);
	L_varOut = AE_SRAA32S_scalar(L_varOut, 15);//DVTXOP_L_shr(L_varOut, 15);
	L_varOut = AE_MULAF16X4SS_scalar(L_varOut, var1, hi);//DVTXOP_L_mac(L_varOut, var1, hi);

	return L_varOut;
#else
	ae_int64 tmp;
	ae_int32x2 tmp32;
	int out;
	//////////////////////////////////////////////////
	L_var2 = L_var2&0xfffffffe;
	//////////////////////////////////////////////////
	tmp = AE_MUL32_LL(L_var2, var1);
	tmp = AE_SRAI64(tmp,15);
	tmp32 = AE_MOVF32X2_FROMF64(tmp);
	out = AE_MOVAD32_L(tmp32);
	return out;
#endif

}


#else

#ifdef HW_FIXED
short DVTXOP_saturate(int L_var1);
short DVTXOP_add(short var1, short var2);    /* Short DVTXOP_add,           1   */
short DVTXOP_sub(short var1, short var2);    /* Short DVTXOP_sub,           1   */
short DVTXOP_abs_s(short var1);               /* Short abs,           1   */
short DVTXOP_shl(short var1, short var2);    /* Short shift left,    1   */
short DVTXOP_shr(short var1, short var2);    /* Short shift right,   1   */
short DVTXOP_mult(short var1, short var2);   /* Short DVTXOP_mult,          1   */
int DVTXOP_L_mult(short var1, short var2); /* Long DVTXOP_mult,           1   */
short DVTXOP_negate(short var1);              /* Short DVTXOP_negate,        1   */
short DVTXOP_extract_h(int L_var1);         /* Extract high,        1   */
short DVTXOP_extract_l(int L_var1);         /* Extract low,         1   */
short DVTXOP_round(int L_var1);             /* DVTXOP_round,               1   */
int DVTXOP_L_mac(int L_var3, short var1, short var2);   /* Mac,  1  */
int DVTXOP_L_msu(int L_var3, short var1, short var2);   /* Msu,  1  */
int DVTXOP_L_add(int L_var1, int L_var2);    /* Long DVTXOP_add,        2 */
int DVTXOP_L_sub(int L_var1, int L_var2);    /* Long DVTXOP_sub,        2 */
int DVTXOP_L_negate(int L_var1);                /* Long DVTXOP_negate,     2 */
short DVTXOP_mult_r(short var1, short var2);       /* Mult with DVTXOP_round, 2 */
int DVTXOP_L_shl(int L_var1, short var2);      /* Long shift left, 2 */
int DVTXOP_L_shr(int L_var1, short var2);      /* Long shift right, 2*/
short DVTXOP_shr_r(short var1, short var2);        /* Shift right with DVTXOP_round, 2*/
short DVTXOP_mac_r(int L_var3, short var1, short var2); /* Mac with DVTXOP_rounding,2 */
short DVTXOP_msu_r(int L_var3, short var1, short var2); /* Msu with DVTXOP_rounding,2 */
int DVTXOP_L_deposit_h(short var1);        /* 16 bit var1 -> MSB,     2 */
int DVTXOP_L_deposit_l(short var1);        /* 16 bit var1 -> LSB,     2 */
int DVTXOP_L_shr_r(int L_var1, short var2); /* Long shift right with DVTXOP_round,  3             */
int DVTXOP_L_abs(int L_var1);            /* Long abs,              3  */
short DVTXOP_norm_s(short var1);             /* Short norm,           15  */
short DVTXOP_div_s(short var1, short var2); /* Short division,       18  */
short DVTXOP_norm_l(int L_var1);           /* Long norm,            30  */
short DVTXOP_norm_ll(long long L_var1);
int DVTXOP_Ls_mult_r(int L_var1, short var2);
int DVTXOP_L_mult_r(int L_var1, int L_var2);
#endif

#endif







