#include "platform.h"
#include "hal_headfile.h"
#include "system.h"
#include "debug.h"
#include "fixed_generic.h"
#include "config.h"
#include <math.h>
#include "drc.h"
// ========================
// DRC模块开关配置
// ========================
static int Limiter = 1;     // 限幅器开关(1=开启, 0=关闭)
static int Compressor = 1;  // 压缩器开关(1=开启, 0=关闭)
static int Expander = 1;    // 扩展器开关(1=开启, 0=关闭)
static int NoiseGate = 1;   // 噪声门开关(1=开启, 0=关闭)

// ========================
// 时间参数配置(单位: ms或s)
// ========================
static int ATtd = 3;    // 主攻击时间(3ms) - 增益下降速度
static int RTtd = 150;  // 主释放时间(150ms) - 增益恢复速度
static int AVt = 1;     // RMS平均时间(1ms) - 能量检测窗口
static int ATt = 1;     // 峰值攻击时间(1ms) - 瞬态响应速度
static int RTt = 5;    // 峰值释放时间(5s) - 峰值保持时间 -推荐 1-10s 单位ms

// ========================
// 动态范围阈值(单位: dB)
// ========================
static int NT = -35;  // 噪声门阈值(-35dB)
static int ET = -30;  // 扩展器阈值(-30dB)
static int CT = -15;   // 压缩器阈值(-6dB)
static int LT = -9;   // 限幅器阈值(-3dB)

// ========================
// 动态范围比率
// ========================
static float NR = 0.1;   // 噪声门比率(0.1:1)
static float ER = 0.75;  // 扩展器比率(0.75:1)
static float CR = 20;     // 压缩器比率(2:1)
static float LR = 1000;     // 限幅器比率(∞:1)

// ========================
// 高级参数
// ========================
static float hyst = 0.1;  // 滞后曲线宽度(0.1) - 防止阈值附近振荡

/*************** 运行时计算参数(初始化为0) ***************/
// 1. DRC核心参数
// ===================================================
// 斜率参数(根据比率动态计算)
static int NS = 0;  // 噪声门斜率: 1 - 1.0/NR
static int ES = 0;  // 扩展器斜率: 1 - 1.0/ER
static int CS = 0;  // 压缩器斜率: 1 - 1.0/CR
static int LS = 0;  // 限幅器斜率: 1 - 1.0/LR

static int hystD = 0;  // 滞后值(定点数表示)

// 时间常数(根据采样率转换)
static int TAV = 0;  // RMS平均时间常数
static int AT = 0;   // 峰值攻击时间常数
static int RT = 0;   // 峰值释放时间常数
static int ATD = 0;  // 主攻击时间常数
static int RTD = 0;  // 主释放时间常数

// 阈值(定点数表示)
static int NT_C = 0;  // 噪声门阈值(定点数)
static int ET_C = 0;  // 扩展器阈值(定点数)
static int CT_C = 0;  // 压缩器阈值(定点数)
static int LT_C = 0;  // 限幅器阈值(定点数)

// ===================================================
// 2. 状态变量
// ===================================================
// 信号检测状态
static int xpeak[2] = {0, 0};  // 各通道的峰值状态
static int xrms[2] = {0, 0};   // 各通道的RMS状态
static int lpeak = 0;           // 限幅器峰值状态(全局)
static int lrms = 0;            // 限幅器RMS状态(全局)

// 增益计算状态
static int f[MAXCHANNEL] = {0, 0};  // 当前增益(未平滑)
static int g[MAXCHANNEL] = {0, 0};  // 平滑后增益(应用值)

// ===================================================
// 3. 高通滤波器参数
// ===================================================
static int alpha = 0;    // 滤波器系数α
static int beta = 0;     // 滤波器系数β
static int gammaD = 0;   // 滤波器系数γ

// 滤波器历史状态(每个通道)
static int yhigh[MAXCHANNEL][2];  // 输出历史: [通道][0]=y(n-1), [通道][1]=y(n-2)
static int xhigh[MAXCHANNEL][2];  // 输入历史: [通道][0]=x(n-1), [通道][1]=x(n-2)

/*************** 参数定义结束 ***************/

// 不同采样率对应的滤波器系数表
/* 系数说明：
   这些系数实现了一个二阶高通滤波器，其通用传递函数为：
        H(z) = α(1 - 2z⁻¹ + z⁻²) / (1 + βz⁻¹ + γz⁻²)

   设计特点：
    1. 截止频率：约80-100Hz (去除直流和超低频)
    2. 滤波器类型：Butterworth或Chebyshev设计
    3. 稳定性：所有极点都在单位圆内(保证稳定)

   系数特性：
    - 满足关系：α + β + γ ≈ 1 (直流增益为0)
    - 随着采样率增加，系数趋近于1.0 (更高采样率需要更精细的频率控制)
*/
coeff coeffnum[SAMPLERATE_FORMAT_NUM] =
{
    // 采样率: 8000Hz
    {0.935526706991350, -1.866892279711715, 0.875214548253684},

    // 采样率: 11025Hz
    {0.952792085363768, -1.90335434048751,  0.907814000967563},

    // 采样率: 12000Hz
    {0.956543225556877, -1.911197067426073, 0.914975834801434},

    // 采样率: 16000Hz
    {0.967227282714777, -1.93338022587993,  0.935528904979179},

    // 采样率: 22050Hz
    {0.976110973497808, -1.951651179964643, 0.95279271402659},

    // 采样率: 24000Hz
    {0.978030479206560, -1.955578240315035, 0.956543676511203},

    // 采样率: 32000Hz
    {0.983477203353836, -1.966681385263485, 0.967227428151861},

    // 采样率: 44100Hz (CD质量)
    {0.987983304133502, -1.975822202074169, 0.976111014459839},

    // 采样率: 48000Hz (专业音频)
    {0.988954248067140, -1.977786483776764, 0.978030508491796},

    // 采样率: 96000Hz (高清音频)
    {0.994461788958195, -1.988892905899653, 0.988954249933127}
};

static void highpass(short* xout, int samplenum, int nch)
{
    int i = 0;
    int ytemp1 = 0; // 历史输出值 y(n-1)
    int ytemp2 = 0; // 历史输出值 y(n-2)
    int xtemp1 = 0; // 历史输入值 x(n-1)
    int xtemp2 = 0; // 历史输入值 x(n-2)
    int ytemp0 = 0; // 当前输出 y(n)
    int xtemp0 = 0; // 当前输入 x(n)
    short *x = 0;   // 当前采样点指针
    int temp = 0;   // 临时计算结果
    int channel = 0;// 通道索引

    // 遍历所有音频通道
    for(channel = 0; channel < nch; channel++)
    {
        // 定位当前通道的起始位置（交错存储）
        x = xout + channel;

        // 加载该通道的历史状态
        ytemp1 = yhigh[channel][0]; // 上一次调用保留的 y(n-1)
        ytemp2 = yhigh[channel][1]; // 上一次调用保留的 y(n-2)
        xtemp1 = xhigh[channel][0]; // 上一次调用保留的 x(n-1)
        xtemp2 = xhigh[channel][1]; // 上一次调用保留的 x(n-2)

        // 处理当前通道的所有采样点
        for(i = 0; i < samplenum; i++)
        {
            // 1. 读取当前采样值并进行增益调整
            // DEFINEHIGHPASS 确保足够的计算精度
            xtemp0 = (int)(*x) << DEFINEXGAIN;

            // 2. 计算高通滤波器输出（差分方程实现）
            ytemp0 = (
                (__int64)(alpha) * (xtemp0 - 2*xtemp1 + xtemp2) // 输入部分：x(n)-2x(n-1)+x(n-2)
                - (__int64)(beta) * ytemp1                      // 反馈部分：-β*y(n-1)
                - (__int64)(gammaD) * ytemp2                    // 反馈部分：-γ*y(n-2)
            ) / (1 << DEFINEHIGHPASS);                          // 量化调整

            // 3. 反向增益调整并转换为16位整数
            temp = ytemp0 / (1 << DEFINEXGAIN);

            // 4. 饱和处理（防止16位溢出）
            if(temp > 0x7fff) {         // 超过正最大值(32767)
                temp = 0x7fff;
            }
            else if(temp < -32768) {    // 低于负最小值(-32768)
                temp = -32768;
            }

            // 5. 写回处理后的采样值
            *x = (short)temp;

            // 6. 移动到下一帧的当前通道位置（交错存储）
            x += nch;

            // 7. 更新历史状态
            xtemp2 = xtemp1;  // x(n-2) = 旧的x(n-1)
            ytemp2 = ytemp1;  // y(n-2) = 旧的y(n-1)
            xtemp1 = xtemp0;  // 新的x(n-1) = 当前x(n)
            ytemp1 = ytemp0;  // 新的y(n-1) = 当前y(n)
        }

        // 保存该通道的最终状态供下次调用使用
        yhigh[channel][0] = ytemp1;
        yhigh[channel][1] = ytemp2;
        xhigh[channel][0] = xtemp1;
        xhigh[channel][1] = xtemp2;
    }
}

