📄 msconf.c
字号:
speex_preprocess_estimate_update(chan->speex_pp, (short*)chan->input); }#endif if (i==0 || s->channels[0].is_speaking<=0) { for(j=0;j<s->conf_nsamples;++j){ s->sum[j]+=chan->input[j]; } chan->has_contributed=TRUE; } chan->stat_processed++; } else { chan->stat_missed++; if (i>0 && chan->is_used == TRUE) { chan->missed++; /* delete stream if data is missing since a long time */ if (chan->missed>15) { chan->is_used=FALSE; ms_message("msconf: deleted contributing stream (pin=%i)", i); } /* couldn't we add confort noise for those outputs? */ } chan->has_contributed=FALSE; } } return;}static inline int16_t saturate(int sample){ if (sample>32000) sample=32000; else if (sample<-32000) sample=-32000; return (int16_t)sample;}static mblk_t * conf_output(ConfState *s, Channel *chan){ mblk_t *m=allocb(s->conf_gran,0); int i; int tmp; if (chan->has_contributed==TRUE){ for (i=0;i<s->conf_nsamples;++i){ tmp=s->sum[i]-(int)chan->input[i]; *((int16_t*)m->b_wptr)=saturate(tmp); m->b_wptr+=2; } }else{ for (i=0;i<s->conf_nsamples;++i){ tmp=s->sum[i]; *((int16_t*)m->b_wptr)=saturate(tmp); m->b_wptr+=2; } } return m;}static void conf_dispatch(MSFilter *f, ConfState *s){ int i; Channel *chan; mblk_t *m; //memset(s->sum,0,s->conf_nsamples*sizeof(int)); for (i=0;i<CONF_MAX_PINS;++i){ if (f->outputs[i]!=NULL){ chan=&s->channels[i]; m=conf_output(s,chan); ms_queue_put(f->outputs[i],m); } }}static void conf_process(MSFilter *f){ int i; ConfState *s=(ConfState*)f->data; Channel *chan; Channel *chan0; /*read from all inputs and put into bufferizers*/ for (i=0;i<CONF_MAX_PINS;++i){ if (f->inputs[i]!=NULL){ chan=&s->channels[i]; ms_bufferizer_put_from_queue(&chan->buff,f->inputs[i]); if (ms_bufferizer_get_avail(&chan->buff)>0) { chan->missed=0; /* reset counter of missed packet */ if (i>0 && chan->is_used==FALSE) { chan->is_used=TRUE; ms_message("msconf: new contributing stream", ms_bufferizer_get_avail(&chan->buff)); } } } } /*do the job */ while(should_process(f,s)==TRUE){ conf_sum(s); conf_dispatch(f,s); } /* mixer is disabled! -> copy A->B and B->A*/ if (s->mix_mode == FALSE) { /* get the soundread data and copy it to pinX */ for (i=1;i<CONF_MAX_PINS;i=i+2){ if (f->inputs[i]!=NULL){ chan0=&s->channels[0]; chan=&s->channels[i]; if (chan->is_used==TRUE) { while (ms_bufferizer_read(&chan->buff,(uint8_t*)chan->input,s->conf_gran)==s->conf_gran) { if (f->outputs[0]!=NULL) { /* send in pin0 */ mblk_t *m=allocb(s->conf_gran,0); memcpy(m->b_wptr, chan->input, s->conf_gran); m->b_wptr+=s->conf_gran; ms_queue_put(f->outputs[0],m); } } } if (chan0->is_used==TRUE) { while (ms_bufferizer_read(&chan0->buff,(uint8_t*)chan0->input,s->conf_gran)==s->conf_gran) { if (f->outputs[i]!=NULL) { /* send in pinI */ mblk_t *m=allocb(s->conf_gran,0); memcpy(m->b_wptr, chan0->input, s->conf_gran); m->b_wptr+=s->conf_gran; ms_queue_put(f->outputs[i],m); } } } break; } } }}static void conf_postprocess(MSFilter *f){ int i; ConfState *s=(ConfState*)f->data; for (i=0;i<CONF_MAX_PINS;i++) channel_uninit(&s->channels[i]); for (i=0;i<CONF_MAX_PINS;i++) channel_init(s, &s->channels[i], i);}static int msconf_set_sr(MSFilter *f, void *arg){ ConfState *s=(ConfState*)f->data; int i; s->samplerate = *(int*)arg; s->conf_gran = ((16 * s->samplerate) / 800) *2; s->conf_nsamples=s->conf_gran/2; for (i=0;i<CONF_MAX_PINS;i++) channel_uninit(&s->channels[i]); for (i=0;i<CONF_MAX_PINS;i++) channel_init(s, &s->channels[i], i); return 0;}static int msconf_enable_directmode(MSFilter *f, void *arg){ ConfState *s=(ConfState*)f->data; s->enable_directmode = *(int*)arg; return 0;}static int msconf_enable_agc(MSFilter *f, void *arg){ ConfState *s=(ConfState*)f->data; int i; s->agc_level = *(int*)arg; for (i=0;i<CONF_MAX_PINS;i++) channel_uninit(&s->channels[i]); for (i=0;i<CONF_MAX_PINS;i++) channel_init(s, &s->channels[i], i); return 0;}static int msconf_enable_halfduplex(MSFilter *f, void *arg){ ConfState *s=(ConfState*)f->data; int i; s->enable_halfduplex = *(int*)arg; for (i=0;i<CONF_MAX_PINS;i++) channel_uninit(&s->channels[i]); for (i=0;i<CONF_MAX_PINS;i++) channel_init(s, &s->channels[i], i); return 0;}static int msconf_set_vad_prob_start(MSFilter *f, void *arg){ ConfState *s=(ConfState*)f->data; int i; s->vad_prob_start = *(int*)arg; for (i=0;i<CONF_MAX_PINS;i++) channel_uninit(&s->channels[i]); for (i=0;i<CONF_MAX_PINS;i++) channel_init(s, &s->channels[i], i); return 0;}static int msconf_set_vad_prob_continue(MSFilter *f, void *arg){ ConfState *s=(ConfState*)f->data; int i; s->vad_prob_continue = *(int*)arg; for (i=0;i<CONF_MAX_PINS;i++) channel_uninit(&s->channels[i]); for (i=0;i<CONF_MAX_PINS;i++) channel_init(s, &s->channels[i], i); return 0;}static int msconf_enable_vad(MSFilter *f, void *arg){ ConfState *s=(ConfState*)f->data; int i; s->enable_vad = *(int*)arg; for (i=0;i<CONF_MAX_PINS;i++) channel_uninit(&s->channels[i]); for (i=0;i<CONF_MAX_PINS;i++) channel_init(s, &s->channels[i], i); return 0;}static int msconf_get_stat_discarded(MSFilter *f, void *arg){ ConfState *s=(ConfState*)f->data; Channel *chan; int i; i = *(int*)arg; /*read from all inputs and put into bufferizers*/ if (i<0 || i>CONF_MAX_PINS) return -1; if (f->inputs[i]!=NULL){ chan=&s->channels[i]; return chan->stat_discarded; } return -1;}static int msconf_get_stat_missed(MSFilter *f, void *arg){ ConfState *s=(ConfState*)f->data; Channel *chan; int i; i = *(int*)arg; /*read from all inputs and put into bufferizers*/ if (i<0 || i>CONF_MAX_PINS) return -1; if (f->inputs[i]!=NULL){ chan=&s->channels[i]; return chan->stat_missed; } return -1;}static int msconf_get_stat_processed(MSFilter *f, void *arg){ ConfState *s=(ConfState*)f->data; Channel *chan; int i; i = *(int*)arg; /*read from all inputs and put into bufferizers*/ if (i<0 || i>CONF_MAX_PINS) return -1; if (f->inputs[i]!=NULL){ chan=&s->channels[i]; return chan->stat_processed; } return -1;}static MSFilterMethod msconf_methods[]={ { MS_FILTER_SET_SAMPLE_RATE, msconf_set_sr }, { MS_FILTER_ENABLE_DIRECTMODE, msconf_enable_directmode }, { MS_FILTER_ENABLE_VAD, msconf_enable_vad }, { MS_FILTER_ENABLE_AGC, msconf_enable_agc }, { MS_FILTER_GET_STAT_DISCARDED, msconf_get_stat_discarded }, { MS_FILTER_GET_STAT_MISSED, msconf_get_stat_missed }, { MS_FILTER_GET_STAT_OUTPUT, msconf_get_stat_processed }, { MS_FILTER_ENABLE_HALFDUPLEX, msconf_enable_halfduplex }, { MS_FILTER_SET_VAD_PROB_START, msconf_set_vad_prob_start }, { MS_FILTER_SET_VAD_PROB_CONTINUE, msconf_set_vad_prob_continue }, { 0 , NULL}};#ifdef _MSC_VERMSFilterDesc ms_conf_desc={ MS_CONF_ID, "MSConf", N_("A filter to make conferencing"), MS_FILTER_OTHER, NULL, CONF_MAX_PINS, CONF_MAX_PINS, conf_init, conf_preprocess, conf_process, conf_postprocess, conf_uninit, msconf_methods};#elseMSFilterDesc ms_conf_desc={ .id=MS_CONF_ID, .name="MSConf", .text=N_("A filter to make conferencing"), .category=MS_FILTER_OTHER, .ninputs=CONF_MAX_PINS, .noutputs=CONF_MAX_PINS, .init=conf_init, .preprocess=conf_preprocess, .process=conf_process, .postprocess=conf_postprocess, .uninit=conf_uninit, .methods=msconf_methods};#endifMS_FILTER_DESC_EXPORT(ms_conf_desc)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -