static void generic_plc_process(MSFilter *f) { generic_plc_struct *mgps=(generic_plc_struct*)f->data; unsigned int buff_size = mgps->rate*sizeof(int16_t)*mgps->nchannels*f->ticker->interval/1000; mblk_t *m; while((m=ms_queue_get(f->inputs[0]))!=NULL){ int transitionBufferSize = mgps->rate*sizeof(int16_t)*TRANSITION_DELAY/1000; unsigned char buf[128]; unsigned int time = (1000*(m->b_wptr - m->b_rptr))/(mgps->rate*sizeof(int16_t)*mgps->nchannels); ms_concealer_inc_sample_time(mgps->concealer, f->ticker->time, time, TRUE); /* introduce 16 sample delay (2ms) */ memcpy(buf, m->b_wptr-transitionBufferSize, transitionBufferSize); memmove(m->b_rptr+transitionBufferSize, m->b_rptr, m->b_wptr - m->b_rptr - transitionBufferSize); memcpy(m->b_rptr, mgps->continuity_buffer, transitionBufferSize); memcpy(mgps->continuity_buffer, buf, transitionBufferSize); if (mgps->cng_running){ /*we were doing CNG, now resuming with normal audio*/ int16_t continuity_buffer[80]; #ifdef HAVE_G729B bcg729Decoder(mgps->decoderChannelContext, NULL, 0, 1, 1, 1, continuity_buffer); #else memset (continuity_buffer, 0, 80*sizeof(int16_t)); #endif memcpy(m->b_rptr, continuity_buffer, transitionBufferSize); generic_plc_transition_mix((int16_t *)(m->b_rptr+transitionBufferSize), &(continuity_buffer[mgps->rate*TRANSITION_DELAY/1000]), mgps->rate*TRANSITION_DELAY/1000); mgps->cng_running=FALSE; mgps->cng_set=FALSE; } ms_queue_put(f->outputs[0], m); } if (ms_concealer_context_is_concealement_required(mgps->concealer, f->ticker->time)) { #ifdef HAVE_G729B m = allocb(buff_size, 0); /* Transmitted CNG data is in mgps->cng_data : give it to bcg729 decoder -> output in m->b_wptr */ if (mgps->cng_set) { /* received some CNG data */ mgps->cng_set=FALSE; /* reset flag */ mgps->cng_running=TRUE; bcg729Decoder(mgps->decoderChannelContext, mgps->cng_data.data, mgps->cng_data.datasize, 0, 1, 1, (int16_t *)(m->b_wptr)); mblk_set_cng_flag(m, 1); generic_plc_transition_mix((int16_t *)m->b_wptr, (int16_t *)mgps->continuity_buffer, mgps->rate*TRANSITION_DELAY/1000); /* TODO: if ticker->interval is not 10 ms which is also G729 frame length, we must generate untransmitted frame CNG until we reach the requested data amount */ } else if (mgps->cng_running) { /* missing frame but CNG is ongoing: shall be an untransmitted frame */ bcg729Decoder(mgps->decoderChannelContext, NULL, 0, 1, 1, 1, (int16_t *)(m->b_wptr)); mblk_set_cng_flag(m, 1); } else { mblk_set_plc_flag(m, 1); memset(m->b_wptr, 0, buff_size); } #else m = allocb(buff_size, 0); if (!mgps->cng_running && mgps->cng_set){ mgps->cng_running=TRUE; mblk_set_cng_flag(m, 1); /*TODO do something with the buffer*/ }else{ mblk_set_plc_flag(m, 1); } memset(m->b_wptr, 0, buff_size); #endif m->b_wptr += buff_size; ms_queue_put(f->outputs[0], m); ms_concealer_inc_sample_time(mgps->concealer, f->ticker->time, f->ticker->interval, FALSE); } }
static void generic_plc_process(MSFilter *f) { generic_plc_struct *mgps=(generic_plc_struct*)f->data; plc_context_t *plc_context = mgps->plc_context; mblk_t *m; while((m=ms_queue_get(f->inputs[0]))!=NULL){ int transitionBufferSize = mgps->rate*sizeof(int16_t)*TRANSITION_DELAY/1000; size_t msg_size = msgdsize(m); unsigned int time = (unsigned int)((1000*msg_size)/(mgps->rate*sizeof(int16_t)*mgps->nchannels)); ms_concealer_inc_sample_time(mgps->concealer, f->ticker->time, time, TRUE); /* Store current msg in plc_buffer */ generic_plc_update_plc_buffer(plc_context, m->b_rptr, msg_size); /* introduce delay (TRANSITION_DELAY ms) */ generic_plc_update_continuity_buffer(plc_context, m->b_rptr, msg_size); if (mgps->cng_running){ /*we were doing CNG, now resuming with normal audio*/ int16_t continuity_buffer[80]; #ifdef HAVE_G729B bcg729Decoder(mgps->decoderChannelContext, NULL, 0, 1, 1, 1, continuity_buffer); #else memset (continuity_buffer, 0, 80*sizeof(int16_t)); #endif memcpy(m->b_rptr, continuity_buffer, transitionBufferSize); generic_plc_transition_mix((int16_t *)(m->b_rptr+transitionBufferSize), continuity_buffer, mgps->rate*TRANSITION_DELAY/1000); mgps->cng_running=FALSE; mgps->cng_set=FALSE; } if (plc_context->plc_samples_used!=0) { /*we were doing PLC, now resuming with normal audio, continuity buffer is twice the transition delay lengths, * the second half is untouched by the update function and contains transition data generated by PLC */ generic_plc_transition_mix((int16_t *)(m->b_rptr+transitionBufferSize), (int16_t *)(plc_context->continuity_buffer+transitionBufferSize), mgps->rate*TRANSITION_DELAY/1000); } plc_context->plc_index=0; plc_context->plc_samples_used=0; ms_queue_put(f->outputs[0], m); } if (ms_concealer_context_is_concealement_required(mgps->concealer, f->ticker->time)) { unsigned int buff_size = mgps->rate*sizeof(int16_t)*mgps->nchannels*f->ticker->interval/1000; #ifdef HAVE_G729B m = allocb(buff_size, 0); /* Transmitted CNG data is in mgps->cng_data : give it to bcg729 decoder -> output in m->b_wptr */ if (mgps->cng_set) { /* received some CNG data */ mgps->cng_set=FALSE; /* reset flag */ mgps->cng_running=TRUE; bcg729Decoder(mgps->decoderChannelContext, mgps->cng_data.data, mgps->cng_data.datasize, 0, 1, 1, (int16_t *)(m->b_wptr)); mblk_set_cng_flag(m, 1); generic_plc_transition_mix((int16_t *)m->b_wptr, (int16_t *)plc_context->continuity_buffer, mgps->rate*TRANSITION_DELAY/1000); /* TODO: if ticker->interval is not 10 ms which is also G729 frame length, we must generate untransmitted frame CNG until we reach the requested data amount */ } else if (mgps->cng_running) { /* missing frame but CNG is ongoing: shall be an untransmitted frame */ bcg729Decoder(mgps->decoderChannelContext, NULL, 0, 1, 1, 1, (int16_t *)(m->b_wptr)); mblk_set_cng_flag(m, 1); } else { /* plc */ mblk_set_plc_flag(m, 1); generic_plc_generate_samples(plc_context, (int16_t *)m->b_wptr, buff_size/sizeof(int16_t)); /* store the generated samples into plc_buffer */ generic_plc_update_plc_buffer(plc_context, m->b_wptr, buff_size); //memset(m->b_wptr, 0, buff_size); } #else m = allocb(buff_size, 0); if (mgps->cng_set){ mgps->cng_set=FALSE; /* reset flag */ mgps->cng_running=TRUE; mblk_set_cng_flag(m, 1); /*TODO do something with the buffer*/ memset(m->b_wptr, 0, buff_size); } else if (mgps->cng_running) { /* missing frame but CNG is ongoing: shall be an untransmitted frame */ memset(m->b_wptr, 0, buff_size); mblk_set_cng_flag(m, 1); }else{ /* plc */ mblk_set_plc_flag(m, 1); generic_plc_generate_samples(plc_context, (int16_t *)m->b_wptr, buff_size/sizeof(int16_t)); /* store the generated samples into plc_buffer */ generic_plc_update_plc_buffer(plc_context, m->b_wptr, buff_size); //memset(m->b_wptr, 0, buff_size); } #endif m->b_wptr += buff_size; ms_queue_put(f->outputs[0], m); ms_concealer_inc_sample_time(mgps->concealer, f->ticker->time, f->ticker->interval, FALSE); } }