//#if 0
static  __inline int spx_ilog2(unsigned int x)
{
   int r=0;
   if (x>=(unsigned int)65536)
   {
      x >>= 16;
      r += 16;
   }
   if (x>=256)
   {
      x >>= 8;
      r += 8;
   }
   if (x>=16)
   {
      x >>= 4;
      r += 4;
   }
   if (x>=4)
   {
      x >>= 2;
      r += 2;
   }
   if (x>=2)
   {
      r += 1;
   }
   return r;
}
//#endif
// DRC模块初始化函数
// 参数：fs - 音频采样率(单位Hz)
void drcinit(int fs,DRC_init_typedef drc_init_struct)
{
	// ========================
	// DRC模块开关配置
	// ========================
	Limiter = drc_init_struct.Limiter;     // 限幅器开关(1=开启, 0=关闭)
	Compressor = drc_init_struct.Compressor;  // 压缩器开关(1=开启, 0=关闭)
	Expander = drc_init_struct.Expander;    // 扩展器开关(1=开启, 0=关闭)
	NoiseGate = drc_init_struct.NoiseGate;   // 噪声门开关(1=开启, 0=关闭)

	// ========================
	// 时间参数配置(单位: ms或s)
	// ========================
	ATtd = drc_init_struct.ATtd;    // 主攻击时间(3ms) - 增益下降速度
	RTtd = drc_init_struct.RTtd;  // 主释放时间(150ms) - 增益恢复速度
	AVt = drc_init_struct.AVt;     // RMS平均时间(1ms) - 能量检测窗口
	ATt = drc_init_struct.ATt;     // 峰值攻击时间(1ms) - 瞬态响应速度
	RTt = drc_init_struct.RTt;    // 峰值释放时间(5s) - 峰值保持时间 -推荐 1-10s 单位ms

	// ========================
	// 动态范围阈值(单位: dB)
	// ========================
	NT = drc_init_struct.NT;  // 噪声门阈值(-35dB)
	ET = drc_init_struct.ET;  // 扩展器阈值(-30dB)
	CT = drc_init_struct.CT;   // 压缩器阈值(-6dB)
	LT = drc_init_struct.LT;   // 限幅器阈值(-3dB)

	// ========================
	// 动态范围比率
	// ========================
	NR = drc_init_struct.NR;   // 噪声门比率(0.1:1)
	ER = drc_init_struct.ER;  // 扩展器比率(0.75:1)
	CR = drc_init_struct.CR;     // 压缩器比率(2:1)
	LR = drc_init_struct.LR;     // 限幅器比率(∞:1)

	// ========================
	// 高级参数
	// ========================
	hyst = drc_init_struct.hyst;  // 滞后曲线宽度(0.1) - 防止阈值附近振荡


    int i = 0;

    // ===========================================
    // 1. 动态范围斜率参数计算(定点数转换)
    // ===========================================
    // 噪声门斜率(16位定点数)
    NS = (1 - 1.0 / NR) * ((int)1 << 16);
    // 扩展器斜率(16位定点数)
    ES = (1 - 1.0 / ER) * ((int)1 << 16);
    // 压缩器斜率(16位定点数)
    CS = (1 - 1.0 / CR) * ((int)1 << 16);
    // 限幅器斜率(16位定点数)
    LS = (1 - 1.0 / LR) * ((int)1 << 16);

    // 滞后参数转换(DEFINEQNUM精度定点数)
    hystD = hyst * (0X01 << DEFINEQNUM);

    // ===========================================
    // 2. 时间常数计算(基于采样率)
    // ===========================================
    // RMS平均时间常数(指数衰减模型)
    // 公式：TAV = [1 - exp(-2.2/(fs * (AVt/1000.0))] * (1<<DEFINEQNUM)*4
    TAV=(1-exp((-2.2*(1.0/fs))/(AVt/1000.0)))*(0X01<<DEFINEQNUM)*4;

    // 峰值检测攻击时间常数
    AT=(1-exp((-2.2*(1.0/fs))/(ATt/1000.0)))*(0X01<<DEFINEQNUM)*4;

    // 峰值检测释放时间常数
    RT=(1-exp((-2.2*(1.0/fs))/(RTt/1000.0)))*(0X01<<DEFINEQNUM)*4;

    // 主处理攻击时间常数
    ATD=(1-exp((-2.2*(1.0/fs))/(ATtd/1000.0)))*(0X01<<DEFINEQNUM)*4;

    // 主处理释放时间常数
    RTD=(1-exp((-2.2*(1.0/fs))/(RTtd/1000.0)))*(0X01<<DEFINEQNUM)*4;

    // ===========================================
    // 3. 动态阈值转换(dB到线性定点数)
    // ===========================================

//    // 限幅器阈值转换：dB -> 线性幅度 -> 16位定点数
//    // 公式：20*log10(x) = dB => x = 10^(dB/20)
//    LT_C = (LT / (log10(2) * 20.0) + DEFINEQNUM) * ((int)1 << 16);
//    // 压缩器阈值转换
//    CT_C = (CT / (log10(2) * 20.0) + DEFINEQNUM) * ((int)1 << 16);
//    // 扩展器阈值转换
//    ET_C = (ET / (log10(2) * 20.0) + DEFINEQNUM) * ((int)1 << 16);
//    // 噪声门阈值转换
//    NT_C = (NT / (log10(2) * 20.0) + DEFINEQNUM) * ((int)1 << 16);


    LT_C = (LT/log10(2)/20.0+DEFINEQNUM)*((int)1<<16);
    CT_C = (CT/log10(2)/20.0+DEFINEQNUM)*((int)1<<16);
    ET_C = (ET/log10(2)/20.0+DEFINEQNUM)*((int)1<<16);
    NT_C = (NT/log10(2)/20.0+DEFINEQNUM)*((int)1<<16);

    // ===========================================
    // 4. 状态变量初始化
    // ===========================================
    for(i = 0; i < MAXCHANNEL; i++)
    {
        // 初始化RMS能量为1.0 (Q格式表示)
        xrms[i] = 0x01 << DEFINEQNUM;

        // 初始化峰值检测为1.0 (Q格式表示)
        xpeak[i] = 0x01 << DEFINEQNUM;

        // 重置当前增益
        f[i] = 0;

        // 重置平滑后增益
        g[i] = 0;
    }

    // ===========================================
    // 5. 高通滤波器系数选择与转换
    // ===========================================
    // 根据采样率选择对应的滤波器系数集
    if(fs >= 96000) {
        i = SAMPLERATE_FORMAT_96000;      // 96kHz
    }
    else if(fs >= 48000) {
        i = SAMPLERATE_FORMAT_48000;      // 48kHz
    }
    else if(fs >= 44100) {
        i = SAMPLERATE_FORMAT_44100;      // 44.1kHz
    }
    else if(fs >= 32000) {
        i = SAMPLERATE_FORMAT_32000;      // 32kHz
    }
    else if(fs >= 24000) {
        i = SAMPLERATE_FORMAT_24000;      // 24kHz
    }
    else if(fs >= 22050) {
        i = SAMPLERATE_FORMAT_22050;      // 22.05kHz
    }
    else if(fs >= 16000) {
        i = SAMPLERATE_FORMAT_16000;      // 16kHz
    }
    else if(fs >= 12000) {
        i = SAMPLERATE_FORMAT_12000;      // 12kHz
    }
    else if(fs >= 11025) {
        i = SAMPLERATE_FORMAT_11025;      // 11.025kHz
    }
    else {
        i = SAMPLERATE_FORMAT_8000;       // 8kHz
    }

    // 将浮点系数转换为DEFINEHIGHPASS精度的定点数
    alpha = coeffnum[i].alphaf * (1 << DEFINEHIGHPASS);
    beta  = coeffnum[i].betaf * (1 << DEFINEHIGHPASS);
    gammaD = coeffnum[i].gammaf * (1 << DEFINEHIGHPASS);

    // ===========================================
    // 6. 高通滤波器历史状态初始化
    // ===========================================
    for(i = 0; i < MAXCHANNEL; i++)
    {
        // 重置滤波器输出历史
        yhigh[i][0] = 0;  // y(n-1)
        yhigh[i][1] = 0;  // y(n-2)

        // 重置滤波器输入历史
        xhigh[i][0] = 0;  // x(n-1)
        xhigh[i][1] = 0;  // x(n-2)
    }
}

