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);
	}
}
示例#2
0
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);
	}
}