chenlh
2026-01-28 8758151dcdb0f89e362dd297405a384d3a034380
src/tg/tg_user_ctrl.cpp
@@ -8,19 +8,22 @@
#include "IModule.h"
#include "module_def.h"
#include "tg_user_ctrl.h"
#include "tg_scene.h"
#include "../var_state.h"
#include "../ModuleExport.h"
u32 tg_param_ctrl::Signalgen_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num)
u32 tg_param_ctrl::Signalgen_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param)
{
   enum SGItemType{
      SG_MUTE = 0x1,
      SG_TYPE ,
      SG_REQ ,
      SG_FREQ ,
      SG_GAIN,
   };
   short val[4];
   int channel = val_c[0]&(MAX_INPUT_NUM-1);
   int channel = RESSIGNBIT(val_c[0]); //&(MAX_INPUT_NUM-1);
   if(pID == INPUT_TYPE) {//signal gen
      if(val_c[1] > 3) {
@@ -40,47 +43,91 @@
   }
   else if(pID == INPUT_FREQ) {
      val[0] = channel;  val[1] = RESSIGNBIT(val_c[1]);
      m->Ctrl(SG_REQ, val, 2);
      m->Ctrl(SG_FREQ, val, 2);
   }
   else if(pID == INPUT_LEVEL) {
      val[0] = channel;  val[1] = RESSIGNBIT(val_c[1]);
      m->Ctrl(SG_GAIN, val, 2);
   }
   // copy the channel params.
   ptag_input psg = (ptag_input)param;
   switch(pID) {
      case SG_MUTE:
         psg->input[channel].mute = val[1];
         break;
      case SG_TYPE:
         psg->input[channel].type = val[1];
         break;
      case SG_FREQ:
         psg->input[channel].freq = val[1];
         break;
      case SG_GAIN:
         psg->input[channel].level = val[1];
         break;
      default:
         break;
   }
   return 0;
}
u32 tg_param_ctrl::Input_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num)
u32 tg_param_ctrl::Input_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param)
{
   enum Input_ID{
      GAIN = 0x1,
      MUTE,
      SENSI,
      PHANTOM,
      TYPE,
   enum SigSrcID {
            GAIN = 0x1,        //val[0]: 通道号,val[1] : 增益 ,乘以100 , 范围: -7200 ~ 1200
            MUTE,             //val[0]: 通道号,val[1] : 静音 , 0-取消静音,1-静音
            SENSI,
            PHANTO,
            SIGNAL_TYPE = 5,
      FREQ,
      LEVEL,
      NAME,
      PHASE,
      STEP,
      LINK,
      CHANNEL_LEVEL,
      INPUT_MIN,
      INPUT_MAX,
   };
            GENERATE_FREQ,
            GENERATE_LEVEL,
            PHASE = 9, //val[0]: 通道号,val[1] : 反相 , 0-取消反相, 1-反相
            STEP,
         };
   short val[4];
   int channel = val_c[0];//&(MAX_INPUT_NUM-1);
   int channel = RESSIGNBIT(val_c[0]);//&(MAX_INPUT_NUM-1);
   val[0] = channel;  val[1] = RESSIGNBIT(val_c[1]);
   m->Ctrl(pID, val, 2);
   ptag_input pin = (ptag_input)param;
   switch(pID) {
      case GAIN:
         pin->input[channel].gain = val[1];
         break;
      case MUTE:
         pin->input[channel].mute = val[1];
         break;
      case SENSI:
         pin->input[channel].sensitivity = val[1];
         break;
      case PHANTO:
         pin->input[channel].phant = val[1];
         break;
      case SIGNAL_TYPE:
         pin->input[channel].type = val[1];
         break;
      case GENERATE_FREQ:
         pin->input[channel].freq = val[1];
         break;
      case GENERATE_LEVEL:
         pin->input[channel].level = val[1];
         break;
      case PHASE:
         pin->input[channel].phase = val[1];
         break;
      case STEP:
         pin->input[channel].gain += val[1];
         break;
      default:
         break;
   }
   return 0;
}
u32 tg_param_ctrl::Gain_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num)
u32 tg_param_ctrl::Gain_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param)
{
   enum GainID {
      GAIN = 0x1,
@@ -103,13 +150,13 @@
   return 0;
}
u32 tg_param_ctrl::Output_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num)
u32 tg_param_ctrl::Output_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param)
{
   enum GainID {
      GAIN = 0x1,
      MUTE,
      SENSI,
      PHANTOM,
      PHANTO,
      PHASE = 9,
      STEP,
@@ -124,10 +171,30 @@
   m->Ctrl(cmd[pID-1], val, 2);
   ptag_output pin = (ptag_output)param;
   switch(pID) {
      case GAIN:
         pin->output[channel].gain = val[1];
         break;
      case MUTE:
         pin->output[channel].mute = val[1];
         break;
      case SENSI:
         pin->output[channel].sensitivity = val[1];
         break;
      case PHASE:
         pin->output[channel].phase = val[1];
         break;
      case STEP:
         pin->output[channel].gain += val[1];
         break;
      default:
         break;
   }
   return 0;
}
u32 tg_param_ctrl::Mixer_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num)
u32 tg_param_ctrl::Mixer_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param)
{
   short val[4];
@@ -149,7 +216,7 @@
   return 0;
}
u32 tg_param_ctrl::Crossover_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num)
u32 tg_param_ctrl::Crossover_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param)
{
   enum CFilterID {
      _BYPASS = 0x1,
@@ -173,37 +240,32 @@
   m->Ctrl(pID, val, 2);
   // copy the ctrl params
   ptag_module pmodu = (ptag_module)param;
   ptag_crossover pxov = (ptag_crossover)pmodu->proc_ins;
   switch(pID) {
      case _BYPASS:
         (0==val[0]) ? (pxov->lowpass.bypass = val[1]) : (pxov->highpass.bypass = val[1]);
         break;
      case _TYPE:
         (0==val[0]) ? (pxov->lowpass.type = val[1]) : (pxov->highpass.type = val[1]);
         break;
      case _TAPS:
         (0==val[0]) ? (pxov->lowpass.taps = val[1]) : (pxov->highpass.taps = val[1]);
         break;
      case _FREQ:
         (0==val[0]) ? (pxov->lowpass.freq = val[1]) : (pxov->highpass.freq = val[1]);
         break;
      case _GAIN:
         (0==val[0]) ? (pxov->lowpass.gain = val[1]) : (pxov->highpass.gain = val[1]);
         break;
      default:
         break;
   }
   return 0;
}
u32 tg_param_ctrl::Feedback_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num)
{
   enum NHSID{
      FB_BYPASS= 0x1,
      FB_FLT_FREQ,
      FB_FLT_GAIN,
      FB_FLT_Q,
      FB_FLT_TYPE,
      FB_STEP,
      FB_CLEAR,
      FB_PANIC,
      FB_FLT_DEPTH,
      FB_THRS,
   };
   short val[4];
//   short cmd[16] = {FB_BYPASS, FB_FLT_FREQ, FB_FLT_GAIN, FB_FLT_Q, FB_FLT_TYPE, FB_STEP,\
//         FB_CLEAR, FB_PANIC, FB_FLT_DEPTH, FB_THRS, 0, 0 ,0 ,0 ,0 ,0 };
   val[0] = RESSIGNBIT(val_c[0]); val[1] = RESSIGNBIT(val_c[1]);
   m->Ctrl(pID, val, 2);
   return 0;
}
u32 tg_param_ctrl::Automixer_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num)
u32 tg_param_ctrl::Automixer_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param)
{
   enum GainSharingAMID {
      AM_BYPASS =0x1,
@@ -227,7 +289,7 @@
   return 0;
}
u32 tg_param_ctrl::Aec_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num)
u32 tg_param_ctrl::Aec_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param)
{
   enum AECID{
     BYPASS = 0X1,
@@ -254,7 +316,7 @@
   return 0;
}
u32 tg_param_ctrl::Sysctl_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num)
u32 tg_param_ctrl::Sysctl_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param)
{
   enum SYSCTRLID{
      SYSCTL_MUTE = 0x1, //val[0]:0-unmute,1-mute
@@ -270,27 +332,7 @@
   return 0;
}
u32 tg_param_ctrl::Geq_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num)
{
   enum GEQID{
      GEQ_BYPASS_ALL = 0x1,//val[0]: 0-取消bypass, 1- 使能bypass
      GEQ_QVALUE,//val[0]: 1-narrow, 2-normal, 3-wide
      GEQ_GAIN,//val[0]: 段序号,val[1] : 增益,乘以100,范围:-4800~2400
      GEQ_CLEAR,//val[0]: 复位EQ参数
   };
   short val[4];
   short cmd[8] = {0, GEQ_BYPASS_ALL, GEQ_QVALUE, GEQ_GAIN, GEQ_CLEAR};
   val[0] = RESSIGNBIT(val_c[0]);
   val[1] = RESSIGNBIT(val_c[1]);
   m->Ctrl(cmd[pID], val, 2);
   return 0;
}
u32 tg_param_ctrl::Reverb_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num)
u32 tg_param_ctrl::Reverb_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param)
{
   short val[4];
@@ -302,7 +344,7 @@
   return 0;
}
u32 tg_param_ctrl::Echo_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num)
u32 tg_param_ctrl::Echo_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param)
{
   enum EchoID{
      ECHO_BYPASS = 1,
@@ -322,20 +364,46 @@
   return 0;
}
u32 tg_param_ctrl::General_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num)
u32 tg_param_ctrl::Geq_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param)
{
   enum GEQID{
      GEQ_BYPASS_ALL = 0x1,//val[0]: 0-取消bypass, 1- 使能bypass
      GEQ_QVALUE,//val[0]: 1-narrow, 2-normal, 3-wide
      GEQ_GAIN,//val[0]: 段序号,val[1] : 增益,乘以100,范围:-4800~2400
      GEQ_CLEAR,//val[0]: 复位EQ参数
   };
   short val[4];
   short cmd[8] = {0, GEQ_BYPASS_ALL, GEQ_QVALUE, GEQ_GAIN, GEQ_CLEAR};
   val[0] = RESSIGNBIT(val_c[0]);
   val[1] = RESSIGNBIT(val_c[1]);
   m->Ctrl(pID, val, 2);
//   dbg_printf("pID:%d v[0]:%d v[1]:%d\n", pID, val[0], val[1]);
   m->Ctrl(cmd[pID], val, 2);
   // save the modul param
   ptag_module pmodu = (ptag_module)param;
   ptag_geq pgeq = (ptag_geq)pmodu->proc_ins;
   switch(pID) {
      case GEQ_BYPASS_ALL:
         pgeq->bypass = val[0];
         break;
      case GEQ_QVALUE:
         pgeq->q_index = val[0];
         break;
      case GEQ_GAIN:
         if (val[0] < 31)
            pgeq->eq_attr[val[0]].gain = val[1];
         break;
      default:
         break;
   }
   return 0;
}
u32 tg_param_ctrl::Fir_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num)
u32 tg_param_ctrl::Fir_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param)
{
   enum FIRID {
      FIR_BYPASS = 0x1,  ////val[0]: 0-取消bypass, 1- 使能bypass
@@ -353,58 +421,432 @@
      m->Ctrl(pID, val_c, num);
   }
   ptag_module pmodu = (ptag_module)param;
   ptag_fir pfir = (ptag_fir)pmodu->proc_ins;
   switch(pID) {
      case FIR_BYPASS:
         pfir->bypass = val[0];
         break;
      case FIR_COEFFS:
         memcpy((void*)&pfir->coeffs, val_c, num * sizeof(*val_c));
         break;
      default:
         break;
   }
   return 0;
}
u32 tg_param_ctrl::Spl_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num)
u32 tg_param_ctrl::General_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param)
{
   enum ContinousSPLID {
      SPL_BYPASS = 0x1,
   short val[4];
   val[0] = RESSIGNBIT(val_c[0]);
   val[1] = RESSIGNBIT(val_c[1]);
   m->Ctrl(pID, val, 2);
//   dbg_printf("pID:%d v[0]:%d v[1]:%d\n", pID, val[0], val[1]);
   return 0;
}
u32 tg_param_ctrl::Agc_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param)
{
   General_Ctrl(m, pID, val_c, num, param);
   enum AGCID {
      AGC_BYPASS = 0x1, //val[0]:0-取消bypass,1-bypass
      AGC_NOISE_THR, //val[0]: 阈值,乘以100,范围:-9600~-2000
      AGC_TARGET_LEVEL, //val[0]:目标阈值,乘以100,范围-4000~0
      AGC_RATIO, //val[0]:比率,乘以100,范围1-10000.
      AGC_ATTACKTIME, //val[0]:建立时间,范围1~2000
      AGC_RELEASETIME, //val[0]:释放时间,范围1~2000
   };
   short val[4];
   val[0] = RESSIGNBIT(val_c[0]);
   // save the modul param
   ptag_module pmodu = (ptag_module)param;
   ptag_agc pagc = (ptag_agc)pmodu->proc_ins;
   switch(pID) {
      case AGC_BYPASS:
         pagc->bypass = val[0];
         break;
      case AGC_NOISE_THR:
         pagc->threshold = val[0];
         break;
      case AGC_TARGET_LEVEL:
         pagc->tar_threshold = val[0];
         break;
      case AGC_RATIO:
         pagc->ratio = val[0];
         break;
      case AGC_ATTACKTIME:
         pagc->attacktime = val[0];
         break;
      case AGC_RELEASETIME:
         pagc->releasetime = val[0];
         break;
      default:
         break;
   }
   return 0;
}
u32 tg_param_ctrl::Peq_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param)
{
   General_Ctrl(m, pID, val_c, num, param);
   enum PEQID{
      EQ_BYPASS_ALL = 0x1,//val[0]: 0-取消bypass, 1- 使能bypass
      EQ_BYPASS,//val[0]: 段序号,val[1] : 0-取消bypass, 1- 使能bypass
      EQ_FREQ,//val[0]: 段序号,val[1] : 频率, 范围:20-20K
      EQ_GAIN,//val[0]: 段序号,val[1] : 增益,乘以100,范围:-4800~2400
      EQ_QVALUE,//val[0]: 段序号,val[1] :Q值,乘以100,范围1~5000
      EQ_TYPE,//val[0]: 段序号,val[1] : EQ类型 范围参考枚举类型EQType定义
      EQ_CLEAR,//val[0]: 复位EQ参数
   };
   short val[4];
   val[0] = RESSIGNBIT(val_c[0]);
   val[1] = RESSIGNBIT(val_c[1]);
   // save the modul param
   ptag_module pmodu = (ptag_module)param;
   ptag_eq pexp = (ptag_eq)pmodu->proc_ins;
   switch(pID) {
      case EQ_BYPASS_ALL:
         pexp->bypass = val[0];
         break;
      case EQ_BYPASS:
         pexp->eq_attr[val[0]].bypass = val[1];
         break;
      case EQ_FREQ:
         pexp->eq_attr[val[0]].freq = val[1];
         break;
      case EQ_GAIN:
         pexp->eq_attr[val[0]].gain = val[1];
         break;
      case EQ_QVALUE:
         pexp->eq_attr[val[0]].q = val[1];
         break;
      case EQ_TYPE:
         pexp->eq_attr[val[0]].type = val[1];
         break;
      default:
         break;
   }
   return 0;
}
u32 tg_param_ctrl::Expander_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param)
{
   General_Ctrl(m, pID, val_c, num, param);
   enum ExpanderID{
      EXPANDER_BYPASS = 0x1,
      EXPANDER_THRESHOLD,
      EXPANDER_RADIO,
      EXPANDER_ATTACK,
      EXPANDER_RELEASE,
   };
   short val[4];
   val[0] = RESSIGNBIT(val_c[0]);
   // save the modul param
   ptag_module pmodu = (ptag_module)param;
   ptag_expander pexp = (ptag_expander)pmodu->proc_ins;
   switch(pID) {
      case EXPANDER_BYPASS:
         pexp->bypass = val[0];
         break;
      case EXPANDER_THRESHOLD:
         pexp->threshold = val[0];
         break;
      case EXPANDER_RADIO:
         pexp->ratio = val[0];
         break;
      case EXPANDER_ATTACK:
         pexp->attack = val[0];
         break;
      case EXPANDER_RELEASE:
         pexp->release = val[0];
         break;
      default:
         break;
   }
   return 0;
}
u32 tg_param_ctrl::CompAndLimt_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param)
{
   General_Ctrl(m, pID, val_c, num, param);
   enum CompressorID {
      COMPRESS_BYPASS = 0x1,
      COMPRESS_THERSHOLD,
      COMPRESS_RADIO,
      COMPRESS_ATTACK,
      COMPRESS_RELEASE,
      COMPRESS_GAIN,
   };
   short val[4];
   val[0] = RESSIGNBIT(val_c[0]);
   // save the modul param
   ptag_module pmodu = (ptag_module)param;
   ptag_compress pco2li = (ptag_compress)pmodu->proc_ins;
   switch(pID) {
      case COMPRESS_BYPASS:
         pco2li->bypass = val[0];
         break;
      case COMPRESS_THERSHOLD:
         pco2li->threshold = val[0];
         break;
      case COMPRESS_RADIO:
         pco2li->ratio = val[0];
         break;
      case COMPRESS_ATTACK:
         pco2li->attack = val[0];
         break;
      case COMPRESS_RELEASE:
         pco2li->release = val[0];
         break;
      case COMPRESS_GAIN:
         pco2li->gain = val[0];
         break;
      default:
         break;
   }
   return 0;
}
u32 tg_param_ctrl::Delay_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param)
{
   General_Ctrl(m, pID, val_c, num, param);
   enum DelayID {
      DELAY_BYPASS = 0x1,
      DELAY_MSEC,
   };
   short val[4];
   val[0] = RESSIGNBIT(val_c[0]);
   ptag_module pmodu = (ptag_module)param;
   ptag_delay pdelay = (ptag_delay)pmodu->proc_ins;
   switch(pID) {
      case DELAY_BYPASS:
         pdelay->bypass = val[0];
         break;
      case DELAY_MSEC:
         pdelay->ms = val[0];
         break;
      default:
         break;
   }
   return 0;
}
u32 tg_param_ctrl::Gating_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param)
{
   General_Ctrl(m, pID, val_c, num, param);
   enum NoiseGateID {
      GATE_BYPASS = 0x1, //val[0]:0-取消bypass, 1-使能bypass
      GATE_THRESHOLD,//val[0]:阈值,乘以100,范围-9600~0
      GATE_DEPTH, //val[0]:深度,乘以100,范围-7200~0
      GATE_HOLDTIME, //val[0]: 保持时间,范围1~10000ms
      GATE_ATTACK, //val[0]:建立时间,范围1~2000ms
      GATE_RELEASE,//val[0]:释放时间,范围1~2000ms
   };
   short val[4];
   val[0] = RESSIGNBIT(val_c[0]);
   ptag_module pmodu = (ptag_module)param;
   ptag_gate pgate = (ptag_gate)pmodu->proc_ins;
   switch(pID) {
      case GATE_BYPASS:
         pgate->bypass = val[0];
         break;
      case GATE_THRESHOLD:
         pgate->threshold = val[0];
         break;
      case GATE_DEPTH:
         pgate->depth = val[0];
         break;
      case GATE_HOLDTIME:
         pgate->holdtime = val[0];
         break;
      case GATE_ATTACK:
         pgate->attacktime = val[0];
         break;
      case GATE_RELEASE:
         pgate->releasetime = val[0];
         break;
      default:
         break;
   }
   return 0;
}
u32 tg_param_ctrl::Feedback_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param)
{
   General_Ctrl(m, pID, val_c, num, param);
   enum NHSID{
      FB_BYPASS= 0x1,
      FB_FLT_FREQ,
      FB_FLT_GAIN,
      FB_FLT_Q,
      FB_FLT_TYPE,
      FB_STEP,
      FB_CLEAR,
      FB_PANIC,
      FB_FLT_DEPTH,
      FB_THRS,
   };
   short val[4];
   val[0] = RESSIGNBIT(val_c[0]);
   val[1] = RESSIGNBIT(val_c[1]);
   // save the modul param
   ptag_module pmodu = (ptag_module)param;
   ptag_feedback pfb = (ptag_feedback)pmodu->proc_ins;
   switch(pID) {
      case FB_BYPASS:
         pfb->bypass = val[0];
         break;
      case FB_FLT_FREQ:
         pfb->flt_group[val[0]].fc = val[1];
         break;
      case FB_FLT_GAIN:
         pfb->flt_group[val[0]].gain = val[1];
         break;
      case FB_FLT_Q:
         pfb->bw = val[0];
         break;
      case FB_FLT_TYPE:
         pfb->flt_group[val[0]].type = val[1];
         break;
      case FB_STEP:
         pfb->step = val[0];
         break;
      case FB_PANIC:
         pfb->panic_threshold = val[0];
         break;
      case FB_FLT_DEPTH:
         pfb->flt_depth = val[0];
         break;
      case FB_THRS:
         pfb->fb_threshold = val[0];
         break;
      default:
         break;
   }
   return 0;
}
u32 tg_param_ctrl::Ducker_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param)
{
   General_Ctrl(m, pID, val_c, num, param);
   enum DuckerWithMixID {
      DUCKER_BYPASS = 0x1, //val[0]:0-取消bypass,1-使能bypass
      DUCKER_THRESHOLD,//val[0]:阈值,乘以100,范围:-6000~0
      DUCKER_DEPTH,//val[0]:深度,乘以100,范围:-7200~0
      DUCKER_ATTACK,//val[0]:建立时间,范围:1~2000ms
      DUCKER_HOLD,//val[0]:保持时间,范围:1~10000ms
      DUCKER_RELEASE,//val[0]:释放时间,范围:1~60000ms
      DUCKER_SIDE_GAIN,//val[0]:侧链增益,乘以100,范围:-7200~1200
      DUCKER_SIDE_MUTE,//val[0]:侧链静音,0-取消静音,1-静音
      DUCKER_SIDE_MIX,//val[0]:侧链混音,0-取消混音,1-混音
   };
   short val[4];
   val[0] = RESSIGNBIT(val_c[0]);
   val[1] = RESSIGNBIT(val_c[1]);
   ptag_module pmodu = (ptag_module)param;
   ptag_ducker pduck = (ptag_ducker)pmodu->proc_ins;
   switch(pID) {
      case DUCKER_BYPASS:
         pduck->bypass = val[0];
         break;
      case DUCKER_THRESHOLD:
         pduck->threshold = val[0];
         break;
      case DUCKER_DEPTH:
         pduck->depth = val[0];
         break;
      case DUCKER_ATTACK:
         pduck->attacktime = val[0];
         break;
      case DUCKER_HOLD:
         pduck->holdtime = val[0];
         break;
      case DUCKER_RELEASE:
         pduck->releasetime = val[0];
         break;
      case DUCKER_SIDE_GAIN:
         pduck->side_gain = val[0];
         break;
      case DUCKER_SIDE_MUTE:
         pduck->mute = val[0];
         break;
      case DUCKER_SIDE_MIX:
         if (val[1])
            pduck->mask[val[0]/16] |= (1>>(val[0]&15));
         else
            pduck->mask[val[0]/16] &= (0>>(val[0]&15));
         break;
      default:
         break;
   }
   return 0;
}
u32 tg_param_ctrl::Spler_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param)
{
   General_Ctrl(m, pID, val_c, num, param);
   enum ContSplWithMixID {
      SPLMIX_BYPASS = 0x1, //val[0]:0-取消bypass,1-bypass
      SPL_MAX_GAIN,
      SPL_MIN_GAIN,
      SPL_SENSE_RATIO = 4,
      SPL_UPSPEED = 5,
      SPL_DOWNSPEED,
      SPL_SENSE_RATIO,
      SPL_SPEED,
      SPL_TRIM,
      SPL_THR,
      SPL_DISTANCE,
      SPL_MIX,
   };
   enum ContSplWithMixID {
      SPLMIX_BYPASS = 0x1, //val[0]:0-取消bypass,1-bypass
      SPLMIX_MAX_GAIN,
      SPLMIX_MIN_GAIN,
      SPLMIX_SENSE_RATIO,
      SPLMIX_SPEED = 5,
      SPLMIX_TRIM,
      SPLMIX_THR,
      SPLMIX_DISTANCE,
      SPLMIX_MIX,
   };
   s16 val[4];
   val[0] = RESSIGNBIT(val_c[0]), val[0] = RESSIGNBIT(val_c[1]);
   if (pID < 5) {
      General_Ctrl(m, pID, val_c, num);
   }
   else {
      switch (pID) {
         case ContSplWithMixID::SPLMIX_SPEED:
            m->Ctrl(ContinousSPLID::SPL_UPSPEED, val, 1);
            m->Ctrl(ContinousSPLID::SPL_DOWNSPEED, val, 1);
            break;
         case ContSplWithMixID::SPLMIX_TRIM:
            m->Ctrl(ContinousSPLID::SPL_TRIM, val, 1);
            break;
         case ContSplWithMixID::SPLMIX_THR:
            m->Ctrl(ContinousSPLID::SPL_THR, val, 1);
            break;
         case ContSplWithMixID::SPLMIX_DISTANCE:
            m->Ctrl(ContinousSPLID::SPL_DISTANCE, val, 1);
            break;
         default:
            break;
      }
   short val[4];
   val[0] = RESSIGNBIT(val_c[0]);
   val[1] = RESSIGNBIT(val_c[1]);
   ptag_module pmodu = (ptag_module)param;
   ptag_spl pspl = (ptag_spl)pmodu->proc_ins;
   switch(pID) {
      case SPLMIX_BYPASS:
         pspl->bypass = val[0];
         break;
      case SPL_MAX_GAIN:
         pspl->maxgain = val[0];
         break;
      case SPL_MIN_GAIN:
         pspl->mingain = val[0];
         break;
      case SPL_SENSE_RATIO:
         pspl->sense_ratio = val[0];
         break;
      case SPL_SPEED:
         pspl->speed = val[0];
         break;
      case SPL_TRIM:
         pspl->trim = val[0];
         break;
      case SPL_THR:
         pspl->noise_thr = val[0];
         break;
      case SPL_DISTANCE:
         pspl->distance = val[0];
         break;
      case SPL_MIX:
         if (val[1])
            pspl->mask[val[0]/16] |= (1>>(val[0]&15));
         else
            pspl->mask[val[0]/16] &= (0>>(val[0]&15));
         break;
      default:
         break;
   }
   return 0;
}