//int y[SAMPLENUM];

#define kLn2 0.69315  // ln(2)的近似值，用于对数/指数计算

// 对数表 - 用于log2计算的泰勒展开系数(16位小数精度)
static const int log2table[3] = {
    QCONST32(1/kLn2,16),       // 1/ln(2) ≈ 1.442695
    QCONST32(1/(kLn2*2),16),   // 1/(2*ln(2)) ≈ 0.7213475
    QCONST32(1/(kLn2*3),16)    // 1/(3*ln(2)) ≈ 0.480898
};

/**
 * 计算32位无符号整数的log2(定点数)
 * @param x 输入值(32位无符号整数)
 * @return log2(x)的定点数结果(Q16格式)
 */
static int spx_flog2(spx_uint32_t x)
{
    // 1. 计算整数部分: index = floor(log2(x))
    int index = spx_ilog2(x);  // 返回最高位位置(如x=5(101b)返回2)

    // 2. 提取小数部分: 归一化到[1,2)区间
    //    x1 = (x - 2^index) / 2^index  (Q14格式)
    int x1 = SH32((x - (1 << index)), 14 - index);

    // 3. 计算多项式展开项
    int x2 = MULT32_32_Q14(x1, x1);   // x1^2 (Q14)
    int x3 = MULT32_32_Q14(x1, x2);   // x1^3 (Q14)

    // 4. 泰勒级数展开: log2(1+x1) ≈
    //    (1/ln2)*x1 - (1/(2*ln2))*x1^2 + (1/(3*ln2))*x1^3
    int xt = MULT32_32_Q14(log2table[0], x1)  // 第一项
           - MULT32_32_Q14(log2table[1], x2)  // 第二项
           + MULT32_32_Q14(log2table[2], x3); // 第三项

    // 5. 组合结果: log2(x) = index + log2(1+x1)
    xt = xt + (index << 16);  // 整数部分左移16位(Q16格式)
    return xt;
}

