chenlh
2026-01-28 8758151dcdb0f89e362dd297405a384d3a034380
天宫输入源模块设置时爆音及参数拷贝更新
已修改8个文件
1021 ■■■■ 文件已修改
src/tg/module_def.h 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tg/tg_adapter.cpp 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tg/tg_param_ctrl.cpp 20 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tg/tg_param_ctrl.h 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tg/tg_scene.cpp 208 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tg/tg_scene.h 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tg/tg_user_ctrl.cpp 694 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tg/tg_user_ctrl.h 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/tg/module_def.h
@@ -583,4 +583,11 @@
    int pad;
}tag_dummy, *ptag_dummy;
typedef struct {
    short bOutput;    // 0: input channel; 1: output_channel
    short src_ch_index;    // From zero to start
    short dst_ch_index;    // From zero to start
    short pad;
}tag_ch_param_copy,*ptag_ch_param_copy;
#endif /* MODULE_DEF_H_ */
src/tg/tg_adapter.cpp
@@ -5,7 +5,7 @@
s32 tg_hw_adapter_t::get_physical_channel(s32 input , s32 logic_channel)
{
    if(input) {
        s32 input_num = ana_input_num + dante_input_num ;
        s32 input_num = ana_input_num + dante_input_num;
        if(logic_channel < ana_input_num) {
            //analog
            return logic_channel + 1;
@@ -16,14 +16,13 @@
        }
        else {
            //usb
//            return 17 + (logic_channel - input_num);
            return (logic_channel > input_num) ? 17 : 18;
        }
    }
    else {    //output
        s32 output_num = ana_output_num + dante_output_num ;
        //analog
        s32 output_num = ana_output_num + dante_output_num;
        if(logic_channel < ana_output_num) {
            //analog
            return logic_channel + 1;
        }
        else if(logic_channel < output_num) {
@@ -32,8 +31,7 @@
        }
        else {
            //usb
//            return 17 + (logic_channel - output_num);
            return (logic_channel > output_num) ? 17 : 18;
            return ((logic_channel > output_num) ? 17 : 18);
        }
    }
}
src/tg/tg_param_ctrl.cpp
@@ -3,7 +3,6 @@
#include <stdlib.h>
#include <string.h>
#include "module_def.h"
#include "../ModuleExport.h"
#include "tg_param_ctrl.h"
#include "tg_user_ctrl.h"
#include "tg_param_convert.h"
@@ -14,16 +13,16 @@
{
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_INPUT, ParamEntry(tg_param_convert::InputParamCtrl, tg_param_ctrl::Input_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_OUTPUT, ParamEntry(tg_param_convert::OutputParamCtrl, tg_param_ctrl::Output_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_EQ, ParamEntry(tg_param_convert::EqParamCtrl, tg_param_ctrl::General_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_EXPANDER, ParamEntry(tg_param_convert::ExpanderParamCtrl, tg_param_ctrl::General_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_COMPRESS, ParamEntry(tg_param_convert::CompressParamCtrl, tg_param_ctrl::General_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_LIMIT, ParamEntry(tg_param_convert::LimitParamCtrl, tg_param_ctrl::General_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_EQ, ParamEntry(tg_param_convert::EqParamCtrl, tg_param_ctrl::Peq_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_EXPANDER, ParamEntry(tg_param_convert::ExpanderParamCtrl, tg_param_ctrl::Expander_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_COMPRESS, ParamEntry(tg_param_convert::CompressParamCtrl, tg_param_ctrl::CompAndLimt_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_LIMIT, ParamEntry(tg_param_convert::LimitParamCtrl, tg_param_ctrl::CompAndLimt_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_MIXER, ParamEntry(tg_param_convert::MixerParamCtrl, tg_param_ctrl::Mixer_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_DELAY, ParamEntry(tg_param_convert::DelayParamCtrl, tg_param_ctrl::General_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_DELAY, ParamEntry(tg_param_convert::DelayParamCtrl, tg_param_ctrl::Delay_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_CROSSOVER, ParamEntry(tg_param_convert::CrossoverParamCtrl, tg_param_ctrl::Crossover_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_FEEDBACK, ParamEntry(tg_param_convert::FeedbackParamCtrl, tg_param_ctrl::Feedback_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_AUTOMIXER, ParamEntry(tg_param_convert::AutomixerParamCtrl, tg_param_ctrl::Automixer_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_AGC, ParamEntry(tg_param_convert::AgcParamCtrl, tg_param_ctrl::General_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_AGC, ParamEntry(tg_param_convert::AgcParamCtrl, tg_param_ctrl::Agc_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_AEC, ParamEntry(tg_param_convert::AecParamCtrl, tg_param_ctrl::Aec_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_ANS, ParamEntry(tg_param_convert::AnsParamCtrl, tg_param_ctrl::General_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_SYSCTL, ParamEntry(tg_param_convert::SysctlParamCtrl, tg_param_ctrl::Sysctl_Ctrl)));
@@ -31,10 +30,10 @@
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_ROUTE, ParamEntry(tg_param_convert::EmptyParamCtrl, tg_param_ctrl::General_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_SELECTOR, ParamEntry(tg_param_convert::SelectorParamCtrl, tg_param_ctrl::Mixer_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_GATING_AUTOMIXER, ParamEntry(tg_param_convert::Gating_automixerParamCtrl, tg_param_ctrl::General_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_DUCKER, ParamEntry(tg_param_convert::DuckerParamCtrl, tg_param_ctrl::General_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_DUCKER, ParamEntry(tg_param_convert::DuckerParamCtrl, tg_param_ctrl::Ducker_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_SIGNALGEN, ParamEntry(tg_param_convert::SignalgenParamCtrl, tg_param_ctrl::Signalgen_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_GATING, ParamEntry(tg_param_convert::GatingParamCtrl, tg_param_ctrl::General_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_CONTINUNOUS_SPL, ParamEntry(tg_param_convert::SplParamCtrl, tg_param_ctrl::General_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_GATING, ParamEntry(tg_param_convert::GatingParamCtrl, tg_param_ctrl::Gating_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_CONTINUNOUS_SPL, ParamEntry(tg_param_convert::SplParamCtrl, tg_param_ctrl::Spler_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_GEQ, ParamEntry(tg_param_convert::GeqParamCtrl, tg_param_ctrl::Geq_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_GAIN, ParamEntry(tg_param_convert::GainParamCtrl, tg_param_ctrl::Gain_Ctrl)));
    mctrl_list.insert(std::pair<u32, ParamEntry>((u32)PROC_METER, ParamEntry(tg_param_convert::EmptyParamCtrl, tg_param_ctrl::General_Ctrl)));
@@ -49,3 +48,4 @@
src/tg/tg_param_ctrl.h
@@ -1,7 +1,9 @@
#ifndef PARAMCTRL_H_
#define PARAMCTRL_H_
#include "module_def.h"
#include "../param_ctrl.h"
#include "../ModuleExport.h"
class tg_param_ctrl_t : public param_ctrl_t
{
@@ -9,6 +11,36 @@
public:
    tg_param_ctrl_t();
    template<typename A>
    bool decide_modu_type_equal(A *pmodu, s16 dst_ch, s16 src_ch)
    {
        bool ret = false;
        const auto& dst_module = pmodu[dst_ch];
        const auto& src_module = pmodu[src_ch];
        if (dst_module.proc_type == src_module.proc_type) {
            switch (dst_module.proc_type) {
                case PROC_EQ: {
                    ptag_eq dst_eq = (ptag_eq)&dst_module.proc_ins;
                    ptag_eq src_eq = (ptag_eq)&src_module.proc_ins;
                    ret = (dst_eq->nsection == src_eq->nsection);
                    break;
                }
                case PROC_GEQ: {
                    ptag_geq dst_geq = (ptag_geq)&dst_module.proc_ins;
                    ptag_geq src_geq = (ptag_geq)&src_module.proc_ins;
                    ret = (dst_geq->nsections == src_geq->nsections);
                    break;
                }
                default:
                    ret = true;
                    break;
            }
        }
        return ret;
    }
};
#endif
src/tg/tg_scene.cpp
@@ -7,16 +7,31 @@
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <vector>
#include "tg_scene.h"
#include "../protocol_internal.h"
#include "../ModuleExport.h"
tgScene::~tgScene()
{
    for (s32 i = 0; i < input_num; i++)
        delete chin_mid[i];
    for (s32 i = 0; i < output_num; i++)
        delete chout_mid[i];
    delete chin_mid;
    delete chout_mid;
    paramPtr.clear();
}
tgScene::tgScene(hw_adapter_t* adapter):Scene(adapter)
{
    s32 i;
    s8 inport_str[16],outport_str[16];
    s8 ana_input_num, ana_output_num, loc_input_num, loc_output_num, dante_input_num, dante_output_num ;
    s8 usb_input_num, usb_output_num;
    s16 input_num, output_num ;
//    s16 input_num, output_num ;
    s32 n, new_idx = 300; //ID of the USB channel starts from 300.
    s16 dual_dsp = adapter->get_system_is_dual_dsp();
@@ -29,68 +44,92 @@
    //物理输入共16+16+2
    input_num = ana_input_num + dante_input_num + usb_input_num; //2 USB
    output_num = ana_output_num + dante_output_num + usb_output_num;
    chin_mid = new s32*[input_num];
    chout_mid = new s32*[output_num];
    for (i = 0; i < input_num; i++) {
        chin_mid[i] = new s32[6];
    }
    for (i = 0; i < output_num; i++) {
        chout_mid[i] = new s32[5];
    }
    paramPtr.resize(new_idx + usb_input_num * 5 + usb_output_num * 4, nullptr);
    tgScene_param_default(&parameters);
    sprintf(inport_str, "1-%d", input_num);
    __MADD(299,PROC_INPUT,inport_str,inport_str,0, 1 ,&parameters.input,  0, ModuleInterfaceType::PHY_INPUT);
    __MADD(299, PROC_INPUT,inport_str,inport_str,0, 1 ,&parameters.input,  0, ModuleInterfaceType::PHY_INPUT);
    for (i = 0; i < input_num; i++)
        chin_mid[i][0] = 299;
    sprintf(inport_str, "1-%d", input_num);
    __MADD(298,PROC_METER,inport_str,"",0,1 ,NULL,0, ModuleInterfaceType::SOFT_MODULE); //tag:0-peak,1-rms
    __MADD(298, PROC_METER,inport_str,"",0,1 ,NULL,0, ModuleInterfaceType::SOFT_MODULE); //tag:0-peak,1-rms
    //The number of DSPs is 1, but the number of input and output channels is greater than 16.
    //It only processes analog input and output.
    //However, for the channels that do not need to be processed, the level offset needs to be calculated.
//    if(!dual_dsp && input_num >16) {
//        n = ana_input_num;
//    }
//    else {
//        n= input_num;
//    }
    //expander
    for(s32 i =0 ;i < input_num ; i++) {
        sprintf(inport_str, "%d|", i+1);
        if(i < input_num - usb_input_num)
            __MADD(1+i,PROC_EXPANDER, inport_str, inport_str, 0, 0, &parameters.in1[i], 0, ModuleInterfaceType::SOFT_MODULE);
        else
            __MADD(new_idx++,PROC_EXPANDER, inport_str, inport_str, 0, 0, &parameters.in1[i], 0, ModuleInterfaceType::SOFT_MODULE);
        if(i < input_num - usb_input_num) {
            __MADD(1+i, PROC_EXPANDER, inport_str, inport_str, 0, 0, &parameters.in1[i], 0, ModuleInterfaceType::SOFT_MODULE);
            chin_mid[i][1] = 1+i;
        }
        else {
            __MADD(new_idx, PROC_EXPANDER, inport_str, inport_str, 0, 0, &parameters.in1[i], 0, ModuleInterfaceType::SOFT_MODULE);
            chin_mid[i][1] = new_idx++;
        }
    }
    //compresser
    for(s32 i =0 ;i < input_num ; i++) {
        sprintf(inport_str, "%d|", i+1);
        if(i < input_num - usb_input_num)
            __MADD(33+i,PROC_COMPRESS, inport_str, inport_str, 0, 0, &parameters.in2[i], 0, ModuleInterfaceType::SOFT_MODULE);
        else
            __MADD(new_idx++,PROC_COMPRESS, inport_str, inport_str, 0, 0, &parameters.in2[i], 0, ModuleInterfaceType::SOFT_MODULE);
        if(i < input_num - usb_input_num) {
            __MADD(33+i, PROC_COMPRESS, inport_str, inport_str, 0, 0, &parameters.in2[i], 0, ModuleInterfaceType::SOFT_MODULE);
            chin_mid[i][2] = 33+i;
        }
        else {
            __MADD(new_idx, PROC_COMPRESS, inport_str, inport_str, 0, 0, &parameters.in2[i], 0, ModuleInterfaceType::SOFT_MODULE);
            chin_mid[i][2] = new_idx++;
        }
    }
    //agc
    for(s32 i =0 ;i < input_num ; i++) {
        sprintf(inport_str, "%d|", i+1);
        if(i < input_num - usb_input_num)
            __MADD(65+i,PROC_AGC, inport_str, inport_str, 0, 0, &parameters.in3[i], 0, ModuleInterfaceType::SOFT_MODULE);
        else
            __MADD(new_idx++,PROC_AGC, inport_str, inport_str, 0, 0, &parameters.in3[i], 0, ModuleInterfaceType::SOFT_MODULE);
        if(i < input_num - usb_input_num) {
            __MADD(65+i, PROC_AGC, inport_str, inport_str, 0, 0, &parameters.in3[i], 0, ModuleInterfaceType::SOFT_MODULE);
            chin_mid[i][3] = 65+i;
        }
        else {
            __MADD(new_idx, PROC_AGC, inport_str, inport_str, 0, 0, &parameters.in3[i], 0, ModuleInterfaceType::SOFT_MODULE);
            chin_mid[i][3] = new_idx++;
        }
    }
    //eq
    for(s32 i =0 ;i < input_num ; i++) {
        sprintf(inport_str, "%d|", i+1);
        if(i < input_num - usb_input_num)
            __MADD(97+i,PROC_EQ, inport_str, inport_str, 0, 0, &parameters.in4[i],  8, ModuleInterfaceType::SOFT_MODULE);
        else
            __MADD(new_idx++,PROC_EQ, inport_str, inport_str, 0, 0, &parameters.in4[i],  8, ModuleInterfaceType::SOFT_MODULE);
        if(i < input_num - usb_input_num) {
            __MADD(97+i, PROC_EQ, inport_str, inport_str, 0, 0, &parameters.in4[i],  8, ModuleInterfaceType::SOFT_MODULE);
            chin_mid[i][4] = 97+i;
        }
        else {
            __MADD(new_idx, PROC_EQ, inport_str, inport_str, 0, 0, &parameters.in4[i],  8, ModuleInterfaceType::SOFT_MODULE);
            chin_mid[i][4] = new_idx++;
        }
    }
    //nhs
    for(s32 i =0 ;i < input_num ; i++) {
        sprintf(inport_str, "%d|", i+1);
        if(i < input_num - usb_input_num)
            __MADD(129+i,PROC_FEEDBACK, inport_str, inport_str, 0, 0, &parameters.in5[i], 8, ModuleInterfaceType::SOFT_MODULE);
        else
            __MADD(new_idx++,PROC_FEEDBACK, inport_str, inport_str, 0, 0, &parameters.in5[i], 8, ModuleInterfaceType::SOFT_MODULE);
        if(i < input_num - usb_input_num) {
            __MADD(129+i, PROC_FEEDBACK, inport_str, inport_str, 0, 0, &parameters.in5[i], 8, ModuleInterfaceType::SOFT_MODULE);
            chin_mid[i][5] = 129+i;
        }
        else {
            __MADD(new_idx, PROC_FEEDBACK, inport_str, inport_str, 0, 0, &parameters.in5[i], 8, ModuleInterfaceType::SOFT_MODULE);
            chin_mid[i][5] = new_idx++;
        }
    }
    //am
@@ -121,53 +160,78 @@
    //mixer
    sprintf(inport_str, "1-%d", input_num+ 3);
    sprintf(outport_str, "%d-%d",input_num+4, input_num+output_num+4);
    __MADD(166,PROC_MIXER,inport_str,outport_str,1, 1 ,&parameters.mixer, 0, ModuleInterfaceType::SOFT_MODULE);    // .begin()+48
    __MADD(166,PROC_MIXER,inport_str,outport_str,1, 1 ,&parameters.mixer, 0, ModuleInterfaceType::SOFT_MODULE);
    //crossover
    //dummy
    for(s32 i =0 ;i < output_num ; i++) {
        sprintf(inport_str, "%d|", i+input_num+4);
        sprintf(outport_str, "%d|", i+1);
        if(i < output_num - usb_output_num)
            __MADD(167+i,PROC_CROSSOVER,inport_str,outport_str,1, 0, &parameters.out1[i],2, ModuleInterfaceType::SOFT_MODULE);
        else
            __MADD(new_idx++,PROC_CROSSOVER,inport_str,outport_str,1, 0, &parameters.out1[i],2, ModuleInterfaceType::SOFT_MODULE);
        __MADD(500+i, PROC_NONE, inport_str, outport_str, 1, 0, &parameters.out1[i], 2, ModuleInterfaceType::SOFT_MODULE); //预防删除了第一个输出模块时硬件无声音输出
    }
    //crossover
    for(s32 i =0 ;i < output_num ; i++) {
        sprintf(outport_str, "%d|", i+1);
        if(i < output_num - usb_output_num) {
            __MADD(167+i, PROC_CROSSOVER, outport_str, outport_str, 1, 0, &parameters.out1[i],2, ModuleInterfaceType::SOFT_MODULE);
            chout_mid[i][1] = 167+i;
        }
        else {
            __MADD(new_idx, PROC_CROSSOVER, outport_str, outport_str, 1, 0, &parameters.out1[i],2, ModuleInterfaceType::SOFT_MODULE);
            chout_mid[i][1] = new_idx++;
        }
    }
//    printf("ou_adr ou1[2]:0x%x, ou1[3]:0x%x\n", &parameters.out1[2], &parameters.out1[3]);
    //eq
    for(s32 i =0 ;i < output_num ; i++) {
        sprintf(outport_str, "%d|", i+1);
        if(i < output_num - usb_output_num)
            __MADD(199+i,PROC_EQ,outport_str, outport_str,1, 0, &parameters.out2[i], 8, ModuleInterfaceType::SOFT_MODULE);
        else
            __MADD(new_idx++,PROC_EQ,outport_str, outport_str,1, 0, &parameters.out2[i], 8, ModuleInterfaceType::SOFT_MODULE);
        if(i < output_num - usb_output_num) {
            __MADD(199+i, PROC_EQ, outport_str, outport_str,1, 0, &parameters.out2[i], 8, ModuleInterfaceType::SOFT_MODULE);
            chout_mid[i][2] = 199+i;
        }
        else {
            __MADD(new_idx, PROC_EQ, outport_str, outport_str,1, 0, &parameters.out2[i], 8, ModuleInterfaceType::SOFT_MODULE);
            chout_mid[i][2] = new_idx++;
        }
    }
    //delay
    for(s32 i =0 ;i < output_num ; i++) {
        sprintf(outport_str, "%d|", i+1);
        if(i < output_num - usb_output_num)
            __MADD(231+i,PROC_DELAY,outport_str, outport_str,1, 0, &parameters.out3[i], 1200, ModuleInterfaceType::SOFT_MODULE);
        else
            __MADD(new_idx++,PROC_DELAY,outport_str, outport_str,1, 0, &parameters.out3[i], 1200, ModuleInterfaceType::SOFT_MODULE);
        if(i < output_num - usb_output_num) {
            __MADD(231+i,PROC_DELAY, outport_str, outport_str,1, 0, &parameters.out3[i], 1200, ModuleInterfaceType::SOFT_MODULE);
            chout_mid[i][3] = 231+i;
        }
        else {
            __MADD(new_idx,PROC_DELAY, outport_str, outport_str,1, 0, &parameters.out3[i], 1200, ModuleInterfaceType::SOFT_MODULE);
            chout_mid[i][3] = new_idx++;
        }
    }
    //limit
    for(s32 i =0 ;i < output_num ; i++) {
        sprintf(outport_str, "%d|", i+1);
        if(i < output_num - usb_output_num)
            __MADD(263+i,PROC_LIMIT,outport_str, outport_str,1, 0, &parameters.out4[i],0, ModuleInterfaceType::SOFT_MODULE);
        else
            __MADD(new_idx++,PROC_LIMIT,outport_str, outport_str,1, 0, &parameters.out4[i],0, ModuleInterfaceType::SOFT_MODULE);
        if(i < output_num - usb_output_num) {
            __MADD(263+i, PROC_LIMIT, outport_str, outport_str,1, 0, &parameters.out4[i],0, ModuleInterfaceType::SOFT_MODULE);
            chout_mid[i][4] = 263+i;
        }
        else {
            __MADD(new_idx, PROC_LIMIT, outport_str, outport_str,1, 0, &parameters.out4[i],0, ModuleInterfaceType::SOFT_MODULE);
            chout_mid[i][4] = new_idx++;
        }
    }
    //output
    sprintf(outport_str, "1-%d", output_num);
    __MADD(295,PROC_OUTPUT,outport_str,outport_str,1, 1, &parameters.output,0, ModuleInterfaceType::SOFT_MODULE);
    for (i = 0; i < output_num; i++)
        chout_mid[i][0] = 295;
    //sysctrl
    __MADD(296,PROC_SYSCTL,outport_str,outport_str,1, 1, &parameters.sysctl,0, ModuleInterfaceType::SOFT_MODULE);
    //meter
    __MADD(297,PROC_METER,outport_str,outport_str,1, 1, NULL, 0, ModuleInterfaceType::PHY_OUTPUT);
    __MADD(297,PROC_METER,outport_str,outport_str,1, 1, &parameters.output, 0, ModuleInterfaceType::PHY_OUTPUT);
};
@@ -176,6 +240,7 @@
{
    int j;
    int allbypass = 1;
    ptag_module pmodu = (ptag_module)param_ptr;
    switch(proc_type) {
        case PROC_INPUT:
@@ -197,12 +262,14 @@
        break;
        case PROC_METER:
            ptag_Meter pMeter = (ptag_Meter)param_ptr;
            pmodu->proc_type = PROC_METER;
            ptag_Meter pMeter = (ptag_Meter)pmodu->proc_ins;
            pMeter->input_num = 8;
        break;
        case PROC_SHELF:
            ptag_shelf pshelf = (ptag_shelf)param_ptr;
            pmodu->proc_type = PROC_SHELF;
            ptag_shelf pshelf = (ptag_shelf)pmodu->proc_ins;
            pshelf->highshelf.bypass = allbypass;
            pshelf->highshelf.freq = 500;
            pshelf->highshelf.gain = -4500;
@@ -215,7 +282,8 @@
        case PROC_GEQ:
            int j;
            ptag_geq pGEQ = (ptag_geq)param_ptr;
            pmodu->proc_type = PROC_GEQ;
            ptag_geq pGEQ = (ptag_geq)pmodu->proc_ins;
            pGEQ->bypass = allbypass;
            pGEQ->q_index = 2;
            pGEQ->nsections = 31;
@@ -224,7 +292,8 @@
            }
            break;
        case PROC_EQ:
            ptag_eq pEQ = (ptag_eq)param_ptr;
            pmodu->proc_type = PROC_EQ;
            ptag_eq pEQ = (ptag_eq)pmodu->proc_ins;
            u16  freq[]={40,80,200,500,1000,2000,4000,8000,10000,12500,16000,20000};
            pEQ->bypass = allbypass;
            pEQ->nsection = MAX_EQ_SECTION;
@@ -238,7 +307,8 @@
        break;
        case PROC_EXPANDER:
            ptag_expander pExpander = (ptag_expander)param_ptr;
            pmodu->proc_type = PROC_EXPANDER;
            ptag_expander pExpander = (ptag_expander)pmodu->proc_ins;
            pExpander->bypass = allbypass;
            pExpander->threshold = -6000;
            pExpander->ratio = 100;
@@ -247,7 +317,8 @@
        break;
        case PROC_COMPRESS:
            ptag_compress pcompress = (ptag_compress)param_ptr;
            pmodu->proc_type = PROC_COMPRESS;
            ptag_compress pcompress = (ptag_compress)pmodu->proc_ins;
            pcompress->bypass = allbypass;
            pcompress->threshold = -4800;
            pcompress->ratio = 100;
@@ -258,7 +329,8 @@
        break;
        case PROC_LIMIT:
            ptag_compress limiter = (ptag_compress)param_ptr;
            pmodu->proc_type = PROC_LIMIT;
            ptag_compress limiter = (ptag_compress)pmodu->proc_ins;
            limiter->bypass = allbypass;
            limiter->threshold = 0;
            limiter->ratio = 10000;
@@ -284,13 +356,15 @@
        break;
        case PROC_DELAY:
            ptag_delay pDelay = (ptag_delay)param_ptr;
            pmodu->proc_type = PROC_DELAY;
            ptag_delay pDelay = (ptag_delay)pmodu->proc_ins;
            pDelay->bypass = allbypass;
            pDelay->ms  = 1;
        break;
        case PROC_CROSSOVER:
            ptag_crossover pCross = (ptag_crossover)param_ptr;
            pmodu->proc_type = PROC_CROSSOVER;
            ptag_crossover pCross = (ptag_crossover)pmodu->proc_ins;
            pCross->highpass.bypass = allbypass;
            pCross->highpass.freq = 500;//454;
            pCross->highpass.taps = 18;//48;
@@ -338,7 +412,8 @@
        break;
        case PROC_FEEDBACK:
            ptag_feedback pfb = (ptag_feedback)param_ptr;
            pmodu->proc_type = PROC_FEEDBACK;
            ptag_feedback pfb = (ptag_feedback)pmodu->proc_ins;
            pfb->bypass = allbypass;
            pfb->panic_threshold = 0;
            pfb->flt_depth = 1800;
@@ -357,7 +432,8 @@
        break;
        case PROC_ANS:
            ptag_ans pans = (ptag_ans)param_ptr;
            pmodu->proc_type = PROC_ANS;
            ptag_ans pans = (ptag_ans)pmodu->proc_ins;
            pans->bypass = allbypass;
            pans->mode = 0;
        break;
@@ -419,7 +495,8 @@
        break;
        case PROC_DUCKER:
            ptag_ducker pducker = (ptag_ducker)param_ptr;
            pmodu->proc_type = PROC_DUCKER;
            ptag_ducker pducker = (ptag_ducker)pmodu->proc_ins;
            pducker->bypass = allbypass;
            pducker->threshold = -4500;
            pducker->depth = -2000;
@@ -436,7 +513,8 @@
        break;
        case PROC_FIR:
            ptag_fir pfir = (ptag_fir)param_ptr;
            pmodu->proc_type = PROC_FIR;
            ptag_fir pfir = (ptag_fir)pmodu->proc_ins;
            pfir->bypass = allbypass;
            pfir->taps = 1024;
            memset((void*)pfir->coeffs, 0, sizeof(pfir->coeffs));
src/tg/tg_scene.h
@@ -52,11 +52,15 @@
{
private:
    tag_parameters parameters; //预设参数由ARM下发
    s32 **chin_mid, **chout_mid;    //chin_mid[i][0]、chout_mid[i][0]为输入输出ID,算法模块ID第二维从1开始; i表示通道,从0开始
    std::vector<void *> paramPtr;
    s32 input_num, output_num;
    //更新动态模块level_num和tag. 非动态模块已经静态固定.
    s32 update_dynmodule_tag(s32 proc_type,struct proc_field* proc);
public:
    tgScene(hw_adapter_t* adapter);
    ~tgScene();
    void module_def(s32 proc_type, void* param_ptr);
    void tgScene_param_default(ptag_parameters p);
@@ -67,6 +71,12 @@
    virtual uvoid* get_module_param_ptr(s32 mType, uvoid *param, s32 fixed) override;
    virtual void* get_parameters() override { return &parameters; }
    virtual s32** get_chin_mid() override { return chin_mid; }
    virtual s32** get_chout_mid() override { return chout_mid; }
    virtual s32 get_input_num() override { return input_num; }
    virtual s32 get_output_num() override { return output_num; }
//    virtual u32 get_module_id(u32 mid, s32 mtype ,u32 pid) override;
};
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;
}
src/tg/tg_user_ctrl.h
@@ -11,22 +11,30 @@
class tg_param_ctrl {
public:
    static u32 Signalgen_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num);
    static u32 Input_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num);
    static u32 Gain_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num);
    static u32 Output_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num);
    static u32 Mixer_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num);
    static u32 Crossover_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num);
    static u32 Feedback_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num);
    static u32 Automixer_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num);
    static u32 Aec_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num);
    static u32 Sysctl_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num);
    static u32 Geq_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num);
    static u32 Reverb_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num);
    static u32 Echo_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num);
    static u32 General_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num);
    static u32 Fir_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num);
    static u32 Spl_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num);
    static u32 Signalgen_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param);
    static u32 Input_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param);
    static u32 Gain_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param);
    static u32 Output_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param);
    static u32 Mixer_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param);
    static u32 Crossover_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param);
    static u32 Feedback_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param);
    static u32 Automixer_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param);
    static u32 Agc_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param);
    static u32 Aec_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param);
    static u32 Sysctl_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param);
    static u32 Geq_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param);
    static u32 Peq_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param);
    static u32 Reverb_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param);
    static u32 Echo_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param);
    static u32 General_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param);
    static u32 Fir_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param);
    static u32 Expander_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param);
    static u32 CompAndLimt_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param);
    static u32 Delay_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param);
    static u32 Gating_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param);
    static u32 Ducker_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param);
    static u32 Spler_Ctrl(IModule* m, u32 pID, s16* val_c, u32 num, void* param);
};