#ifndef SOUND_ALARM_H__
#define SOUND_ALARM_H__
/*本文件实现声音报警排序及具体播放事宜*/
/*对于优先级而言，区分两种版本的报警策略，
1、所有报警优先级一定不同，按照报警枚举数值来定义优先级。
2、允许有同优先级存在。优先级不同的，按优先级顺序执行，优先级相同的，按照触发顺序执行。*/
/*********************************************************************************/
// #define SOUND_PLATFORM_16BIT
#ifdef SOUND_PLATFORM_16BIT
typedef unsigned char Sound_uint8_t;
typedef unsigned int  Sound_uint16_t;
typedef unsigned long Sound_uint32_t;
#else
typedef unsigned char      Sound_uint8_t;
typedef unsigned short     Sound_uint16_t;
typedef unsigned int       Sound_uint32_t;
typedef unsigned long long Sound_uint64_t;
#endif
/*********************************************************************************/
/*所有最小单位音源的枚举*/
typedef enum
{
    SOUND_SOURCE_0 = 0U,
    SOUND_SOURCE_1,
    SOUND_SOURCE_2,
    SOUND_SOURCE_3,
    SOUND_SOURCE_4,
    SOUND_SOURCE_RADAR_0,
    SOUND_SOURCE_RADAR_1,
    SOUND_SOURCE_RADAR_2,
    SOUND_SOURCE_RADAR_4,
    SOUND_SOURCE_RADAR_8,
    SOUND_SOURCE_TICK,
    SOUND_SOURCE_TOCK,
    SOUND_SOURCE_5,
    SOUND_SOURCE_6,
    SOUND_SOURCE_MAX,
} Sound_Source_en_t;
/*由各种音源组合后的声音种类。*/
/*该枚举必须和 stSoundVarietyAttribute 一一对应*/
typedef enum
{
    SOUND_VARIETY_0 = 0U,
    SOUND_VARIETY_1,
    SOUND_VARIETY_2,
    SOUND_VARIETY_3,
    SOUND_VARIETY_4,
    SOUND_VARIETY_RADAR_0,
    SOUND_VARIETY_RADAR_1,
    SOUND_VARIETY_RADAR_2,
    SOUND_VARIETY_RADAR_4,
    SOUND_VARIETY_RADAR_8,
    SOUND_VARIETY_TICK,
    SOUND_VARIETY_TOCK,
    SOUND_VARIETY_5,
    SOUND_VARIETY_6,
    SOUND_VARIETY_NO,
    SOUND_VARIETY_MAX,
} Sound_Variety_en_t;
/*所有声音报警列表
有优先级参数时按照优先级参数执行，
没有优先级参数时按照枚举数值比较优先级，数值越小优先级越高。*/
/*该枚举必须和 stSoundAlarmAttribute 一一对应*/
typedef enum
{
    SOUND_ALARM_VOLUME = 0U,            /*音量*/
    SOUND_ALARM_DPF,                    /*DPF再生中*/
    SOUND_ALARM_DOOR,                   /*门未关*/
    SOUND_ALARM_RADAR_LOOP,             /*倒车雷达*/
    SOUND_ALARM_RADAR_8,                /*倒车雷达*/
    SOUND_ALARM_RADAR_4,                /*倒车雷达*/
    SOUND_ALARM_RADAR_2,                /*倒车雷达*/
    SOUND_ALARM_RADAR_1,                /*倒车雷达*/
    SOUND_ALARM_RADAR_0,                /*倒车雷达*/
    SOUND_ALARM_GEAR_P,                 /* P档相关 */
    SOUND_ALARM_START_IN_P,             /*请挂P档启动车辆*/
    SOUND_ALARM_PARK_IN_P,              /*仅限停车挂P档*/
    SOUND_ALARM_P_INVALID,              /*P档无效请用紧急解锁*/
    SOUND_ALARM_GEARBOX_HIGH_TEMP,      /*变速箱温度高*/
    SOUND_ALARM_GEARBOX_FAILURE,        /*变速箱严重故障*/
    SOUND_ALARM_TEMP,                   /*水温高*/
    SOUND_ALARM_ENGINE_LUBRICATE,       /*请检查引擎润滑系统*/
    SOUND_ALARM_PAR_FULL_MANUAL_RESET,  /*颗粒捕集器集满，请按手动复位*/
    SOUND_ALARM_PAR_FULL_SERVICE_RESET, /*颗粒捕集器集满，请联系服务站复位*/
    SOUND_ALARM_SPEED_LIMIT,            /*限速报警*/
    SOUND_ALARM_UREA,                   /*尿素报警*/
    SOUND_ALARM_UREA_2,                 /*尿素报警*/
    SOUND_ALARM_UREA_3,                 /*尿素报警*/
    SOUND_ALARM_UREA_4,                 /*尿素报警*/
    SOUND_ALARM_UREA_5,                 /*尿素报警*/
    SOUND_ALARM_UREA_6,                 /*尿素报警*/
    SOUND_ALARM_UREA_7,                 /*尿素报警*/
    SOUND_ALARM_UREA_8,                 /*尿素报警*/
    SOUND_ALARM_UREA_9,                 /*尿素报警*/
    SOUND_ALARM_UREA_10,                /*尿素报警*/
    SOUND_ALARM_UREA_11,                /*尿素报警*/
    SOUND_ALARM_UREA_12,                /*尿素报警*/
    SOUND_ALARM_UREA_13,                /*尿素报警*/
    SOUND_ALARM_UREA_14,                /*尿素报警*/
    SOUND_ALARM_UREA_15,                /*尿素报警*/
    SOUND_ALARM_TPMS,                   /*胎压异常*/
    SOUND_ALARM_TPMS_CONFIG_ERROR,      /*胎压配置错误*/
    SOUND_ALARM_SAFE_BELT,              /*安全带未系*/
  
    SOUND_ALARM_FUEL_SEN_FAIL,          /*燃油传感器故障*/
    SOUND_ALARM_START_IN_P_ONCE,        /*请挂P档启动车辆*/
    SOUND_ALARM_BRAKE_TO_SHIFT,         /*请踩制动换挡*/
    SOUND_ALARM_GEARBOX_CAUTION,        /*变速箱警示*/
    SOUND_ALARM_TBOX,                   /*   TBOX被拆除 */
    SOUND_ALARM_ESC_FAILURE,            /* ESP故障 */
    SOUND_ALARM_ESC_ATCIVE,             /* ESP激活 */
    SOUND_ALARM_ESC_CLOSE,              /* ESP关闭 */
    SOUND_ALARM_HILL_HOLD_MALF,         /* 坡道保持故障 */

    SOUND_ALARM_UNPLUGGED_KEY,    /*钥匙未拔 OFF */
    SOUND_ALARM_LIGHT_LEFT_ON,    /*小灯未关 OFF*/
   
    SOUND_ALARM_TICK,                   /*tick*/
    SOUND_ALARM_TOCK,                   /*tock*/
    
    SOUND_ALARM_LDWS,             /*LDWS车道偏离报警音*/
    SOUND_ALARM_LOW_OIL_PRESSURE, /*机油压力低   */
    SOUND_ALARM_MAX,
} Sound_Alarm_en_t;
/*同一个优先级中最多有几个报警，不可为0。根据不同项目而修改*/
#define SOUND_SAME_PRIO_NUM 1
/*有多少个不同优先级的报警，不可为0。根据不同项目而修改*/
#define SOUND_DIFF_PRIO_NUM SOUND_ALARM_MAX
/****************************************Do not modify the following***********************************************************/
/****************************************Do not modify the following***********************************************************/
/****************************************Do not modify the following***********************************************************/
/*当前文件版本号*/
#define SOUND_VERSION_NUM        0X18U
#define SOUND_SAME_PRIORITY_RANK 0U /*Do not modify*/
#define SOUND_ALARM_PLAY_SYN     1U /*Do not modify*/
#define SOUND_ALARM_TRIGGER_SYN  1U /*Do not modify*/
#define SOUND_SOURCE_NUM_MEMORY  0U /*Do not modify*/
#define SOUND_RAM_DATA_LEN       ((SOUND_ALARM_MAX * 2UL) + (( SOUND_ALARM_MAX )*SOUND_ALARM_PLAY_SYN) + (( SOUND_ALARM_MAX )*SOUND_ALARM_TRIGGER_SYN) + ((SOUND_ALARM_MAX * 2UL) * SOUND_SOURCE_NUM_MEMORY) + (((SOUND_ALARM_MAX * 2UL) + (SOUND_DIFF_PRIO_NUM)) * SOUND_SAME_PRIORITY_RANK))
/*********************************************************************************/
/*音源播放方式*/
typedef enum
{
    SOUND_SOURCE_PLAY_TYPE_ONCE = 0UL,
    SOUND_SOURCE_PLAY_TYPE_LOOP,
} Sound_Source_Play_Type_en_t;
/*报警触发条件*/
typedef enum
{
    SOUND_ALARM_TRIGGER_1   = 0x01U,
    SOUND_ALARM_TRIGGER_2   = 0x02U,
    SOUND_ALARM_TRIGGER_3   = 0x04U,
    SOUND_ALARM_TRIGGER_4   = 0x08U,
    SOUND_ALARM_TRIGGER_5   = 0x10U,
    SOUND_ALARM_TRIGGER_6   = 0x20U,
    SOUND_ALARM_TRIGGER_7   = 0x40U,
    SOUND_ALARM_TRIGGER_8   = 0x80U,
    SOUND_ALARM_TRIGGER_ALL = 0xFFU,
} Sound_Alarm_Trigger_Condition_en_t;
/*声音报警触发类型*/
typedef enum
{
    /*正常类型，报警触发之后，当播放次数播放完毕之后，必须删除报警之后才能再次触发*/
    SOUND_ALARM_TRIGGER_NORMAL = 0U,
    /*多次触发类型,报警触发之后，当播放次数播放完毕之后会自动删除该报警，也可手动删除该报警。*/
    SOUND_ALARM_TRIGGER_MULTI,
} Sound_Alarm_Trigger_Type_en_t;
/*当报警已经有一个触发条件存在时，有新的条件触发时对报警次数的处理*/
typedef enum
{
    SOUND_ALARM_NUM_FINISH_RESET = 0U, /*如果当前播放次数已经完成，那么重新计数播放。如果没播放完成时，那么无影响。*/
    SOUND_ALARM_NUM_RESET,             /*当前次数清零，重新计数播放*/
} Sound_Alarm_Num_Condition_en_t;
/*报警被打断时的处理方式*/
typedef enum
{
    SOUND_ALARM_RECOVER_NONE = 0U, /*不恢复，不播*/
    SOUND_ALARM_RECOVER_AGAIN,     /*恢复，重播*/
    SOUND_ALARM_RECOVER_CONTINUE,  /*恢复，续播*/
    SOUND_ALARM_BREAK_NONE,        /*不可被打断，报警次数播放完成后才允许切换到其他报警*/
} Sound_Alarm_Break_Type_en_t;
/*针对同优先级的报警的处理方式*/
typedef enum
{
    SOUND_ALARM_SORTORD_FIRST = 0U, /*先触发先报警*/
    SOUND_ALARM_SORTORD_AFTER,      /*后触发先报警*/
} Sound_Alarm_Sortord_Type_en_t;
/*当前音源播放状态*/
typedef enum
{
    SOUND_SOURCE_PLAY_IDLE = 0UL, /*当前空闲，没有在播放，音源播放完成*/
    SOUND_SOURCE_PLAY_BUSY,       /*当前动作未执行完，需等待*/
} Sound_Source_Play_Status_en_t;
/*操作函数返回状态*/
typedef enum
{
    SOUND_OPERATE_SUCCESS = 0UL, /*函数操作成功*/
    SOUND_OPERATE_FAIL,          /*函数操作失败*/
} Sound_Operate_Type_en_t;
/*播放同步方式*/
typedef enum
{
    SOUND_PLAY_SYN_FALL = 0UL, /*下降沿/播放停止*/
    SOUND_PLAY_SYN_RISE,       /*上升沿同步*/
    SOUND_PLAY_SYN_ENABLE,     /*播放使能*/
} Sound_Play_Syn_Type_en_t;
/*********************************************************************************/
typedef Sound_Operate_Type_en_t (*Sound_Operate_Process)(Sound_Source_en_t enSoundSourceIndex);
typedef Sound_Operate_Type_en_t (*Sound_Operate_Set_Volume)(Sound_Source_en_t enSoundSourceIndex, Sound_uint8_t u8SoundVolume);
// typedef Sound_Source_Play_Status_en_t (*Sound_Get_Status)(Sound_Source_en_t enSoundSourceIndex);
typedef Sound_Source_Play_Status_en_t (*Sound_Get_Status)(void);
/*********************************************************************************/
/*音源组合种类固定属性*/
typedef struct
{
    /*本种组合对应的音源索引，一个音源组合种类只对应一个音源。*/
    Sound_Source_en_t enSoundSource;
    /*播放时间(ms)，如果播放时间小于音源实际时长，那么以音源时长为准。需要一直播放时填 0xFFFFFFFFUL */
    Sound_uint32_t u32SoundPlayOnTime;
    /*播放完成后的停止时间(ms)，一般用于调节一个完整音源组合周期的时长，从而调节声音播放频率。*/
    /*需要播放同步时，此时间可设置成0*/
    Sound_uint32_t u32SoundPlayOffTime;
    /*音源播放方式，单次还是循环*/
    Sound_Source_Play_Type_en_t enSoundSourcePlayType;
    /*音源音量大小，数值没有具体含义，调用设置音量函数时传入。*/
    /*根据驱动不同，转成不同参数。或可当做一个百分比使用。*/
    /*如不支持音量调节，默认填0即可。*/
    Sound_uint8_t u8SoundSourceVolume;
    /*当一个声音报警对应一个音源时填0*/
    /*当一个声音报警对应多个音源时填1*/
    Sound_uint8_t u8SoundVarietyNum;
    /*播放次数（仅次数），播放完整一个音源的次数，需要一直播放时填 0xFFU  */
    /*一般情况下填1即可，在声音报警属性表中填写具体播放次数*/
    Sound_uint8_t u8SoundSourcePlayNum;
} Sound_Variety_Attribute_st_t;
/*声音报警固定属性*/
typedef struct
{
    /*声音报警对应要播放的音源组合种类。*/
    Sound_Variety_en_t enSoundAlarmVariety;
    /*声音报警播放次数（仅次数）。需要一直播放时填 0xFFU 。*/
    Sound_uint8_t u8SoundAlarmPlayTime;
#if ( SOUND_SAME_PRIORITY_RANK )
    /*声音报警优先级，数字小的优先级高。*/
    /*优先级相同的，按照初始化配置参数执行*/
    /*根据报警策略版本不同，选择是否支持该属性*/
    Sound_uint8_t u8SoundAlarmPrio;
#endif
    /*声音报警触发类型*/
    Sound_Alarm_Trigger_Type_en_t enSoundAlarmTriggerType;
    /*报警被打断时的处理方式,不可恢复的 需要条件取消后再次触发*/
    Sound_Alarm_Break_Type_en_t enSoundAlarmRecoverTypeBreak;
    /*当报警已经有一个触发条件存在时，再有新的条件触发时的处理方式。*/
    /*只有一个报警条件的，枚举内成员随意填*/
    Sound_Alarm_Num_Condition_en_t enSoundAlarmNumCondition;
} Sound_Alarm_Attribute_st_t;
/* 声音报警初始化参数*/
typedef struct
{
    /*一共有多少个音源组合种类，不可为0。一般填 SOUND_VARIETY_MAX */
    Sound_Variety_en_t enSoundVarietyLen;
    /*一共有多少个报警，不可为0。一般填 SOUND_ALARM_MAX */
    Sound_Alarm_en_t enSoundAlarmLen;
    /*同优先级之间的排序方式，先来先报，还是后来先报。不支持同优先级时随意填*/
    Sound_Alarm_Sortord_Type_en_t enSoundAlarmSortord;
    /*一共有多少种不同的报警优先级，不可为0。一般填 SOUND_DIFF_PRIO_NUM */
    /*具体填写的数值要小于等于  SOUND_ALARM_MAX  */
    Sound_uint8_t u8SoundDiffPrioNum;
    /*同一个优先级中最多有几个报警，不可为0。*/
    /*一般填 SOUND_SAME_PRIO_NUM 。*/
    Sound_uint8_t u8SoundSamePrioNum;
    Sound_uint8_t u8SoundReserved1; /*预留*/
    Sound_uint8_t u8SoundReserved2; /*预留*/
    /*对音源的单次播放函数*/
    Sound_Operate_Process pfnSoundOperatePlayOnce;
    /*对音源的循环播放函数*/
    Sound_Operate_Process pfnSoundOperatePlayLoop;
    /*对音源的停止函数-单次类型*/
    Sound_Operate_Process pfnSoundOperateStopOnce;
    /*对音源的停止函数-循环类型*/
    Sound_Operate_Process pfnSoundOperateStopLoop;
    /*设置音量函数，传入的音量大小形参就是属性表中填写的参数。*/
    /*需在驱动内进行对应处理。参数本身无实际意义。*/
    /*函数内部需做参数没变化，重复设置不执行判断*/
    Sound_Operate_Set_Volume pfnSoundOperateSetVolume;
    /*获取当前音源播放状态函数*/
    Sound_Get_Status pfnSoundGetStatus;
} Sound_Alarm_Init_st_t;
/*********************************************************************************/
/*********************************************************************************/
/*首次上电和唤醒时都要调用一次初始化函数*/
Sound_Operate_Type_en_t Sound_Alarm_Init(Sound_uint8_t *pu8SoundRamData, const Sound_Alarm_Attribute_st_t *pstSoundAlarmAttribute, const Sound_Variety_Attribute_st_t *pstSoundVarietyAttribute, Sound_Alarm_Init_st_t *pstSoundAlarmInit);
/*申请报警*/
Sound_Operate_Type_en_t Sound_Alarm_Request_Normal(Sound_Alarm_en_t enSoundAlarmIndex);
/*删除报警*/
Sound_Operate_Type_en_t Sound_Alarm_Delete_Normal(Sound_Alarm_en_t enSoundAlarmIndex);
/*报警需要多个触发条件时: 申请报警，触发条件任意对应*/
Sound_Operate_Type_en_t Sound_Alarm_Request_Mul(Sound_Alarm_en_t enSoundAlarmIndex, Sound_Alarm_Trigger_Condition_en_t enSoundTrigger);
/*报警需要多个触发条件时: 删除报警，触发条件和申请时对应。*/
Sound_Operate_Type_en_t Sound_Alarm_Delete_Mul(Sound_Alarm_en_t enSoundAlarmIndex, Sound_Alarm_Trigger_Condition_en_t enSoundTrigger);
/*主循环内实时调用，或者比计时函数调用的更快也可*/
void Sound_Alarm_Service(void);
/*声音报警计时相关，多少ms调用一次，那就传入多少*/
void Sound_Alarm_Handle_Time(Sound_uint8_t u8SoundTimeBase);
#if ( SOUND_ALARM_PLAY_SYN )
/*初始化后默认播放使能。*/
void Sound_Play_Enable_Suspend(Sound_Alarm_en_t enSoundAlarmIndex, Sound_Play_Syn_Type_en_t enSoundPlayEN);
#endif
#if ( SOUND_ALARM_TRIGGER_SYN )
/*初始化后默认有效。传参 0：暂停。1：使能。*/ /*主循环内调用*/
void Sound_Alarm_Enable_Suspend(Sound_Alarm_en_t enSoundAlarmIndex, Sound_uint8_t u8SoundAlarmEN);
#endif
/*读取当前正在播放的报警*/
Sound_Alarm_en_t Sound_Alarm_Current_Read(void);
/*读取版本号*/
Sound_uint8_t Sound_Version_Read(void);
/*读取当前可选功能配置参数*/
Sound_uint8_t Sound_Opt_Function_Read(void);
/*获取某个报警的播放次数，0xFFFF表示无效*/
Sound_uint16_t Sound_Get_Play_Time(Sound_Alarm_en_t enSoundAlarmIndex);
/**************************************************************************************************************************/
/***正常使用时，请测试所有报警的正常触发，播放，删除是否正常。***/
/**************************************************************************************************************************/
/****************************************Do not modify the above***********************************************************/
/****************************************Do not modify the above***********************************************************/
/****************************************Do not modify the above***********************************************************/
#endif