// 指数表 - 用于2^x计算的泰勒展开系数(14位小数精度)
int pow2table[4] = {
    QCONST32(1,14),                   // 常数项: 1
    QCONST32(kLn2,14),                // 线性项: ln(2)
    QCONST32(kLn2*kLn2/2,14),         // 二次项: (ln2)^2/2
    QCONST32(kLn2*kLn2*kLn2/6,14)     // 三次项: (ln2)^3/6
};

/**
 * 计算2^x (定点数指数函数)
 * @param xfrac 输入值(Q16格式定点数)
 * @return 2^x的定点数结果
 */
static int pow2(int xfrac)
{
    // 1. 分离整数和小数部分
    int xint = xfrac >> 16;    // 整数部分
    int x = xfrac & 0xffff;    // 小数部分(0 ≤ x < 1)
    int square = 0;            // 平方标志

    // 2. 收敛加速: 若小数部分≥0.5则减半处理
    int xt = ABS32(x);         // 取绝对值(实际x始终正)
    if(xt & 0x8000) {          // 检查是否≥0.5(0x8000=0.5)
        x >>= 1;               // 小数部分减半
        square = 1;            // 设置平方标志
    }

    // 3. 计算多项式项
    int x2 = MULT32_32_Q16(x, x);     // x^2 (Q16)
    int x3 = MULT32_32_Q16(x2, x);    // x^3 (Q16)

    // 4. 泰勒级数展开: 2^x = e^(x*ln2) ≈
    //    1 + (ln2)x + (ln2)^2/2! x^2 + (ln2)^3/3! x^3
    xt = pow2table[0]                         // 常数项
        + MULT32_32_Q16(pow2table[1], x)      // 线性项
        + MULT32_32_Q16(pow2table[2], x2)     // 二次项
        + MULT32_32_Q16(pow2table[3], x3);    // 三次项

    // 5. 处理减半部分: 若之前减半则平方结果
    if(square) {
        xt = MULT32_32_Q14(xt, xt);  // 平方运算(2^x = [2^(x/2)]^2)
    }

    // 6. 结果调整
    xt = xt << 15;         // 转换为Q15格式(左移15位)
    xt = SH32(xt, xint);   // 乘以2^(整数部分)
    return xt;
}


