/* * ctrl.c * Description: ¸÷¸öË㷨ģ¿éµÄ²ÎÊý¿ØÖÆ´úÂë * * Created on: 2014-10-28 * Author: Graydon * Modify: */ #include #include #include "drv/global.h" #include "ctrl.h" #include "drv/fft.h" int input_ctrl(pinput_handle handle,int cmd,int *val,int num) { int setting =0; int channel = val[0]&(MAX_INPUT_NUM-1); ptag_input pInput = handle->param_ptr; switch(cmd){ case INPUT_GAIN: if(val[1]>=pInput->input[channel].mingain && val[1]<=pInput->input[channel].maxgain){ handle->input[channel].gain = val[1]/100.0f; pInput->input[channel].gain = val[1]; } break; case INPUT_LEVEL: pInput->input[channel].level = val[1]; setting =1; break; case INPUT_MUTE: handle->input[channel].mute = val[1]&0x1; handle->input[channel].time = FADE_OUT_TIME; if(val[1]&0x1){ handle->input[channel].step_gain = (FADE_OUT_GAIN - handle->input[channel].old_gain)/FADE_OUT_TIME; } else{ handle->input[channel].step_gain = (handle->input[channel].gain - handle->input[channel].old_gain)/FADE_OUT_TIME; } pInput->input[channel].mute = val[1]&0x1;; break; case INPUT_PHANT: if(val[1]&0x1){ handle->input[channel].delay = RATE_SAMPLES*5; } break; case INPUT_SENS: handle->input[channel].delay = RATE_SAMPLES; break; case INPUT_TYPE: pInput->input[channel].type = val[1]; handle->input[channel].type = val[1]; setting =1; break; case INPUT_FREQ: pInput->input[channel].freq = val[1]; setting =1; break; case INPUT_STEP: pInput->input[channel].gain += val[1]; if(pInput->input[channel].gain>pInput->input[channel].maxgain){ pInput->input[channel].gain = pInput->input[channel].maxgain; } if(pInput->input[channel].gain< pInput->input[channel].mingain){ pInput->input[channel].gain = pInput->input[channel].mingain; } handle->input[channel].gain = pInput->input[channel].gain/100.0f; break; case INPUT_POL: pInput->input[channel].phase = val[1]&0x1; handle->input[channel].phase = val[1]&0x1; break; case INPUT_MIN: if(val[1]>1200 || val[1]<-7200){ return -1; } pInput->input[channel].mingain = val[1]; if(pInput->input[channel].gain < pInput->input[channel].mingain){ pInput->input[channel].gain = pInput->input[channel].mingain; handle->input[channel].gain = pInput->input[channel].gain*0.01; } break; case INPUT_MAX: if(val[1]>1200 || val[1]<-7200){ return -1; } pInput->input[channel].maxgain = val[1]; if(pInput->input[channel].gain > pInput->input[channel].maxgain){ pInput->input[channel].gain = pInput->input[channel].maxgain; handle->input[channel].gain = pInput->input[channel].gain*0.01; } break; default: break; } if(setting){ alg_sg_set_param(handle->input[channel].hgen,pInput->input[channel].freq,pInput->input[channel].type,pInput->input[channel].level/100.f); } return 0; } int gain_ctrl(pgain_handle handle,int cmd,int *val,int num) { ptag_gain pgain = handle->param_ptr; switch(cmd){ case GAIN_SET: if(val[0]>=-7200 && val[0]<=1200){ handle->gain = val[0]*(1.0f/100); pgain->gain = val[0]; } break; default:break; } return 0; } int meter_ctrl(pmeter_handle handle,int cmd,int *val,int num) { return 0; } int delay_ctrl(pdelay_handle handle,int cmd,int *val,int num) { ptag_delay pdealy = (ptag_delay)handle->param_ptr; switch(cmd){ case DELAY_BYPASS: handle->bypass = val[0]&0x1; pdealy->bypass = handle->bypass; alg_delay_set_msec(handle->halg,pdealy->ms*1.0f); break; case DELAY_MSEC: if(val[0]<0 || val[0]>2000){ return -1; } pdealy->ms = val[0]; alg_delay_set_msec(handle->halg,pdealy->ms + pdealy->us*0.001); break; case DELAY_USEC: if(val[0]<0 || val[1]>1000){ return -1; } pdealy->us = val[0]; alg_delay_set_msec(handle->halg,pdealy->ms + pdealy->us*0.001); break; default: break; } return 0; } int eq_ctrl(peq_handle handle,int cmd,int *val,int num) { ptag_eq peq = (ptag_eq)handle->param_ptr; int setting =0; val[0]&=0x1f; switch(cmd){ case EQ_BYPASS_ALL: handle->bypass = val[0]&0x1; peq->bypass = handle->bypass; break; case EQ_BYPASS: peq->eq_attr[val[0]].bypass = val[1]&0x1; setting=1; break; case EQ_FREQ: if(val[1]<0 || val[1]>32000){ return -1; } peq->eq_attr[val[0]].freq = val[1]; setting=1; break; case EQ_GAIN: if(val[1]<-4800 || val[1]>2400){ return -1; } peq->eq_attr[val[0]].gain = val[1]; setting=1; break; case EQ_QVALUE: if(val[1]<0 || val[1]>5000){ return -1; } peq->eq_attr[val[0]].q = val[1]; setting=1; break; case EQ_TYPE: if(val[1]>eq_highshelf || val[1]< eq_lpf){ return -1; } peq->eq_attr[val[0]].type = val[1]; setting=1; break; default: break; } if(setting){ alg_eq_set_param(handle->halg,val[0], (eq_type_t)peq->eq_attr[val[0]].type, peq->eq_attr[val[0]].bypass ,peq->eq_attr[val[0]].freq,peq->eq_attr[val[0]].gain/100.0f,peq->eq_attr[val[0]].q/100.0f); } return 0; } int expander_ctrl(pexpander_handle handle,int cmd,int *val,int num) { ptag_expander pexpander = (ptag_expander)handle->param_ptr; int setting = 0; switch(cmd){ case EXPANDER_BYPASS: handle->bypass = val[0]&0x1; pexpander->bypass = handle->bypass; break; case EXPANDER_THRESHOLD: if(val[0]<-7200 || val[0]>0){ return -1; } pexpander->threshold = val[0]; setting=1; break; case EXPANDER_RADIO: if(val[0]<100 || val[0]>10000){ return -1; } pexpander->ratio= val[0]; setting=1; break; case EXPANDER_RELEASE: if(val[0]<1 || val[0]>10000){ return -1; } pexpander->release= val[0]; setting=1; break; case EXPANDER_ATTACK: if(val[0]<1 || val[0]>10000){ return -1; } pexpander->attack= val[0]; setting=1; break; default: break; } if(setting){ alg_expander_set_param(handle->halg,pexpander->threshold/100.0f ,pexpander->ratio/100.0f,pexpander->attack,pexpander->release); } return 0; } int compressor_ctrl(pcompressor_handle handle,int cmd,int *val,int num) { ptag_compress pcompressor = (ptag_compress)handle->param_ptr; int setting = 0; switch(cmd){ case COMPRESS_BYPASS: handle->bypass = val[0]&0x1; pcompressor->bypass = handle->bypass; // if(handle->bypass){ // alg_compress_clr_buf(handle->halg); // } break; case COMPRESS_THERSHOLD: if(val[0]<-4800 || val[0]>0){ return -1; } pcompressor->threshold = val[0]; setting=1; break; case COMPRESS_RADIO: if(val[0]<1 || val[0]>10000){ return -1; } pcompressor->ratio= val[0]; setting=1; break; case COMPRESS_RELEASE: if(val[0]<1 || val[0]>10000){ return -1; } pcompressor->release= val[0]; setting=1; break; case COMPRESS_ATTACK: if(val[0]<1 || val[0]>10000){ return -1; } pcompressor->attack= val[0]; setting=1; break; case COMPRESS_GAIN: if(val[0]<-7200 || val[0]>1200){ return -1; } pcompressor->gain= val[0]; setting=1; break; default: break; } if(setting){ alg_compress_set_param(handle->halg,pcompressor->threshold/100.0f ,pcompressor->ratio/100.0f, pcompressor->attack ,pcompressor->release,pcompressor->gain/100.0f ,0); } return 0; } #if 0 int mixer_ctrl(pmixer_handle handle,int cmd,int *val,int num) { int ni,no; ptag_mixer pmixer = (ptag_mixer)handle->param_ptr; ni = val[0]&0xff; no = (val[0]>>8)&0xff; if(no>=MAX_MIXER_OUTPUT){ return -1; } if(ni>=MAX_MIXER_INPUT){ return -1; } switch(cmd){ case MIXER_SWITCH: if(val[1]&0x1){ //handle->mask[no][ni/16]|= 1<<(ni&15); handle->gain[no*handle->input_num+ni] = fgain_get_factor(pmixer->input_gain[no][ni]/100.0f); // handle->step[no*handle->input_num+ni] = (handle->input[channel].gain - handle->input[channel].old_gain)/FADE_OUT_TIME; } else{ //handle->mask[no][ni/16]&= ~(1<<(ni&15)); handle->gain[no*handle->input_num+ni] = 0; } break; case MIXER_GAIN: handle->gain[no*handle->input_num+ni] = fgain_get_factor(val[1]/100.0f); pmixer->input_gain[no][ni] = val[1]; break; default: break; } return 0; } #else int mixer_ctrl(pmixer_handle handle,int cmd,int *val,int num) { int ni,no; ptag_mixer pmixer = (ptag_mixer)handle->param_ptr; ni = val[0]&0xff; no = (val[0]>>8)&0xff; if(no>=MAX_MIXER_OUTPUT){ return -1; } if(ni>=MAX_MIXER_INPUT){ return -1; } switch(cmd){ case MIXER_SWITCH: if(val[1]&0x1){ handle->mask[no][ni/16]|= 1<<(ni&15); // handle->gain[no][ni/16] = pmixer->input_gain[no][ni]/100.0f; handle->gain[no][ni] = pmixer->input_gain[no][ni]/100.0f;///////////////////////////////////////////////// // handle->step[no*handle->input_num+ni] = (handle->input[channel].gain - handle->input[channel].old_gain)/FADE_OUT_TIME; } else{ handle->mask[no][ni/16]&= ~(1<<(ni&15)); } break; case MIXER_GAIN: if(val[1]<-7200 || val[1]>1200){ return -1; } //handle->gain[no*handle->input_num+ni] = GF(val[1]/100.0f); pmixer->input_gain[no][ni] = val[1]; if((handle->mask[no][ni/16] >> (ni&15))&0x1) { handle->gain[no][ni] = (val[1]/100.0f); } break; default: break; } return 0; } #endif int shelf_ctrl(pshelf_handle handle,int cmd,int *val,int num) { ptag_shelf pshelf = (ptag_shelf)handle->param_ptr; bool high_setting =0 ,low_setting=0; switch(cmd){ case HIGH_SHELF_BYPASS: pshelf->highshelf.bypass = val[0]&0x1; high_setting =1; break; case HIGH_SHELF_FREQ: if(val[0]<20 || val[0]>20000){ return -1; } pshelf->highshelf.freq = val[0]; high_setting =1; break; case HIGH_SHELF_QVALUE: if(val[0]>5000 || val[0]<2){ return -1; } pshelf->highshelf.q = val[0]; high_setting =1; break; case HIGH_SHELF_GAIN: if(val[0]>1500 || val[0]<-4500){ return -1; } pshelf->highshelf.gain = val[0]; high_setting=1; break; case LOW_SHELF_BYPASS: pshelf->lowshelf.bypass = val[0]&0x1; low_setting=1; break; case LOW_SHELF_FREQ: if(val[0]<20 || val[0]>20000){ return -1; } pshelf->lowshelf.freq = val[0]; low_setting =1; break; case LOW_SHELF_QVALUE: if(val[0]>5000 || val[0]<2){ return -1; } pshelf->lowshelf.q = val[0]; low_setting =1; break; case LOW_SHELF_GAIN: if(val[0]>1500 || val[0]<-4500){ return -1; } pshelf->lowshelf.gain = val[0]; low_setting=1; break; default: break; } if(pshelf->lowshelf.bypass && pshelf->highshelf.bypass){ handle->bypass =1 ; } else{ handle->bypass =0 ; } if(high_setting){ alg_eq_set_param(handle->halg,0,eq_highshelf, pshelf->highshelf.bypass,pshelf->highshelf.freq,pshelf->highshelf.gain/100.0f ,pshelf->highshelf.q/100.0f); } if(low_setting){ alg_eq_set_param(handle->halg,1,eq_lowshelf, pshelf->lowshelf.bypass,pshelf->lowshelf.freq,pshelf->lowshelf.gain/100.0f ,pshelf->lowshelf.q/100.0f); } return 0; } int crossover_ctrl(pcrossover_handle handle,int cmd,int *val,int num) { ptag_crossover pCross = (ptag_crossover)handle->param_ptr; bool high_setting=0,low_setting=0; switch(cmd){ case XOVER_HIGHPASS_BYPASS: pCross->highpass.bypass = val[0]&0x1; handle->highbypass = pCross->highpass.bypass; high_setting =1; break; case XOVER_HIGHPASS_TYPE: pCross->highpass.type = val[0]; high_setting =1; break; case XOVER_HIGHPASS_FREQ: if(val[0]<20 || val[0]>20000){ return -1; } pCross->highpass.freq = val[0]; high_setting =1; break; case XOVER_HIGHPASS_ORDER: if(val[0]>48){ return -1; } pCross->highpass.taps = val[0]; high_setting =1; break; case XOVER_HIGHPASS_GAIN: if(val[0]>1500 || val[0]<-1500){ return -1; } pCross->highpass.gain = val[0]; high_setting =1; break; case XOVER_LOWPASS_BYPASS: pCross->lowpass.bypass = val[0]&0x1; handle->lowbypass=pCross->lowpass.bypass; low_setting=1; break; case XOVER_LOWPASS_TYPE: pCross->lowpass.type = val[0]; low_setting=1; break; case XOVER_LOWPASS_FREQ: if(val[0]<20 || val[0]>20000){ return -1; } pCross->lowpass.freq = val[0]; low_setting=1; break; case XOVER_LOWPASS_ORDER: if(val[0]>48){ return -1; } pCross->lowpass.taps = val[0]; low_setting=1; break; case XOVER_LOWPASS_GAIN: if(val[0]>1500 || val[0]<-1500){ return -1; } pCross->lowpass.gain = val[0]; low_setting =1; break; default: break; } if(low_setting){ alg_filter_set_param(handle->hLowalg,pCross->lowpass.freq,pCross->lowpass.taps,(eFilterType)pCross->lowpass.type,pCross->lowpass.gain/100.0f); } if(high_setting){ alg_filter_set_param(handle->hHighalg,pCross->highpass.freq,pCross->highpass.taps,(eFilterType)pCross->highpass.type,pCross->highpass.gain/100.0f); } return 0; } int output_ctrl(poutput_handle handle,int cmd,int *val,int num) { int channel = val[0]&(MAX_OUTPUT_NUM-1); ptag_output poutput = handle->param_ptr; switch(cmd){ case OUTPUT_GAIN: if(val[1]>=poutput->output[channel].mingain && val[1]<=poutput->output[channel].maxgain){ handle->output[channel].gain = val[1]/100.0f; poutput->output[channel].gain = val[1]; } break; case OUTPUT_MUTE: handle->output[channel].mute = val[1]&0x1; handle->output[channel].time = FADE_OUT_TIME; if(val[1]&0x1){ handle->output[channel].step_gain = (FADE_OUT_GAIN - handle->output[channel].old_gain)/FADE_OUT_TIME; } else{ handle->output[channel].step_gain = (handle->output[channel].gain - handle->output[channel].old_gain)/FADE_OUT_TIME; } poutput->output[channel].mute = handle->output[channel].mute; break; case OUTPUT_STEP:{ poutput->output[channel].gain += val[1]; if(poutput->output[channel].gain>poutput->output[channel].maxgain){ poutput->output[channel].gain = poutput->output[channel].maxgain; } if(poutput->output[channel].gainoutput[channel].mingain){ poutput->output[channel].gain = poutput->output[channel].mingain; } handle->output[channel].gain = poutput->output[channel].gain/100.0f; } case OUTPUT_POL: poutput->output[channel].phase = val[1]&0x1; handle->output[channel].phase = val[1]&0x1; break; case OUTPUT_MIN: if(val[1]>1200 || val[1]<-7200){ return -1; } poutput->output[channel].mingain = val[1]; if(poutput->output[channel].gain < poutput->output[channel].mingain){ poutput->output[channel].gain = poutput->output[channel].mingain; handle->output[channel].gain = poutput->output[channel].gain*0.01; } break; case OUTPUT_MAX: if(val[1]>1200 || val[1]<-7200){ return -1; } poutput->output[channel].maxgain = val[1]; if(poutput->output[channel].gain > poutput->output[channel].maxgain){ poutput->output[channel].gain = poutput->output[channel].maxgain; handle->output[channel].gain = poutput->output[channel].gain*0.01; } break; default: break; } return 0; } int feedback_ctrl(pfeedback_handle handle,int cmd,int *val, int num) { int setting =0, setting1 =0; ptag_feedback p = handle->param_ptr; switch(cmd){ case FB_BYPASS: handle->bypass = val[0]&0x1; p->bypass = handle->bypass; //alg_afc_set_calibration(handle->halg , !(val[0]&0x1)); break; case FB_PANIC: if(val[0]<-3600 || val[0]>0){ return -1; } p->panic_threshold = val[0]; alg_nhs_set_panic(handle->halg, val[0]*0.01); //alg_afc_enhanced_mode_enable(handle->halg ,1); break; case FB_FLT_DEPTH: if(val[0]<100 || val[0]>2400){ return -1; } p->flt_depth = val[0]; //alg_afc_set_highpass_freq(handle->halg , val[0]); setting =1; break; case FB_MODE: p->mode = val[0]&0x3; setting =1; break; case FB_CLEAR: alg_nhs_filters_clear(handle->halg); break; case FB_FLT_FREQ: p->flt_group[val[0]].fc = val[1]; setting1 =1; break; case FB_FLT_GAIN: p->flt_group[val[0]].gain = val[1]; setting1 =1; break; case FB_FLT_TYPE: p->flt_group[val[0]].type = val[1]; setting1 =1; break; case FB_THRS: p->fb_threshold = val[0]; //alg_afc_set_highpass_gain(handle->halg , val[0]*0.01/6); alg_nhs_set_threshold(handle->halg, val[0]*0.01); break; case FB_FLT_Q: p->bw = val[0]; setting = 1; break; default: break; } if(setting){ alg_nhs_set_parameters(handle->halg, 2.5 , p->flt_depth*0.01, p->bw*0.01 ); } if(setting1 ){ alg_nhs_filters_set_unit(handle->halg , val[0], p->flt_group[val[0]].type , p->flt_group[val[0]].fc, p->flt_group[val[0]].gain*0.01); } return 0; } #if 1 int automixer_ctrl(pautomixer_handle handle,int cmd,int *val, int num) { int setting=0 ;// ptag_automixer p = handle->param_ptr; switch(cmd){ case AM_BYPASS: handle->bypass = val[0]&0x1; break; case AM_MUTE: alg_automixer_set_mute(handle->halg,val[0]&0x1); break; case AM_GAIN: if(val[0]<-7200 || val[0]>1200){ return -1; } alg_automixer_set_gain(handle->halg,val[0]/100.f); break; case AM_SLOPE: if(val[0]<100 || val[0]>600){ return -1; } alg_automixer_set_slope(handle->halg,val[0]/100.f); break; case AM_RESPONSE: if(val[0]<5 || val[0]>5000){ return -1; } alg_automixer_set_response(handle->halg,val[0]); break; case AM_CHANNEL_AUTO: p->channels[val[0]].automatic = val[1]&0x1; setting =1; break; case AM_CHANNEL_MUTE: p->channels[val[0]].master = val[1]&0x1; setting =1; break; case AM_CHANNEL_GAIN: if(val[1]<-7200 || val[1]>1200){ return -1; } p->channels[val[0]].gain = val[1]; setting =1; break; case AM_CHANNEL_PRIORITY: if(val[1]<0 || val[1]>10){ return -1; } p->channels[val[0]].threshold = val[1]; setting =1; break; default: break; } if(setting){ alg_automixer_set_param(handle->halg, val[0], p->channels[val[0]].automatic, p->channels[val[0]].master , p->channels[val[0]].threshold, p->channels[val[0]].gain/100.f); } return 0; } #else int automixer_ctrl(pautomixer_handle handle,int cmd,int *val, int num) { int setting=0 ;// ptag_automixer p = handle->param_ptr; switch(cmd){ case AM_BYPASS: handle->bypass = val[0]&0x1; break; case AM_MUTE: alg_pri_automixer_set_mute(handle->halg,val[0]&0x1); break; case AM_GAIN: if(val[0]<-7200 || val[0]>1200){ return -1; } alg_pri_automixer_set_gain(handle->halg,val[0]/100.f); break; case AM_SLOPE: if(val[0]<100 || val[0]>600){ return -1; } alg_pri_automixer_set_slope(handle->halg,val[0]/100.f); break; case AM_RESPONSE: if(val[0]<5 || val[0]>5000){ return -1; } alg_pri_automixer_set_response(handle->halg,val[0]); break; case AM_CHANNEL_AUTO: p->channels[val[0]].automatic = val[1]&0x1; setting =1; break; case AM_CHANNEL_MUTE: p->channels[val[0]].master = val[1]&0x1; setting =1; break; case AM_CHANNEL_GAIN: if(val[1]<-7200 || val[1]>1200){ return -1; } p->channels[val[0]].gain = val[1]; setting =1; break; case AM_CHANNEL_PRIORITY: if(val[1]<-6000 || val[1]>0){ return -1; } p->channels[val[0]].threshold = val[1]; setting =1; break; default: break; } if(setting){ alg_pri_automixer_set_param(handle->halg, val[0], p->channels[val[0]].automatic, p->channels[val[0]].master , p->channels[val[0]].threshold*0.01 , p->channels[val[0]].gain/100.f); } return 0; } #endif int fir_ctrl(pcommon_handle handle,int cmd,int *val, int num) { switch(cmd){ case FIR_BYPASS: handle->bypass = val[0]&0x1; break; case FIR_COEFFS: //alg_fir_set_coeffs(handle->halg, val, num); break; default: break; } return 0; } int agc_ctrl(pagc_handle handle, int cmd,int *val,int num) { int setting=0 ; ptag_agc pagc = handle->param_ptr; switch(cmd){ case AGC_BYPASS: handle->bypass = val[0]&0x1; pagc->bypass = handle->bypass; break; case AGC_THRESHOLD: if(val[0]<-9600 || val[0]>-2000){ return -1; } pagc->threshold = val[0]; setting = 1; break; case AGC_TARGET_THRES: if(val[0]<-4000 || val[0]>0){ return -1; } pagc->tar_threshold = val[0]; setting = 1; break; case AGC_RATIO: if(val[0]<100 || val[0]>2000){ return -1; } pagc->ratio= val[0]; setting = 1; break; case AGC_ATTACKTIME: if(val[0] >10000 || val[0]<1){ return -1; } pagc->attacktime = val[0]; setting = 1; break; case AGC_RELEASETIME: if(val[0] >10000 || val[0]<1){ return -1; } pagc->releasetime = val[0]; setting = 1; break; default: break; } if(setting ){ alg_agc_set_param(handle->halg ,pagc->threshold/100.0f , pagc->tar_threshold/100.0f, pagc->ratio/100.0f ,pagc->attacktime , pagc->releasetime); } return 0; } int aec_ctrl(paec_handle p,int cmd,int *val, int num) { if(p == NULL) return -1; extern void* haec; switch(cmd){ case AEC_BYPASS: p->bypass = val[0]&0x1; alg_aec_clr_ulitily(p->halg); ////////////////////////////////////////////// if(p->bypass) { haec = 0; } else{ haec = p->halg; } ///////////////////////////////////////////// break; case AEC_MODE:{ aec_mode_t mode = (aec_mode_t)(val[0]&0x3); alg_aec_set_param(p->halg, mode); } break; } return 0; } int ans_ctrl(pans_handle p,int cmd,int *val, int num) { if(p == NULL) return -1; extern void* hans; switch(cmd){ case ANS_BYPASS: p->bypass = val[0]&0x1; //alg_ans_clr_ulitily(p->halg); ///////////////////////////////////////////// if(p->bypass) { hans = 0; } else{ hans = p->halg; } ///////////////////////////////////////////// break; case ANS_MODE:{ ans_mode mode = (ans_mode)(val[0]&7); alg_ans_set_policy(p->halg, mode); } break; } return 0; } int sysctl_ctrl(psysctl_handle p, int cmd ,int *val ,int num) { int i; switch(cmd){ case SYSCTL_GAIN: if(val[0]>=-7200 && val[0]<=1200){ p->gain = val[0]*(1.0f/100); } break; case SYSCTL_MUTE: if(val[0]&0x1){ for(i=0;i< p->input_num ;i++){ p->step_gain[i] = (FADE_OUT_GAIN - p->old_gain[i])/FADE_OUT_TIME; } } else{ for(i=0;i< p->input_num ;i++){ p->step_gain[i] = (p->gain - p->old_gain[i])/FADE_OUT_TIME; } } p->mute = val[0]&0x1; p->time = FADE_OUT_TIME*p->input_num; break; default:break; } return 0; } int selector_ctrl(pselector_handle handle, int cmd ,int *val ,int num) { int ni,no; ni = val[0]&0xff; no = (val[0]>>8)&0xff; if(no>=MAX_MIXER_OUTPUT){ return -1; } if(ni>=MAX_MIXER_INPUT){ return -1; } switch(cmd){ case MIXER_SWITCH: if(val[1]&0x1){ handle->mask[no][ni/16]|= 1<<(ni&15); } else{ handle->mask[no][ni/16]&= ~(1<<(ni&15)); } break; default: break; } return 0; }