chenlh
2025-08-29 faba6b022b86f066d95b1cfdf752573724d5fbcd
src/tg/tg_scene.cpp
@@ -13,7 +13,7 @@
tgScene::tgScene(hw_adapter_t* adapter):Scene(adapter)
{
   s8 inport_str[8],outport_str[8];
   s8 inport_str[10],outport_str[10];
   s8 ana_input_num, ana_output_num,dante_input_num,dante_output_num ;
   s16 input_num, output_num ;
   s32 n;
@@ -23,9 +23,10 @@
   adapter->get_channel_num(&ana_input_num, &ana_output_num, &dante_input_num, &dante_output_num);
   input_num = ana_input_num + dante_input_num;
   output_num = dante_input_num + dante_output_num;
   output_num = ana_output_num + dante_output_num;
   //port from 1 start.
   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(298,PROC_METER,inport_str,"",0,1 ,NULL,0, ModuleInterfaceType::SOFT_MODULE); //tag:0-peak,1-rms
@@ -73,7 +74,7 @@
   //am
   sprintf(inport_str, "1-%d", input_num);
   sprintf(outport_str, "1-%d", input_num+1);
   __MADD(161,PROC_AUTOMIXER,inport_str, outport_str,0, 0, &parameters.automixer, 0, ModuleInterfaceType::SOFT_MODULE);  //可替换
   __MADD(161,PROC_AUTOMIXER,inport_str, outport_str, 0, 0, &parameters.automixer, 0, ModuleInterfaceType::SOFT_MODULE);  //可替换
   //aec selector
   sprintf(inport_str, "1-%d", input_num+ 2);//+1 add usb
@@ -97,31 +98,32 @@
   //mixer
   sprintf(inport_str, "1-%d", input_num+ 4);
   sprintf(outport_str, "1-%d", output_num+1);
   __MADD(166,PROC_MIXER,"0-35","0-32",1, 1 ,&parameters.mixer, 0, ModuleInterfaceType::SOFT_MODULE);
   sprintf(outport_str, "%d-%d",input_num+5, input_num+output_num+6);
   __MADD(166,PROC_MIXER,inport_str,outport_str,1, 1 ,&parameters.mixer, 0, ModuleInterfaceType::SOFT_MODULE);   // .begin()+48
   //crossover
   for(s32 i =0 ;i < output_num ; i++) {
      sprintf(outport_str, "%d|", i+1);
      __MADD(167+i,PROC_CROSSOVER,outport_str, outport_str,1, 0, &parameters.out1[i],2, ModuleInterfaceType::SOFT_MODULE);
      sprintf(inport_str, "%d|", i+input_num+5);
      __MADD(167+i,PROC_CROSSOVER,inport_str,inport_str,1, 0, &parameters.out1[i],2, ModuleInterfaceType::SOFT_MODULE);
   }
   //eq
   for(s32 i =0 ;i < output_num ; i++) {
      sprintf(outport_str, "%d|", i+1);
      __MADD(199+i,PROC_EQ,outport_str, outport_str,1, 0, &parameters.out2[i], 8, ModuleInterfaceType::SOFT_MODULE);
      sprintf(inport_str, "%d|", i+input_num+5);
      __MADD(199+i,PROC_EQ,inport_str, inport_str,1, 0, &parameters.out2[i], 8, ModuleInterfaceType::SOFT_MODULE);
   }
   //delay
   for(s32 i =0 ;i < output_num ; i++) {
      sprintf(outport_str, "%d|", i+1);
      __MADD(231+i,PROC_DELAY,outport_str, outport_str,1, 0, &parameters.out3[i], 1200, ModuleInterfaceType::SOFT_MODULE);
      sprintf(inport_str, "%d|", i+input_num+5);
      __MADD(231+i,PROC_DELAY,inport_str, inport_str,1, 0, &parameters.out3[i], 1200, ModuleInterfaceType::SOFT_MODULE);
   }
   //limit
   for(s32 i =0 ;i < output_num ; i++) {
      sprintf(inport_str, "%d|", i+input_num+5);
      sprintf(outport_str, "%d|", i+1);
      __MADD(263+i,PROC_LIMIT,outport_str, outport_str,1, 0, &parameters.out4[i],0, ModuleInterfaceType::SOFT_MODULE);
      __MADD(263+i,PROC_LIMIT,inport_str, outport_str,1, 0, &parameters.out4[i],0, ModuleInterfaceType::SOFT_MODULE);
   }
   //output
@@ -134,11 +136,317 @@
};
void tgScene::module_def(s32 proc_type, void* param_ptr)
{
   int j;
   int allbypass = 1;
   switch(proc_type) {
      case PROC_INPUT:
         ptag_input pInput = (ptag_input)param_ptr;
         pInput->input_num = MAX_INPUT_NUM;
         for(j=0; j<pInput->input_num; j++){
            pInput->input[j].freq = 1000;
            pInput->input[j].level = -4800;
            pInput->input[j].phant = 0;
            pInput->input[j].sensitivity = 0;
            pInput->input[j].channelID = j;
            pInput->input[j].gain =0;
            pInput->input[j].mute = 0;
            pInput->input[j].type=0;
            pInput->input[j].phase =0 ;
            pInput->input[j].mingain = -8000;
            pInput->input[j].maxgain = 1200;
         }
      break;
      case PROC_METER:
         ptag_Meter pMeter = (ptag_Meter)param_ptr;
         pMeter->input_num = 8;
      break;
      case PROC_SHELF:
         ptag_shelf pshelf = (ptag_shelf)param_ptr;
         pshelf->highshelf.bypass = allbypass;
         pshelf->highshelf.freq = 500;
         pshelf->highshelf.gain = -4500;
         pshelf->highshelf.q = 71;
         pshelf->lowshelf.bypass = 1;
         pshelf->lowshelf.freq = 500;
         pshelf->lowshelf.gain =-4500;
         pshelf->lowshelf.q = 71;
      break;
      case PROC_GEQ:
         int j;
         ptag_geq pGEQ = (ptag_geq)param_ptr;
         pGEQ->bypass = allbypass;
         pGEQ->q = 2;
         pGEQ->nsections = 31;
         for(j=0;j<31;j++){
            pGEQ->eq_attr[j].gain = 0;
         }
         break;
      case PROC_EQ:
         ptag_eq pEQ = (ptag_eq)param_ptr;
         u16  freq[]={40,80,200,500,1000,2000,4000,8000,10000,12500,16000,20000};
         pEQ->bypass = allbypass;
         pEQ->nsection = MAX_EQ_SECTION;
         for(j=0;j<pEQ->nsection;j++){
            pEQ->eq_attr[j].bypass = allbypass;
            pEQ->eq_attr[j].freq = freq[j];
            pEQ->eq_attr[j].gain = 0;
            pEQ->eq_attr[j].q = 250;
            //pEQ->eq_attr[j].type =
         }
      break;
      case PROC_EXPANDER:
         ptag_expander pExpander = (ptag_expander)param_ptr;
         pExpander->bypass = allbypass;
         pExpander->threshold = -6000;
         pExpander->ratio = 100;
         pExpander->attack = 1;
         pExpander->release = 1;
      break;
      case PROC_COMPRESS:
         ptag_compress pcompress = (ptag_compress)param_ptr;
         pcompress->bypass = allbypass;
         pcompress->threshold = -4800;
         pcompress->ratio = 100;
         pcompress->attack = 1;
         pcompress->release = 1;
         pcompress->gain = 0;
         pcompress->soft = 0;
      break;
      case PROC_LIMIT:
         ptag_compress limiter = (ptag_compress)param_ptr;
         limiter->bypass = allbypass;
         limiter->threshold = 0;
         limiter->ratio = 10000;
         limiter->attack = 1;
         limiter->release = 1;
         limiter->gain = 0;
         limiter->soft = 0;
      break;
      case PROC_MIXER:
         int m;
         ptag_mixer pMixer = (ptag_mixer)param_ptr;
         pMixer->input_num = MAX_MIXER_INPUT;
         pMixer->output_num = MAX_MIXER_OUTPUT;
         memset(pMixer->input_mask,0,sizeof(pMixer->input_mask));
         for (m=0;m<pMixer->output_num ;m ++){
            for(j=0;j<pMixer->input_num;j++){
                pMixer->input_gain[m][j]=0;
                pMixer->delay[m][j] =0;
            }
            pMixer->input_mask[m][m/16]=1<<(m&15);
         }
      break;
      case PROC_DELAY:
         ptag_delay pDelay = (ptag_delay)param_ptr;
         pDelay->bypass = allbypass;
         pDelay->ms  = 1;
      break;
      case PROC_CROSSOVER:
         ptag_crossover pCross = (ptag_crossover)param_ptr;
         pCross->highpass.bypass = allbypass;
         pCross->highpass.freq = 500;//454;
         pCross->highpass.taps = 18;//48;
         pCross->highpass.type = 0;
         pCross->highpass.gain  =0 ;
         pCross->lowpass.bypass = allbypass;
         pCross->lowpass.freq = 500;
         pCross->lowpass.taps = 18;
         pCross->lowpass.type = 0;
         pCross->lowpass.gain =0;
      break;
      case PROC_OUTPUT:
         ptag_output pOutput= (ptag_output)param_ptr;
         pOutput->output_num  = MAX_OUTPUT_NUM;
         for(j=0;j<pOutput->output_num;j++){
            pOutput->output[j].gain = 0;
            pOutput->output[j].mute = 0;
            pOutput->output[j].channelID = j;
            pOutput->output[j].phase = 0;
            pOutput->output[j].mingain = -8000;
            pOutput->output[j].maxgain = 1200;
         }
      break;
      case PROC_GAIN:
         ptag_gain pgain = (ptag_gain)param_ptr;
         pgain->gain = 0;
         pgain->mute = 0;
      break;
      case PROC_AUTOMIXER:
         ptag_gainsharing_mixer pautomixer = (ptag_gainsharing_mixer)param_ptr;
         pautomixer->bypass = allbypass;
         pautomixer->master_mute =0;
         pautomixer->master_gain =0;
         pautomixer->response = 5;
         pautomixer->slope = 200;
         for(j=0;j<AUTOMIXER_CHANNEL_NUM;j++){
            pautomixer->channels[j].automatic = 0;
            pautomixer->channels[j].mute = 0;
            pautomixer->channels[j].gain = 0;
            pautomixer->channels[j].priority = 5;
         }
      break;
      case PROC_FEEDBACK:
         ptag_feedback pfb = (ptag_feedback)param_ptr;
         pfb->bypass = allbypass;
         pfb->panic_threshold = 0;
         pfb->flt_depth = 1800;
      break;
      case PROC_SYSCTL:
         ptag_sysctl psysctl = (ptag_sysctl)param_ptr;
         psysctl->gain =  0;
         psysctl->mute = 0;
      break;
      case PROC_AEC:
         ptag_aec paec = (ptag_aec)param_ptr;
         paec->bypass = allbypass;
         paec->mode = 0;
      break;
      case PROC_ANS:
         ptag_ans pans = (ptag_ans)param_ptr;
         pans->bypass = allbypass;
         pans->mode = 0;
      break;
      case PROC_SELECTOR:
         ptag_selector pselector = (ptag_selector)param_ptr;
         pselector->input_num = MAX_MIXER_INPUT;
         pselector->output_num = MAX_MIXER_OUTPUT;
         memset(pselector->input_mask,0,sizeof(pselector->input_mask));
      break;
      case PROC_AGC:
         ptag_agc pAGC = (ptag_agc)param_ptr;
         pAGC->bypass = allbypass;
         pAGC->attacktime = 1;
         pAGC->releasetime = 500;
         pAGC->ratio = 100;
         pAGC->tar_threshold = 0;
         pAGC->threshold =-4800;
      break;
      case PROC_GATING_AUTOMIXER:
         ptag_gating_mixer pgautomixer = (ptag_gating_mixer)param_ptr;
         pgautomixer->bypass = allbypass;
         pgautomixer->master_mute =0;
         pgautomixer->master_gain =0;
         pgautomixer->holdtime = 500;
         pgautomixer->offgain = -4000;
         pgautomixer->sensitivity = 600;
         pgautomixer->nom_atten = 300;
         pgautomixer->nom_num = 4;
         for(j=0;j<AUTOMIXER_CHANNEL_NUM;j++){
            pgautomixer->channels[j].automatic = 0;
            pgautomixer->channels[j].mute = 0;
            pgautomixer->channels[j].gain = 0;
            pgautomixer->channels[j].priority = 5;
         }
      break;
      case PROC_CONTINUNOUS_SPL:
         ptag_spl pspl = (ptag_spl)param_ptr;
         pspl->maxgain = 2000;
         pspl->mingain = -2000;
         pspl->sense_ratio = 75;
         pspl->speed = 5;
         pspl->trim =0;
         pspl->bypass = allbypass;
         memset((void*)pspl->mask,0,sizeof(pspl->mask));
      break;
      case PROC_GATING:
         ptag_gate pgate = (ptag_gate)param_ptr;
         pgate->bypass = allbypass;
         pgate->threshold = -3000;
         pgate->depth = -6000;
         pgate->attacktime = 2;
         pgate->holdtime = 5;
         pgate->releasetime = 1000;
      break;
      case PROC_DUCKER:
         ptag_ducker pducker = (ptag_ducker)param_ptr;
         pducker->bypass = allbypass;
         pducker->threshold = -4500;
         pducker->depth = -2000;
         pducker->attacktime = 20;
         pducker->holdtime = 1000;
         pducker->releasetime = 1000;
         memset((void*)pducker->mask,0,sizeof(pducker->mask));
      break;
      case PROC_REVERB:
      break;
      case PROC_ECHO:
      break;
      case PROC_FIR:
      break;
      default:
      break;
      }
}
void tgScene::tgScene_param_default(ptag_parameters p)
{
   int i,j,module_cnt=0;
   module_def(PROC_INPUT, &p->input);
   for (i=0; i<MAX_INPUT_NUM; i++) {
      module_def(PROC_EXPANDER, &p->in1[i]);
      module_def(PROC_COMPRESS, &p->in2[i]);
      module_def(PROC_AGC, &p->in3[i]);
      module_def(PROC_EQ, &p->in4[i]);
      module_def(PROC_FEEDBACK, &p->in5[i]);
   }
   module_def(PROC_AUTOMIXER, &p->automixer);
   module_def(PROC_SELECTOR, &p->aec_selector);
   module_def(PROC_AEC, &p->aec);
   module_def(PROC_SELECTOR, &p->ans_selector);
   module_def(PROC_ANS, &p->ans_selector);
   module_def(PROC_MIXER, &p->mixer);
   for (i=0; i<MAX_OUTPUT_NUM; i++) {
      module_def(PROC_CROSSOVER, &p->out1[i]);
      module_def(PROC_EQ, &p->out2[i]);
      module_def(PROC_DELAY, &p->out3[i]);
      module_def(PROC_LIMIT, &p->out4[i]);
   }
   module_def(PROC_OUTPUT, &p->output);
   module_def(PROC_SYSCTL, &p->sysctl);
}
s32 tgScene::set_parameters_content(uvoid* param, s32 size)
{
   tag_parameters* pp = (tag_parameters*)param;
   if(pp->magic != 0xb34c && size != sizeof(tag_parameters)) {
      //basic check.
   if(pp->magic != 0xbcba || size != sizeof(tag_parameters)) {
      printf("preset param error!\n");
      return -1;
   }
   memcpy(&parameters, param, sizeof(tag_parameters));
@@ -149,14 +457,14 @@
s32 tgScene::update_dynmodule_tag(s32 proc_type,struct proc_field* proc)
{
   switch(proc_type) {
   case  ModuleType::PROC_EQ:{
   case  ModuleType::PROC_GEQ:{
      ptag_module pmodule  = (ptag_module)proc->parameters;
      ptag_geq geq = (ptag_geq)pmodule->proc_ins;
      proc->tag = geq->nsections;
   }
   break;
   case  ModuleType::PROC_GEQ:{
   case  ModuleType::PROC_EQ:{
      ptag_module pmodule  = (ptag_module)proc->parameters;
      ptag_eq eq = (ptag_eq)pmodule->proc_ins;
@@ -175,7 +483,7 @@
      proc->tag =1200;
      break;
   case  ModuleType::PROC_CROSSOVER:
      proc->tag =2;
      proc->tag =1;
      break;
   case  ModuleType::PROC_FEEDBACK:{
      ptag_module pmodule  = (ptag_module)proc->parameters;
@@ -206,7 +514,6 @@
s32 tgScene::update_module()
{
   u8 port_number[16];
   s8 ana_input_num, ana_output_num,dante_input_num,dante_output_num ;
   s16 input_num, output_num ;
   s16 dual_dsp = hw_adapter->get_system_is_dual_dsp();
@@ -214,7 +521,7 @@
   hw_adapter->get_channel_num(&ana_input_num, &ana_output_num, &dante_input_num, &dante_output_num);
   input_num = ana_input_num + dante_input_num;
   output_num = dante_input_num + dante_output_num;
   output_num = ana_output_num + dante_output_num;
   for(auto& iter: proc_list){
      //update dynamic module info.