/**
 * DRC音频处理主函数
 * @param xout     音频数据缓冲区(输入输出)
 * @param samplenum 每通道采样数
 * @param nch      通道数
 */
void drcdec(short* xout, int samplenum, int nch)
{
    int j = 0;
    int rf = 0;       // 原始增益调整值
    int k = 0;        // 时间常数选择
    int len = samplenum;  // 处理长度
    int temp = 0;     // 临时计算值
    int channel = 0;  // 通道索引

    // 状态变量(双通道处理)
    int xrms1 = 0, xrms0 = 0;  // RMS能量状态(新/旧)
    int xpeak1 = 0, xpeak0 = 0;// 峰值状态(新/旧)
    int f0 = 0, f1 = 0;        // 当前增益(新/旧)
    int g0 = 0, g1 = 0;        // 平滑后增益(新/旧)
    int gtmp;                  // 增益临时变量
    short *x = 0;              // 当前采样指针

    // ===========================================
    // 1. 高通滤波预处理
    // ===========================================
    // 去除直流偏移和低频噪声
    highpass(xout, samplenum, nch);

    // ===========================================
    // 2. DRC主处理循环
    // ===========================================
    x = xout;  // 指向缓冲区起始位置

    // 加载初始状态
    xrms0 = xrms[0];   // 前一帧的RMS能量
    xpeak0 = xpeak[0]; // 前一帧的峰值
    f0 = f[0];         // 前一帧的增益
    g0 = g[0];         // 前一帧的平滑增益

    // 逐采样处理
    for(j = 0; j < len; j++)
    {
        // 2.1 多通道能量计算(双通道时取平均值)
        temp = *x;  // 当前通道值
        if(nch == 2) {
            temp += *(x + 1);  // 双通道时求和
        }

        // 2.2 RMS能量更新(一阶递归滤波器)
        // 公式: xrms[n] = (1-2α)xrms[n-1] + α*(x[n]^2)
        xrms1 = xrms0 - MULSHIFT32(TAV, xrms0 * 2)
               + MULSHIFT32(TAV, (int)(temp) * (temp));

        // 2.3 峰值检测更新
#ifdef MODIFIED_PEAKDETECT  // 改进的峰值检测算法
        if(xpeak0 > abs((int)(temp)) << 14) {
            // 释放阶段: 峰值衰减
            xpeak1 = xpeak0 - MULSHIFT32(RT, xpeak0 * 2);
        } else {
            // 攻击阶段: 跟踪新峰值
            xpeak1 = xpeak0 - MULSHIFT32(AT, xpeak0 * 2)
                    + MULSHIFT32(AT, abs((int)(temp)) << 15);
        }
#else  // 传统峰值检测
        xpeak1 = xpeak0 - MULSHIFT32((AT + RT) * 2, xpeak0)
                + MULSHIFT32(AT, abs((int)(temp)) << 15);
#endif

        // 2.4 能量对数转换(用于DRC阈值判断)
#ifdef MODIFIED_PRECISION  // 高精度对数计算
        lpeak = spx_flog2(xpeak1);  // 峰值对数(Q16格式)
        lrms = spx_flog2(xrms1);    // RMS对数(Q16格式)
        lrms = (lrms >> 1) + (DEFINEQNUM << 15); // 调整格式
#else  // 传统对数近似
        lpeak = spx_ilog2(xpeak1) << 16;  // 峰值对数(近似)
        lrms = spx_ilog2(xrms1) << 16;    // RMS对数(近似)
#endif

        // 2.5 更新状态变量
        xrms0 = xrms1;
        xpeak0 = xpeak1;

        // 2.6 动态增益计算(根据能量区域)
#ifndef ONLY_PEAK_OR_RMS  // 使用RMS和峰值组合判断

        // 峰值仅用于计算限幅器区域
        if(lpeak >= LT_C && Limiter == 1) {
            // 限幅器区域(防止削波)
            rf = MULT32_32_Q16(-LS, (lpeak - LT_C))
                + MULT32_32_Q16(CS, (CT_C - LT_C));
        } else if(lrms >= CT_C && Compressor == 1) {
            // 压缩器区域(降低动态范围)
            rf = MULT32_32_Q16(-CS, (lrms - CT_C));
        } else if(lrms > ET_C && lrms < CT_C) {
            // 无处理区域(保持原始动态)
            rf = 0;
        } else if(lrms < ET_C && lrms > NT_C && Expander == 1) {
            // 扩展器区域(提升低电平)
            rf = MULT32_32_Q16(-ES, (lrms - ET_C));
        } else if(lrms <= NT_C && NoiseGate == 1) {
            // 噪声门区域(消除背景噪声)
            rf = MULT32_32_Q16(-NS, (lrms - NT_C))
                + MULT32_32_Q16(ES, (ET_C - NT_C));
        } else {
            rf = 0;
        }
#else  // 仅使用峰值或RMS单一检测
        // (省略类似分支结构)
#endif

        // 2.7 增益转换(dB到线性)
#ifdef MODIFIED_PRECISION
        f1 = pow2(rf);  // 高精度指数计算(2^rf)
#else
        f1 = 1 << ((int)rf + DEFINEQNUM);  // 近似计算
#endif

        // 2.8 增益平滑处理(应用时间常数)
        if(f0 - f1 < hystD) {
            // 增益增加时使用释放时间常数(平滑变化)
            k = RTD;
        } else {
            // 增益减少时使用攻击时间常数(快速响应)
            k = ATD;
        }

        // 2.9 更新增益状态
        f0 = f1;  // 当前增益

        // 一阶递归平滑: g[n] = (1-k)*g[n-1] + k*f[n]
        g1 = g0 + MULSHIFT32(k * 2, f1 - g0);
        g0 = g1;  // 更新平滑增益

        // 2.10 应用增益到音频数据
        for(channel = 0; channel < nch; channel++) {
            // 增益应用: sample * gain
            temp = MULSHIFT32((int)(*x) * 8, g1);

            // 饱和处理(防止16位溢出)
            if(temp > 0x7fff) {
                temp = 0x7fff;  // 正极限值(32767)
            } else if(temp < -32768) {
                temp = -32768;  // 负极限值(-32768)
            }

            // 写回处理后的采样值
            *x = (short)temp;
            x++;  // 移动到下一采样
        }
    }

    // ===========================================
    // 3. 保存状态供下一帧使用
    // ===========================================
    xrms[0] = xrms1;    // 保存RMS能量状态
    xpeak[0] = xpeak1;  // 保存峰值状态
    f[0] = f1;          // 保存当前增益
    g[0] = g1;          // 保存平滑增益
}
